249 lines
7.7 KiB
C
249 lines
7.7 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"
|
|
|
|
#if (DEF_ELITE_MODEL == DEF_PULSE_E_LOAD_10)
|
|
|
|
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();
|
|
}
|
|
|
|
#define MIN_PULSE_WIDTH 2
|
|
#define MIN_PULSE_IDLE 2
|
|
#define MAX_PULSE_WIDTH INT16_MAX
|
|
#define MAX_PULSE_IDLE INT16_MAX
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t anode_pin;
|
|
uint32_t cathode_pin;
|
|
uint32_t pulse_idle; // min: 2, max: 32767, unit: us
|
|
uint32_t pulse_width; // min: 2, max: 32767, unit: us,
|
|
uint32_t pulse_cnt; // min: 1, max: 0xFFFFFFFF
|
|
} pusle_gen_t;
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t gpiote_idx[2];
|
|
NRF_TIMER_Type *pulse_tmr;
|
|
uint32_t pulse_irq_n;
|
|
uint32_t pulse_cnt;
|
|
} pusle_gen_hw_t;
|
|
|
|
pusle_gen_hw_t pusle_gen_hw = {
|
|
.gpiote_idx = {0, 1},
|
|
.pulse_tmr = NRF_TIMER3,
|
|
.pulse_irq_n = TIMER3_IRQn,
|
|
.pulse_cnt = 0,
|
|
};
|
|
|
|
void TIMER3_IRQHandler(void)
|
|
{
|
|
if (pusle_gen_hw.pulse_tmr->EVENTS_COMPARE[1])
|
|
{
|
|
pusle_gen_hw.pulse_tmr->EVENTS_COMPARE[1] = 0;
|
|
pusle_gen_hw.pulse_cnt--;
|
|
if (pusle_gen_hw.pulse_cnt == 1)
|
|
{
|
|
pusle_gen_hw.pulse_tmr->SHORTS |= NRF_TIMER_SHORT_COMPARE1_STOP_MASK;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool pel10_pulse_gen(pusle_gen_t *p_pusle_gen)
|
|
{
|
|
/* hardware limitation */
|
|
if (p_pusle_gen->pulse_cnt == 0 ||
|
|
p_pusle_gen->pulse_idle < MIN_PULSE_IDLE ||
|
|
p_pusle_gen->pulse_width < MIN_PULSE_WIDTH ||
|
|
p_pusle_gen->pulse_idle > MAX_PULSE_IDLE ||
|
|
p_pusle_gen->pulse_width > MAX_PULSE_WIDTH)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
pusle_gen_hw.pulse_cnt = p_pusle_gen->pulse_cnt;
|
|
|
|
pusle_gen_hw.pulse_tmr->TASKS_STOP = 1;
|
|
|
|
sd_nvic_DisableIRQ(pusle_gen_hw.pulse_irq_n);
|
|
sd_nvic_ClearPendingIRQ(pusle_gen_hw.pulse_irq_n);
|
|
|
|
nrf_gpiote_task_configure(pusle_gen_hw.gpiote_idx[0], p_pusle_gen->anode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_HIGH);
|
|
nrf_gpiote_task_configure(pusle_gen_hw.gpiote_idx[1], p_pusle_gen->cathode_pin, NRF_GPIOTE_POLARITY_TOGGLE, NRF_GPIOTE_INITIAL_VALUE_LOW);
|
|
|
|
nrf_gpiote_task_enable(pusle_gen_hw.gpiote_idx[0]);
|
|
nrf_gpiote_task_enable(pusle_gen_hw.gpiote_idx[1]);
|
|
|
|
NRF_PPI->CH[0].EEP = (uint32_t)&pusle_gen_hw.pulse_tmr->EVENTS_COMPARE[0];
|
|
NRF_PPI->CH[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw.gpiote_idx[0]];
|
|
NRF_PPI->FORK[0].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw.gpiote_idx[1]];
|
|
NRF_PPI->CHENSET = (1 << (0));
|
|
|
|
NRF_PPI->CH[1].EEP = (uint32_t)&pusle_gen_hw.pulse_tmr->EVENTS_COMPARE[1];
|
|
NRF_PPI->CH[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw.gpiote_idx[0]];
|
|
NRF_PPI->FORK[1].TEP = (uint32_t)&NRF_GPIOTE->TASKS_OUT[pusle_gen_hw.gpiote_idx[1]];
|
|
NRF_PPI->CHENSET = (1 << (1));
|
|
|
|
pusle_gen_hw.pulse_tmr->TASKS_CLEAR = 1;
|
|
|
|
pusle_gen_hw.pulse_tmr->PRESCALER = NRF_TIMER_FREQ_16MHz;
|
|
pusle_gen_hw.pulse_tmr->MODE = NRF_TIMER_MODE_TIMER;
|
|
pusle_gen_hw.pulse_tmr->BITMODE = NRF_TIMER_BIT_WIDTH_32;
|
|
pusle_gen_hw.pulse_tmr->CC[0] = p_pusle_gen->pulse_idle * 16;
|
|
pusle_gen_hw.pulse_tmr->CC[1] = pusle_gen_hw.pulse_tmr->CC[0] + p_pusle_gen->pulse_width * 16;
|
|
pusle_gen_hw.pulse_tmr->SHORTS = pusle_gen_hw.pulse_cnt > 1 ? NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK : NRF_TIMER_SHORT_COMPARE1_STOP_MASK;
|
|
pusle_gen_hw.pulse_tmr->INTENSET = NRF_TIMER_INT_COMPARE1_MASK;
|
|
|
|
sd_nvic_SetPriority(pusle_gen_hw.pulse_irq_n, _PRIO_APP_HIGH);
|
|
sd_nvic_EnableIRQ(pusle_gen_hw.pulse_irq_n);
|
|
|
|
pusle_gen_hw.pulse_tmr->TASKS_START = 1;
|
|
|
|
return true;
|
|
}
|
|
|
|
void pel10_pulse_gen_demo(void)
|
|
{
|
|
pusle_gen_t pusle_gen = {
|
|
.anode_pin = ANODE_PIN,
|
|
.cathode_pin = CATHODE_PIN,
|
|
.pulse_width = 10,
|
|
.pulse_idle = 10,
|
|
.pulse_cnt = 0xFFFFFFFF
|
|
};
|
|
|
|
if (pel10_pulse_gen(&pusle_gen) == false)
|
|
{
|
|
// fail handling
|
|
}
|
|
}
|
|
|
|
void pel10_io_init(void)
|
|
{
|
|
const uint32_t pel_pins_default_high[] = {
|
|
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
|
|
};
|
|
|
|
const uint32_t pel_pins_default_low[] = {
|
|
ANODE_PIN,
|
|
CATHODE_PIN,
|
|
SAMPLE_R_PIN,
|
|
SAMPLE_V_PIN,
|
|
RELAY1_PIN,
|
|
RELAY2_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]);
|
|
}
|
|
|
|
// 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;
|
|
|
|
pel10_pulse_gen_demo();
|
|
}
|
|
|
|
#endif
|