From 3f980237c7e42a6508a1bbb114e09ae3d5e640d8 Mon Sep 17 00:00:00 2001 From: chain40 Date: Sat, 8 Jun 2024 09:30:46 +0800 Subject: [PATCH] feat: implement iv_cycle mode --- bmd380_peripheral.vcxproj | 12 + bmd380_peripheral.vcxproj.filters | 21 ++ dac_drv_if.h | 8 +- edc.h | 21 ++ edc20.c | 8 +- edc20_cycle_iv_mode.c | 483 ++++++++++++++++++++++++++++++ edc20_io.c | 119 ++++---- edc20_io.h | 20 +- 8 files changed, 627 insertions(+), 65 deletions(-) create mode 100644 edc20_cycle_iv_mode.c diff --git a/bmd380_peripheral.vcxproj b/bmd380_peripheral.vcxproj index d269a75..6f10a39 100644 --- a/bmd380_peripheral.vcxproj +++ b/bmd380_peripheral.vcxproj @@ -49,6 +49,7 @@ DEBUG=1;USE_APP_CONFIG=1;LFS_THREADSAFE=1;%(ClCompile.PreprocessorDefinitions) + O0 ;%(Link.AdditionalLinkerInputs) @@ -57,6 +58,16 @@ nRF52840_XXAA_S140_reserve.lds + + THUMB + + + hard + + + fpv4-sp-d16 + cortex-m4 + @@ -188,6 +199,7 @@ + diff --git a/bmd380_peripheral.vcxproj.filters b/bmd380_peripheral.vcxproj.filters index 9cb6849..e0cf1e1 100644 --- a/bmd380_peripheral.vcxproj.filters +++ b/bmd380_peripheral.vcxproj.filters @@ -1431,6 +1431,18 @@ Source files + + Source files + + + Source files + + + Source files + + + Source files + @@ -1777,6 +1789,15 @@ Header files + + Header files + + + Header files + + + Header files + diff --git a/dac_drv_if.h b/dac_drv_if.h index cff3ea9..b806c0d 100644 --- a/dac_drv_if.h +++ b/dac_drv_if.h @@ -5,10 +5,10 @@ #include #include -#define DAC0 (0x01 << 0) -#define DAC1 (0x01 << 1) -#define DAC2 (0x01 << 2) -#define DAC3 (0x01 << 3) +#define DAC0 (0x01 << 0) +#define DAC1 (0x01 << 1) +#define DAC2 (0x01 << 2) +#define DAC3 (0x01 << 3) typedef struct { diff --git a/edc.h b/edc.h index e6b5e39..230218d 100644 --- a/edc.h +++ b/edc.h @@ -109,6 +109,27 @@ typedef struct } instru; } edc20_t; +typedef struct +{ + float coeff; + float offset; +} edc20_cal_data_t; + +typedef struct +{ + struct + { + float coeff; + float offset; + } dac_c; + struct + { + float coeff; + float offset; + float Voffset; + } dac_f[3]; +} edc20_dac_cal_data_t; + extern edc20_t edc; #endif // !__EDC_H__ diff --git a/edc20.c b/edc20.c index e4ff910..e50883e 100644 --- a/edc20.c +++ b/edc20.c @@ -932,7 +932,13 @@ static void vis_shiny_dis(uint8_t *ins, uint16_t size) } static void curve_iv(uint8_t *ins, uint16_t size) { NRF_LOG_INFO("%s", __FUNCTION__); } -static void curve_iv_cy(uint8_t *ins, uint16_t size) { NRF_LOG_INFO("%s", __FUNCTION__); } +static void curve_iv_cy(uint8_t *ins, uint16_t size) +{ + NRF_LOG_INFO("%s", __FUNCTION__); + extern void edc20_cycle_iv_mode_start(uint8_t * ins, uint16_t size); + edc20_cycle_iv_mode_start(ins, size); +} + static void curve_vo(uint8_t *ins, uint16_t size) { NRF_LOG_INFO("%s", __FUNCTION__); } static void curve_rt(uint8_t *ins, uint16_t size) { NRF_LOG_INFO("%s", __FUNCTION__); } static void curve_vt(uint8_t *ins, uint16_t size) { NRF_LOG_INFO("%s", __FUNCTION__); } diff --git a/edc20_cycle_iv_mode.c b/edc20_cycle_iv_mode.c new file mode 100644 index 0000000..d03d82c --- /dev/null +++ b/edc20_cycle_iv_mode.c @@ -0,0 +1,483 @@ +#include "app_config.h" +#include "edc.h" +#include "elite_board.h" + +#include "dac_drv.h" + +#include "nrf.h" +#include "nrf_log.h" + +#include "FreeRTOS.h" +#include "elite_board.h" +#include "semphr.h" +#include "task.h" + +#include +#include +#include +#include + +#if (DEF_ELITE_MODEL == DEF_ELITE_EDC_20) + +#define OUT_0 DAC0 +#define OUT_1 DAC1 + +typedef struct __PACKED +{ + uint32_t notify_time; + int32_t ch1_data; + int32_t ch2_data; + int32_t ch3_data; + uint16_t cycle; + uint8_t finish_flag; + uint32_t bat_volt; + uint8_t packet_seq; + int32_t ch4_data; + int32_t ch5_data; + int32_t ch6_data; +} payload_t; + +typedef struct __PACKED +{ + uint8_t mem_board_id; + payload_t payload; + uint8_t : 8; + uint8_t : 8; + uint8_t : 8; +} elite_notify_packet_t; + +typedef struct +{ + uint32_t id; + uint32_t mS_period; + elite_dac_config_t config; +} iv_cycle_mode_param_t; + +const edc20_dac_cal_data_t edc20_dac_cal_data = { + .dac_c = { 2.9701475, 121.9763670 }, + .dac_f = { + [0] = { 65.7454092, -290.3872456, -36.65060000 }, + [1] = { 27.4300538, -100.6332479, -37.39872222 }, + [2] = { 7.61192880, -0.568019000, -40.99282222 } } +}; +#define FS_1000mV 1000 +#define FS_2800mV 2800 +#define FS_8000mV 8000 +const float edc20_range_mV[] = { + [0] = FS_1000mV, + [1] = FS_2800mV, + [2] = FS_8000mV, +}; + +static SemaphoreHandle_t semphr_start = NULL; + +static TaskHandle_t task_handle = NULL; + +static bool running = false; + +extern ret_code_t le_event_notify(uint8_t *p_value, uint16_t len); + +static ret_code_t _send_start_packet(elite_notify_packet_t *p_buf, uint32_t loops) +{ + memset(&p_buf->payload, 0x00, sizeof(p_buf->payload)); + for (uint32_t i = 0; i < loops; i++) + { + ret_code_t ret = le_event_notify((void *)p_buf, sizeof(*p_buf)); + if (ret != NRF_SUCCESS) + { + return ret; + } + } + return NRF_SUCCESS; +} + +static ret_code_t _send_data_packet(elite_notify_packet_t *p_notify_buf, bool is_last_notify) +{ + static int32_t ch1 = 0; + static int32_t ch2 = 0; + static int32_t ch3 = 0; + + ch1 += 100; + ch2++; + ch3 = ch2; + + p_notify_buf->payload.notify_time = xTaskGetTickCount(); + p_notify_buf->payload.ch1_data = ch1; + p_notify_buf->payload.ch2_data = ch2; + p_notify_buf->payload.ch3_data = ch3; + p_notify_buf->payload.bat_volt = 3600; + p_notify_buf->payload.packet_seq++; + p_notify_buf->payload.finish_flag = is_last_notify; + + return le_event_notify((void *)p_notify_buf, sizeof(*p_notify_buf)); +} + +typedef struct +{ + int32_t dir; + float mV_output; + float mV_max; + float mV_min; + float mV_start; + float mV_stop; + uint32_t step; + uint32_t cycle_cnt; + uint32_t cycle_max; + uint32_t fullscale; + struct + { + float eta_c; + float eta_f; + float Voffset; + float Vc; + float Nc; + float Nc0; + float Nf; + }; +} cycle_iv_dac_t; + +typedef struct +{ + uint32_t period; +} cycle_iv_adc_t; + +static uint32_t mV_out_0(cycle_iv_dac_t *p) +{ + for (uint32_t i = 0; i < COUNTOF(edc20_range_mV); i++) + { + if ((p->mV_max - p->mV_min) <= edc20_range_mV[i]) + { + p->fullscale = edc20_range_mV[i]; + p->eta_c = edc20_dac_cal_data.dac_c.coeff; + p->eta_f = edc20_dac_cal_data.dac_f[i].coeff; + p->Voffset = edc20_dac_cal_data.dac_f[i].Voffset; + break; + } + } + p->Vc = (p->mV_max + p->mV_min) / 2; + p->Nc = round((p->Vc - p->Voffset) * p->eta_c) + 32768; + p->Nc0 = round((0 - p->Voffset) * p->eta_c) + 32768; + return p->Nc; +} + +static uint32_t mV_out_1(cycle_iv_dac_t *p) +{ + p->Nf = round((p->mV_output - p->Vc - p->Voffset - (p->Nc0 - 32768) / p->eta_c) * p->eta_f) + 32768; + return p->Nf; +} + +static uint32_t cal_dac_timer_interval(elite_dac_config_t *p_config, cycle_iv_dac_t *p_cycle_iv_dac) +{ + const float STEP_TIME_FACTOR = 2.0f; + uint32_t intvl; + uint32_t step_time = p_config->uS_step * STEP_TIME_FACTOR; + for (uint32_t intvl = 100; intvl < 1000000; intvl *= 10) + { + p_cycle_iv_dac->step = (p_config->mV_step * intvl) / step_time; + if (p_cycle_iv_dac->step) + { + return intvl; + } + } + return intvl; +} + +void _callback(void *p_arg) +{ + cycle_iv_dac_t *p = p_arg; + + if (p->mV_output <= p->mV_min) + { + p->mV_output = p->mV_min; + p->dir = 1; + } + + if (p->mV_output >= p->mV_max) + { + p->mV_output = p->mV_max; + p->dir = -1; + } + + dac_write_through(OUT_1, mV_out_1(p)); + + if (p->mV_output == p->mV_start) + { + p->cycle_cnt++; + if (p->cycle_cnt > p->cycle_max) + { + running = false; + } + } + p->mV_output += p->dir * p->step; +} + +static void edc20_cycle_iv_mode_task(void *p_arg) +{ + elite_notify_packet_t packet_buf; + cycle_iv_dac_t dac_param; + cycle_iv_adc_t adc_param; + iv_cycle_mode_param_t mode_param; + + taskENTER_CRITICAL(); + + /* copy iv cycle parameter */ + memcpy(&mode_param, p_arg, sizeof(mode_param)); + + memset(&packet_buf, 0x00, sizeof(packet_buf)); + memset(&dac_param, 0x00, sizeof(dac_param)); + memset(&adc_param, 0x00, sizeof(adc_param)); + + taskEXIT_CRITICAL(); + + if (1) + { + char info[256]; + snprintf(info, 256, "%s() @ %p start", __FUNCTION__, xTaskGetCurrentTaskHandle()); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%8ld", "id", mode_param.id); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%7.0fmV", "V_start", mode_param.config.mV_start); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%7.0fmV", "V_stop", mode_param.config.mV_stop); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%7.0fmV", "uV_step", mode_param.config.mV_step); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%8ldus", "uS_step_time", mode_param.config.uS_step); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%8ld", "cycles", mode_param.config.cycles); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%8ldms", "mS_period", mode_param.mS_period); + NRF_LOG_INFO("%s", info); + } + + /* set memborad id */ + packet_buf.mem_board_id = mode_param.id; + + /* send start packet 4 times */ + _send_start_packet(&packet_buf, 4); + + dac_param.mV_output = mode_param.config.mV_start; + dac_param.mV_max = MAX(mode_param.config.mV_start, mode_param.config.mV_stop); + dac_param.mV_min = MIN(mode_param.config.mV_start, mode_param.config.mV_stop); + dac_param.mV_start = mode_param.config.mV_start; + dac_param.mV_stop = mode_param.config.mV_stop; + dac_param.dir = dac_param.mV_output == dac_param.mV_min ? 1 : -1; + dac_param.cycle_cnt = 0; + dac_param.cycle_max = mode_param.config.cycles; + dac_param.fullscale = 0; + + if (1) + { + NRF_LOG_INFO("%s", ""); + mV_out_0(&dac_param); + char info[256]; + snprintf(info, 256, "%16s:%10.3f", "eta_c", dac_param.eta_c); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%10.3f", "eta_f", dac_param.eta_f); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%10.3f", "Voffset", dac_param.Voffset); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%10.3f", "Vc", dac_param.Vc); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%10.3f", "Nc", dac_param.Nc); + NRF_LOG_INFO("%s", info); + snprintf(info, 256, "%16s:%10.3f", "Nc0", dac_param.Nc0); + NRF_LOG_INFO("%s", info); + + dac_param.mV_output = dac_param.mV_start; + mV_out_1(&dac_param); + snprintf(info, 256, "%16s:%10.3f", "V1 Nf", dac_param.Nf); + NRF_LOG_INFO("%s", info); + + dac_param.mV_output = dac_param.mV_stop; + mV_out_1(&dac_param); + snprintf(info, 256, "%16s:%10.3f", "V2 Nf", dac_param.Nf); + NRF_LOG_INFO("%s", info); + } + + // dac_write_through(OUT_0, mV_out_0(&dac_param)); + // dac_write_through(OUT_1, mV_out_1(&dac_param)); + + + + + // + // /* start DAC timer */ + // edc20_dac_tim_start(cal_dac_timer_interval(&mode_param.config, &dac_param), _callback, &dac_param); + // + // /* start ADC timer */ + // edc20_adc_tim_start(&mode_param.config); + // + // /* get current tick */ + // TickType_t tick = xTaskGetTickCount(); + // + // uint32_t notify_delay = pdMS_TO_TICKS(mode_param.mS_period); + // + // /* start data update process */ + // running = true; + // + // while (running) + // { + // ret_code_t ret = _send_data_packet(&packet_buf, false); + // switch (ret) + // { + // case NRF_SUCCESS: + // case NRF_ERROR_RESOURCES: + // vTaskDelayUntil(&tick, notify_delay); + // break; + // default: + // running = false; + // break; + // } + // } + // + // edc20_dac_tim_stop(); + // edc20_adc_tim_stop(); + + if (1) + { + char info[256]; + snprintf(info, 256, "%s() @ %p stop", __FUNCTION__, xTaskGetCurrentTaskHandle()); + NRF_LOG_INFO("%s", info); + } + + vTaskDelete(NULL); +} + +void edc20_cycle_iv_mode_init(void) +{ +} + +#define VDIRECTION(v1, v2) ((v1 > v2) ? 0 : 1) +// Step time macro +#define STEPTIME_HALF_SEC 5000 +#define STEPTIME_ONE_SEC 10000 +#define STEPTIME_TWO_SEC 20000 +static uint32_t step2VsetRate(uint32_t step) +{ + /*step = 100 mv, index = 0, n = 2 + 10 mv, index = 1, n = 10 + 1 mv, index = 2, n = 100 + 0.1 mv, index = 3, n = 1000 + 0.01mv, index = 4, n = 10000 */ + + if (step >= 10000) + { + return 0; + } + else if (step >= 1000) + { + return 1; + } + else if (step >= 100) + { + return 2; + } + else if (step >= 10) + { + return 3; + } + else if (step >= 1) + { + return 4; + } + else + { + return 5; + } +} + +static uint32_t get_step_time(uint8_t StepTime) +{ + switch (StepTime) + { + case 0: { // 0.5 sec + return STEPTIME_HALF_SEC; + } + case 1: { // 1 sec + return STEPTIME_ONE_SEC; + } + case 2: { // 2 sec + return STEPTIME_TWO_SEC; + } + default: { // 1 sec + return STEPTIME_ONE_SEC; + } + } +} + +#define STEP_TO_VSETRATE(step) step2VsetRate(step) +const uint32_t VsetRateTable[5] = { 2, 10, 100, 1000, 10000 }; + +static uint32_t convt_uS_step(uint32_t idx) +{ + switch (idx) + { + case 0: { // 0.5 sec + return 500000; + } + case 1: { // 1 sec + return 1000000; + } + case 2: { // 2 sec + return 2000000; + } + default: { // 1 sec + return 1000000; + } + } +} + +void edc20_cycle_iv_mode_start(uint8_t *ins, uint16_t size) +{ + /* + instru.eliteFxn = CURVE_IV_CY; + instru.Ve1 = ((uint16_t)(ins[3]) << 8) | (uint16_t)(ins[4]); + instru.Ve2 = ((uint16_t)(ins[5]) << 8) | (uint16_t)(ins[6]); + instru.Vinit = (int32_t)instru.Ve1; + instru.Vmax = (int32_t)VMAX(instru.Ve1,instru.Ve2); + instru.Vmin = (int32_t)VMIN(instru.Ve1,instru.Ve2); + instru.directionInit = VDIRECTION(instru.Ve1,instru.Ve2); + instru.steptime = get_step_time(ins[9]); //5000;10000;20000; + instru.step = ((uint32_t)(ins[7]) << 8) | (uint32_t)(ins[8]);//1~1000 = 0.1mv ~ 100mv + instru.step = instru.step * 100000 / instru.steptime; + STEP_TO_VSETRATE(instru.step); + instru.VsetRate = VsetRateTable[instru.VsetRateIndex];//N + instru.cycleNumber = ((uint16_t)(ins[10]) << 8) | (uint16_t)(ins[11]); + instru.hign_z_en = ins[13] & 0x0F; + instru.notifyRate = ((uint32_t)ins[14] << 8) | (uint32_t)ins[15]; + instru.notifyRate = 10000 / instru.notifyRate * 10; + */ + + struct __PACKED + { + uint8_t id : 4; + uint8_t : 4; + uint8_t : 8; + uint8_t : 8; + uint16_t volt_start; // unit: 100uV, -5V = 0, 0V = 25000, 5V = 50000 + uint16_t volt_stop; // unit: 100uV, -5V = 0, 0V = 25000, 5V = 50000 + uint16_t step; // unit: 100uV + uint8_t step_time; // enum: 0 = 5000us, 1 = 10000us, 2 = 20000us + uint16_t cycles; // 0 ~ 500000 + uint8_t : 8; + uint8_t hi_z_en; // lower nibble + uint16_t sample_rate; // unit: 0.1Hz + } *p = (void *)ins; + + iv_cycle_mode_param_t mode_param = { + .id = p->id, + .mS_period = 1000 * 10 / __REVSH(p->sample_rate), + .config.mV_start = ((__REVSH(p->volt_start) & 0xFFFF) / 10 - 2500) * 2, + .config.mV_stop = ((__REVSH(p->volt_stop) & 0xFFFF) / 10 - 2500) * 2, + .config.mV_step = (uint32_t)__REVSH(p->step) / 10, + .config.uS_step = convt_uS_step(p->step_time), + .config.cycles = (__REVSH(p->cycles) & 0xFFFF) + }; + + xTaskCreate(edc20_cycle_iv_mode_task, "iv_mode", 2048, (void *)&mode_param, 3, &task_handle); + + portYIELD(); +} + +#endif diff --git a/edc20_io.c b/edc20_io.c index 61f00c1..232fa17 100644 --- a/edc20_io.c +++ b/edc20_io.c @@ -555,37 +555,68 @@ void spim_xfer(uint32_t cs_pin, nrf_spim_mode_t spi_mode, uint8_t *p_tx_buffer, #define ELITE_DAC_TMR NRF_TIMER2 -uint32_t dac_val = 0; -uint32_t step = 0; -int32_t dir = 1; -uint32_t dac_max = 0xFF00; -uint32_t dac_min = 0x0000; -uint32_t dac_step = 0x100; -extern int dac_write_through(uint32_t channel_mask, int32_t dac_val); -void dac_callback(void) -{ - if (dac_val <= dac_min) - { - dir = 1; - } - else if (dac_val >= dac_max) - { - dir = -1; - } - dac_write_through(DAC0, dac_val); - dac_val += dir * dac_step; -} +static void (*dac_tmr_cb)(void *p_arg) = NULL; +static void *dac_tmr_p_arg = NULL; void TIMER2_IRQHandler(void) { if (ELITE_DAC_TMR->EVENTS_COMPARE[0]) { ELITE_DAC_TMR->EVENTS_COMPARE[0] = 0; - dac_callback(); + if (dac_tmr_cb) + { + dac_tmr_cb(dac_tmr_p_arg); + } return; } } +void edc20_dac_tim_start(uint32_t period, void (*callback)(void *p_arg), void *p_arg) +{ + NRF_LOG_INFO("%s()", __FUNCTION__); + + __disable_irq(); + + sd_nvic_DisableIRQ(TIMER2_IRQn); + sd_nvic_ClearPendingIRQ(TIMER2_IRQn); + ELITE_DAC_TMR->SHORTS = 0; + ELITE_DAC_TMR->TASKS_STOP = 1; + + dac_tmr_p_arg = p_arg; + dac_tmr_cb = callback; + + ELITE_DAC_TMR->PRESCALER = NRF_TIMER_FREQ_1MHz; + ELITE_DAC_TMR->MODE = NRF_TIMER_MODE_TIMER; + ELITE_DAC_TMR->BITMODE = NRF_TIMER_BIT_WIDTH_32; + ELITE_DAC_TMR->INTENSET = NRF_TIMER_INT_COMPARE0_MASK; + ELITE_DAC_TMR->CC[0] = period; + ELITE_DAC_TMR->SHORTS = NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK; + sd_nvic_SetPriority(TIMER2_IRQn, _PRIO_APP_HIGH); + sd_nvic_EnableIRQ(TIMER2_IRQn); + + ELITE_DAC_TMR->TASKS_CLEAR = 1; + ELITE_DAC_TMR->TASKS_START = 1; + + __enable_irq(); +} + +void edc20_dac_tim_stop(void) +{ + NRF_LOG_INFO("%s()", __FUNCTION__); + + __disable_irq(); + + dac_tmr_cb = NULL; + dac_tmr_p_arg = NULL; + + sd_nvic_DisableIRQ(TIMER2_IRQn); + sd_nvic_ClearPendingIRQ(TIMER2_IRQn); + ELITE_DAC_TMR->TASKS_STOP = 1; + ELITE_DAC_TMR->SHORTS = 0; + + __enable_irq(); +} + #endif /* ! DEF_DAC_DRV_ENABLED */ #if (DEF_ADC_DRV_ENABLED) @@ -599,11 +630,14 @@ void TIMER3_IRQHandler(void) ELITE_ADC_TMR->EVENTS_COMPARE[0] = 0; float mv; + extern int adc_read_milivolt(uint32_t channel, float *mv); adc_read_milivolt(2, &mv); + float v = mv / 1000.0 - 5; + #if (DEF_RTT_JSCOP_ENABLED) extern void j_scope_update(float f); - j_scope_update(mv / 1000.0); + j_scope_update(v * 5); #endif return; @@ -625,57 +659,30 @@ void TIMER3_IRQHandler(void) return; } } -#endif /* ! DEF_ADC_DRV_ENABLED */ -#if (DEF_ADC_DRV_ENABLED == 1 && DEF_DAC_DRV_ENABLED) - -void elite_peripheral_tim_init(void) +void edc20_adc_tim_start(elite_dac_config_t *p_config) { - // DAC Sample Rate 10KHz - ELITE_DAC_TMR->PRESCALER = NRF_TIMER_FREQ_1MHz; - ELITE_DAC_TMR->MODE = NRF_TIMER_MODE_TIMER; - ELITE_DAC_TMR->BITMODE = NRF_TIMER_BIT_WIDTH_32; - ELITE_DAC_TMR->INTENSET = NRF_TIMER_INT_COMPARE0_MASK; - ELITE_DAC_TMR->CC[0] = 100; - ELITE_DAC_TMR->SHORTS = NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK; - sd_nvic_SetPriority(TIMER2_IRQn, _PRIO_APP_HIGH); - sd_nvic_EnableIRQ(TIMER2_IRQn); + NRF_LOG_INFO("%s()", __FUNCTION__); /* - ADC Sample rate 10KHz + ADC Sample rate 10KHz */ ELITE_ADC_TMR->PRESCALER = NRF_TIMER_FREQ_1MHz; ELITE_ADC_TMR->MODE = NRF_TIMER_MODE_TIMER; ELITE_ADC_TMR->BITMODE = NRF_TIMER_BIT_WIDTH_32; ELITE_ADC_TMR->INTENSET = NRF_TIMER_INT_COMPARE0_MASK; - ELITE_ADC_TMR->CC[0] = 100; + ELITE_ADC_TMR->CC[0] = 1000; ELITE_ADC_TMR->SHORTS = NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK; sd_nvic_SetPriority(TIMER3_IRQn, _PRIO_APP_HIGH); sd_nvic_EnableIRQ(TIMER3_IRQn); } -void elite_peripheral_tim_period(uint32_t us) +void edc20_adc_tim_stop(void) { - ELITE_DAC_TMR->CC[0] = us; - - ELITE_ADC_TMR->CC[0] = us; - - ELITE_DAC_TMR->TASKS_CLEAR = ELITE_ADC_TMR->TASKS_CLEAR = 1; + NRF_LOG_INFO("%s()", __FUNCTION__); } -void elite_peripheral_tim_enable(void) -{ - ELITE_DAC_TMR->TASKS_CLEAR = ELITE_ADC_TMR->TASKS_CLEAR = 1; - ELITE_DAC_TMR->TASKS_START = ELITE_ADC_TMR->TASKS_START = 1; -} - -void elite_peripheral_tim_disable(void) -{ - ELITE_DAC_TMR->TASKS_STOP = 1; - ELITE_ADC_TMR->TASKS_STOP = 1; -} - -#endif /* ! DEF_ADC_DRV_ENABLED && DEF_DAC_DRV_ENABLED*/ +#endif /* ! DEF_ADC_DRV_ENABLED */ void edc20_io_init(void) { diff --git a/edc20_io.h b/edc20_io.h index a9aae20..2bedeb2 100644 --- a/edc20_io.h +++ b/edc20_io.h @@ -43,6 +43,16 @@ #define SPIM_MOSI_PIN NRF_GPIO_PIN_MAP(0, 7) #define SPIM_MISO_PIN NRF_GPIO_PIN_MAP(1, 9) +typedef struct +{ + float mV_start; + float mV_stop; + float mV_step; + uint32_t uS_step; + uint32_t cycles; + bool hi_z_en; +} elite_dac_config_t; + void gpio_init(void); void circuit_selection_vin_0(void); void circuit_selection_vin_1(void); @@ -72,9 +82,11 @@ void spi2_set_mode(nrf_drv_spi_mode_t mode); void edc20_io_init(void); void edc20_io_power_off(void); void edc20_io_power_on(void); -void elite_peripheral_tim_init(void); -void elite_peripheral_tim_period(uint32_t us); -void elite_peripheral_tim_enable(void); -void elite_peripheral_tim_disable(void); + +void edc20_dac_tim_start(uint32_t period, void (*callback)(void *p_arg), void *p_arg); +void edc20_dac_tim_stop(void); + +void edc20_adc_tim_start(elite_dac_config_t *p_config); +void edc20_adc_tim_stop(void); #endif // !__EDC20_PIN_CTRL_H__