Files
microchip-application-bmd38…/cpg10_io.c
T

299 lines
9.8 KiB
C

#include "elite_board.h"
#include "nrf_gpio.h"
#include "nrf_gpiote.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_10)
#define PLE_GRP0_TMR NRF_TIMER4
#define PLE_GRP0_TMR_IRQn TIMER1_IRQn
#define PLE_GRP1_TMR NRF_TIMER2
#define PLE_GRP1_TMR_IRQn TIMER2_IRQn
const uint32_t pel_pins[] = {
VA1H_PIN,
VA1L_PIN,
VA2H_PIN,
VA2L_PIN,
VA3H_PIN,
VA3L_PIN,
VA4H_PIN,
VA4L_PIN,
};
const uint32_t grp0_pin[] = {
VB1H_PIN,
VB1L_PIN,
VA1H_PIN,
VA1L_PIN,
};
typedef struct
{
uint32_t VAxH;
uint32_t VAxL;
uint32_t VBxH;
uint32_t VBxL;
uint32_t idle_us; // min: 500us, max: 60sec
uint32_t point_us[7]; // toggle point timestamp
uint32_t pulse_cnt; // min: 1, max: 0xFFFFFFFF
uint32_t op_mode;
} pusle_gen_t;
typedef struct
{
const uint32_t gpiote_idx[4];
NRF_TIMER_Type *TMR_A;
NRF_TIMER_Type *TMR_B;
uint32_t IRQn;
uint32_t pulse_cnt;
} pusle_gen_hw_t;
pusle_gen_hw_t pusle_gen_hw[] = {
{{ 0, 1, 2, 3 },
NRF_TIMER3,
NRF_TIMER1,
TIMER1_IRQn,
0},
{{ 4, 5, 6, 7 },
NRF_TIMER4,
NRF_TIMER2,
TIMER2_IRQn,
0},
};
void TIMER1_IRQHandler(void)
{
if (pusle_gen_hw[0].TMR_B->EVENTS_COMPARE[3])
{
pusle_gen_hw[0].TMR_B->EVENTS_COMPARE[3] = 0;
pusle_gen_hw[0].pulse_cnt--;
if (pusle_gen_hw[0].pulse_cnt == 0)
{
pusle_gen_hw[0].TMR_A->TASKS_STOP = 1;
pusle_gen_hw[0].TMR_B->TASKS_STOP = 1;
}
}
}
void TIMER2_IRQHandler(void)
{
if (pusle_gen_hw[1].TMR_B->EVENTS_COMPARE[3])
{
pusle_gen_hw[1].TMR_B->EVENTS_COMPARE[3] = 0;
pusle_gen_hw[1].pulse_cnt--;
if (pusle_gen_hw[1].pulse_cnt == 0)
{
pusle_gen_hw[1].TMR_A->TASKS_STOP = 1;
pusle_gen_hw[1].TMR_B->TASKS_STOP = 1;
}
}
}
bool cpg10_pulse_gen(uint32_t idx, pusle_gen_t *p_pusle_gen)
{
if (pusle_gen_hw[idx].pulse_cnt)
{
return false;
}
pusle_gen_hw[idx].pulse_cnt = p_pusle_gen->pulse_cnt;
pusle_gen_hw[idx].TMR_B->TASKS_STOP = 1;
pusle_gen_hw[idx].TMR_A->TASKS_STOP = 1;
sd_nvic_DisableIRQ(pusle_gen_hw[idx].IRQn);
sd_nvic_ClearPendingIRQ(pusle_gen_hw[idx].IRQn);
switch (p_pusle_gen->op_mode)
{
case 1:
nrf_gpiote_task_configure(pusle_gen_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[idx].gpiote_idx[1], p_pusle_gen->VBxL, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_gpiote_task_configure(pusle_gen_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[idx].gpiote_idx[3], p_pusle_gen->VAxL, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
break;
case 0:
default:
nrf_gpiote_task_configure(pusle_gen_hw[idx].gpiote_idx[0], p_pusle_gen->VAxH, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_gpiote_task_configure(pusle_gen_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[idx].gpiote_idx[2], p_pusle_gen->VBxH, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
nrf_gpiote_task_configure(pusle_gen_hw[idx].gpiote_idx[3], p_pusle_gen->VAxL, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
break;
}
nrf_gpiote_task_enable(pusle_gen_hw[idx].gpiote_idx[0]);
nrf_gpiote_task_enable(pusle_gen_hw[idx].gpiote_idx[1]);
nrf_gpiote_task_enable(pusle_gen_hw[idx].gpiote_idx[2]);
nrf_gpiote_task_enable(pusle_gen_hw[idx].gpiote_idx[3]);
uint32_t offs = 8 * idx;
NRF_PPI->CH[offs + 0].EEP = (uint32_t)&pusle_gen_hw[idx].TMR_A->EVENTS_COMPARE[0];
NRF_PPI->CH[offs + 0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[idx].gpiote_idx[0]];
NRF_PPI->CHENSET = (1 << (offs + 0));
NRF_PPI->CH[offs + 1].EEP = (uint32_t)&pusle_gen_hw[idx].TMR_A->EVENTS_COMPARE[1];
NRF_PPI->CH[offs + 1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[idx].gpiote_idx[1]];
NRF_PPI->CHENSET = (1 << (offs + 1));
NRF_PPI->CH[offs + 2].EEP = (uint32_t)&pusle_gen_hw[idx].TMR_A->EVENTS_COMPARE[2];
NRF_PPI->CH[offs + 2].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[idx].gpiote_idx[1]];
NRF_PPI->CHENSET = (1 << (offs + 2));
NRF_PPI->CH[offs + 3].EEP = (uint32_t)&pusle_gen_hw[idx].TMR_A->EVENTS_COMPARE[3];
NRF_PPI->CH[offs + 3].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[idx].gpiote_idx[0]];
NRF_PPI->FORK[offs + 3].TEP = (uint32_t)&pusle_gen_hw[idx].TMR_B->TASKS_START;
NRF_PPI->CHENSET = (1 << (offs + 3));
NRF_PPI->CH[offs + 4].EEP = (uint32_t)&pusle_gen_hw[idx].TMR_B->EVENTS_COMPARE[0];
NRF_PPI->CH[offs + 4].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[idx].gpiote_idx[2]];
NRF_PPI->CHENSET = (1 << (offs + 4));
NRF_PPI->CH[offs + 5].EEP = (uint32_t)&pusle_gen_hw[idx].TMR_B->EVENTS_COMPARE[1];
NRF_PPI->CH[offs + 5].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[idx].gpiote_idx[3]];
NRF_PPI->CHENSET = (1 << (offs + 5));
NRF_PPI->CH[offs + 6].EEP = (uint32_t)&pusle_gen_hw[idx].TMR_B->EVENTS_COMPARE[2];
NRF_PPI->CH[offs + 6].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[idx].gpiote_idx[3]];
NRF_PPI->CHENSET = (1 << (offs + 6));
NRF_PPI->CH[offs + 7].EEP = (uint32_t)&pusle_gen_hw[idx].TMR_B->EVENTS_COMPARE[3];
NRF_PPI->CH[offs + 7].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw[idx].gpiote_idx[2]];
NRF_PPI->FORK[offs + 7].TEP = (uint32_t)&pusle_gen_hw[idx].TMR_A->TASKS_START;
NRF_PPI->CHENSET = (1 << (offs + 7));
pusle_gen_hw[idx].TMR_B->TASKS_CLEAR = 1;
pusle_gen_hw[idx].TMR_A->TASKS_CLEAR = 1;
pusle_gen_hw[idx].TMR_B->PRESCALER = NRF_TIMER_FREQ_16MHz;
pusle_gen_hw[idx].TMR_B->MODE = NRF_TIMER_MODE_TIMER;
pusle_gen_hw[idx].TMR_B->BITMODE = NRF_TIMER_BIT_WIDTH_32;
pusle_gen_hw[idx].TMR_B->INTENSET = NRF_TIMER_INT_COMPARE3_MASK;
pusle_gen_hw[idx].TMR_B->CC[0] = 1 + p_pusle_gen->point_us[3] * 16;
pusle_gen_hw[idx].TMR_B->CC[1] = pusle_gen_hw[idx].TMR_B->CC[0] + p_pusle_gen->point_us[4] * 16;
pusle_gen_hw[idx].TMR_B->CC[2] = pusle_gen_hw[idx].TMR_B->CC[1] + p_pusle_gen->point_us[5] * 16;
pusle_gen_hw[idx].TMR_B->CC[3] = pusle_gen_hw[idx].TMR_B->CC[2] + p_pusle_gen->point_us[6] * 16;
pusle_gen_hw[idx].TMR_B->SHORTS = NRF_TIMER_SHORT_COMPARE3_STOP_MASK | NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK;
pusle_gen_hw[idx].TMR_A->PRESCALER = NRF_TIMER_FREQ_16MHz;
pusle_gen_hw[idx].TMR_A->MODE = NRF_TIMER_MODE_TIMER;
pusle_gen_hw[idx].TMR_A->BITMODE = NRF_TIMER_BIT_WIDTH_32;
pusle_gen_hw[idx].TMR_A->CC[0] = p_pusle_gen->idle_us * 16;
pusle_gen_hw[idx].TMR_A->CC[1] = pusle_gen_hw[idx].TMR_A->CC[0] + p_pusle_gen->point_us[0] * 16;
pusle_gen_hw[idx].TMR_A->CC[2] = pusle_gen_hw[idx].TMR_A->CC[1] + p_pusle_gen->point_us[1] * 16;
pusle_gen_hw[idx].TMR_A->CC[3] = pusle_gen_hw[idx].TMR_A->CC[2] + p_pusle_gen->point_us[2] * 16;
pusle_gen_hw[idx].TMR_A->SHORTS = NRF_TIMER_SHORT_COMPARE3_STOP_MASK | NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK;
sd_nvic_SetPriority(pusle_gen_hw[idx].IRQn, _PRIO_APP_HIGH);
sd_nvic_EnableIRQ(pusle_gen_hw[idx].IRQn);
pusle_gen_hw[idx].TMR_A->TASKS_START = 1;
return true;
}
void cpg_pulse_demo(void)
{
pusle_gen_t pusle_gen[2] = {
{.VBxH = VB1H_PIN,
.VBxL = VB1L_PIN,
.VAxH = VA1H_PIN,
.VAxL = VA1L_PIN,
.idle_us = 1000,
.point_us[0] = 1,
.point_us[1] = 10,
.point_us[2] = 1,
.point_us[3] = 0,
.point_us[4] = 1,
.point_us[5] = 10,
.point_us[6] = 1,
.pulse_cnt = 3,
.op_mode = 0,},
{.VBxH = VB2H_PIN,
.VBxL = VB2L_PIN,
.VAxH = VA2H_PIN,
.VAxL = VA2L_PIN,
.idle_us = 1000,
.point_us[0] = 1,
.point_us[1] = 10,
.point_us[2] = 1,
.point_us[3] = 0,
.point_us[4] = 1,
.point_us[5] = 10,
.point_us[6] = 1,
.pulse_cnt = 5,
.op_mode = 1,}
};
cpg10_pulse_gen(0, &pusle_gen[0]);
cpg10_pulse_gen(1, &pusle_gen[1]);
}
void cpg10_io_init(void)
{
const uint32_t pel_pins_default_high[] = {
LED_R_PIN,
LED_G_PIN,
LED_B_PIN
};
const uint32_t pel_pins_default_low[] = {
ADPT0_S4_PIN,
ADPT0_S3_PIN,
ADPT0_S2_PIN,
ADPT0_S1_PIN,
ADPT_LE_PIN,
ADPT_CLR_PIN,
TW_SCKI_0_PIN,
TW_SCKI_1_PIN,
TW_SDI_PIN,
HV_EN_PIN,
ADPT1_S1_PIN,
VA1H_PIN,
VA1L_PIN,
VA2H_PIN,
VA2L_PIN,
VA3H_PIN,
VA3L_PIN,
VA4H_PIN,
VA4L_PIN,
VB1H_PIN,
VB1L_PIN,
VB2H_PIN,
VB2L_PIN,
VB3H_PIN,
VB3L_PIN,
VB4H_PIN,
VB4L_PIN,
ADPT1_S4_PIN,
ADPT1_S3_PIN,
ADPT1_S2_PIN
};
for (int i = 0; i < COUNTOF(pel_pins_default_high); i++)
{
nrf_gpio_pin_set(pel_pins_default_high[i]);
nrf_gpio_cfg_output(pel_pins_default_high[i]);
}
for (int i = 0; i < COUNTOF(pel_pins_default_low); i++)
{
nrf_gpio_pin_clear(pel_pins_default_low[i]);
nrf_gpio_cfg_output(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);
}
#endif