#ifndef __MOD_IO2_H #define __MOD_IO2_H #include #include "i2c_slave.h" #define MOD_IO2_ADDRESS 0x21 #define MOD_IO2_BOARD_ID 0x23 #define MOD_IO2_VER_MAJOR 0x5 #define MOD_IO2_VER_MINOR 0x0 #define MOD_IO2_REG_COUNT 21 #define MOD_IO2_GPIO_COUNT 7 #define MOD_IO2_RELAY_COUNT 2 #define MOD_IO2_RELAY_MASK 0x03 #define MOD_IO2_ADC_TIMEOUT 100 //#define MOD_IO2_ADC_VOLTAGE #define MOD_IO2_PWM_COUNT 3 typedef enum { MOD_IO2_SET_DIR = 0x01, MOD_IO2_SET_OUT = 0x02, MOD_IO2_GET_IN = 0x03, MOD_IO2_SET_PULL_UP = 0x04, MOD_IO2_GET_ANALOG0 = 0x10, MOD_IO2_GET_ANALOG1 = 0x11, MOD_IO2_GET_ANALOG2 = 0x12, MOD_IO2_GET_ANALOG3 = 0x13, MOD_IO2_GET_ANALOG4 = 0x14, MOD_IO2_GET_ANALOG5 = 0x15, MOD_IO2_GET_ANALOG6 = 0x16, MOD_IO2_GET_BOARD_ID = 0x20, MOD_IO2_GET_VERSION = 0x21, MOD_IO2_RELAY_STATE = 0x40, MOD_IO2_RELAY_ON = 0x41, MOD_IO2_RELAY_OFF = 0x42, MOD_IO2_RELAY_STATE_GET = 0x43, MOD_IO2_SET_PWM_OFF = 0x50, MOD_IO2_SET_PWM1 = 0x51, MOD_IO2_SET_PWM2 = 0x52, MOD_IO2_SET_ADDRESS = 0xF0, } MOD_IO2_REG_Type; /* MOD-IO2 Reg Mapping */ typedef struct { uint8_t reg; i2c_read_callback_t onRead; i2c_write_callback_t onWrite; } MOD_IO2_REG_Map_Type; /* MOD-IO2 GPIO Mapping */ typedef struct { GPIO_TypeDef* port; uint16_t pin; uint8_t adc; TIM_TypeDef * tim; uint8_t tch; } MOD_IO2_GPIO_Map_Type; /* MOD-IO2 PWM Mapping */ typedef struct { uint8_t gpio; } MOD_IO2_PWM_Map_Type; class MOD_IO2 { protected: inline static uint8_t i2c_address = MOD_IO2_ADDRESS; static void onSetDir(uint8_t reg, uint8_t offset, uint8_t data); static uint8_t onGetDir(uint8_t reg, uint8_t offset); static void onSetPullUp(uint8_t reg, uint8_t offset, uint8_t data); static uint8_t onGetPullUp(uint8_t reg, uint8_t offset); static void onSetLevel(uint8_t reg, uint8_t offset, uint8_t data); static uint8_t onGetLevel(uint8_t reg, uint8_t offset); static uint8_t onAnalogGet(uint8_t reg, uint8_t offset); static uint8_t onGetBoardID(uint8_t reg, uint8_t offset); static uint8_t onGetVersion(uint8_t reg, uint8_t offset); static uint8_t onGetRelayState(uint8_t reg, uint8_t offset); static void onSetRelayState(uint8_t reg, uint8_t offset, uint8_t data); static void onRelayOn(uint8_t reg, uint8_t offset, uint8_t data); static void onRelayOff(uint8_t reg, uint8_t offset, uint8_t data); static uint8_t onGetRelayOff(uint8_t reg, uint8_t offset); static void onSetPWM(uint8_t reg, uint8_t offset, uint8_t data); static void onSetAddress(uint8_t reg, uint8_t offset, uint8_t data); inline static const MOD_IO2_REG_Map_Type REG_MAP[MOD_IO2_REG_COUNT] = { {.reg = MOD_IO2_SET_DIR, .onRead = onGetDir, .onWrite = onSetDir}, {.reg = MOD_IO2_SET_OUT, .onRead = onGetLevel, .onWrite = onSetLevel}, {.reg = MOD_IO2_GET_IN, .onRead = onGetLevel, .onWrite = NULL}, {.reg = MOD_IO2_SET_PULL_UP, .onRead = onGetPullUp, .onWrite = onSetPullUp}, // Analog input {.reg = MOD_IO2_GET_ANALOG0, .onRead = onAnalogGet, .onWrite = NULL}, {.reg = MOD_IO2_GET_ANALOG5, .onRead = onAnalogGet, .onWrite = NULL}, {.reg = MOD_IO2_GET_ANALOG6, .onRead = onAnalogGet, .onWrite = NULL}, {.reg = MOD_IO2_GET_BOARD_ID, .onRead = onGetBoardID, .onWrite = NULL}, {.reg = MOD_IO2_GET_VERSION, .onRead = onGetVersion, .onWrite = NULL}, {.reg = MOD_IO2_RELAY_STATE, .onRead = onGetRelayState, .onWrite = onSetRelayState}, {.reg = MOD_IO2_RELAY_ON, .onRead = onGetRelayState, .onWrite = onRelayOn}, {.reg = MOD_IO2_RELAY_OFF, .onRead = onGetRelayOff, .onWrite = onRelayOff}, {.reg = MOD_IO2_RELAY_STATE_GET, .onRead = onGetRelayState, .onWrite = NULL}, // PWM {.reg = MOD_IO2_SET_PWM_OFF, .onRead = NULL, .onWrite = onSetPWM}, {.reg = MOD_IO2_SET_PWM1, .onRead = NULL, .onWrite = onSetPWM}, {.reg = MOD_IO2_SET_PWM2, .onRead = NULL, .onWrite = onSetPWM}, // DAC is NOT available {.reg = 0x60, .onRead = NULL, .onWrite = NULL}, {.reg = MOD_IO2_SET_ADDRESS, .onRead = NULL, .onWrite = onSetAddress}, }; inline static const MOD_IO2_GPIO_Map_Type PGM1_JUMPER = { .port = GPIOD, .pin = GPIO_Pin_1, .adc = 255, .tim = NULL, .tch = 255 }; // GPIO map inline static const MOD_IO2_GPIO_Map_Type GPIO_MAP[MOD_IO2_GPIO_COUNT] = { {.port = GPIOC, .pin = GPIO_Pin_4, .adc = 2, .tim = NULL, .tch = 255}, // GPIO0 - PC4 {.port = GPIOC, .pin = GPIO_Pin_5, .adc = 255, .tim = NULL, .tch = 255}, // GPIO1 - PC5 {.port = GPIOC, .pin = GPIO_Pin_6, .adc = 255, .tim = NULL, .tch = 255}, // GPIO2 - PC6 {.port = GPIOC, .pin = GPIO_Pin_7, .adc = 255, .tim = NULL, .tch = 255}, // GPIO3 - PC7 {.port = GPIOC, .pin = GPIO_Pin_0, .adc = 255, .tim = NULL, .tch = 255}, // GPIO4 - PC0 {.port = GPIOD, .pin = GPIO_Pin_3, .adc = 4, .tim = TIM2, .tch = 2}, // GPIO5 - PD3 - A4 - T2CH2 {.port = GPIOD, .pin = GPIO_Pin_2, .adc = 3, .tim = TIM1, .tch = 1}, // GPIO6 - PD2 - A3 - T1CH1 }; // GPIO cofiguration inline static GPIOMode_TypeDef gpio_config[MOD_IO2_GPIO_COUNT] = { GPIO_Mode_IN_FLOATING, // GPIO0 GPIO_Mode_IN_FLOATING, // GPIO1 GPIO_Mode_IN_FLOATING, // GPIO2 GPIO_Mode_IN_FLOATING, // GPIO3 GPIO_Mode_IN_FLOATING, // GPIO4 GPIO_Mode_IN_FLOATING, // GPIO5 GPIO_Mode_IN_FLOATING, // GPIO6 }; // RELAY map inline static const MOD_IO2_GPIO_Map_Type RELAY_MAP[MOD_IO2_RELAY_COUNT] = { {.port = GPIOA, .pin = GPIO_Pin_1}, // RELAY1 {.port = GPIOA, .pin = GPIO_Pin_2}, // RELAY2 }; // PWM map inline static const MOD_IO2_PWM_Map_Type PWM_MAP[MOD_IO2_PWM_COUNT] = { {.gpio = 255}, // PWM0 {.gpio = 6}, // PWM1 {.gpio = 5}, // PWM2 }; // MOD_IO2 state inline static const MOD_IO2_REG_Map_Type* i2c_reg = NULL; inline static uint8_t gpio_direction = 0x7F; inline static uint8_t gpio_pullup = 0x00; inline static uint8_t gpio_state = 0x00; inline static bool adc_error = false; inline static uint16_t adc_value = 0x0000; inline static uint16_t adc_voltage = 0x0000; inline static uint8_t relay_state = 0x00; static void Begin(); static void GPIOConfig(uint8_t gpio, GPIOMode_TypeDef mode, bool initial = false); static void GPIOSet(uint8_t gpio, BitAction level); static uint8_t GPIOGet(uint8_t gpio); static void RelayConfig(uint8_t relay); static void RelaySet(uint8_t relay, BitAction level); static void PWMDisable(TIM_TypeDef *TIM); static void PWMConfig(TIM_TypeDef *TIM, uint8_t channel, uint16_t pulse); public: static void Setup(); static void Setup(uint8_t addr); static void onRegisterSet(uint8_t reg); static uint8_t onRegRead(uint8_t reg, uint8_t offset); static void onRegWrite(uint8_t reg, uint8_t offset, uint8_t data); }; #endif /* __MOD_IO2_H */