muele/red/mod-io2/src/mod_io2.h

209 lines
7.1 KiB
C++

#ifndef __MOD_IO2_H
#define __MOD_IO2_H
#include <ch32v00x.h>
#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 */