827 lines
24 KiB
C
827 lines
24 KiB
C
#include "app_config.h"
|
|
#include "app_error.h"
|
|
|
|
#include "elite_board.h"
|
|
#include "pel.h"
|
|
|
|
#include "elite_def.h"
|
|
|
|
#include "nrf_delay.h"
|
|
#include "nrf_gpio.h"
|
|
#include "nrf_log.h"
|
|
|
|
#include "adc_drv.h"
|
|
|
|
#include "FreeRTOS.h"
|
|
#include "message_buffer.h"
|
|
#include "queue.h"
|
|
#include "semphr.h"
|
|
#include "stream_buffer.h"
|
|
#include "task.h"
|
|
|
|
#if (DEF_ELITE_MODEL == DEF_ELITE_PEL_V2_0)
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t pattern_index;
|
|
uint32_t resistor_mask;
|
|
float resistor_conductance;
|
|
} resistor_t;
|
|
|
|
typedef struct
|
|
{
|
|
resistor_t resistor;
|
|
bool use_pattern_index;
|
|
} load_config_t;
|
|
|
|
static load_config_t load_config;
|
|
|
|
static float _load_set(uint32_t mask)
|
|
{
|
|
typedef struct
|
|
{
|
|
float val;
|
|
uint32_t pin;
|
|
uint32_t mask;
|
|
} input_pin_t;
|
|
|
|
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.3, INPUT_5_PIN, PEL_8P0R_MASK},
|
|
{ 16.2, INPUT_6_PIN, PEL_16P2R_MASK},
|
|
{ 32.4, INPUT_7_PIN, PEL_32P4R_MASK},
|
|
{ 62.5, INPUT_8_PIN, PEL_63P4R_MASK},
|
|
{ 130.0, INPUT_9_PIN, PEL_127R_MASK},
|
|
{ 270.0, INPUT_10_PIN, PEL_255R_MASK},
|
|
{ 510.0, INPUT_11_PIN, PEL_511R_MASK},
|
|
{1000.0, INPUT_12_PIN, PEL_1000R_MASK},
|
|
};
|
|
|
|
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;
|
|
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
|
|
{
|
|
nrf_gpio_pin_set(input_pin_tab[i].pin);
|
|
}
|
|
}
|
|
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;
|
|
load_config.resistor.resistor_conductance = _load_set(load_config.resistor.resistor_mask);
|
|
}
|
|
|
|
static void set_resistor_load_pattern(uint32_t index)
|
|
{
|
|
const resistor_t pattern_tab[] = {
|
|
{ 1, 0b0000000000000111},
|
|
{ 2, 0b0000000000000011},
|
|
{ 3, 0b0000000000000101},
|
|
{ 4, 0b0000000000000001},
|
|
{ 5, 0b0000000000001110},
|
|
{ 6, 0b0000000000000110},
|
|
{ 7, 0b0000000000001010},
|
|
{ 8, 0b0000000000000010},
|
|
{ 9, 0b0000000000011100},
|
|
{10, 0b0000000000001100},
|
|
{11, 0b0000000000010100},
|
|
{12, 0b0000000000000100},
|
|
{13, 0b0000000000111000},
|
|
{14, 0b0000000000011000},
|
|
{15, 0b0000000000101000},
|
|
{16, 0b0000000000001000},
|
|
{17, 0b0000000001110000},
|
|
{18, 0b0000000000110000},
|
|
{19, 0b0000000001010000},
|
|
{20, 0b0000000000010000},
|
|
{21, 0b0000000011100000},
|
|
{22, 0b0000000001100000},
|
|
{23, 0b0000000010100000},
|
|
{24, 0b0000000000100000},
|
|
{25, 0b0000000111000000},
|
|
{26, 0b0000000011000000},
|
|
{27, 0b0000000101000000},
|
|
{28, 0b0000000001000000},
|
|
{29, 0b0000001110000000},
|
|
{30, 0b0000000110000000},
|
|
{31, 0b0000001010000000},
|
|
{32, 0b0000000010000000},
|
|
{33, 0b0000011100000000},
|
|
{34, 0b0000001100000000},
|
|
{35, 0b0000010100000000},
|
|
{36, 0b0000000100000000},
|
|
{37, 0b0000111000000000},
|
|
{38, 0b0000011000000000},
|
|
{39, 0b0000101000000000},
|
|
{40, 0b0000001000000000},
|
|
{41, 0b0000110000000000},
|
|
{42, 0b0000010000000000},
|
|
{43, 0b0000100000000000},
|
|
};
|
|
|
|
for (int32_t i = 0; i < ARRAY_SIZE(pattern_tab); i++)
|
|
{
|
|
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;
|
|
load_config.resistor.resistor_conductance = _load_set(load_config.resistor.resistor_mask);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void set_resistor_to_high_z(void)
|
|
{
|
|
NRF_LOG_INFO("%s", __FUNCTION__);
|
|
set_resistor_load_bits(0);
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t setting_pattern_id_max;
|
|
uint32_t setting_pattern_id_min;
|
|
uint16_t setting_notify_cnt_every_pattern;
|
|
} auto_scan_mode_params_t;
|
|
|
|
typedef struct
|
|
{
|
|
union
|
|
{
|
|
uint32_t value;
|
|
uint32_t bitmask;
|
|
uint32_t pattern;
|
|
};
|
|
bool is_pattern;
|
|
} resistor_setting_t;
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t count;
|
|
uint32_t drop;
|
|
bool the_last_record_flag;
|
|
void (*complete_cb)(void);
|
|
} notify_setting_t;
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t opcode;
|
|
union
|
|
{
|
|
uint32_t raw[256 / sizeof(uint32_t)];
|
|
resistor_setting_t resistor_setting;
|
|
notify_setting_t notify_setting;
|
|
};
|
|
} pel_scan_msg_t;
|
|
|
|
static uint8_t global_memoryboard_id = 0xFF;
|
|
static SemaphoreHandle_t auto_scan_cplt_sem = NULL;
|
|
static SemaphoreHandle_t adc_convt_cplt_sem = NULL;
|
|
static MessageBufferHandle_t pel_scan_msqQ = NULL;
|
|
|
|
static void vis_rst(uint8_t *ins, uint16_t size)
|
|
{
|
|
NRF_LOG_INFO("%s", __FUNCTION__);
|
|
}
|
|
|
|
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_update(uint8_t * p_value, uint16_t len);
|
|
le_data_update((void *)cis_ver, sizeof(cis_ver));
|
|
}
|
|
|
|
static void send_start_package(void *packet_buf, uint32_t packet_len)
|
|
{
|
|
NRF_LOG_INFO(__FUNCTION__);
|
|
|
|
for (uint32_t i = 0; i < 4; i++)
|
|
{
|
|
ret_code_t le_event_notify(uint8_t * p_value, uint16_t len);
|
|
nrf_gpio_pin_set(TP2_PIN);
|
|
ret_code_t ret = le_event_notify(packet_buf, packet_len);
|
|
nrf_gpio_pin_clear(TP2_PIN);
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(10));
|
|
|
|
NRF_LOG_HEXDUMP_INFO(packet_buf, packet_len);
|
|
NRF_LOG_INFO("\n");
|
|
}
|
|
}
|
|
|
|
static void pel_scan_mode_notify(scan_mode_notify_packet_t *packet_buf, uint32_t packet_len)
|
|
{
|
|
int32_t adc_raw[COUNTOF(pel_hw.adc.results)] = { 0 };
|
|
|
|
for (int i = 0; i < COUNTOF(pel_hw.adc.results); i++)
|
|
{
|
|
adc_raw[i] = pel_hw.adc.results[i];
|
|
}
|
|
|
|
adc_read_mutiple_channels_convert_milivolt(adc_raw, pel_hw.adc.results_f, COUNTOF(pel_hw.adc.channels));
|
|
|
|
packet_buf->mem_board_id = global_memoryboard_id;
|
|
packet_buf->packet_seq++;
|
|
packet_buf->notify_time = xTaskGetTickCount();
|
|
packet_buf->output_vo_raw = pel_hw.adc.results[2];
|
|
packet_buf->output_vc_raw = pel_hw.adc.results[3];
|
|
packet_buf->output_ve_raw = pel_hw.adc.results[4];
|
|
packet_buf->hold_OUT_v = pel_hw.adc.results_f[2] * 10 / 1000;
|
|
packet_buf->hold_VCC_v = pel_hw.adc.results_f[3] * 10 / 1000;
|
|
packet_buf->hold_VEE_v = pel_hw.adc.results_f[4] * 10 / 1000;
|
|
packet_buf->resis_pattern_id = load_config.resistor.pattern_index;
|
|
packet_buf->resis_bitsmask = load_config.resistor.resistor_mask;
|
|
packet_buf->resis_g_value = load_config.resistor.resistor_conductance;
|
|
packet_buf->val_1 = 0xFFFFFFFF;
|
|
packet_buf->val_2 = 0xFFFFFFFF;
|
|
packet_buf->val_3 = 0xFFFF;
|
|
ret_code_t ret = le_event_async_notify((void *)packet_buf, packet_len, pdMS_TO_TICKS(5));
|
|
|
|
// NRF_LOG_HEXDUMP_INFO(packet_buf,packet_len);
|
|
{
|
|
char str[128];
|
|
snprintf(str, sizeof(str), "{%3d, %3d, %10lu, %10lu, %10lu, %10lu, %2.7f, %2.7f, %2.7f, %5d, 0x%04X, %.7f, %d}", packet_buf->mem_board_id, packet_buf->packet_seq, packet_buf->notify_time, packet_buf->output_vo_raw, packet_buf->output_vc_raw, packet_buf->output_ve_raw, packet_buf->hold_OUT_v, packet_buf->hold_VCC_v, packet_buf->hold_VEE_v, packet_buf->resis_pattern_id, packet_buf->resis_bitsmask, packet_buf->resis_g_value, packet_buf->mode_complete);
|
|
NRF_LOG_INFO("%s", str);
|
|
}
|
|
}
|
|
|
|
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
|
|
};
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
static void decode_and_set_resistor_pattern(uint8_t *param)
|
|
{
|
|
uint16_t pattern_id = u8_to_u16(param[0], param[1]);
|
|
|
|
set_resistor_load_pattern(pattern_id);
|
|
}
|
|
|
|
static void decode_and_set_manual_resistor(uint8_t *param)
|
|
{
|
|
uint16_t manual_val = u8_to_u16(param[0], param[1]);
|
|
|
|
set_resistor_load_bits(manual_val);
|
|
}
|
|
|
|
static void dev_mode_input_resistor(uint8_t *ins)
|
|
{
|
|
NRF_LOG_INFO("[DEV MODE] %s", __FUNCTION__);
|
|
|
|
struct __PACKED
|
|
{
|
|
uint8_t id : 4;
|
|
uint8_t ins_type : 4;
|
|
uint8_t pkg_size;
|
|
uint8_t mode;
|
|
uint8_t func_id;
|
|
uint8_t opcode;
|
|
uint8_t param[];
|
|
} *p_ins = (void *)ins;
|
|
|
|
switch (p_ins->opcode)
|
|
{
|
|
case 0x00:
|
|
set_resistor_to_high_z();
|
|
break;
|
|
|
|
case 0x01:
|
|
decode_and_set_resistor_pattern(p_ins->param);
|
|
break;
|
|
|
|
case 0x02:
|
|
decode_and_set_manual_resistor(p_ins->param);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void start_adc_pulse(uint32_t pusle_cnt, void (*convt_done_cb)(void))
|
|
{
|
|
pel_config_t pel_cfg = {
|
|
.anode_pin = ANODE_PIN,
|
|
.cathode_pin = CATHODE_PIN,
|
|
.smaple_r_pin = SAMPLE_R_PIN,
|
|
.sample_v_pin = SAMPLE_V_PIN,
|
|
.test_pin = TP1_PIN,
|
|
.mode = BOARD_IOPx,
|
|
.point_us = {
|
|
10000,
|
|
3,
|
|
5,
|
|
2,
|
|
0,
|
|
},
|
|
.pulse_cnt = pusle_cnt,
|
|
.gain = NRF_SAADC_GAIN1_6,
|
|
.smaple_time = NRF_SAADC_ACQTIME_10US,
|
|
.adc_timing_shift = 0,
|
|
.convt_new_arrival_cb = convt_done_cb,
|
|
};
|
|
|
|
pel_pulse_gen_init(pel_cfg);
|
|
pel_pulse_gen_start();
|
|
}
|
|
|
|
static void stop_adc_pulse(void)
|
|
{
|
|
pel_pulse_gen_stop();
|
|
}
|
|
|
|
static void adc_event_end_cb(void)
|
|
{
|
|
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
|
|
xSemaphoreGiveFromISR(adc_convt_cplt_sem, &xHigherPriorityTaskWoken);
|
|
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
|
|
}
|
|
|
|
static void pel_pulse_start(void *p_arg)
|
|
{
|
|
NRF_LOG_INFO("%s()", __FUNCTION__);
|
|
|
|
resistor_setting_t *p_setting = p_arg;
|
|
|
|
stop_adc_pulse();
|
|
|
|
vTaskDelay(pdMS_TO_TICKS(20));
|
|
|
|
if (p_setting->is_pattern == true)
|
|
{
|
|
nrf_gpio_pin_set(RELAY1_PIN);
|
|
set_resistor_load_pattern(p_setting->pattern);
|
|
nrf_gpio_pin_clear(RELAY1_PIN);
|
|
}
|
|
else
|
|
{
|
|
nrf_gpio_pin_set(RELAY1_PIN);
|
|
set_resistor_load_bits(p_setting->bitmask);
|
|
nrf_gpio_pin_clear(RELAY1_PIN);
|
|
}
|
|
|
|
nrf_gpio_pin_set(TP2_PIN); // For testing
|
|
start_adc_pulse(0xFFFFFFFF, adc_event_end_cb);
|
|
nrf_gpio_pin_clear(TP2_PIN); // For testing
|
|
}
|
|
|
|
static void pel_pulse_stop(void *p_arg)
|
|
{
|
|
NRF_LOG_INFO("%s()", __FUNCTION__);
|
|
|
|
UNUSED_PARAMETER(p_arg);
|
|
|
|
stop_adc_pulse();
|
|
}
|
|
|
|
#define MODE_COMPLETE (0xA)
|
|
static void pel_pulse_notify(void *p_arg)
|
|
{
|
|
NRF_LOG_INFO("%s()", __FUNCTION__);
|
|
|
|
notify_setting_t *p_setting = p_arg;
|
|
|
|
static scan_mode_notify_packet_t packet_buf = { 0 };
|
|
|
|
xSemaphoreTake(adc_convt_cplt_sem, 0);
|
|
|
|
for (uint32_t i = 0; i < p_setting->drop; i++)
|
|
{
|
|
xSemaphoreTake(adc_convt_cplt_sem, pdMS_TO_TICKS(1000));
|
|
}
|
|
|
|
for (uint32_t i = 0; i < p_setting->count; i++)
|
|
{
|
|
xSemaphoreTake(adc_convt_cplt_sem, pdMS_TO_TICKS(1000));
|
|
|
|
if (p_setting->the_last_record_flag && (i == p_setting->count - 1))
|
|
{
|
|
packet_buf.mode_complete |= MODE_COMPLETE;
|
|
}
|
|
else
|
|
{
|
|
packet_buf.mode_complete &= ~MODE_COMPLETE;
|
|
}
|
|
|
|
nrf_gpio_pin_set(TP2_PIN);
|
|
pel_scan_mode_notify(&packet_buf, sizeof(packet_buf));
|
|
nrf_gpio_pin_clear(TP2_PIN);
|
|
}
|
|
|
|
if (p_setting->complete_cb)
|
|
{
|
|
p_setting->complete_cb();
|
|
}
|
|
}
|
|
|
|
#define PEL_START 0x00
|
|
#define PEL_SET_RESISTOR 0x01
|
|
#define PEL_STOP 0x02
|
|
#define PEL_NOTIFY 0x03
|
|
|
|
static void pel_scan_mode_task(void *pvArg)
|
|
{
|
|
uint8_t recv[sizeof(pel_scan_msg_t)];
|
|
|
|
for (;;)
|
|
{
|
|
pel_scan_msg_t *p = (void *)recv;
|
|
uint32_t recv_size = xMessageBufferReceive(pel_scan_msqQ, recv, sizeof(recv), portMAX_DELAY);
|
|
if (recv_size)
|
|
{
|
|
switch (p->opcode)
|
|
{
|
|
case PEL_START:
|
|
pel_pulse_start(&p->resistor_setting);
|
|
break;
|
|
case PEL_SET_RESISTOR:
|
|
pel_pulse_start(&p->resistor_setting);
|
|
break;
|
|
case PEL_STOP:
|
|
pel_pulse_stop(NULL);
|
|
break;
|
|
case PEL_NOTIFY:
|
|
pel_pulse_notify(&p->notify_setting);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void dev_mode(uint8_t *ins, uint16_t size)
|
|
{
|
|
struct __PACKED
|
|
{
|
|
uint8_t id : 4;
|
|
uint8_t ins_type : 4;
|
|
uint8_t pkg_size;
|
|
uint8_t mode;
|
|
uint8_t func_id;
|
|
uint8_t opcode;
|
|
uint8_t param[];
|
|
} *p_ins = (void *)ins;
|
|
|
|
global_memoryboard_id = p_ins->id;
|
|
|
|
switch (p_ins->func_id)
|
|
{
|
|
case 0x01:
|
|
dev_mode_input_resistor(ins);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void manual_scan_mode(uint8_t *ins, uint16_t size)
|
|
{
|
|
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;
|
|
|
|
global_memoryboard_id = p_ins->id;
|
|
|
|
static pel_scan_msg_t pel_scan_msg;
|
|
scan_mode_notify_packet_t packet_buf = { 0 };
|
|
|
|
switch (p_ins->opcode)
|
|
{
|
|
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((void *)&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;
|
|
}
|
|
}
|
|
|
|
static void auto_scan_complete(void)
|
|
{
|
|
xSemaphoreGive(auto_scan_cplt_sem);
|
|
}
|
|
|
|
static void wait_auto_scan_complete(void)
|
|
{
|
|
xSemaphoreTake(auto_scan_cplt_sem, portMAX_DELAY);
|
|
}
|
|
|
|
static void auto_scan_mode(uint8_t *ins, uint16_t size)
|
|
{
|
|
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;
|
|
|
|
global_memoryboard_id = p_ins->id;
|
|
|
|
static pel_scan_msg_t pel_scan_msg;
|
|
scan_mode_notify_packet_t packet_buf = { 0 };
|
|
|
|
switch (p_ins->opcode)
|
|
{
|
|
case 0x00: {
|
|
// auto_scan_mode stop
|
|
// 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]);
|
|
pel_scan_msg.notify_setting.the_last_record_flag = false;
|
|
|
|
send_start_package((void *)&packet_buf, sizeof(packet_buf));
|
|
|
|
for (uint16_t i = pattern_max; i >= pattern_min; 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;
|
|
if (i == pattern_min)
|
|
{
|
|
pel_scan_msg.notify_setting.the_last_record_flag = true;
|
|
}
|
|
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;
|
|
}
|
|
}
|
|
|
|
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;
|
|
scan_mode_notify_packet_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
|
|
pel_scan_msg.notify_setting.the_last_record_flag = false;
|
|
|
|
send_start_package((void *)&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;
|
|
if (i == COUNTOF(calibration_bits_pattern_tab) - 1)
|
|
{
|
|
pel_scan_msg.notify_setting.the_last_record_flag = true;
|
|
}
|
|
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 = {
|
|
[CIS_VERSION] = cis_version,
|
|
},
|
|
.vis_func = {
|
|
[VIS_RST] = vis_rst,
|
|
},
|
|
.ris_func = {
|
|
[MANUAL_SCAN_MODE] = manual_scan_mode,
|
|
[AUTO_SCAN_MODE] = auto_scan_mode,
|
|
[R_EXTERNAL_CALIBRATION_MODE] = R_external_calibration_mode,
|
|
[DEV_MODE] = dev_mode,
|
|
}
|
|
};
|
|
|
|
const elite_instance_t *pel_init(void)
|
|
{
|
|
NRF_LOG_INFO("[Board] FW ver: %02d%02d%02d %02d:%02d", VERSION_DATE_YEAR, VERSION_DATE_MONTH, VERSION_DATE_DAY, VERSION_DATE_HOUR, VERSION_DATE_MINUTE);
|
|
NRF_LOG_INFO("[Board] %s", BOARD_IOPx ? "IOPH" : "IOPL");
|
|
|
|
auto_scan_cplt_sem = xSemaphoreCreateBinary();
|
|
ASSERT(auto_scan_cplt_sem);
|
|
|
|
adc_convt_cplt_sem = xSemaphoreCreateBinary();
|
|
ASSERT(adc_convt_cplt_sem);
|
|
|
|
pel_scan_msqQ = xMessageBufferCreate(1024);
|
|
ASSERT(pel_scan_msqQ);
|
|
|
|
ASSERT(xTaskCreate(pel_scan_mode_task, "pel_scan_mode", 512, NULL, 4, NULL));
|
|
|
|
return &pel_elite_instance;
|
|
}
|
|
|
|
#endif
|