373 lines
10 KiB
C
373 lines
10 KiB
C
#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_10)
|
|
|
|
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 (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_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 */
|
|
_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 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__);
|
|
}
|
|
|
|
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);
|
|
}
|
|
}
|
|
|
|
#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 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;
|
|
}
|
|
|
|
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
|