#include "pel.h" #include "elite_board.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_ELITE_PEL_V2_0) typedef struct { float val; uint32_t pin; uint32_t mask; } input_pin_t; TaskHandle_t test_gpio_task_Handle = NULL; 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 (int32_t i = COUNTOF(input_pin_tab) - 1; i >= 0; 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 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... return ohms; } static void _sample_measure_out_is_low(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(3); nrf_gpio_pin_toggle(SAMPLE_R_PIN); nrf_gpio_pin_toggle(SAMPLE_V_PIN); nrf_delay_us(5); nrf_gpio_pin_toggle(SAMPLE_R_PIN); nrf_gpio_pin_toggle(SAMPLE_V_PIN); nrf_gpio_pin_toggle(CATHODE_PIN); nrf_gpio_pin_toggle(ANODE_PIN); } static void _sample_measure_out_is_high(void) { nrf_gpio_pin_clear(ANODE_PIN); nrf_gpio_pin_set(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(3); nrf_gpio_pin_toggle(SAMPLE_R_PIN); nrf_gpio_pin_toggle(SAMPLE_V_PIN); nrf_delay_us(5); nrf_gpio_pin_toggle(SAMPLE_R_PIN); nrf_gpio_pin_toggle(SAMPLE_V_PIN); nrf_gpio_pin_toggle(CATHODE_PIN); nrf_gpio_pin_toggle(ANODE_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 measure_out, uint32_t load_mask) { uint32_t ch_list[] = { [OUTPUT_R1_IDX] = OUTPUT_R1_CHANNEL, [OUTPUT_R2_IDX] = OUTPUT_R2_CHANNEL, [OUTPUT_VO_IDX] = OUTPUT_VO_CHANNEL, [OUTPUT_VC_IDX] = OUTPUT_VC_CHANNEL, [OUTPUT_VE_IDX] = OUTPUT_VE_CHANNEL }; 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) { adc_read_mutiple_channels_ex(ch_list, results, COUNTOF(ch_list), _sample_measure_out_is_high); adc_read_multiple_milivolt_ex(ch_list, f_results, COUNTOF(ch_list), _sample_measure_out_is_high); } else { adc_read_mutiple_channels_ex(ch_list, results, COUNTOF(ch_list), _sample_measure_out_is_low); adc_read_multiple_milivolt_ex(ch_list, f_results, COUNTOF(ch_list), _sample_measure_out_is_low); } /* copy results */ output_data.output_r1 = results[OUTPUT_R1_IDX]; output_data.output_r2 = results[OUTPUT_R2_IDX]; output_data.output_vo = results[OUTPUT_VO_IDX]; output_data.output_vc = results[OUTPUT_VC_IDX]; output_data.output_ve = results[OUTPUT_VE_IDX]; { char str[128]; snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_r1", output_data.output_r1, f_results[OUTPUT_R1_IDX]); NRF_LOG_INFO("%s", str); snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_r2", output_data.output_r2, f_results[OUTPUT_R2_IDX]); NRF_LOG_INFO("%s", str); snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_vo", output_data.output_vo, f_results[OUTPUT_VO_IDX]); NRF_LOG_INFO("%s", str); snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_vc", output_data.output_vc, f_results[OUTPUT_VC_IDX]); NRF_LOG_INFO("%s", str); snprintf(str, sizeof(str), "%s: 0x%04lX, %.3fmV", "output_ve", output_data.output_ve, f_results[OUTPUT_VE_IDX]); NRF_LOG_INFO("%s", str); } return output_data; } #define VERSION_DATE_YEAR 24 #define VERSION_DATE_MONTH 7 #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__); 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__); } void test_gpio_task(void *pArg) { 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 }; for (;;) { NRF_LOG_INFO("[test] all output pin set low"); for (int i = 0; i < COUNTOF(pel_pins); i++) { nrf_gpio_pin_clear(pel_pins[i]); } vTaskDelay(1000); NRF_LOG_INFO("[test] all output pin set high"); for (int i = 0; i < COUNTOF(pel_pins); i++) { nrf_gpio_pin_set(pel_pins[i]); } vTaskDelay(1000); NRF_LOG_INFO("[test] alternating high and low signals on all output pins"); for (int i = 0; i < COUNTOF(pel_pins); i++) { nrf_gpio_pin_clear(pel_pins[i]); } vTaskDelay(1000); for (int i = 0; i < COUNTOF(pel_pins); i++) { nrf_gpio_pin_set(pel_pins[i]); vTaskDelay(100); nrf_gpio_pin_clear(pel_pins[i]); } vTaskDelay(1000); } } 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) { 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; } switch (p_ins->opcode) { case 0x60: { struct { uint8_t status; uint16_t mask; } __PACKED *p_param = (void *)p_ins->param; pel_relays_set(p_param->status); dev_mode_pel_output = pel_smaple_and_convt_all(p_param->status, __REVSH(p_param->mask)); break; } case 0x61: { struct { uint8_t channel; } __PACKED *p_param = (void *)p_ins->param; if (p_param->channel == 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)); } else if (p_param->channel == 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)); } else if (p_param->channel == 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)); } else if (p_param->channel == 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)); } else if (p_param->channel == 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; } case 0x62: { pel_select_resistor_combinations_mode(ins); break; } case 0xF0: { pel10_io_init(); break; } case 0xF1: { struct { uint8_t status; } __PACKED *p_param = (void *)p_ins->param; if (p_param->status == 0x01) { if (test_gpio_task_Handle == NULL) { NRF_LOG_INFO("[test] start test_gpio_task task"); xTaskCreate(test_gpio_task, "test_gpio_task", 1024, NULL, 4, &test_gpio_task_Handle); } } else if (p_param->status == 0x00) { if (test_gpio_task_Handle != NULL) { NRF_LOG_INFO("[test] delete test_gpio_task task"); vTaskDelete(test_gpio_task_Handle); test_gpio_task_Handle = NULL; } } break; } case 0xF2: { struct { uint8_t input_n; uint8_t status; } __PACKED *p_param = (void *)p_ins->param; uint32_t high_low = p_param->status; 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); break; } 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