Files
microchip-application-bmd38…/pel.c
T
chain40 5892bffd3c feat: 支援 Pulse-E-Load 1.0 初版
1. 實作 Dev mode
2. 實作 cis_version
3. ADC_DRV 新增 adc_read_mutiple_channels()/adc_read_mutiple_channels_ex(), 連續轉換多個 ADC channel

備註: 目前設定使用 adc_read_mutiple_channels()/adc_read_mutiple_channels_ex() 每筆 ADC 需要 sample 40us
2024-05-21 21:36:36 +08:00

235 lines
6.1 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_01)
typedef struct
{
float val;
uint32_t pin;
uint32_t mask;
} input_pin_t;
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(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(5);
nrf_gpio_pin_toggle(SAMPLE_R_PIN);
nrf_gpio_pin_toggle(SAMPLE_V_PIN);
nrf_delay_us(5);
nrf_gpio_pin_toggle(CATHODE_PIN);
nrf_gpio_pin_toggle(ANODE_PIN);
nrf_gpio_pin_toggle(SAMPLE_R_PIN);
nrf_gpio_pin_toggle(SAMPLE_V_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 load_mask)
{
uint32_t ch_list[] = {
OUTPUT_R1_CHANNEL,
OUTPUT_R2_CHANNEL,
OUTPUT_VO_CHANNEL,
OUTPUT_VC_CHANNEL,
OUTPUT_VE_CHANNEL
};
int32_t results[COUNTOF(ch_list)];
/* config E-load */
_load_set(load_mask);
/* send a pulse to sample and then read ADC channels */
adc_read_mutiple_channels_ex(ch_list, results, COUNTOF(ch_list), _sample);
/* copy results */
output_data.output_r1 = results[0];
output_data.output_r2 = results[1];
output_data.output_vo = results[2];
output_data.output_vc = results[3];
output_data.output_ve = results[4];
NRF_LOG_INFO("output_r1: 0x%04X", output_data.output_r1);
NRF_LOG_INFO("output_r2: 0x%04X", output_data.output_r2);
NRF_LOG_INFO("output_vo: 0x%04X", output_data.output_vo);
NRF_LOG_INFO("output_vc: 0x%04X", output_data.output_vc);
NRF_LOG_INFO("output_ve: 0x%04X", output_data.output_ve);
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__);
}
#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;
}
struct
{
uint8_t status;
uint16_t mask;
} __PACKED *p_param = (void *)p_ins->param;
switch (p_ins->opcode)
{
case 0x00: {
pel_relays_set(p_param->status);
dev_mode_pel_output = pel_smaple_and_convt_all(p_param->mask);
break;
}
case 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));
break;
}
case 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));
break;
}
case 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));
break;
}
case 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));
break;
}
case 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;
}
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