From 66935e66ced53e85f4b86da928bbcf6fcbda3b35 Mon Sep 17 00:00:00 2001 From: bartool Date: Sun, 26 Mar 2023 01:53:19 +0100 Subject: [PATCH] driver: mcp41x --- firmware/func_gen_stm32f303re_nucleo/Makefile | 4 + firmware/shared_libs/drivers/mcp41x/mcp41x.c | 74 +++++++++++++++++++ firmware/shared_libs/drivers/mcp41x/mcp41x.h | 50 +++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 firmware/shared_libs/drivers/mcp41x/mcp41x.c create mode 100644 firmware/shared_libs/drivers/mcp41x/mcp41x.h diff --git a/firmware/func_gen_stm32f303re_nucleo/Makefile b/firmware/func_gen_stm32f303re_nucleo/Makefile index 8db43f6..9ac5855 100644 --- a/firmware/func_gen_stm32f303re_nucleo/Makefile +++ b/firmware/func_gen_stm32f303re_nucleo/Makefile @@ -71,6 +71,8 @@ Core/Src/i2c.c C_SOURCES += ../shared_libs/drivers/ad9833/ad9833.c # ltc2631 C_SOURCES += ../shared_libs/drivers/ltc2631/ltc2631.c +# mcp41x +C_SOURCES += ../shared_libs/drivers/mcp41x/mcp41x.c # ASM sources ASM_SOURCES = \ @@ -137,6 +139,8 @@ C_INCLUDES = \ C_INCLUDES += -I../shared_libs/drivers/ad9833 # ltc2631 includes C_INCLUDES += -I../shared_libs/drivers/ltc2631 +# mcp41x includes +C_INCLUDES += -I../shared_libs/drivers/mcp41x # compile gcc flags ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections diff --git a/firmware/shared_libs/drivers/mcp41x/mcp41x.c b/firmware/shared_libs/drivers/mcp41x/mcp41x.c new file mode 100644 index 0000000..83b616d --- /dev/null +++ b/firmware/shared_libs/drivers/mcp41x/mcp41x.c @@ -0,0 +1,74 @@ +#include "main.h" +#include "mcp41x.h" + +static uint32_t pot_value[MCP41X_RES_MAX] = {10000, 50000, 100000}; + +static void mcp41x_transmit(mcp41x_handle_t *hpot, uint8_t *data) +{ + HAL_GPIO_WritePin(hpot->cs_port, hpot->cs_pin, GPIO_PIN_RESET); + HAL_SPI_Transmit(hpot->hspi, data, 2, 1); + HAL_GPIO_WritePin(hpot->cs_port, hpot->cs_pin, GPIO_PIN_SET); +} + +void mcp41x_init(mcp41x_handle_t *hpot, SPI_HandleTypeDef *hspi, GPIO_TypeDef *cs_port, uint16_t cs_pin, mcp41x_res_t res) +{ + hpot->hspi = hspi; + hpot->cs_port = cs_port; + hpot->cs_pin = cs_pin; + hpot->max_res = res; + hpot->dir = MCP41X_ATOB; +} + +void mcp41x_setValue(mcp41x_handle_t *hpot, uint8_t value) +{ + if (hpot->dir == MCP41X_BTOA) + { + value = 255 - value; + } + + hpot->value = value; + uint8_t data[2] = {MCP41X_WRITE0, value}; + mcp41x_transmit(hpot, data); +} + +void mcp41x_setVolume(mcp41x_handle_t *hpot, uint8_t volume) +{ + if (volume > 100) + { + volume = 100; + } + uint32_t value = volume * 255U / 100U; + mcp41x_setValue(hpot, value); +} + +uint8_t mcp41x_getVolume(mcp41x_handle_t *hpot) +{ + return hpot->value * 100U / 255U; +} + +void mcp41x_setResistance(mcp41x_handle_t *hpot, uint32_t resistance) +{ + if (resistance > pot_value[hpot->max_res]) + { + resistance = pot_value[hpot->max_res]; + } + + uint32_t value = resistance * 255U / pot_value[hpot->max_res]; + mcp41x_setValue(hpot, value); +} + +uint32_t mcp41x_getResistance(mcp41x_handle_t *hpot) +{ + return hpot->value * pot_value[hpot->max_res] / 255; +} + +void mcp41x_setWiperDir(mcp41x_handle_t *hpot, mcp41x_dir_t dir) +{ + hpot->dir = dir; +} + +void mcp41x_sleep(mcp41x_handle_t *hpot) +{ + uint8_t data[2] = {MCP41X_SLEEP, 0}; + mcp41x_transmit(hpot, data); +} \ No newline at end of file diff --git a/firmware/shared_libs/drivers/mcp41x/mcp41x.h b/firmware/shared_libs/drivers/mcp41x/mcp41x.h new file mode 100644 index 0000000..7a53452 --- /dev/null +++ b/firmware/shared_libs/drivers/mcp41x/mcp41x.h @@ -0,0 +1,50 @@ +#pragma once + +#define MCP41X_C1 5 +#define MCP41X_C0 4 +#define MCP41X_P1 1 +#define MCP41X_P0 0 + +#define MCP41X_SHUTDOWN_BIT (1 << MCP41X_C1) +#define MCP41X_WRITE_BIT (1 << MCP41X_C0) +#define MCP41X_POT0_BIT (1 << MCP41X_P0) +#define MCP41X_POT1_BIT (1 << MCP41X_P1) + +#define MCP41X_SLEEP (MCP41X_SHUTDOWN_BIT | MCP41X_POT0_BIT | MCP41X_POT0_BIT) +#define MCP41X_WRITE0 (MCP41X_WRITE_BIT | MCP41X_POT0_BIT) +#define MCP41X_WRITE1 (MCP41X_WRITE_BIT | MCP41X_POT1_BIT) + +typedef enum +{ + MCP41X_ATOB, + MCP41X_BTOA +} mcp41x_dir_t; + +typedef enum +{ + MCP41X_10K, + MCP41X_50K, + MCP41X_100K, + MCP41X_RES_MAX +} mcp41x_res_t; + +typedef struct +{ + mcp41x_res_t max_res; + mcp41x_dir_t dir; + + uint8_t value; + + SPI_HandleTypeDef *hspi; + GPIO_TypeDef *cs_port; + uint16_t cs_pin; +} mcp41x_handle_t; + +void mcp41x_init(mcp41x_handle_t *hpot, SPI_HandleTypeDef *hspi, GPIO_TypeDef *cs_port, uint16_t cs_pin, mcp41x_res_t res); +void mcp41x_setValue(mcp41x_handle_t *hpot, uint8_t value); +void mcp41x_setVolume(mcp41x_handle_t *hpot, uint8_t volume); +uint8_t mcp41x_getVolume(mcp41x_handle_t *hpot); +void mcp41x_setResistance(mcp41x_handle_t *hpot, uint32_t resistance); +uint32_t mcp41x_getResistance(mcp41x_handle_t *hpot); +void mcp41x_setWiperDir(mcp41x_handle_t *hpot, mcp41x_dir_t dir); +void mcp41x_sleep(mcp41x_handle_t *hpot); \ No newline at end of file