209 lines
7.1 KiB
C++
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 */
|