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
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
#include "adc_drv.h"
|
||||
|
||||
|
||||
#if (DEF_ADS8691_ENABLED)
|
||||
#include "ads8691.h"
|
||||
extern const adc_drv_if_t ads8691;
|
||||
static const adc_drv_if_t *p_inst = &ads8691;
|
||||
#else
|
||||
#else
|
||||
#include "builtin_saadc.h"
|
||||
static const adc_drv_if_t *p_inst = &builtin_saadc;
|
||||
#endif
|
||||
@@ -48,6 +47,25 @@ int adc_read(uint32_t channel, int32_t *adc_val)
|
||||
return p_inst->read(channel, adc_val);
|
||||
}
|
||||
|
||||
int adc_read_mutiple_channels(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->read_multiple_channels(p_channel, p_adc_val, cnt);
|
||||
}
|
||||
|
||||
int adc_read_mutiple_channels_ex(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt, void (*preliminary_action)(void))
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
{
|
||||
return ADC_DRV_ERROR;
|
||||
}
|
||||
return p_inst->read_multiple_channels_ex(p_channel, p_adc_val, cnt, preliminary_action);
|
||||
}
|
||||
|
||||
|
||||
int adc_read_milivolt(uint32_t channel, float *mv)
|
||||
{
|
||||
if (p_inst == NULL)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#ifndef __ADC_DRV_H__
|
||||
#define __ADC_DRV_H__
|
||||
|
||||
#include "app_config.h"
|
||||
#include "adc_drv_if.h"
|
||||
#include "app_config.h"
|
||||
|
||||
#define ADC_DRV_ERROR (-1)
|
||||
#define ADC_DRV_SUCCESS (0)
|
||||
@@ -23,12 +23,16 @@ int adc_reset(void);
|
||||
int adc_gain(adc_gain_t gain);
|
||||
int adc_read(uint32_t channel, int32_t *adc_val);
|
||||
int adc_read_milivolt(uint32_t channel, float *mv);
|
||||
int adc_read_mutiple_channels(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt);
|
||||
int adc_read_mutiple_channels_ex(uint32_t *p_channel, int32_t *p_adc_val, uint32_t cnt, void (*preliminary_action)(void));
|
||||
#else
|
||||
#define adc_init()
|
||||
#define adc_reset()
|
||||
#define adc_gain(x)
|
||||
#define adc_read(x, y)
|
||||
#define adc_read_milivolt(x, y)
|
||||
#define adc_read_mutiple_channels(x, y, z)
|
||||
#define adc_read_mutiple_channels_ex(x, y, z, a)
|
||||
#endif /* ! DEF_ADC_DRV_ENABLED */
|
||||
|
||||
#endif // !__ADC_DRV_H__
|
||||
|
||||
@@ -31,6 +31,8 @@ typedef struct
|
||||
int (*reset)(void);
|
||||
int (*read)(uint32_t channel, int32_t *adc_val);
|
||||
int (*read_milivolt)(uint32_t channel, float *adc_val);
|
||||
int (*read_multiple_channels)(uint32_t *p_channels, int32_t *adc_val, uint32_t count);
|
||||
int (*read_multiple_channels_ex)(uint32_t *p_channels, int32_t *adc_val, uint32_t count, void (*preliminary_action)(void));
|
||||
int (*gain)(adc_gain_t gain);
|
||||
} adc_drv_if_t;
|
||||
|
||||
|
||||
+19
-1
@@ -104,7 +104,8 @@ extern "C"
|
||||
|
||||
// BLE device name
|
||||
#define DEF_ELITE_EDC_20 0x00020109
|
||||
#define DEF_ELITE_MODEL DEF_ELITE_EDC_20
|
||||
#define DEF_PULSE_E_LOAD_01 0x00070000
|
||||
#define DEF_ELITE_MODEL DEF_PULSE_E_LOAD_01
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
#define ELITE_DEVICE_NAME "Elite-EDC"
|
||||
@@ -132,6 +133,23 @@ extern "C"
|
||||
|
||||
#define DEF_RTT_JSCOP_ENABLED 0
|
||||
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01)
|
||||
|
||||
#define ELITE_DEVICE_NAME "Pulse-E-Load"
|
||||
#define MAJOR_PRODUCT_NUMBER 0
|
||||
#define MINOR_PRODUCT_NUMBER 7
|
||||
#define MAJOR_VERSION_NUMBER 0
|
||||
#define MINOR_VERSION_NUMBER 0
|
||||
|
||||
#define DEF_FS_ENABLED 0
|
||||
#define DEF_FS_RTT_DIR 0
|
||||
#define DEF_GD25D10C_ENABLED 0
|
||||
|
||||
#define DEF_ADC_DRV_ENABLED 1
|
||||
#define DEF_BULTIN_ADC_ENABED 1
|
||||
|
||||
#define DEF_RTT_JSCOP_ENABLED 0
|
||||
|
||||
#endif
|
||||
|
||||
#define BLE_ELITE_SRV_ENABLED 1
|
||||
|
||||
@@ -205,6 +205,8 @@
|
||||
<ClCompile Include="main.c" />
|
||||
<ClCompile Include="builtin_saadc.c.c" />
|
||||
<ClCompile Include="j_scop.c" />
|
||||
<ClCompile Include="pel.c" />
|
||||
<ClCompile Include="pel10_io.c" />
|
||||
<ClCompile Include="sw_drv.c" />
|
||||
<ClCompile Include="syscalls.c" />
|
||||
<None Include="nRF52811_XXAA_s140.lds" />
|
||||
@@ -375,6 +377,8 @@
|
||||
<ClInclude Include="led_drv.h" />
|
||||
<ClInclude Include="led_drv_if.h" />
|
||||
<ClInclude Include="max5136.h" />
|
||||
<ClInclude Include="pel.h" />
|
||||
<ClInclude Include="pel10_io.h" />
|
||||
<ClInclude Include="sw_drv.h" />
|
||||
<ClInclude Include="sw_drv_if.h" />
|
||||
<ClInclude Include="sdk_config.h" />
|
||||
|
||||
+189
-21
@@ -8,10 +8,27 @@ static uint32_t m_gain = NRF_SAADC_GAIN1_6;
|
||||
static int read(uint32_t channel, int32_t *adc_val);
|
||||
static int init(void)
|
||||
{
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
/* enable ssadc */
|
||||
NRF_SAADC->ENABLE = 1;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
/* config resolution */
|
||||
NRF_SAADC->RESOLUTION = SAADC_RESOLUTION_VAL_14bit;
|
||||
NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_4X;
|
||||
/* auto calibration ssadc */
|
||||
NRF_SAADC->EVENTS_CALIBRATEDONE = 0;
|
||||
NRF_SAADC->TASKS_CALIBRATEOFFSET = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_CALIBRATEDONE == 0);
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -64,25 +81,38 @@ static double adc_convert_volt(uint16_t range_sel, int32_t val_14bit, bool is_di
|
||||
break;
|
||||
}
|
||||
|
||||
// differential V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 1) ¡V V(N)
|
||||
// single end V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 0)
|
||||
// differential V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 1) - V(N)
|
||||
// single end V(P) = RESULT * (REFERENCE / GAIN/) / 2(RESOLUTION - 0)
|
||||
|
||||
volt = ((double)val_14bit) * (vref / gain) / (0x01 << (14 - m));
|
||||
|
||||
/*
|
||||
NRF_LOG_INFO("adc_convert_volt(input_range_idx:%d, val_14bit:%d)", range_sel, val_14bit);
|
||||
{
|
||||
char str[32];
|
||||
snprintf(str, sizeof(str), "%.16lf", volt);
|
||||
NRF_LOG_INFO("adc_convert_result: %sV", str);
|
||||
}
|
||||
|
||||
*/
|
||||
return volt;
|
||||
}
|
||||
|
||||
static int read(uint32_t channel, int32_t *adc_val)
|
||||
{
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
/*
|
||||
ref: p.381, nrf52840_PS_v1.1.pdf
|
||||
Note: Oversampling should only be used when a single input channel is enabled, as averaging is
|
||||
performed over all enabled channels.
|
||||
*/
|
||||
NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_DISABLED;
|
||||
/* config analog input */
|
||||
NRF_SAADC->CH[0].PSELP = NRF_SAADC_INPUT_AIN0 + channel;
|
||||
NRF_SAADC->CH[0].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[0].CONFIG =
|
||||
@@ -93,22 +123,158 @@ static int read(uint32_t channel, int32_t *adc_val)
|
||||
(NRF_SAADC_ACQTIME_40US << SAADC_CH_CONFIG_TACQ_Pos) |
|
||||
(NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) |
|
||||
(NRF_SAADC_BURST_ENABLED << SAADC_CH_CONFIG_BURST_Pos);
|
||||
|
||||
/* enable ssadc */
|
||||
NRF_SAADC->ENABLE = 1;
|
||||
|
||||
uint16_t val = 0;
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&val;
|
||||
NRF_SAADC->RESULT.MAXCNT = 1;
|
||||
NRF_SAADC->EVENTS_RESULTDONE = 0;
|
||||
NRF_SAADC->TASKS_START = 1;
|
||||
NRF_SAADC->TASKS_SAMPLE = 1;
|
||||
/* read single channel */
|
||||
uint16_t val = 0;
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&val;
|
||||
NRF_SAADC->RESULT.MAXCNT = 1;
|
||||
NRF_SAADC->EVENTS_END = 0;
|
||||
NRF_SAADC->TASKS_SAMPLE = 1;
|
||||
NRF_SAADC->TASKS_START = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_RESULTDONE == 0);
|
||||
} while (NRF_SAADC->EVENTS_END == 0);
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
/* copy value */
|
||||
*adc_val = val;
|
||||
adc_convert_volt(m_gain, *adc_val, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_channels(uint32_t *p_channel, int32_t *adc_val, uint32_t count)
|
||||
{
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
/*
|
||||
ref: p.381, nrf52840_PS_v1.1.pdf
|
||||
Note: Oversampling should only be used when a single input channel is enabled, as averaging is
|
||||
performed over all enabled channels.
|
||||
*/
|
||||
NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_DISABLED;
|
||||
/* config analog inputs */
|
||||
for (uint32_t i = 0; i < COUNTOF(NRF_SAADC->CH); i++)
|
||||
{
|
||||
if (i < count)
|
||||
{
|
||||
NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_AIN0 + p_channel[i];
|
||||
NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].CONFIG =
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESP_Pos) |
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESN_Pos) |
|
||||
(m_gain << SAADC_CH_CONFIG_GAIN_Pos) |
|
||||
(NRF_SAADC_REFERENCE_INTERNAL << SAADC_CH_CONFIG_REFSEL_Pos) |
|
||||
(NRF_SAADC_ACQTIME_40US << SAADC_CH_CONFIG_TACQ_Pos) |
|
||||
(NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) |
|
||||
(NRF_SAADC_BURST_ENABLED << SAADC_CH_CONFIG_BURST_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].CONFIG = 0;
|
||||
}
|
||||
}
|
||||
/* enable ssadc */
|
||||
NRF_SAADC->ENABLE = 1;
|
||||
/* start convert */
|
||||
uint16_t val[16] = { 0 };
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&val[0];
|
||||
NRF_SAADC->RESULT.MAXCNT = count;
|
||||
NRF_SAADC->EVENTS_END = 0;
|
||||
NRF_SAADC->TASKS_SAMPLE = 1;
|
||||
NRF_SAADC->TASKS_START = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_END == 0);
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
/* copy values */
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
adc_val[i] = val[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_channels_ex(uint32_t *p_channel, int32_t *adc_val, uint32_t count, void (*preliminary_callback)(void))
|
||||
{
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->EVENTS_STOPPED = 0;
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_STOPPED == 0);
|
||||
/*
|
||||
ref: p.381, nrf52840_PS_v1.1.pdf
|
||||
Note: Oversampling should only be used when a single input channel is enabled, as averaging is
|
||||
performed over all enabled channels.
|
||||
*/
|
||||
NRF_SAADC->OVERSAMPLE = NRF_SAADC_OVERSAMPLE_DISABLED;
|
||||
/* config analog inputs */
|
||||
for (uint32_t i = 0; i < COUNTOF(NRF_SAADC->CH); i++)
|
||||
{
|
||||
if (i < count)
|
||||
{
|
||||
NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_AIN0 + p_channel[i];
|
||||
NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].CONFIG =
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESP_Pos) |
|
||||
(NRF_SAADC_RESISTOR_DISABLED << SAADC_CH_CONFIG_RESN_Pos) |
|
||||
(m_gain << SAADC_CH_CONFIG_GAIN_Pos) |
|
||||
(NRF_SAADC_REFERENCE_INTERNAL << SAADC_CH_CONFIG_REFSEL_Pos) |
|
||||
(NRF_SAADC_ACQTIME_40US << SAADC_CH_CONFIG_TACQ_Pos) |
|
||||
(NRF_SAADC_MODE_SINGLE_ENDED << SAADC_CH_CONFIG_MODE_Pos) |
|
||||
(NRF_SAADC_BURST_ENABLED << SAADC_CH_CONFIG_BURST_Pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
NRF_SAADC->CH[i].PSELP = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].PSELN = NRF_SAADC_INPUT_DISABLED;
|
||||
NRF_SAADC->CH[i].CONFIG = 0;
|
||||
}
|
||||
}
|
||||
/* enable ssadc */
|
||||
NRF_SAADC->ENABLE = 1;
|
||||
/* disable irq */
|
||||
__disable_irq();
|
||||
/* do preliminary job */
|
||||
if (preliminary_callback)
|
||||
{
|
||||
preliminary_callback();
|
||||
}
|
||||
/* start convert */
|
||||
uint16_t val[COUNTOF(NRF_SAADC->CH)] = { 0 };
|
||||
NRF_SAADC->RESULT.PTR = (uint32_t)&val[0];
|
||||
NRF_SAADC->RESULT.MAXCNT = count;
|
||||
NRF_SAADC->EVENTS_END = 0;
|
||||
NRF_SAADC->TASKS_SAMPLE = 1;
|
||||
NRF_SAADC->TASKS_START = 1;
|
||||
/* enabl irq */
|
||||
__enable_irq();
|
||||
do {
|
||||
} while (NRF_SAADC->EVENTS_END == 0);
|
||||
/* disable ssadc */
|
||||
NRF_SAADC->ENABLE = 0;
|
||||
/* stop ssadc */
|
||||
NRF_SAADC->TASKS_STOP = 1;
|
||||
/* copy values */
|
||||
for (uint32_t i = 0; i < count; i++)
|
||||
{
|
||||
adc_val[i] = val[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int gain(adc_gain_t gain)
|
||||
{
|
||||
int ret;
|
||||
@@ -155,8 +321,10 @@ static int gain(adc_gain_t gain)
|
||||
}
|
||||
|
||||
const adc_drv_if_t builtin_saadc = {
|
||||
.init = init,
|
||||
.reset = reset,
|
||||
.read = read,
|
||||
.gain = gain
|
||||
.init = init,
|
||||
.reset = reset,
|
||||
.read = read,
|
||||
.gain = gain,
|
||||
.read_multiple_channels = read_channels,
|
||||
.read_multiple_channels_ex = read_channels_ex,
|
||||
};
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
#include "edc.h"
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01)
|
||||
#include "pel.h"
|
||||
#else
|
||||
#error "Unknown DEF_ELITE_MODEL"
|
||||
#endif
|
||||
@@ -97,6 +99,8 @@ void elite_init(void)
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
edc.init();
|
||||
p_instance = edc.p_elite_instance;
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01)
|
||||
p_instance = pel_init();
|
||||
#else
|
||||
#error "Unknown DEF_ELITE_MODEL"
|
||||
#endif
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
#include "edc20_io.h"
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01)
|
||||
#include "pel10_io.h"
|
||||
#endif
|
||||
|
||||
#include "adc_drv.h"
|
||||
@@ -16,6 +18,8 @@ void elite_board_init(void)
|
||||
{
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
edc20_io_init();
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01)
|
||||
epl10_io_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "app_config.h"
|
||||
#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20)
|
||||
#include "edc20_io.h"
|
||||
#elif (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01)
|
||||
#include "pel10_io.h"
|
||||
#else
|
||||
#error "Not implemented xxx_pin_ctrl.h"
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
#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
|
||||
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#ifndef __PEL_H__
|
||||
#define __PEL_H__
|
||||
|
||||
#include "app_config.h"
|
||||
#include "elite_board.h"
|
||||
#include "elite.h"
|
||||
|
||||
#define PEL_0P5R_MASK (0x01 << 0)
|
||||
#define PEL_1P0R_MASK (0x01 << 1)
|
||||
#define PEL_2P0R_MASK (0x01 << 2)
|
||||
#define PEL_4P0R_MASK (0x01 << 3)
|
||||
#define PEL_8P0R_MASK (0x01 << 4)
|
||||
#define PEL_16P2R_MASK (0x01 << 5)
|
||||
#define PEL_32P4R_MASK (0x01 << 6)
|
||||
#define PEL_63P4R_MASK (0x01 << 7)
|
||||
#define PEL_127R_MASK (0x01 << 8)
|
||||
#define PEL_255R_MASK (0x01 << 9)
|
||||
#define PEL_511R_MASK (0x01 << 10)
|
||||
#define PEL_1000R_MASK (0x01 << 11)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int32_t output_r1;
|
||||
int32_t output_r2;
|
||||
int32_t output_vo;
|
||||
int32_t output_vc;
|
||||
int32_t output_ve;
|
||||
} pel_output_t;
|
||||
|
||||
void pel_relays_set(uint32_t measure_out);
|
||||
pel_output_t pel_smaple_and_convt_all(uint32_t load_mask);
|
||||
const elite_instance_t *pel_init(void);
|
||||
|
||||
#endif // !__PEL_H__
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
#include "app_config.h"
|
||||
#include "elite_board.h"
|
||||
|
||||
#include "nrf_spim.h"
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
|
||||
#if (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_01)
|
||||
|
||||
void spim_xfer(uint32_t cs_pin,
|
||||
nrf_spim_mode_t spi_mode,
|
||||
uint8_t *p_tx_buffer,
|
||||
uint16_t tx_buffer_length,
|
||||
uint8_t *p_rx_buf,
|
||||
uint16_t rx_buffer_length)
|
||||
{
|
||||
__disable_irq();
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
|
||||
switch (spi_mode)
|
||||
{
|
||||
default:
|
||||
case NRF_SPIM_MODE_0:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_1:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_2:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
|
||||
case NRF_SPIM_MODE_3:
|
||||
NRF_SPIM3->CONFIG = (SPIM_CONFIG_ORDER_MsbFirst << SPIM_CONFIG_ORDER_Pos) |
|
||||
(SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
|
||||
(SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
|
||||
break;
|
||||
}
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
|
||||
NRF_SPIM3->TXD.MAXCNT = tx_buffer_length;
|
||||
NRF_SPIM3->TXD.PTR = (uint32_t)p_tx_buffer;
|
||||
|
||||
NRF_SPIM3->RXD.MAXCNT = rx_buffer_length;
|
||||
NRF_SPIM3->RXD.PTR = (uint32_t)p_rx_buf;
|
||||
|
||||
nrf_gpio_pin_clear(cs_pin);
|
||||
|
||||
NRF_SPIM3->EVENTS_END = 0;
|
||||
NRF_SPIM3->TASKS_START = 1;
|
||||
do {
|
||||
} while (NRF_SPIM3->EVENTS_END == 0);
|
||||
|
||||
nrf_gpio_pin_set(cs_pin);
|
||||
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
void epl10_io_init(void)
|
||||
{
|
||||
for (int i = 0; i < COUNTOF(pel_pins); i++)
|
||||
{
|
||||
nrf_gpio_pin_set(pel_pins[i]);
|
||||
nrf_gpio_cfg_output(pel_pins[i]);
|
||||
}
|
||||
|
||||
// Config spi module
|
||||
|
||||
nrf_gpio_pin_set(WP_MEM_PIN);
|
||||
nrf_gpio_cfg_output(WP_MEM_PIN);
|
||||
nrf_gpio_pin_set(CS_MEM_PIN);
|
||||
nrf_gpio_cfg_output(CS_MEM_PIN);
|
||||
nrf_gpio_pin_clear(SPIM_MOSI_PIN);
|
||||
nrf_gpio_cfg_output(SPIM_MOSI_PIN);
|
||||
nrf_gpio_pin_clear(SPIM_CLK_PIN);
|
||||
nrf_gpio_cfg_output(SPIM_CLK_PIN);
|
||||
nrf_gpio_cfg_input(SPIM_MISO_PIN, NRF_GPIO_PIN_NOPULL);
|
||||
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
NRF_SPIM3->ORC = 0x00000000;
|
||||
NRF_SPIM3->FREQUENCY = SPIM_FREQUENCY_FREQUENCY_M32;
|
||||
NRF_SPIM3->CSNPOL = SPIM_CSNPOL_CSNPOL_LOW;
|
||||
NRF_SPIM3->IFTIMING.CSNDUR = 8;
|
||||
NRF_SPIM3->PSEL.CSN = CS_MEM_PIN;
|
||||
NRF_SPIM3->PSEL.SCK = SPIM_CLK_PIN;
|
||||
NRF_SPIM3->PSEL.MOSI = SPIM_MOSI_PIN;
|
||||
NRF_SPIM3->PSEL.MISO = SPIM_MISO_PIN;
|
||||
NRF_SPIM3->ENABLE = SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos;
|
||||
}
|
||||
|
||||
#endif
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
#pragma once
|
||||
#ifndef __PULSE_E_LOAD10_H__
|
||||
#define __PULSE_E_LOAD10_H__
|
||||
|
||||
#include "app_config.h"
|
||||
#include "elite_board.h"
|
||||
#include "nrf_gpio.h"
|
||||
#include "nrf_spim.h"
|
||||
|
||||
#define RELAY1_PIN NRF_GPIO_PIN_MAP(1, 10)
|
||||
#define RELAY2_PIN NRF_GPIO_PIN_MAP(1, 15)
|
||||
|
||||
#define SAMPLE_R_PIN NRF_GPIO_PIN_MAP(1, 11)
|
||||
#define SAMPLE_V_PIN NRF_GPIO_PIN_MAP(1, 6)
|
||||
|
||||
#define ANODE_PIN NRF_GPIO_PIN_MAP(0, 7)
|
||||
#define CATHODE_PIN NRF_GPIO_PIN_MAP(0, 28)
|
||||
|
||||
#define OUTPUT_VC_PIN NRF_GPIO_PIN_MAP(0, 2)
|
||||
#define OUTPUT_VO_PIN NRF_GPIO_PIN_MAP(0, 29)
|
||||
#define OUTPUT_VE_PIN NRF_GPIO_PIN_MAP(0, 3)
|
||||
#define OUTPUT_R1_PIN NRF_GPIO_PIN_MAP(0, 31)
|
||||
#define OUTPUT_R2_PIN NRF_GPIO_PIN_MAP(0, 28)
|
||||
|
||||
#define OUTPUT_VC_CHANNEL 0
|
||||
#define OUTPUT_VO_CHANNEL 5
|
||||
#define OUTPUT_VE_CHANNEL 1
|
||||
#define OUTPUT_R1_CHANNEL 7
|
||||
#define OUTPUT_R2_CHANNEL 4
|
||||
|
||||
#define INPUT_1_PIN NRF_GPIO_PIN_MAP(0, 15)
|
||||
#define INPUT_2_PIN NRF_GPIO_PIN_MAP(0, 13)
|
||||
#define INPUT_3_PIN NRF_GPIO_PIN_MAP(0, 20)
|
||||
#define INPUT_4_PIN NRF_GPIO_PIN_MAP(1, 0)
|
||||
#define INPUT_5_PIN NRF_GPIO_PIN_MAP(0, 25)
|
||||
#define INPUT_6_PIN NRF_GPIO_PIN_MAP(0, 11)
|
||||
#define INPUT_7_PIN NRF_GPIO_PIN_MAP(0, 14)
|
||||
#define INPUT_8_PIN NRF_GPIO_PIN_MAP(0, 17)
|
||||
#define INPUT_9_PIN NRF_GPIO_PIN_MAP(0, 18)
|
||||
#define INPUT_10_PIN NRF_GPIO_PIN_MAP(0, 21)
|
||||
#define INPUT_11_PIN NRF_GPIO_PIN_MAP(0, 19)
|
||||
#define INPUT_12_PIN NRF_GPIO_PIN_MAP(0, 22)
|
||||
|
||||
#define WP_MEM_PIN NRF_GPIO_PIN_MAP(0, 12)
|
||||
#define CS_MEM_PIN NRF_GPIO_PIN_MAP(0, 6)
|
||||
#define SPIM_MOSI_PIN NRF_GPIO_PIN_MAP(0, 27)
|
||||
#define SPIM_CLK_PIN NRF_GPIO_PIN_MAP(0, 4)
|
||||
#define SPIM_MISO_PIN NRF_GPIO_PIN_MAP(1, 9)
|
||||
|
||||
void spim_xfer(uint32_t cs_pin,
|
||||
nrf_spim_mode_t spi_mode,
|
||||
uint8_t *p_tx_buffer,
|
||||
uint16_t tx_buffer_length,
|
||||
uint8_t *p_rx_buf,
|
||||
uint16_t rx_buffer_length);
|
||||
|
||||
void epl10_io_init(void);
|
||||
|
||||
#endif // !__PULSE_E_LOAD10_H__
|
||||
Reference in New Issue
Block a user