8db81a445c
2. the state is idle before starting and after finishing the pulse generation
409 lines
13 KiB
C
409 lines
13 KiB
C
#include "elite_board.h"
|
|
|
|
#include "nrf_gpio.h"
|
|
#include "nrf_gpiote.h"
|
|
#include "nrf_log.h"
|
|
#include "nrf_spim.h"
|
|
#include "nrf_timer.h"
|
|
|
|
#include "FreeRTOS.h"
|
|
#include "semphr.h"
|
|
#include "task.h"
|
|
|
|
#pragma GCC optimize("O2")
|
|
|
|
#if (DEF_ELITE_MODEL == DEF_CURRENT_PULSE_GANERATOR_11)
|
|
|
|
typedef struct
|
|
{
|
|
const uint32_t gpiote_idx[4];
|
|
NRF_TIMER_Type *TMR_A;
|
|
NRF_TIMER_Type *TMR_B;
|
|
uint32_t IRQn;
|
|
pusle_gen_t *p_pusle_gen;
|
|
uint32_t pusle_gen_len;
|
|
uint32_t pusle_gen_sel;
|
|
} pusle_gen_hw_t;
|
|
|
|
pusle_gen_hw_t pusle_gen_hw[] = {
|
|
{{ 0, 1, 2, 3 },
|
|
NRF_TIMER1,
|
|
NRF_TIMER3,
|
|
TIMER3_IRQn,
|
|
NULL,
|
|
0,
|
|
0},
|
|
{{ 4, 5, 6, 7 },
|
|
NRF_TIMER2,
|
|
NRF_TIMER4,
|
|
TIMER4_IRQn,
|
|
NULL,
|
|
0,
|
|
0},
|
|
};
|
|
|
|
__STATIC_INLINE void cpg11_tmr_cb(uint32_t hw_idx)
|
|
{
|
|
if (pusle_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[4])
|
|
{
|
|
pusle_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[4] = 0;
|
|
|
|
uint32_t sel = pusle_gen_hw[hw_idx].pusle_gen_sel;
|
|
|
|
if (pusle_gen_hw[hw_idx].p_pusle_gen[sel].pulse_cnt > 0)
|
|
{
|
|
pusle_gen_hw[hw_idx].p_pusle_gen[sel].pulse_cnt--;
|
|
}
|
|
|
|
for (uint32_t i = 0; i < pusle_gen_hw[hw_idx].pusle_gen_len; i++)
|
|
{
|
|
sel = (sel + 1) % pusle_gen_hw[hw_idx].pusle_gen_len;
|
|
if (pusle_gen_hw[hw_idx].p_pusle_gen[sel].pulse_cnt > 0)
|
|
{
|
|
pusle_gen_hw[hw_idx].pusle_gen_sel = sel;
|
|
cpg11_pulse_start(hw_idx, &pusle_gen_hw[hw_idx].p_pusle_gen[sel]);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TIMER3_IRQHandler(void)
|
|
{
|
|
cpg11_tmr_cb(0);
|
|
}
|
|
|
|
void TIMER4_IRQHandler(void)
|
|
{
|
|
cpg11_tmr_cb(1);
|
|
}
|
|
|
|
void cpg11_pulse_stop_by_pulse_id(uint32_t pulse_id)
|
|
{
|
|
for (uint32_t i = 0; i < COUNTOF(pusle_gen_hw); i++)
|
|
{
|
|
for (uint32_t j = 0; j < pusle_gen_hw[i].pusle_gen_len; j++)
|
|
{
|
|
if (pusle_gen_hw[i].p_pusle_gen[j].pulse_id == pulse_id)
|
|
{
|
|
taskENTER_CRITICAL();
|
|
pusle_gen_hw[i].p_pusle_gen[j].VAxH = 0xFFFFFFFF;
|
|
pusle_gen_hw[i].p_pusle_gen[j].VBxH = 0xFFFFFFFF;
|
|
pusle_gen_hw[i].p_pusle_gen[j].VAxL = 0xFFFFFFFF;
|
|
pusle_gen_hw[i].p_pusle_gen[j].VBxL = 0xFFFFFFFF;
|
|
taskEXIT_CRITICAL();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void cpg11_pulse_start(uint32_t hw_idx, pusle_gen_t *p_pusle_gen)
|
|
{
|
|
pusle_gen_hw[hw_idx].TMR_B->TASKS_STOP = 1;
|
|
pusle_gen_hw[hw_idx].TMR_A->TASKS_STOP = 1;
|
|
|
|
sd_nvic_DisableIRQ(pusle_gen_hw[hw_idx].IRQn);
|
|
sd_nvic_ClearPendingIRQ(pusle_gen_hw[hw_idx].IRQn);
|
|
|
|
nrf_gpiote_task_disable(pusle_gen_hw[hw_idx].gpiote_idx[0]);
|
|
nrf_gpiote_task_disable(pusle_gen_hw[hw_idx].gpiote_idx[1]);
|
|
nrf_gpiote_task_disable(pusle_gen_hw[hw_idx].gpiote_idx[2]);
|
|
nrf_gpiote_task_disable(pusle_gen_hw[hw_idx].gpiote_idx[3]);
|
|
|
|
nrf_gpiote_task_configure(pusle_gen_hw[hw_idx].gpiote_idx[0], p_pusle_gen->VBxH, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
|
|
nrf_gpiote_task_configure(pusle_gen_hw[hw_idx].gpiote_idx[1], p_pusle_gen->VBxL, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
|
|
nrf_gpiote_task_configure(pusle_gen_hw[hw_idx].gpiote_idx[2], p_pusle_gen->VAxH, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
|
|
nrf_gpiote_task_configure(pusle_gen_hw[hw_idx].gpiote_idx[3], p_pusle_gen->VAxL, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
|
|
|
|
nrf_gpiote_task_enable(pusle_gen_hw[hw_idx].gpiote_idx[0]);
|
|
nrf_gpiote_task_enable(pusle_gen_hw[hw_idx].gpiote_idx[1]);
|
|
nrf_gpiote_task_enable(pusle_gen_hw[hw_idx].gpiote_idx[2]);
|
|
nrf_gpiote_task_enable(pusle_gen_hw[hw_idx].gpiote_idx[3]);
|
|
|
|
uint32_t offs = 8 * hw_idx;
|
|
|
|
NRF_PPI->CH[offs + 0].EEP = (uint32_t)&pusle_gen_hw[hw_idx].TMR_A->EVENTS_COMPARE[0];
|
|
NRF_PPI->CH[offs + 0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[hw_idx].gpiote_idx[0]];
|
|
NRF_PPI->CHENSET = (1 << (offs + 0));
|
|
|
|
NRF_PPI->CH[offs + 1].EEP = (uint32_t)&pusle_gen_hw[hw_idx].TMR_A->EVENTS_COMPARE[1];
|
|
NRF_PPI->CH[offs + 1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[hw_idx].gpiote_idx[1]];
|
|
NRF_PPI->CHENSET = (1 << (offs + 1));
|
|
|
|
NRF_PPI->CH[offs + 2].EEP = (uint32_t)&pusle_gen_hw[hw_idx].TMR_A->EVENTS_COMPARE[2];
|
|
NRF_PPI->CH[offs + 2].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[hw_idx].gpiote_idx[1]];
|
|
NRF_PPI->CHENSET = (1 << (offs + 2));
|
|
|
|
NRF_PPI->CH[offs + 3].EEP = (uint32_t)&pusle_gen_hw[hw_idx].TMR_A->EVENTS_COMPARE[3];
|
|
NRF_PPI->CH[offs + 3].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[hw_idx].gpiote_idx[0]];
|
|
NRF_PPI->FORK[offs + 3].TEP = (uint32_t)&pusle_gen_hw[hw_idx].TMR_B->TASKS_START;
|
|
NRF_PPI->CHENSET = (1 << (offs + 3));
|
|
|
|
NRF_PPI->CH[offs + 4].EEP = (uint32_t)&pusle_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[0];
|
|
NRF_PPI->CH[offs + 4].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[hw_idx].gpiote_idx[2]];
|
|
NRF_PPI->CHENSET = (1 << (offs + 4));
|
|
|
|
NRF_PPI->CH[offs + 5].EEP = (uint32_t)&pusle_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[1];
|
|
NRF_PPI->CH[offs + 5].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[hw_idx].gpiote_idx[3]];
|
|
NRF_PPI->CHENSET = (1 << (offs + 5));
|
|
|
|
NRF_PPI->CH[offs + 6].EEP = (uint32_t)&pusle_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[2];
|
|
NRF_PPI->CH[offs + 6].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[hw_idx].gpiote_idx[3]];
|
|
NRF_PPI->CHENSET = (1 << (offs + 6));
|
|
|
|
NRF_PPI->CH[offs + 7].EEP = (uint32_t)&pusle_gen_hw[hw_idx].TMR_B->EVENTS_COMPARE[3];
|
|
NRF_PPI->CH[offs + 7].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[hw_idx].gpiote_idx[2]];
|
|
NRF_PPI->CHENSET = (1 << (offs + 7));
|
|
|
|
pusle_gen_hw[hw_idx].TMR_B->TASKS_CLEAR = 1;
|
|
pusle_gen_hw[hw_idx].TMR_A->TASKS_CLEAR = 1;
|
|
|
|
pusle_gen_hw[hw_idx].TMR_B->CC[0] = 1 + p_pusle_gen->point_us[3] * 16;
|
|
pusle_gen_hw[hw_idx].TMR_B->CC[1] = pusle_gen_hw[hw_idx].TMR_B->CC[0] + p_pusle_gen->point_us[4] * 16;
|
|
pusle_gen_hw[hw_idx].TMR_B->CC[2] = pusle_gen_hw[hw_idx].TMR_B->CC[1] + p_pusle_gen->point_us[5] * 16;
|
|
pusle_gen_hw[hw_idx].TMR_B->CC[3] = pusle_gen_hw[hw_idx].TMR_B->CC[2] + p_pusle_gen->point_us[6] * 16;
|
|
pusle_gen_hw[hw_idx].TMR_B->CC[4] = pusle_gen_hw[hw_idx].TMR_B->CC[3] + p_pusle_gen->idle_us * 16;
|
|
pusle_gen_hw[hw_idx].TMR_B->SHORTS = NRF_TIMER_SHORT_COMPARE4_STOP_MASK | NRF_TIMER_SHORT_COMPARE4_CLEAR_MASK;
|
|
pusle_gen_hw[hw_idx].TMR_B->INTENSET = NRF_TIMER_INT_COMPARE4_MASK;
|
|
|
|
pusle_gen_hw[hw_idx].TMR_A->CC[0] = 1;
|
|
pusle_gen_hw[hw_idx].TMR_A->CC[1] = pusle_gen_hw[hw_idx].TMR_A->CC[0] + p_pusle_gen->point_us[0] * 16;
|
|
pusle_gen_hw[hw_idx].TMR_A->CC[2] = pusle_gen_hw[hw_idx].TMR_A->CC[1] + p_pusle_gen->point_us[1] * 16;
|
|
pusle_gen_hw[hw_idx].TMR_A->CC[3] = pusle_gen_hw[hw_idx].TMR_A->CC[2] + p_pusle_gen->point_us[2] * 16;
|
|
pusle_gen_hw[hw_idx].TMR_A->SHORTS = NRF_TIMER_SHORT_COMPARE3_STOP_MASK | NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK;
|
|
|
|
sd_nvic_EnableIRQ(pusle_gen_hw[hw_idx].IRQn);
|
|
|
|
pusle_gen_hw[hw_idx].TMR_A->TASKS_START = 1;
|
|
}
|
|
|
|
void cpg11_pulse_init(uint32_t hw_idx, pusle_gen_t *p_pusle_gen, uint32_t len)
|
|
{
|
|
taskENTER_CRITICAL();
|
|
|
|
if (pusle_gen_hw[hw_idx].p_pusle_gen)
|
|
{
|
|
pusle_gen_hw[hw_idx].TMR_B->TASKS_STOP = 1;
|
|
pusle_gen_hw[hw_idx].TMR_A->TASKS_STOP = 1;
|
|
|
|
sd_nvic_DisableIRQ(pusle_gen_hw[hw_idx].IRQn);
|
|
sd_nvic_ClearPendingIRQ(pusle_gen_hw[hw_idx].IRQn);
|
|
|
|
nrf_gpiote_task_disable(pusle_gen_hw[hw_idx].gpiote_idx[0]);
|
|
nrf_gpiote_task_disable(pusle_gen_hw[hw_idx].gpiote_idx[1]);
|
|
nrf_gpiote_task_disable(pusle_gen_hw[hw_idx].gpiote_idx[2]);
|
|
nrf_gpiote_task_disable(pusle_gen_hw[hw_idx].gpiote_idx[3]);
|
|
}
|
|
|
|
pusle_gen_hw[hw_idx].p_pusle_gen = p_pusle_gen;
|
|
pusle_gen_hw[hw_idx].pusle_gen_len = len;
|
|
pusle_gen_hw[hw_idx].pusle_gen_sel = 0;
|
|
|
|
for (uint32_t i = 0; i < len; i++)
|
|
{
|
|
nrf_gpio_pin_clear(p_pusle_gen[i].VBxL);
|
|
nrf_gpio_pin_set(p_pusle_gen[i].VBxH);
|
|
nrf_gpio_pin_clear(p_pusle_gen[i].VAxL);
|
|
nrf_gpio_pin_set(p_pusle_gen[i].VAxH);
|
|
}
|
|
|
|
taskEXIT_CRITICAL();
|
|
};
|
|
|
|
void cpg_pulse_default_demo_ext(void)
|
|
{
|
|
uint32_t pusle_gen_numb = 2;
|
|
|
|
pusle_gen_t *p_pusle_genA = pvPortMalloc(sizeof(pusle_gen_t) * pusle_gen_numb);
|
|
pusle_gen_t *p_pusle_genB = pvPortMalloc(sizeof(pusle_gen_t) * pusle_gen_numb);
|
|
|
|
memset(p_pusle_genA, 0x00, sizeof(pusle_gen_t) * pusle_gen_numb);
|
|
memset(p_pusle_genB, 0x00, sizeof(pusle_gen_t) * pusle_gen_numb);
|
|
|
|
if (pusle_gen_numb > 0)
|
|
{
|
|
p_pusle_genA[0] = (pusle_gen_t) {
|
|
.VBxH = VB1H_PIN,
|
|
.VBxL = VB1L_PIN,
|
|
.VAxH = VA1H_PIN,
|
|
.VAxL = VA1L_PIN,
|
|
.point_us[0] = 1,
|
|
.point_us[1] = 50,
|
|
.point_us[2] = 1,
|
|
.point_us[3] = 0,
|
|
.point_us[4] = 1,
|
|
.point_us[5] = 50,
|
|
.point_us[6] = 1,
|
|
.idle_us = 1000,
|
|
.pulse_cnt = UINT32_MAX,
|
|
.pulse_id = 0,
|
|
};
|
|
}
|
|
|
|
if (pusle_gen_numb > 1)
|
|
{
|
|
p_pusle_genA[1] = (pusle_gen_t) {
|
|
.VBxH = VB2H_PIN,
|
|
.VBxL = VB2L_PIN,
|
|
.VAxH = VA2H_PIN,
|
|
.VAxL = VA2L_PIN,
|
|
.point_us[0] = 1,
|
|
.point_us[1] = 50,
|
|
.point_us[2] = 1,
|
|
.point_us[3] = 0,
|
|
.point_us[4] = 1,
|
|
.point_us[5] = 50,
|
|
.point_us[6] = 1,
|
|
.idle_us = 1000,
|
|
.pulse_cnt = UINT32_MAX,
|
|
.pulse_id = 1,
|
|
};
|
|
}
|
|
|
|
if (pusle_gen_numb > 0)
|
|
{
|
|
p_pusle_genB[0] = (pusle_gen_t) {
|
|
.VBxH = VB3H_PIN,
|
|
.VBxL = VB3L_PIN,
|
|
.VAxH = VA3H_PIN,
|
|
.VAxL = VA3L_PIN,
|
|
.point_us[0] = 1,
|
|
.point_us[1] = 50,
|
|
.point_us[2] = 1,
|
|
.point_us[3] = 0,
|
|
.point_us[4] = 1,
|
|
.point_us[5] = 50,
|
|
.point_us[6] = 1,
|
|
.idle_us = 1000,
|
|
.pulse_cnt = UINT32_MAX,
|
|
.pulse_id = 2,
|
|
};
|
|
}
|
|
|
|
if (pusle_gen_numb > 1)
|
|
{
|
|
p_pusle_genB[1] = (pusle_gen_t) {
|
|
.VBxH = VB4H_PIN,
|
|
.VBxL = VB4L_PIN,
|
|
.VAxH = VA4H_PIN,
|
|
.VAxL = VA4L_PIN,
|
|
.point_us[0] = 1,
|
|
.point_us[1] = 50,
|
|
.point_us[2] = 1,
|
|
.point_us[3] = 0,
|
|
.point_us[4] = 1,
|
|
.point_us[5] = 50,
|
|
.point_us[6] = 1,
|
|
.idle_us = 1000,
|
|
.pulse_cnt = UINT32_MAX,
|
|
.pulse_id = 3,
|
|
};
|
|
}
|
|
|
|
|
|
cpg11_pulse_init(0, p_pusle_genA, pusle_gen_numb);
|
|
|
|
cpg11_pulse_init(1, p_pusle_genB, pusle_gen_numb);
|
|
|
|
cpg11_pulse_start(0, p_pusle_genA);
|
|
|
|
cpg11_pulse_start(1, p_pusle_genB);
|
|
|
|
vTaskDelay(10);
|
|
|
|
// cpg11_pulse_stop_by_pulse_id(p_pusle_gen[0].pulse_id);
|
|
// cpg11_pulse_stop_by_pulse_id(p_pusle_gen[1].pulse_id);
|
|
// cpg11_pulse_stop_by_pulse_id(p_pusle_gen[2].pulse_id);
|
|
// cpg11_pulse_stop_by_pulse_id(p_pusle_gen[3].pulse_id);
|
|
// cpg11_pulse_stop_by_pulse_id(p_pusle_gen[4].pulse_id);
|
|
|
|
vPortFree(p_pusle_genA);
|
|
vPortFree(p_pusle_genB);
|
|
|
|
for (;;)
|
|
{
|
|
}
|
|
}
|
|
|
|
void cpg11_io_init(void)
|
|
{
|
|
const uint32_t pel_pins_default_high[] = {
|
|
LED_R_PIN,
|
|
LED_G_PIN,
|
|
LED_B_PIN,
|
|
CS_MEM_PIN
|
|
};
|
|
|
|
const uint32_t pel_pins_default_low[] = {
|
|
TW_SCKI_0_PIN,
|
|
TW_SCKI_1_PIN,
|
|
ADPT_CLK,
|
|
HV_EN_PIN,
|
|
SPIM_CLK_PIN,
|
|
SPIM_MOSI_PIN,
|
|
SPIM_MISO_PIN,
|
|
ADPT_LE_PIN,
|
|
ADPT_CLR_PIN,
|
|
ADPT0_S4_PIN,
|
|
ADPT0_S3_PIN,
|
|
ADPT0_S2_PIN,
|
|
ADPT0_S1_PIN,
|
|
ADPT1_S4_PIN,
|
|
ADPT1_S3_PIN,
|
|
ADPT1_S2_PIN,
|
|
ADPT1_S1_PIN,
|
|
|
|
VB1L_PIN,
|
|
VB1H_PIN,
|
|
VA1L_PIN,
|
|
VA1H_PIN,
|
|
|
|
VB2L_PIN,
|
|
VB2H_PIN,
|
|
VA2L_PIN,
|
|
VA2H_PIN,
|
|
|
|
VB3L_PIN,
|
|
VB3H_PIN,
|
|
VA3L_PIN,
|
|
VA3H_PIN,
|
|
|
|
VB4L_PIN,
|
|
VB4H_PIN,
|
|
VA4L_PIN,
|
|
VA4H_PIN,
|
|
};
|
|
|
|
for (int i = 0; i < COUNTOF(pel_pins_default_high); i++)
|
|
{
|
|
nrf_gpio_cfg_output(pel_pins_default_high[i]);
|
|
nrf_gpio_pin_set(pel_pins_default_high[i]);
|
|
}
|
|
|
|
for (int i = 0; i < COUNTOF(pel_pins_default_low); i++)
|
|
{
|
|
nrf_gpio_cfg_output(pel_pins_default_low[i]);
|
|
nrf_gpio_pin_clear(pel_pins_default_low[i]);
|
|
}
|
|
|
|
nrf_gpio_cfg_input(AIN0_PIN, NRF_GPIO_PIN_NOPULL);
|
|
nrf_gpio_cfg_input(AIN1_PIN, NRF_GPIO_PIN_NOPULL);
|
|
|
|
for (uint32_t i = 0; i < COUNTOF(pusle_gen_hw); i++)
|
|
{
|
|
pusle_gen_hw[i].TMR_B->PRESCALER = NRF_TIMER_FREQ_16MHz;
|
|
pusle_gen_hw[i].TMR_B->MODE = NRF_TIMER_MODE_TIMER;
|
|
pusle_gen_hw[i].TMR_B->BITMODE = NRF_TIMER_BIT_WIDTH_32;
|
|
|
|
pusle_gen_hw[i].TMR_A->PRESCALER = NRF_TIMER_FREQ_16MHz;
|
|
pusle_gen_hw[i].TMR_A->MODE = NRF_TIMER_MODE_TIMER;
|
|
pusle_gen_hw[i].TMR_A->BITMODE = NRF_TIMER_BIT_WIDTH_32;
|
|
|
|
sd_nvic_SetPriority(pusle_gen_hw[i].IRQn, _PRIO_APP_HIGH);
|
|
}
|
|
|
|
//cpg_pulse_default_demo_ext();
|
|
}
|
|
|
|
#endif
|