diff --git a/app_config.h b/app_config.h index da41bdc..fa85507 100644 --- a/app_config.h +++ b/app_config.h @@ -169,9 +169,9 @@ extern "C" #elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10) #define ELITE_DEVICE_NAME "Elite-PEL" #define MAJOR_PRODUCT_NUMBER 0 -#define MINOR_PRODUCT_NUMBER 2 -#define MAJOR_VERSION_NUMBER 1 -#define MINOR_VERSION_NUMBER 9 +#define MINOR_PRODUCT_NUMBER 7 +#define MAJOR_VERSION_NUMBER 0 +#define MINOR_VERSION_NUMBER 0 #define DEF_LED_COUNT 0 #define DEF_LED_DRV_ENABLED 0 diff --git a/pel.c b/pel.c index eec7bb2..1e33037 100644 --- a/pel.c +++ b/pel.c @@ -40,7 +40,7 @@ const input_pin_t input_pin_tab[] = { static float _load_set(uint32_t mask) { float ohms = 0; - for (uint32_t i = 0; i < COUNTOF(input_pin_tab); i++) + for (int32_t i = COUNTOF(input_pin_tab) - 1; i >= 0; i--) { if (input_pin_tab[i].mask & mask) { @@ -55,6 +55,13 @@ static float _load_set(uint32_t mask) return ohms; } +static void set_resistor_to_default(void) +{ + const uint32_t resistor_to_default = 0b000000000000; + + _load_set(resistor_to_default); +} + static float _load_set_by_ohms(float ohms) { // TODO... @@ -133,6 +140,7 @@ pel_output_t pel_smaple_and_convt_all(uint32_t measure_out, uint32_t load_mask) int32_t results[COUNTOF(ch_list)]; float f_results[COUNTOF(ch_list)]; /* config E-load */ + set_resistor_to_default(); _load_set(load_mask); /* send a pulse to sample and then read ADC channels */ if (measure_out) @@ -169,9 +177,9 @@ pel_output_t pel_smaple_and_convt_all(uint32_t measure_out, uint32_t load_mask) #define VERSION_DATE_YEAR 24 #define VERSION_DATE_MONTH 7 -#define VERSION_DATE_DAY 9 -#define VERSION_DATE_HOUR 11 -#define VERSION_DATE_MINUTE 8 +#define VERSION_DATE_DAY 30 +#define VERSION_DATE_HOUR 13 +#define VERSION_DATE_MINUTE 40 static void cis_version(uint8_t *ins, uint16_t size) { NRF_LOG_INFO("%s", __FUNCTION__); @@ -248,6 +256,165 @@ void test_gpio_task(void *pArg) } } +void set_a_specific_resistor_combination(uint16_t resistor_combination) +{ + typedef struct + { + uint16_t val; + uint32_t mask; + } resistor_combination_t; + + const resistor_combination_t resis_combination_tab[] = { + { 1, 0b111}, + { 2, 0b011}, + { 3, 0b101}, + { 4, 0b001}, + { 5, 0b111 << 1}, + { 6, 0b011 << 1}, + { 7, 0b101 << 1}, + { 8, 0b001 << 1}, + { 9, 0b111 << 2}, + {10, 0b011 << 2}, + {11, 0b101 << 2}, + {12, 0b001 << 2}, + {13, 0b111 << 3}, + {14, 0b011 << 3}, + {15, 0b101 << 3}, + {16, 0b001 << 3}, + {17, 0b111 << 4}, + {18, 0b011 << 4}, + {19, 0b101 << 4}, + {20, 0b001 << 4}, + {21, 0b111 << 5}, + {22, 0b011 << 5}, + {23, 0b101 << 5}, + {24, 0b001 << 5}, + {25, 0b111 << 6}, + {26, 0b011 << 6}, + {27, 0b101 << 6}, + {28, 0b001 << 6}, + {29, 0b111 << 7}, + {30, 0b011 << 7}, + {31, 0b101 << 7}, + {32, 0b001 << 7}, + {33, 0b111 << 8}, + {34, 0b011 << 8}, + {35, 0b101 << 8}, + {36, 0b001 << 8}, + {37, 0b111 << 9}, + {38, 0b011 << 9}, + {39, 0b101 << 9}, + {40, 0b001 << 9}, + {41, 0b11 << 10}, + {42, 0b01 << 10}, + {43, 0b1 << 11}, + }; + + for (int32_t i = 0; i < COUNTOF(resis_combination_tab); i++) + { + if (resis_combination_tab[i].val == resistor_combination) + { + NRF_LOG_INFO("No.%d resistor_combination: 0x%03X(FW) ", resis_combination_tab[i].val, resis_combination_tab[i].mask); + NRF_LOG_INFO("Input | 1 | 2 | 3 | 4 | 5 | 6 |"); + NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |", + (resis_combination_tab[i].mask & 1 << 0), + (resis_combination_tab[i].mask & 1 << 1) >> 1, + (resis_combination_tab[i].mask & 1 << 2) >> 2, + (resis_combination_tab[i].mask & 1 << 3) >> 3, + (resis_combination_tab[i].mask & 1 << 4) >> 4, + (resis_combination_tab[i].mask & 1 << 5) >> 5); + + NRF_LOG_INFO("Input | 7 | 8 | 9 | 10 | 11 | 12 |"); + NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |", + (resis_combination_tab[i].mask & 1 << 6) >> 6, + (resis_combination_tab[i].mask & 1 << 7) >> 7, + (resis_combination_tab[i].mask & 1 << 8) >> 8, + (resis_combination_tab[i].mask & 1 << 9) >> 9, + (resis_combination_tab[i].mask & 1 << 10) >> 10, + (resis_combination_tab[i].mask & 1 << 11) >> 11); + set_resistor_to_default(); + _load_set(resis_combination_tab[i].mask); + } + } +} + +void pel_select_resistor_combinations_mode(uint8_t *ins) +{ +#define SET_A_SPECIFIC_RESISTOR_COMBINATION 0x00 +#define SET_ALL_RESISTORS_AT_ONCE 0x01 + + uint16_t set_resistor_type = (ins[4] & 0xF0) >> 4; + uint16_t val = ((ins[4] & 0x0F) << 8) | ins[5]; + + if (set_resistor_type == 0) + { + set_a_specific_resistor_combination(val); + } + else if (set_resistor_type == 1) + { + typedef union + { + struct + { + uint32_t input1 : 1; + uint32_t input2 : 1; + uint32_t input3 : 1; + uint32_t input4 : 1; + uint32_t input5 : 1; + uint32_t input6 : 1; + uint32_t input7 : 1; + uint32_t input8 : 1; + uint32_t input9 : 1; + uint32_t input10 : 1; + uint32_t input11 : 1; + uint32_t input12 : 1; + }; + uint32_t val; + } resis_t; + + resis_t resis; + + resis.input1 = (val & 0b0000100000000000) >> 11; + resis.input2 = (val & 0b0000010000000000) >> 10; + resis.input3 = (val & 0b0000001000000000) >> 9; + resis.input4 = (val & 0b0000000100000000) >> 8; + resis.input5 = (val & 0b0000000010000000) >> 7; + resis.input6 = (val & 0b0000000001000000) >> 6; + resis.input7 = (val & 0b0000000000100000) >> 5; + resis.input8 = (val & 0b0000000000010000) >> 4; + resis.input9 = (val & 0b0000000000001000) >> 3; + resis.input10 = (val & 0b0000000000000100) >> 2; + resis.input11 = (val & 0b0000000000000010) >> 1; + resis.input12 = (val & 0b0000000000000001) >> 0; + + NRF_LOG_INFO("Set_all_resistors_at_once: 0x%03X(FW) ", resis.val); + NRF_LOG_INFO("Input | 1 | 2 | 3 | 4 | 5 | 6 |"); + NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |", + (resis.val & 1 << 0), + (resis.val & 1 << 1) >> 1, + (resis.val & 1 << 2) >> 2, + (resis.val & 1 << 3) >> 3, + (resis.val & 1 << 4) >> 4, + (resis.val & 1 << 5) >> 5); + + NRF_LOG_INFO("Input | 7 | 8 | 9 | 10 | 11 | 12 |"); + NRF_LOG_INFO(" | %d | %d | %d | %d | %d | %d |", + (resis.val & 1 << 6) >> 6, + (resis.val & 1 << 7) >> 7, + (resis.val & 1 << 8) >> 8, + (resis.val & 1 << 9) >> 9, + (resis.val & 1 << 10) >> 10, + (resis.val & 1 << 11) >> 11); + + set_resistor_to_default(); + _load_set(resis.val); + } + else + { + printf("No this cmd..."); + } +} + #define MAGIC_NUM 0xFF00 static pel_output_t dev_mode_pel_output; static void dev_mode(uint8_t *ins, uint16_t size) @@ -315,6 +482,11 @@ static void dev_mode(uint8_t *ins, uint16_t size) break; } + case 0x62: { + pel_select_resistor_combinations_mode(ins); + break; + } + case 0xF0: { pel10_io_init(); break; @@ -355,62 +527,63 @@ static void dev_mode(uint8_t *ins, uint16_t size) uint32_t high_low = p_param->status; - switch (p_param->input_n) { + switch (p_param->input_n) + { case 0x01: nrf_gpio_pin_write(INPUT_1_PIN, high_low); NRF_LOG_INFO("set INPUT_1_PIN = %d", high_low); break; - + case 0x02: nrf_gpio_pin_write(INPUT_2_PIN, high_low); NRF_LOG_INFO("set INPUT_2_PIN = %d", high_low); break; - + case 0x03: nrf_gpio_pin_write(INPUT_3_PIN, high_low); NRF_LOG_INFO("set INPUT_3_PIN = %d", high_low); break; - + case 0x04: nrf_gpio_pin_write(INPUT_4_PIN, high_low); NRF_LOG_INFO("set INPUT_4_PIN = %d", high_low); break; - + case 0x05: nrf_gpio_pin_write(INPUT_5_PIN, high_low); NRF_LOG_INFO("set INPUT_5_PIN = %d", high_low); break; - + case 0x06: nrf_gpio_pin_write(INPUT_6_PIN, high_low); NRF_LOG_INFO("set INPUT_6_PIN = %d", high_low); break; - + case 0x07: nrf_gpio_pin_write(INPUT_7_PIN, high_low); NRF_LOG_INFO("set INPUT_7_PIN = %d", high_low); break; - + case 0x08: nrf_gpio_pin_write(INPUT_8_PIN, high_low); NRF_LOG_INFO("set INPUT_8_PIN = %d", high_low); break; - + case 0x09: nrf_gpio_pin_write(INPUT_9_PIN, high_low); NRF_LOG_INFO("set INPUT_9_PIN = %d", high_low); break; - + case 0x0A: nrf_gpio_pin_write(INPUT_10_PIN, high_low); NRF_LOG_INFO("set INPUT_10_PIN = %d", high_low); break; - + case 0x0B: nrf_gpio_pin_write(INPUT_11_PIN, high_low); NRF_LOG_INFO("set INPUT_11_PIN = %d", high_low); break; - + case 0x0C: nrf_gpio_pin_write(INPUT_12_PIN, high_low); NRF_LOG_INFO("set INPUT_12_PIN = %d", high_low); diff --git a/pel10_io.c b/pel10_io.c index 6a22767..39078e1 100644 --- a/pel10_io.c +++ b/pel10_io.c @@ -1,6 +1,9 @@ #include "elite_board.h" +#include "nrf_gpio.h" +#include "nrf_gpiote.h" #include "nrf_spim.h" +#include "nrf_timer.h" #include "FreeRTOS.h" #include "semphr.h" @@ -67,6 +70,117 @@ void spim_xfer(uint32_t cs_pin, __enable_irq(); } +#define MIN_PULSE_WIDTH 2 +#define MIN_PULSE_IDLE 2 +#define MAX_PULSE_WIDTH INT16_MAX +#define MAX_PULSE_IDLE INT16_MAX + +typedef struct +{ + uint32_t anode_pin; + uint32_t cathode_pin; + uint32_t pulse_idle; // min: 2, max: 32767, unit: us + uint32_t pulse_width; // min: 2, max: 32767, unit: us, + uint32_t pulse_cnt; // min: 1, max: 0xFFFFFFFF +} pusle_gen_t; + +typedef struct +{ + uint32_t gpiote_idx[2]; + NRF_TIMER_Type *pulse_tmr; + uint32_t pulse_irq_n; + uint32_t pulse_cnt; +} pusle_gen_hw_t; + +pusle_gen_hw_t pusle_gen_hw = { + .gpiote_idx = {0, 1}, + .pulse_tmr = NRF_TIMER3, + .pulse_irq_n = TIMER3_IRQn, + .pulse_cnt = 0, +}; + +void TIMER3_IRQHandler(void) +{ + if (pusle_gen_hw.pulse_tmr->EVENTS_COMPARE[1]) + { + pusle_gen_hw.pulse_tmr->EVENTS_COMPARE[1] = 0; + pusle_gen_hw.pulse_cnt--; + if (pusle_gen_hw.pulse_cnt == 1) + { + pusle_gen_hw.pulse_tmr->SHORTS |= NRF_TIMER_SHORT_COMPARE1_STOP_MASK; + } + } +} + +bool pel10_pulse_gen(pusle_gen_t *p_pusle_gen) +{ + /* hardware limitation */ + if (p_pusle_gen->pulse_cnt == 0 || + p_pusle_gen->pulse_idle < MIN_PULSE_IDLE || + p_pusle_gen->pulse_width < MIN_PULSE_WIDTH || + p_pusle_gen->pulse_idle > MAX_PULSE_IDLE || + p_pusle_gen->pulse_width > MAX_PULSE_WIDTH) + { + return false; + } + + pusle_gen_hw.pulse_cnt = p_pusle_gen->pulse_cnt; + + pusle_gen_hw.pulse_tmr->TASKS_STOP = 1; + + sd_nvic_DisableIRQ(pusle_gen_hw.pulse_irq_n); + sd_nvic_ClearPendingIRQ(pusle_gen_hw.pulse_irq_n); + + nrf_gpiote_task_configure(pusle_gen_hw.gpiote_idx[0], p_pusle_gen->anode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH); + nrf_gpiote_task_configure(pusle_gen_hw.gpiote_idx[1], p_pusle_gen->cathode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW); + + nrf_gpiote_task_enable(pusle_gen_hw.gpiote_idx[0]); + nrf_gpiote_task_enable(pusle_gen_hw.gpiote_idx[1]); + + NRF_PPI->CH[0].EEP = (uint32_t)&pusle_gen_hw.pulse_tmr->EVENTS_COMPARE[0]; + NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw.gpiote_idx[0]]; + NRF_PPI->FORK[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw.gpiote_idx[1]]; + NRF_PPI->CHENSET = (1 << (0)); + + NRF_PPI->CH[1].EEP = (uint32_t)&pusle_gen_hw.pulse_tmr->EVENTS_COMPARE[1]; + NRF_PPI->CH[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw.gpiote_idx[0]]; + NRF_PPI->FORK[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw.gpiote_idx[1]]; + NRF_PPI->CHENSET = (1 << (1)); + + pusle_gen_hw.pulse_tmr->TASKS_CLEAR = 1; + + pusle_gen_hw.pulse_tmr->PRESCALER = NRF_TIMER_FREQ_16MHz; + pusle_gen_hw.pulse_tmr->MODE = NRF_TIMER_MODE_TIMER; + pusle_gen_hw.pulse_tmr->BITMODE = NRF_TIMER_BIT_WIDTH_32; + pusle_gen_hw.pulse_tmr->CC[0] = p_pusle_gen->pulse_idle * 16; + pusle_gen_hw.pulse_tmr->CC[1] = pusle_gen_hw.pulse_tmr->CC[0] + p_pusle_gen->pulse_width * 16; + pusle_gen_hw.pulse_tmr->SHORTS = pusle_gen_hw.pulse_cnt > 1 ? NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK : NRF_TIMER_SHORT_COMPARE1_STOP_MASK; + pusle_gen_hw.pulse_tmr->INTENSET = NRF_TIMER_INT_COMPARE1_MASK; + + sd_nvic_SetPriority(pusle_gen_hw.pulse_irq_n, _PRIO_APP_HIGH); + sd_nvic_EnableIRQ(pusle_gen_hw.pulse_irq_n); + + pusle_gen_hw.pulse_tmr->TASKS_START = 1; + + return true; +} + +void pel10_pulse_gen_demo(void) +{ + pusle_gen_t pusle_gen = { + .anode_pin = ANODE_PIN, + .cathode_pin = CATHODE_PIN, + .pulse_width = 10, + .pulse_idle = 10, + .pulse_cnt = 0xFFFFFFFF + }; + + if (pel10_pulse_gen(&pusle_gen) == false) + { + // fail handling + } +} + void pel10_io_init(void) { const uint32_t pel_pins_default_high[] = { @@ -127,6 +241,8 @@ void pel10_io_init(void) 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; + + pel10_pulse_gen_demo(); } #endif