diff --git a/pel.c b/pel.c index d001486..3f85193 100644 --- a/pel.c +++ b/pel.c @@ -25,6 +25,7 @@ typedef struct { uint32_t pattern_index; uint32_t resistor_mask; + float resistor_conductance; } resistor_t; typedef struct @@ -50,23 +51,25 @@ static float _load_set(uint32_t 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}, + { 16.0, INPUT_6_PIN, PEL_16P2R_MASK}, + { 32.0, INPUT_7_PIN, PEL_32P4R_MASK}, + { 64.0, INPUT_8_PIN, PEL_63P4R_MASK}, + { 128.0, INPUT_9_PIN, PEL_127R_MASK}, + { 256.0, INPUT_10_PIN, PEL_255R_MASK}, + { 512.0, INPUT_11_PIN, PEL_511R_MASK}, + {1024.0, INPUT_12_PIN, PEL_1000R_MASK}, }; - float ohms = 0; + float ohms = 0; + float sum_of_conductances = 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; + ohms += input_pin_tab[i].val; + sum_of_conductances += 1 / input_pin_tab[i].val; NRF_LOG_INFO("enable R%-2d(" NRF_LOG_FLOAT_MARKER "ohm)", i + 1, NRF_LOG_FLOAT(input_pin_tab[i].val)); } else @@ -74,18 +77,21 @@ static float _load_set(uint32_t mask) nrf_gpio_pin_set(input_pin_tab[i].pin); } } - return ohms; + return sum_of_conductances; } static void set_resistor_load_bits(uint32_t mask) { - load_config.use_pattern_index = false; - load_config.resistor.pattern_index = 0; - load_config.resistor.resistor_mask = mask; - NRF_LOG_INFO("pattern_index[%d] = resistor_mask:0x%08X", - load_config.resistor.pattern_index, - load_config.resistor.resistor_mask); - _load_set(load_config.resistor.resistor_mask); + load_config.use_pattern_index = false; + load_config.resistor.pattern_index = 0; + load_config.resistor.resistor_mask = mask; + load_config.resistor.resistor_conductance = _load_set(load_config.resistor.resistor_mask); + + { + char str[128]; + snprintf(str, sizeof(str), "pattern_index[%d] = resistor_mask:0x%08X, resistor_conductance = %.7f", load_config.resistor.pattern_index, load_config.resistor.resistor_mask, load_config.resistor.resistor_conductance); + NRF_LOG_INFO("%s", str); + } } static void set_resistor_load_pattern(uint32_t index) @@ -140,13 +146,16 @@ static void set_resistor_load_pattern(uint32_t index) { if (pattern_tab[i].pattern_index == index) { - load_config.use_pattern_index = true; - load_config.resistor.pattern_index = index; - load_config.resistor.resistor_mask = pattern_tab[i].resistor_mask; - NRF_LOG_INFO("pattern_index[%d] = resistor_mask:0x%08X", - load_config.resistor.pattern_index, - load_config.resistor.resistor_mask); - _load_set(load_config.resistor.resistor_mask); + load_config.use_pattern_index = true; + load_config.resistor.pattern_index = index; + load_config.resistor.resistor_mask = pattern_tab[i].resistor_mask; + load_config.resistor.resistor_conductance = _load_set(load_config.resistor.resistor_mask); + + { + char str[128]; + snprintf(str, sizeof(str), "pattern_index[%d] = resistor_mask:0x%08X, resistor_conductance = %.7f", load_config.resistor.pattern_index, load_config.resistor.resistor_mask, load_config.resistor.resistor_conductance); + NRF_LOG_INFO("%s", str); + } break; } } @@ -257,15 +266,14 @@ static void pel_scan_mode_notify(pel20_notify_packet1_t *packet_buf, uint32_t pa packet_buf->val_3 = pel_hw.adc.results[2]; packet_buf->val_4 = pel_hw.adc.results[3]; packet_buf->val_5 = pel_hw.adc.results[4]; - packet_buf->val_1_f = pel_hw.adc.results_f[0]; - packet_buf->val_2_f = pel_hw.adc.results_f[1]; - packet_buf->val_3_f = pel_hw.adc.results_f[2]; - packet_buf->val_4_f = pel_hw.adc.results_f[3]; - packet_buf->val_5_f = pel_hw.adc.results_f[4]; + packet_buf->val_1_f = 0; + packet_buf->val_2_f = load_config.resistor.resistor_conductance; + packet_buf->val_3_f = pel_hw.adc.results_f[2] * 10 / 1000; // OUT[V] + packet_buf->val_4_f = pel_hw.adc.results_f[3] * 10 / 1000; // VCC[V] + packet_buf->val_5_f = pel_hw.adc.results_f[4] * 10 / 1000; // VEE[V] packet_buf->pattern_id = load_config.resistor.pattern_index; packet_buf->pattern = load_config.resistor.resistor_mask; - - ret_code_t ret = le_event_async_notify((void *)packet_buf, packet_len, pdMS_TO_TICKS(5)); + ret_code_t ret = le_event_async_notify((void *)packet_buf, packet_len, pdMS_TO_TICKS(5)); { char str[128]; @@ -438,7 +446,7 @@ static void pel_pulse_start(void *p_arg) nrf_gpio_pin_clear(RELAY1_PIN); } - nrf_gpio_pin_set(TP2_PIN); // For testing + nrf_gpio_pin_set(TP2_PIN); // For testing start_adc_pulse(0xFFFFFFFF, adc_event_end_cb); nrf_gpio_pin_clear(TP2_PIN); // For testing } @@ -562,41 +570,46 @@ static void manual_scan_mode(uint8_t *ins, uint16_t size) switch (p_ins->opcode) { - case 0x00: // manual_scan_mode start - // 30 00 01 00 01 00 00 00 05 00 03 - - send_start_package(&packet_buf, sizeof(packet_buf)); - pel_scan_msg.opcode = PEL_START; - pel_scan_msg.resistor_setting.is_pattern = p_ins->param[0]; - pel_scan_msg.resistor_setting.value = u8_to_u32(p_ins->param[1], p_ins->param[2], p_ins->param[3], p_ins->param[4]); - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.resistor_setting), pdMS_TO_TICKS(500))); - - pel_scan_msg.opcode = PEL_NOTIFY; - pel_scan_msg.notify_setting.count = u8_to_u16(p_ins->param[5], p_ins->param[6]); - pel_scan_msg.notify_setting.drop = 0; - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.notify_setting), pdMS_TO_TICKS(500))); - - break; - - case 0x01: // manual_scan_mode set resistor - // 30 00 01 01 01 00 00 00 07 00 03 (pattern_index) - // 30 00 01 01 00 00 00 00 F0 00 03 (resistor_mask) - pel_scan_msg.opcode = PEL_SET_RESISTOR; - pel_scan_msg.resistor_setting.is_pattern = p_ins->param[0]; - pel_scan_msg.resistor_setting.value = u8_to_u32(p_ins->param[1], p_ins->param[2], p_ins->param[3], p_ins->param[4]); - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.resistor_setting), pdMS_TO_TICKS(500))); - - pel_scan_msg.opcode = PEL_NOTIFY; - pel_scan_msg.notify_setting.count = u8_to_u16(p_ins->param[5], p_ins->param[6]); - pel_scan_msg.notify_setting.drop = 0; - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.notify_setting), pdMS_TO_TICKS(500))); - break; - - case 0x02: // manual_scan_mode stop - // 30 00 01 02 + case 0x00: { + // manual_scan_mode stop + // 30 00 01 00 pel_scan_msg.opcode = PEL_STOP; ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode), pdMS_TO_TICKS(500))); break; + } + + case 0x01: { + // manual_scan_mode start + // 30 00 01 01 00 01 00 05 00 0A 00 03 (pattern_index) + // 30 00 01 01 00 00 00 F0 00 0A 00 03 (resistor_mask) + send_start_package(&packet_buf, sizeof(packet_buf)); + pel_scan_msg.opcode = PEL_START; + pel_scan_msg.resistor_setting.is_pattern = u8_to_u16(p_ins->param[0], p_ins->param[1]) & 0x01; + pel_scan_msg.resistor_setting.value = u8_to_u16(p_ins->param[2], p_ins->param[3]); + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.resistor_setting), pdMS_TO_TICKS(500))); + + pel_scan_msg.opcode = PEL_NOTIFY; + pel_scan_msg.notify_setting.drop = u8_to_u16(p_ins->param[4], p_ins->param[5]); + pel_scan_msg.notify_setting.count = u8_to_u16(p_ins->param[6], p_ins->param[7]); + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.notify_setting), pdMS_TO_TICKS(500))); + break; + } + + case 0x02: { + // manual_scan_mode set resistor + // 30 00 01 02 00 01 00 07 00 0A 00 03 (pattern_index) + // 30 00 01 02 00 00 00 F0 00 0A 00 03 (resistor_mask) + pel_scan_msg.opcode = PEL_SET_RESISTOR; + pel_scan_msg.resistor_setting.is_pattern = u8_to_u16(p_ins->param[0], p_ins->param[1]) & 0x01; + pel_scan_msg.resistor_setting.value = u8_to_u16(p_ins->param[2], p_ins->param[3]); + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.resistor_setting), pdMS_TO_TICKS(500))); + + pel_scan_msg.opcode = PEL_NOTIFY; + pel_scan_msg.notify_setting.drop = u8_to_u16(p_ins->param[4], p_ins->param[5]); + pel_scan_msg.notify_setting.count = u8_to_u16(p_ins->param[6], p_ins->param[7]); + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.notify_setting), pdMS_TO_TICKS(500))); + break; + } default: break; @@ -632,81 +645,138 @@ static void auto_scan_mode(uint8_t *ins, uint16_t size) switch (p_ins->opcode) { - case 0x03: { - // auto_scan_mode start with drop n * 10ms - // 30 00 02 03 00 1C 00 01 00 0A 00 05 - uint32_t pattern_max = u8_to_u16(p_ins->param[0], p_ins->param[1]); - uint32_t pattern_min = u8_to_u16(p_ins->param[2], p_ins->param[3]); - uint32_t drop_10ms = u8_to_u16(p_ins->param[4], p_ins->param[5]); - uint32_t notify_count = u8_to_u16(p_ins->param[6], p_ins->param[7]); - - send_start_package(&packet_buf, sizeof(packet_buf)); - - for (uint32_t i = pattern_min; i <= pattern_max; i++) - { - pel_scan_msg.opcode = PEL_START; - pel_scan_msg.resistor_setting.is_pattern = true; - pel_scan_msg.resistor_setting.value = i; - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.resistor_setting), pdMS_TO_TICKS(500))); - - pel_scan_msg.opcode = PEL_NOTIFY; - pel_scan_msg.notify_setting.count = notify_count; - pel_scan_msg.notify_setting.drop = drop_10ms; - pel_scan_msg.notify_setting.complete_cb = auto_scan_complete; - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.notify_setting), pdMS_TO_TICKS(500))); - - wait_auto_scan_complete(); - } - - pel_scan_msg.opcode = PEL_STOP; - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode), pdMS_TO_TICKS(500))); - } - break; - case 0x00: { - // auto_scan_mode start - // 30 00 02 00 00 00 00 1C 00 00 00 01 00 05 - uint32_t pattern_max = u8_to_u32(p_ins->param[0], p_ins->param[1], p_ins->param[2], p_ins->param[3]); - uint32_t pattern_min = u8_to_u32(p_ins->param[4], p_ins->param[5], p_ins->param[6], p_ins->param[7]); - uint32_t notify_count = u8_to_u16(p_ins->param[8], p_ins->param[9]); - - send_start_package(&packet_buf, sizeof(packet_buf)); - - for (uint32_t i = pattern_min; i <= pattern_max; i++) - { - pel_scan_msg.opcode = PEL_START; - pel_scan_msg.resistor_setting.is_pattern = true; - pel_scan_msg.resistor_setting.value = i; - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.resistor_setting), pdMS_TO_TICKS(500))); - - pel_scan_msg.opcode = PEL_NOTIFY; - pel_scan_msg.notify_setting.count = notify_count; - pel_scan_msg.notify_setting.drop = 0; - pel_scan_msg.notify_setting.complete_cb = auto_scan_complete; - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.notify_setting), pdMS_TO_TICKS(500))); - - wait_auto_scan_complete(); - } - - pel_scan_msg.opcode = PEL_STOP; - ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode), pdMS_TO_TICKS(500))); - } - break; - - case 0x01: // auto_scan_mode stop - // 30 00 02 01 + // 30 00 02 00 pel_scan_msg.opcode = PEL_STOP; ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode), pdMS_TO_TICKS(500))); break; + } + + case 0x01: { + // auto_scan_mode start + // 30 00 02 01 00 1C 00 01 00 0A 00 05 + uint16_t pattern_max = u8_to_u16(p_ins->param[0], p_ins->param[1]); + uint16_t pattern_min = u8_to_u16(p_ins->param[2], p_ins->param[3]); + + send_start_package(&packet_buf, sizeof(packet_buf)); + + for (uint16_t i = pattern_min; i <= pattern_max; i++) + { + pel_scan_msg.opcode = PEL_START; + pel_scan_msg.resistor_setting.is_pattern = true; + pel_scan_msg.resistor_setting.value = i; + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.resistor_setting), pdMS_TO_TICKS(500))); + + pel_scan_msg.opcode = PEL_NOTIFY; + pel_scan_msg.notify_setting.drop = u8_to_u16(p_ins->param[4], p_ins->param[5]); + pel_scan_msg.notify_setting.count = u8_to_u16(p_ins->param[6], p_ins->param[7]); + pel_scan_msg.notify_setting.complete_cb = auto_scan_complete; + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.notify_setting), pdMS_TO_TICKS(500))); + + wait_auto_scan_complete(); + } + + pel_scan_msg.opcode = PEL_STOP; + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode), pdMS_TO_TICKS(500))); + break; + } default: break; } } -#define MANUAL_SCAN_MODE 0x01 -#define AUTO_SCAN_MODE 0x02 +static void R_external_calibration_mode(uint8_t *ins, uint16_t size) +{ +#define R1 PEL_0P5R_MASK +#define R2 PEL_1P0R_MASK +#define R3 PEL_2P0R_MASK +#define R4 PEL_4P0R_MASK +#define R5 PEL_8P0R_MASK +#define R6 PEL_16P2R_MASK +#define R7 PEL_32P4R_MASK +#define R8 PEL_63P4R_MASK +#define R9 PEL_127R_MASK +#define R10 PEL_255R_MASK +#define R11 PEL_511R_MASK +#define R12 PEL_1000R_MASK + + struct __PACKED + { + uint8_t id : 4; + uint8_t ins_type : 4; + uint8_t pkg_size; + uint8_t mode; + uint8_t opcode; + uint8_t param[]; + } *p_ins = (void *)ins; + + uint32_t calibration_bits_pattern_tab[] = { + R1, + R2, + R1 | R2, + R3, + R2 | R3, + R4, + R3 | R4, + R5, + R4 | R5, + R6, + R5 | R6, + R7, + R6 | R7, + R8, + R7 | R8, + }; + + global_memoryboard_id = p_ins->id; + + static pel_scan_msg_t pel_scan_msg; + pel20_notify_packet1_t packet_buf = { 0 }; + + switch (p_ins->opcode) + { + case 0x00: { + // R_external_calibration_mode stop + // 30 00 03 00 + break; + } + + case 0x01: { + // R_external_calibration_mode start with drop n * 10ms + // 30 00 03 01 00 0A 00 05 + send_start_package(&packet_buf, sizeof(packet_buf)); + + for (uint16_t i = 0; i < COUNTOF(calibration_bits_pattern_tab); i++) + { + pel_scan_msg.opcode = PEL_START; + pel_scan_msg.resistor_setting.is_pattern = false; + pel_scan_msg.resistor_setting.value = calibration_bits_pattern_tab[i]; + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.resistor_setting), pdMS_TO_TICKS(500))); + + pel_scan_msg.opcode = PEL_NOTIFY; + pel_scan_msg.notify_setting.drop = u8_to_u16(p_ins->param[0], p_ins->param[1]); + pel_scan_msg.notify_setting.count = u8_to_u16(p_ins->param[2], p_ins->param[3]); + pel_scan_msg.notify_setting.complete_cb = auto_scan_complete; + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode) + sizeof(pel_scan_msg.notify_setting), pdMS_TO_TICKS(500))); + + wait_auto_scan_complete(); + } + + pel_scan_msg.opcode = PEL_STOP; + ASSERT(xMessageBufferSend(pel_scan_msqQ, &pel_scan_msg, sizeof(pel_scan_msg.opcode), pdMS_TO_TICKS(500))); + break; + } + + default: + break; + } +} + +#define MANUAL_SCAN_MODE 0x01 +#define AUTO_SCAN_MODE 0x02 +#define R_EXTERNAL_CALIBRATION_MODE 0x03 const elite_instance_t pel_elite_instance = { .cis_func = { @@ -716,9 +786,10 @@ const elite_instance_t pel_elite_instance = { [VIS_RST] = vis_rst, }, .ris_func = { - [MANUAL_SCAN_MODE] = manual_scan_mode, - [AUTO_SCAN_MODE] = auto_scan_mode, - [DEV_MODE] = dev_mode, + [MANUAL_SCAN_MODE] = manual_scan_mode, + [AUTO_SCAN_MODE] = auto_scan_mode, + [R_EXTERNAL_CALIBRATION_MODE] = R_external_calibration_mode, + [DEV_MODE] = dev_mode, } }; diff --git a/pel.h b/pel.h index 60212e3..c0ef787 100644 --- a/pel.h +++ b/pel.h @@ -11,10 +11,10 @@ extern "C" #include "elite_board.h" #define VERSION_DATE_YEAR 25 -#define VERSION_DATE_MONTH 2 -#define VERSION_DATE_DAY 21 +#define VERSION_DATE_MONTH 3 +#define VERSION_DATE_DAY 13 #define VERSION_DATE_HOUR 10 -#define VERSION_DATE_MINUTE 18 +#define VERSION_DATE_MINUTE 0 #define PEL_0P5R_MASK (0x01 << 0) #define PEL_1P0R_MASK (0x01 << 1)