diff --git a/adc_drv.c b/adc_drv.c index 71751dc..18d54f1 100644 --- a/adc_drv.c +++ b/adc_drv.c @@ -1,11 +1,10 @@ #include "adc_drv.h" - #if (DEF_ADS8691_ENABLED) #include "ads8691.h" extern const adc_drv_if_t ads8691; static const adc_drv_if_t *p_inst = &ads8691; -#else +#else #include "builtin_saadc.h" static const adc_drv_if_t *p_inst = &builtin_saadc; #endif @@ -48,6 +47,25 @@ int adc_read(uint32_t channel, int32_t *adc_val) return p_inst->read(channel, adc_val); } +int adc_read_mutiple_channels(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt) +{ + if (p_inst == NULL) + { + return ADC_DRV_ERROR; + } + return p_inst->read_multiple_channels(p_channel, p_adc_val, cnt); +} + +int adc_read_mutiple_channels_ex(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt, void (*preliminary_action)(void)) +{ + if (p_inst == NULL) + { + return ADC_DRV_ERROR; + } + return p_inst->read_multiple_channels_ex(p_channel, p_adc_val, cnt, preliminary_action); +} + + int adc_read_milivolt(uint32_t channel, float *mv) { if (p_inst == NULL) diff --git a/adc_drv.h b/adc_drv.h index 8901de5..fbd4c05 100644 --- a/adc_drv.h +++ b/adc_drv.h @@ -2,8 +2,8 @@ #ifndef __ADC_DRV_H__ #define __ADC_DRV_H__ -#include "app_config.h" #include "adc_drv_if.h" +#include "app_config.h" #define ADC_DRV_ERROR (-1) #define ADC_DRV_SUCCESS (0) @@ -23,12 +23,16 @@ int adc_reset(void); int adc_gain(adc_gain_t gain); int adc_read(uint32_t channel, int32_t *adc_val); int adc_read_milivolt(uint32_t channel, float *mv); +int adc_read_mutiple_channels(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt); +int adc_read_mutiple_channels_ex(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt, void (*preliminary_action)(void)); #else #define adc_init() #define adc_reset() #define adc_gain(x) #define adc_read(x, y) #define adc_read_milivolt(x, y) +#define adc_read_mutiple_channels(x, y, z) +#define adc_read_mutiple_channels_ex(x, y, z, a) #endif /* ! DEF_ADC_DRV_ENABLED */ #endif // !__ADC_DRV_H__ diff --git a/adc_drv_if.h b/adc_drv_if.h index 8d97d14..362bdf7 100644 --- a/adc_drv_if.h +++ b/adc_drv_if.h @@ -31,6 +31,8 @@ typedef struct int (*reset)(void); int (*read)(uint32_t channel, int32_t *adc_val); int (*read_milivolt)(uint32_t channel, float *adc_val); + int (*read_multiple_channels)(uint32_t *p_channels, int32_t *adc_val, uint32_t count); + int (*read_multiple_channels_ex)(uint32_t *p_channels, int32_t *adc_val, uint32_t count, void (*preliminary_action)(void)); int (*gain)(adc_gain_t gain); } adc_drv_if_t; diff --git a/app_config.h b/app_config.h index 976e5d2..939f07e 100644 --- a/app_config.h +++ b/app_config.h @@ -104,7 +104,8 @@ extern "C" // BLE device name #define DEF_ELITE_EDC_20 0x00020109 -#define DEF_ELITE_MODEL DEF_ELITE_EDC_20 +#define DEF_PULSE_E_LOAD_01 0x00070000 +#define DEF_ELITE_MODEL DEF_PULSE_E_LOAD_01 #if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20) #define ELITE_DEVICE_NAME "Elite-EDC" @@ -132,6 +133,23 @@ extern "C" #define DEF_RTT_JSCOP_ENABLED 0 +#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01) + +#define ELITE_DEVICE_NAME "Pulse-E-Load" +#define MAJOR_PRODUCT_NUMBER 0 +#define MINOR_PRODUCT_NUMBER 7 +#define MAJOR_VERSION_NUMBER 0 +#define MINOR_VERSION_NUMBER 0 + +#define DEF_FS_ENABLED 0 +#define DEF_FS_RTT_DIR 0 +#define DEF_GD25D10C_ENABLED 0 + +#define DEF_ADC_DRV_ENABLED 1 +#define DEF_BULTIN_ADC_ENABED 1 + +#define DEF_RTT_JSCOP_ENABLED 0 + #endif #define BLE_ELITE_SRV_ENABLED 1 diff --git a/bmd380_peripheral.vcxproj b/bmd380_peripheral.vcxproj index 92c9a47..633e0e0 100644 --- a/bmd380_peripheral.vcxproj +++ b/bmd380_peripheral.vcxproj @@ -205,6 +205,8 @@ + + @@ -375,6 +377,8 @@ + + diff --git a/builtin_saadc.c.c b/builtin_saadc.c.c index b284215..fb80411 100644 --- a/builtin_saadc.c.c +++ b/builtin_saadc.c.c @@ -8,10 +8,27 @@ static uint32_t m_gain = NRF_SAADC_GAIN1_6; static int read(uint32_t channel, int32_t *adc_val); static int init(void) { - NRF_SAADC->ENABLE = 0; - NRF_SAADC->TASKS_STOP = 1; + /* enable ssadc */ + NRF_SAADC->ENABLE = 1; + /* stop ssadc */ + NRF_SAADC->EVENTS_STOPPED = 0; + NRF_SAADC->TASKS_STOP = 1; + do { + } while (NRF_SAADC->EVENTS_STOPPED == 0); + /* config resolution */ NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_14bit; - NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_4X; + /* auto calibration ssadc */ + NRF_SAADC->EVENTS_CALIBRATEDONE = 0; + NRF_SAADC->TASKS_CALIBRATEOFFSET = 1; + do { + } while (NRF_SAADC->EVENTS_CALIBRATEDONE == 0); + /* disable ssadc */ + NRF_SAADC->ENABLE = 0; + /* stop ssadc */ + NRF_SAADC->EVENTS_STOPPED = 0; + NRF_SAADC->TASKS_STOP = 1; + do { + } while (NRF_SAADC->EVENTS_STOPPED == 0); return 0; } @@ -64,25 +81,38 @@ static double adc_convert_volt(uint16_t range_sel, int32_t val_14bit, bool is_di break; } - // differential V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 1) ¡V V(N) - // single end V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 0) + // differential V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 1) - V(N) + // single end V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 0) volt = ((double)val_14bit) * (vref / gain) / (0x01 << (14 - m)); + /* NRF_LOG_INFO("adc_convert_volt(input_range_idx:%d, val_14bit:%d)", range_sel, val_14bit); { char str[32]; snprintf(str, sizeof(str), "%.16lf", volt); NRF_LOG_INFO("adc_convert_result: %sV", str); } - + */ return volt; } static int read(uint32_t channel, int32_t *adc_val) { - NRF_SAADC->TASKS_STOP = 1; - NRF_SAADC->ENABLE = 0; + /* disable ssadc */ + NRF_SAADC->ENABLE = 0; + /* stop ssadc */ + NRF_SAADC->EVENTS_STOPPED = 0; + NRF_SAADC->TASKS_STOP = 1; + do { + } while (NRF_SAADC->EVENTS_STOPPED == 0); + /* + ref: p.381, nrf52840_PS_v1.1.pdf + Note: Oversampling should only be used when a single input channel is enabled, as averaging is + performed over all enabled channels. + */ + NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_DISABLED; + /* config analog input */ NRF_SAADC->CH[0].PSELP = NRF_SAADC_INPUT_AIN0 + channel; NRF_SAADC->CH[0].PSELN = NRF_SAADC_INPUT_DISABLED; NRF_SAADC->CH[0].CONFIG = @@ -93,22 +123,158 @@ static int read(uint32_t channel, int32_t *adc_val) (NRF_SAADC_ACQTIME_40US << SAADC_CH_CONFIG_TACQ_Pos) | (NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) | (NRF_SAADC_BURST_ENABLED << SAADC_CH_CONFIG_BURST_Pos); - + /* enable ssadc */ NRF_SAADC->ENABLE = 1; - - uint16_t val = 0; - NRF_SAADC->RESULT.PTR = (uint32_t)&val; - NRF_SAADC->RESULT.MAXCNT = 1; - NRF_SAADC->EVENTS_RESULTDONE = 0; - NRF_SAADC->TASKS_START = 1; - NRF_SAADC->TASKS_SAMPLE = 1; + /* read single channel */ + uint16_t val = 0; + NRF_SAADC->RESULT.PTR = (uint32_t)&val; + NRF_SAADC->RESULT.MAXCNT = 1; + NRF_SAADC->EVENTS_END = 0; + NRF_SAADC->TASKS_SAMPLE = 1; + NRF_SAADC->TASKS_START = 1; do { - } while (NRF_SAADC->EVENTS_RESULTDONE == 0); + } while (NRF_SAADC->EVENTS_END == 0); + /* disable ssadc */ + NRF_SAADC->ENABLE = 0; + /* stop ssadc */ + NRF_SAADC->TASKS_STOP = 1; + /* copy value */ *adc_val = val; adc_convert_volt(m_gain, *adc_val, 0); return 0; } +static int read_channels(uint32_t *p_channel, int32_t *adc_val, uint32_t count) +{ + /* disable ssadc */ + NRF_SAADC->ENABLE = 0; + /* stop ssadc */ + NRF_SAADC->EVENTS_STOPPED = 0; + NRF_SAADC->TASKS_STOP = 1; + do { + } while (NRF_SAADC->EVENTS_STOPPED == 0); + /* + ref: p.381, nrf52840_PS_v1.1.pdf + Note: Oversampling should only be used when a single input channel is enabled, as averaging is + performed over all enabled channels. + */ + NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_DISABLED; + /* config analog inputs */ + for (uint32_t i = 0; i < COUNTOF(NRF_SAADC->CH); i++) + { + if (i < count) + { + NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_AIN0 + p_channel[i]; + NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED; + NRF_SAADC->CH[i].CONFIG = + (NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESP_Pos) | + (NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESN_Pos) | + (m_gain << SAADC_CH_CONFIG_GAIN_Pos) | + (NRF_SAADC_REFERENCE_INTERNAL << SAADC_CH_CONFIG_REFSEL_Pos) | + (NRF_SAADC_ACQTIME_40US << SAADC_CH_CONFIG_TACQ_Pos) | + (NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) | + (NRF_SAADC_BURST_ENABLED << SAADC_CH_CONFIG_BURST_Pos); + } + else + { + NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_DISABLED; + NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED; + NRF_SAADC->CH[i].CONFIG = 0; + } + } + /* enable ssadc */ + NRF_SAADC->ENABLE = 1; + /* start convert */ + uint16_t val[16] = { 0 }; + NRF_SAADC->RESULT.PTR = (uint32_t)&val[0]; + NRF_SAADC->RESULT.MAXCNT = count; + NRF_SAADC->EVENTS_END = 0; + NRF_SAADC->TASKS_SAMPLE = 1; + NRF_SAADC->TASKS_START = 1; + do { + } while (NRF_SAADC->EVENTS_END == 0); + /* disable ssadc */ + NRF_SAADC->ENABLE = 0; + /* stop ssadc */ + NRF_SAADC->TASKS_STOP = 1; + /* copy values */ + for (uint32_t i = 0; i < count; i++) + { + adc_val[i] = val[i]; + } + return 0; +} + +static int read_channels_ex(uint32_t *p_channel, int32_t *adc_val, uint32_t count, void (*preliminary_callback)(void)) +{ + /* disable ssadc */ + NRF_SAADC->ENABLE = 0; + /* stop ssadc */ + NRF_SAADC->EVENTS_STOPPED = 0; + NRF_SAADC->TASKS_STOP = 1; + do { + } while (NRF_SAADC->EVENTS_STOPPED == 0); + /* + ref: p.381, nrf52840_PS_v1.1.pdf + Note: Oversampling should only be used when a single input channel is enabled, as averaging is + performed over all enabled channels. + */ + NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_DISABLED; + /* config analog inputs */ + for (uint32_t i = 0; i < COUNTOF(NRF_SAADC->CH); i++) + { + if (i < count) + { + NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_AIN0 + p_channel[i]; + NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED; + NRF_SAADC->CH[i].CONFIG = + (NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESP_Pos) | + (NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESN_Pos) | + (m_gain << SAADC_CH_CONFIG_GAIN_Pos) | + (NRF_SAADC_REFERENCE_INTERNAL << SAADC_CH_CONFIG_REFSEL_Pos) | + (NRF_SAADC_ACQTIME_40US << SAADC_CH_CONFIG_TACQ_Pos) | + (NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) | + (NRF_SAADC_BURST_ENABLED << SAADC_CH_CONFIG_BURST_Pos); + } + else + { + NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_DISABLED; + NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED; + NRF_SAADC->CH[i].CONFIG = 0; + } + } + /* enable ssadc */ + NRF_SAADC->ENABLE = 1; + /* disable irq */ + __disable_irq(); + /* do preliminary job */ + if (preliminary_callback) + { + preliminary_callback(); + } + /* start convert */ + uint16_t val[COUNTOF(NRF_SAADC->CH)] = { 0 }; + NRF_SAADC->RESULT.PTR = (uint32_t)&val[0]; + NRF_SAADC->RESULT.MAXCNT = count; + NRF_SAADC->EVENTS_END = 0; + NRF_SAADC->TASKS_SAMPLE = 1; + NRF_SAADC->TASKS_START = 1; + /* enabl irq */ + __enable_irq(); + do { + } while (NRF_SAADC->EVENTS_END == 0); + /* disable ssadc */ + NRF_SAADC->ENABLE = 0; + /* stop ssadc */ + NRF_SAADC->TASKS_STOP = 1; + /* copy values */ + for (uint32_t i = 0; i < count; i++) + { + adc_val[i] = val[i]; + } + return 0; +} + static int gain(adc_gain_t gain) { int ret; @@ -155,8 +321,10 @@ static int gain(adc_gain_t gain) } const adc_drv_if_t builtin_saadc = { - .init = init, - .reset = reset, - .read = read, - .gain = gain + .init = init, + .reset = reset, + .read = read, + .gain = gain, + .read_multiple_channels = read_channels, + .read_multiple_channels_ex = read_channels_ex, }; diff --git a/elite.c b/elite.c index 8091d99..01d24e9 100644 --- a/elite.c +++ b/elite.c @@ -2,6 +2,8 @@ #if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20) #include "edc.h" +#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01) +#include "pel.h" #else #error "Unknown DEF_ELITE_MODEL" #endif @@ -97,6 +99,8 @@ void elite_init(void) #if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20) edc.init(); p_instance = edc.p_elite_instance; +#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01) + p_instance = pel_init(); #else #error "Unknown DEF_ELITE_MODEL" #endif diff --git a/elite_board.c b/elite_board.c index c576060..53b5e2d 100644 --- a/elite_board.c +++ b/elite_board.c @@ -4,6 +4,8 @@ #if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20) #include "edc20_io.h" +#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01) +#include "pel10_io.h" #endif #include "adc_drv.h" @@ -16,6 +18,8 @@ void elite_board_init(void) { #if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20) edc20_io_init(); +#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01) + epl10_io_init(); #endif } diff --git a/elite_board.h b/elite_board.h index 524cd70..11d16b7 100644 --- a/elite_board.h +++ b/elite_board.h @@ -5,6 +5,8 @@ #include "app_config.h" #if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20) #include "edc20_io.h" +#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01) +#include "pel10_io.h" #else #error "Not implemented xxx_pin_ctrl.h" #endif diff --git a/pel.c b/pel.c new file mode 100644 index 0000000..f7a2e7b --- /dev/null +++ b/pel.c @@ -0,0 +1,234 @@ +#include "pel.h" +#include "pel10_io.h" + +#include "elite_def.h" + +#include "nrf_delay.h" +#include "nrf_gpio.h" +#include "nrf_log.h" + +#include "adc_drv.h" + +#if (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01) + +typedef struct +{ + float val; + uint32_t pin; + uint32_t mask; +} input_pin_t; + +static pel_output_t output_data = { 0 }; + +const input_pin_t input_pin_tab[] = { + { 0.5, INPUT_1_PIN, PEL_0P5R_MASK}, + { 1.0, INPUT_2_PIN, PEL_1P0R_MASK}, + { 2.0, INPUT_3_PIN, PEL_2P0R_MASK}, + { 4.0, INPUT_4_PIN, PEL_4P0R_MASK}, + { 8.0, INPUT_5_PIN, PEL_8P0R_MASK}, + { 16.2, INPUT_6_PIN, PEL_16P2R_MASK}, + { 32.4, INPUT_7_PIN, PEL_32P4R_MASK}, + { 63.4, INPUT_8_PIN, PEL_63P4R_MASK}, + { 127.0, INPUT_9_PIN, PEL_127R_MASK}, + { 255.0, INPUT_10_PIN, PEL_255R_MASK}, + { 511.0, INPUT_11_PIN, PEL_511R_MASK}, + {1000.0, INPUT_12_PIN, PEL_1000R_MASK}, +}; + +static float _load_set(uint32_t mask) +{ + float ohms = 0; + for (uint32_t i = 0; i < COUNTOF(input_pin_tab); i++) + { + if (input_pin_tab[i].mask & mask) + { + nrf_gpio_pin_clear(input_pin_tab[i].pin); + ohms += input_pin_tab[i].val; + } + else + { + nrf_gpio_pin_set(input_pin_tab[i].pin); + } + } + return ohms; +} + +static float _load_set_by_ohms(float ohms) +{ + // TODO... + return ohms; +} + +static void _sample(void) +{ + nrf_gpio_pin_set(ANODE_PIN); + nrf_gpio_pin_clear(CATHODE_PIN); + nrf_gpio_pin_clear(SAMPLE_R_PIN); + nrf_gpio_pin_clear(SAMPLE_V_PIN); + nrf_delay_us(10); + + nrf_gpio_pin_toggle(ANODE_PIN); + nrf_gpio_pin_toggle(CATHODE_PIN); + nrf_delay_us(5); + + nrf_gpio_pin_toggle(SAMPLE_R_PIN); + nrf_gpio_pin_toggle(SAMPLE_V_PIN); + nrf_delay_us(5); + + nrf_gpio_pin_toggle(CATHODE_PIN); + nrf_gpio_pin_toggle(ANODE_PIN); + nrf_gpio_pin_toggle(SAMPLE_R_PIN); + nrf_gpio_pin_toggle(SAMPLE_V_PIN); +} + +void pel_relays_set(uint32_t measure_out) +{ + if (measure_out) + { + nrf_gpio_pin_set(RELAY1_PIN); + nrf_gpio_pin_clear(RELAY2_PIN); + } + else + { + nrf_gpio_pin_clear(RELAY1_PIN); + nrf_gpio_pin_set(RELAY2_PIN); + } + /* delay 30ms */ + vTaskDelay(pdMS_TO_TICKS(30)); +} + +pel_output_t pel_smaple_and_convt_all(uint32_t load_mask) +{ + uint32_t ch_list[] = { + OUTPUT_R1_CHANNEL, + OUTPUT_R2_CHANNEL, + OUTPUT_VO_CHANNEL, + OUTPUT_VC_CHANNEL, + OUTPUT_VE_CHANNEL + }; + int32_t results[COUNTOF(ch_list)]; + /* config E-load */ + _load_set(load_mask); + /* send a pulse to sample and then read ADC channels */ + adc_read_mutiple_channels_ex(ch_list, results, COUNTOF(ch_list), _sample); + /* copy results */ + output_data.output_r1 = results[0]; + output_data.output_r2 = results[1]; + output_data.output_vo = results[2]; + output_data.output_vc = results[3]; + output_data.output_ve = results[4]; + NRF_LOG_INFO("output_r1: 0x%04X", output_data.output_r1); + NRF_LOG_INFO("output_r2: 0x%04X", output_data.output_r2); + NRF_LOG_INFO("output_vo: 0x%04X", output_data.output_vo); + NRF_LOG_INFO("output_vc: 0x%04X", output_data.output_vc); + NRF_LOG_INFO("output_ve: 0x%04X", output_data.output_ve); + return output_data; +} + +#define VERSION_DATE_YEAR 24 +#define VERSION_DATE_MONTH 5 +#define VERSION_DATE_DAY 21 +#define VERSION_DATE_HOUR 18 +#define VERSION_DATE_MINUTE 39 +static void cis_version(uint8_t *ins, uint16_t size) +{ + NRF_LOG_INFO("%s", __FUNCTION__); + uint8_t cis_ver[] = { + CIS_VERSION, + VERSION_DATE_YEAR, + VERSION_DATE_MONTH, + VERSION_DATE_DAY, + VERSION_DATE_HOUR, + VERSION_DATE_MINUTE, + }; + extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); + le_data_upadate((void *)cis_ver, sizeof(cis_ver)); +} + +static void vis_rst(uint8_t *ins, uint16_t size) +{ + NRF_LOG_INFO("%s", __FUNCTION__); +} + +#define MAGIC_NUM 0xFF00 +static pel_output_t dev_mode_pel_output; +static void dev_mode(uint8_t *ins, uint16_t size) +{ + NRF_LOG_INFO("%s", __FUNCTION__); + struct __PACKED + { + uint8_t id : 4; + uint8_t : 4; + uint16_t magic : 16; + uint8_t opcode; + uint8_t param[]; + } *p_ins = (void *)ins; + + if (p_ins->magic != MAGIC_NUM) + { + return; + } + + struct + { + uint8_t status; + uint16_t mask; + } __PACKED *p_param = (void *)p_ins->param; + + switch (p_ins->opcode) + { + case 0x00: { + pel_relays_set(p_param->status); + dev_mode_pel_output = pel_smaple_and_convt_all(p_param->mask); + break; + } + + case 0x01: { + extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); + le_data_upadate((void *)&dev_mode_pel_output.output_r1, sizeof(dev_mode_pel_output.output_r1)); + break; + } + case 0x02: { + extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); + le_data_upadate((void *)&dev_mode_pel_output.output_r2, sizeof(dev_mode_pel_output.output_r2)); + break; + } + case 0x03: { + extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); + le_data_upadate((void *)&dev_mode_pel_output.output_vo, sizeof(dev_mode_pel_output.output_vo)); + break; + } + case 0x04: { + extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); + le_data_upadate((void *)&dev_mode_pel_output.output_vc, sizeof(dev_mode_pel_output.output_vc)); + break; + } + case 0x05: { + extern ret_code_t le_data_upadate(uint8_t * p_value, uint16_t len); + le_data_upadate((void *)&dev_mode_pel_output.output_ve, sizeof(dev_mode_pel_output.output_ve)); + break; + } + default: { + break; + } + } +} + +const elite_instance_t pel_elite_instance = { + .cis_func = { + [CIS_VERSION] = cis_version, + }, + .vis_func = { + [VIS_RST] = vis_rst, + }, + .ris_func = { + [DEV_MODE] = dev_mode, + } +}; + +const elite_instance_t *pel_init(void) +{ + return &pel_elite_instance; +} + +#endif diff --git a/pel.h b/pel.h new file mode 100644 index 0000000..6750464 --- /dev/null +++ b/pel.h @@ -0,0 +1,35 @@ +#pragma once +#ifndef __PEL_H__ +#define __PEL_H__ + +#include "app_config.h" +#include "elite_board.h" +#include "elite.h" + +#define PEL_0P5R_MASK (0x01 << 0) +#define PEL_1P0R_MASK (0x01 << 1) +#define PEL_2P0R_MASK (0x01 << 2) +#define PEL_4P0R_MASK (0x01 << 3) +#define PEL_8P0R_MASK (0x01 << 4) +#define PEL_16P2R_MASK (0x01 << 5) +#define PEL_32P4R_MASK (0x01 << 6) +#define PEL_63P4R_MASK (0x01 << 7) +#define PEL_127R_MASK (0x01 << 8) +#define PEL_255R_MASK (0x01 << 9) +#define PEL_511R_MASK (0x01 << 10) +#define PEL_1000R_MASK (0x01 << 11) + +typedef struct +{ + int32_t output_r1; + int32_t output_r2; + int32_t output_vo; + int32_t output_vc; + int32_t output_ve; +} pel_output_t; + +void pel_relays_set(uint32_t measure_out); +pel_output_t pel_smaple_and_convt_all(uint32_t load_mask); +const elite_instance_t *pel_init(void); + +#endif // !__PEL_H__ diff --git a/pel10_io.c b/pel10_io.c new file mode 100644 index 0000000..96a6a8d --- /dev/null +++ b/pel10_io.c @@ -0,0 +1,124 @@ +#include "app_config.h" +#include "elite_board.h" + +#include "nrf_spim.h" + +#include "FreeRTOS.h" +#include "semphr.h" +#include "task.h" + +#if (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01) + +void spim_xfer(uint32_t cs_pin, + nrf_spim_mode_t spi_mode, + uint8_t *p_tx_buffer, + uint16_t tx_buffer_length, + uint8_t *p_rx_buf, + uint16_t rx_buffer_length) +{ + __disable_irq(); + + NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos; + + switch (spi_mode) + { + default: + case NRF_SPIM_MODE_0: + NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) | + (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); + break; + + case NRF_SPIM_MODE_1: + NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) | + (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); + break; + + case NRF_SPIM_MODE_2: + NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) | + (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos); + break; + + case NRF_SPIM_MODE_3: + NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) | + (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) | + (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos); + break; + } + + NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos; + + NRF_SPIM3->TXD.MAXCNT = tx_buffer_length; + NRF_SPIM3->TXD.PTR = (uint32_t)p_tx_buffer; + + NRF_SPIM3->RXD.MAXCNT = rx_buffer_length; + NRF_SPIM3->RXD.PTR = (uint32_t)p_rx_buf; + + nrf_gpio_pin_clear(cs_pin); + + NRF_SPIM3->EVENTS_END = 0; + NRF_SPIM3->TASKS_START = 1; + do { + } while (NRF_SPIM3->EVENTS_END == 0); + + nrf_gpio_pin_set(cs_pin); + + __enable_irq(); +} + +const uint32_t pel_pins[] = { + INPUT_1_PIN, + INPUT_2_PIN, + INPUT_3_PIN, + INPUT_4_PIN, + INPUT_5_PIN, + INPUT_6_PIN, + INPUT_7_PIN, + INPUT_8_PIN, + INPUT_9_PIN, + INPUT_10_PIN, + INPUT_11_PIN, + INPUT_12_PIN, + ANODE_PIN, + CATHODE_PIN, + SAMPLE_R_PIN, + SAMPLE_V_PIN, + RELAY1_PIN, + RELAY2_PIN +}; + +void epl10_io_init(void) +{ + for (int i = 0; i < COUNTOF(pel_pins); i++) + { + nrf_gpio_pin_set(pel_pins[i]); + nrf_gpio_cfg_output(pel_pins[i]); + } + + // Config spi module + + nrf_gpio_pin_set(WP_MEM_PIN); + nrf_gpio_cfg_output(WP_MEM_PIN); + nrf_gpio_pin_set(CS_MEM_PIN); + nrf_gpio_cfg_output(CS_MEM_PIN); + nrf_gpio_pin_clear(SPIM_MOSI_PIN); + nrf_gpio_cfg_output(SPIM_MOSI_PIN); + nrf_gpio_pin_clear(SPIM_CLK_PIN); + nrf_gpio_cfg_output(SPIM_CLK_PIN); + nrf_gpio_cfg_input(SPIM_MISO_PIN, NRF_GPIO_PIN_NOPULL); + + NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos; + NRF_SPIM3->ORC = 0x00000000; + NRF_SPIM3->FREQUENCY = SPIM_FREQUENCY_FREQUENCY_M32; + NRF_SPIM3->CSNPOL = SPIM_CSNPOL_CSNPOL_LOW; + NRF_SPIM3->IFTIMING.CSNDUR = 8; + NRF_SPIM3->PSEL.CSN = CS_MEM_PIN; + NRF_SPIM3->PSEL.SCK = SPIM_CLK_PIN; + NRF_SPIM3->PSEL.MOSI = SPIM_MOSI_PIN; + NRF_SPIM3->PSEL.MISO = SPIM_MISO_PIN; + NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos; +} + +#endif diff --git a/pel10_io.h b/pel10_io.h new file mode 100644 index 0000000..1d21fb1 --- /dev/null +++ b/pel10_io.h @@ -0,0 +1,59 @@ +#pragma once +#ifndef __PULSE_E_LOAD10_H__ +#define __PULSE_E_LOAD10_H__ + +#include "app_config.h" +#include "elite_board.h" +#include "nrf_gpio.h" +#include "nrf_spim.h" + +#define RELAY1_PIN NRF_GPIO_PIN_MAP(1, 10) +#define RELAY2_PIN NRF_GPIO_PIN_MAP(1, 15) + +#define SAMPLE_R_PIN NRF_GPIO_PIN_MAP(1, 11) +#define SAMPLE_V_PIN NRF_GPIO_PIN_MAP(1, 6) + +#define ANODE_PIN NRF_GPIO_PIN_MAP(0, 7) +#define CATHODE_PIN NRF_GPIO_PIN_MAP(0, 28) + +#define OUTPUT_VC_PIN NRF_GPIO_PIN_MAP(0, 2) +#define OUTPUT_VO_PIN NRF_GPIO_PIN_MAP(0, 29) +#define OUTPUT_VE_PIN NRF_GPIO_PIN_MAP(0, 3) +#define OUTPUT_R1_PIN NRF_GPIO_PIN_MAP(0, 31) +#define OUTPUT_R2_PIN NRF_GPIO_PIN_MAP(0, 28) + +#define OUTPUT_VC_CHANNEL 0 +#define OUTPUT_VO_CHANNEL 5 +#define OUTPUT_VE_CHANNEL 1 +#define OUTPUT_R1_CHANNEL 7 +#define OUTPUT_R2_CHANNEL 4 + +#define INPUT_1_PIN NRF_GPIO_PIN_MAP(0, 15) +#define INPUT_2_PIN NRF_GPIO_PIN_MAP(0, 13) +#define INPUT_3_PIN NRF_GPIO_PIN_MAP(0, 20) +#define INPUT_4_PIN NRF_GPIO_PIN_MAP(1, 0) +#define INPUT_5_PIN NRF_GPIO_PIN_MAP(0, 25) +#define INPUT_6_PIN NRF_GPIO_PIN_MAP(0, 11) +#define INPUT_7_PIN NRF_GPIO_PIN_MAP(0, 14) +#define INPUT_8_PIN NRF_GPIO_PIN_MAP(0, 17) +#define INPUT_9_PIN NRF_GPIO_PIN_MAP(0, 18) +#define INPUT_10_PIN NRF_GPIO_PIN_MAP(0, 21) +#define INPUT_11_PIN NRF_GPIO_PIN_MAP(0, 19) +#define INPUT_12_PIN NRF_GPIO_PIN_MAP(0, 22) + +#define WP_MEM_PIN NRF_GPIO_PIN_MAP(0, 12) +#define CS_MEM_PIN NRF_GPIO_PIN_MAP(0, 6) +#define SPIM_MOSI_PIN NRF_GPIO_PIN_MAP(0, 27) +#define SPIM_CLK_PIN NRF_GPIO_PIN_MAP(0, 4) +#define SPIM_MISO_PIN NRF_GPIO_PIN_MAP(1, 9) + +void spim_xfer(uint32_t cs_pin, + nrf_spim_mode_t spi_mode, + uint8_t *p_tx_buffer, + uint16_t tx_buffer_length, + uint8_t *p_rx_buf, + uint16_t rx_buffer_length); + +void epl10_io_init(void); + +#endif // !__PULSE_E_LOAD10_H__