Before i inserted in my code to use ppi + gpiote + spim usb serial device port worked properly, it connected normally, but now it doesn't connect the port at all, did i create blocking functions even though they should work without CPU. Also my timer interrupt seems not to be happening, in interrupt i set a flag processing_ready = true; but it seems that in main()
if (processing_ready){
processing_ready = false;
nrf_gpio_pin_set(CS_PIN);
k_msleep(3);
} never happens.
/*
* Copyright (c) 2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include "radc.h"
#include "communication.h"
#include "init.h"
#include "spi_mcp3562.h"
#include <zephyr/kernel.h>
#include <nrfx_spim.h>
#include <nrfx_gpiote.h>
#include <hal/nrf_ppi.h>
#include <nrfx_spim.h>
#include <nrfx_timer.h>
#include <nrfx_ppi.h>
LOG_MODULE_REGISTER(main, LOG_LEVEL_DBG);
#define SPI_INSTANCE 1
#define DRDY_PIN NRF_GPIO_PIN_MAP(1, 3) // P1.03
#define CS_PIN NRF_GPIO_PIN_MAP(1, 12) // P1.12
#define LED0_NODE DT_ALIAS(led0)
#define BYTES_PER_SAMPLE 3
#define SAMPLE_COUNT 2000
static volatile bool use_ping = true;
static int sample_count = 0;
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
uint32_t flags = NRFX_SPIM_FLAG_HOLD_XFER
| NRFX_SPIM_FLAG_REPEATED_XFER
| NRFX_SPIM_FLAG_RX_POSTINC
| NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER;
volatile bool ping_ready = false;
volatile bool pong_ready = false;
//static bool using_ping = true;
//volatile bool config = false;
//volatile bool read = false;
volatile bool using_buf_a = true;
volatile bool processing_ready = false;
#define MAX_SAMPLES SAMPLE_COUNT
static const nrfx_timer_t counter_timer = NRFX_TIMER_INSTANCE(2);
static const nrfx_spim_t spi = NRFX_SPIM_INSTANCE(SPI_INSTANCE);
const nrfx_gpiote_t gpiote = NRFX_GPIOTE_INSTANCE(0);
#define PPI_CHANNEL NRF_PPI_CHANNEL0
#define PPI_CH_T NRF_PPI_CHANNEL1
#define ADC_QUE_SIZE 2000
typedef struct ArrayList
{
uint8_t rx_buffer[3];
}ArrayList_type;
static ArrayList_type p_rx_buffer_a[ADC_QUE_SIZE],p_rx_buffer_b[ADC_QUE_SIZE] ;
void spi_init(uint8_t *rx_ptr)
{
//NRF_SPIM1->RXD.MAXCNT = 3;
//NRF_SPIM1->RXD.PTR = (int32_t)rx_ptr;
//NRF_SPIM1->RXD.LIST = SPIM_RXD_LIST_LIST_ArrayList;
nrfx_spim_config_t config = {
.sck_pin = NRF_GPIO_PIN_MAP(1, 11), //43
.mosi_pin = NRF_GPIO_PIN_MAP(1, 2), // 34
.miso_pin = NRF_GPIO_PIN_MAP(1, 10), //42
.ss_pin = NRF_SPIM_PIN_NOT_CONNECTED, //44
.frequency = NRFX_MHZ_TO_HZ(4), //SPIM_FREQUENCY_FREQUENCY_M4,
.mode = NRF_SPIM_MODE_0,
.bit_order = NRF_SPIM_BIT_ORDER_MSB_FIRST,
//.dcx_pin = NRF_SPIM_PIN_NOT_CONNECTED,
//.orc = 0xFF,
//.irq_priority = 6,
//.use_hw_ss = false,
.ss_active_high = false
};
nrfx_err_t err = (nrfx_spim_init(&spi, &config, NULL, NULL));
if (err != NRFX_SUCCESS) {
printk("nrfx_spim_init() failed! Error code: %08X\n", err);
return; // ili k_panic(); ili __ASSERT_NO_MSG(false);
}
else{
LOG_INF("prosao spim");
}
}
void gpiote_init(void)
{
nrf_gpio_cfg_input(DRDY_PIN, NRF_GPIO_PIN_NOPULL);
NRF_GPIOTE->CONFIG[0] =
(GPIOTE_CONFIG_MODE_Event << GPIOTE_CONFIG_MODE_Pos) |
(DRDY_PIN << GPIOTE_CONFIG_PSEL_Pos) |
(GPIOTE_CONFIG_POLARITY_HiToLo << GPIOTE_CONFIG_POLARITY_Pos);
NRF_GPIOTE->EVENTS_IN[0] = 0;
LOG_INF("prosao gpiote");
}
void ppi_init(void)
{
NRF_PPI->CHENCLR = (1U << PPI_CHANNEL);
NRF_GPIOTE->EVENTS_IN[0] = 0;
uint32_t event_addr = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0];
uint32_t task_addr = (uint32_t)&spi.p_reg->TASKS_START;
NRF_PPI->CH[PPI_CHANNEL].EEP = event_addr;
NRF_PPI->CH[PPI_CHANNEL].TEP = task_addr;
NRF_PPI->CHENSET = (1 << PPI_CHANNEL);
LOG_INF("prosao ppi");
}
void mcp3562_conf(void)
{
LOG_INF("→ enter mcp3562_conf");
uint8_t data_to_send[9];
data_to_send[0] = CLOCK_EXTERNAL | CURNT_SRC_DIS | MODE_CONVERTION;
data_to_send[1] = PRESCALER_NO_MCLK | OSR_64;
data_to_send[2] = ADC_CURRENT_X1 | GAIN_X1 | MUX_DIS_AUTO_ZEROING;
data_to_send[3] = CONV_MODE_CONTINUOUS | FORMAT_24_BIT | CRC_DISABLED | OFFCAL_DISABLED | GAINCAL_DISABLED;
data_to_send[4] = DATA_NOT_UPDATED | CRC_ERROR_NOT_OCURRED | POR_NOT_OCURRED | IRQ_MODE_IRQ_SELECTED | IRQ_MODE_NO_EXT_PULL_UP | FAST_COMMANDS_ENABLE | STP_DISABLE;
data_to_send[5] = 0B00001000;
data_to_send[6] = SCAN_DLY_0_DMCLK;
data_to_send[7] = 0B00000000 ;
data_to_send[8] = 0;
uint8_t tx_buf[] = {(DEVICE_ADDRESS | CONFIG0 | FLAG_INCREMENTAL_WRITE), data_to_send[0], data_to_send[1], data_to_send[2], data_to_send[3], data_to_send[4], data_to_send[5], data_to_send[6], data_to_send[7], data_to_send[8]};
//NRF_SPIM1->TXD.PTR = (uint32_t)&tx_buf;
//NRF_SPIM1->TXD.MAXCNT = 10;
nrfx_spim_xfer_desc_t xfer_desc;
xfer_desc.p_tx_buffer = tx_buf;
xfer_desc.tx_length = 10;
xfer_desc.rx_length = 0;
xfer_desc.p_rx_buffer = NULL;
nrfx_err_t err = (nrfx_spim_xfer(&spi, &xfer_desc, NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER)); // startuje se odmah!
if (err != NRFX_SUCCESS) {
printk("SPIM transfer error: %d\n", err);
}
else {
LOG_INF("adc konfigurisan!\n");
}
spi.p_reg->EVENTS_END = 0;
}
void spi_ping_pong_transfer_rx(uint8_t *rx_ptr)
{
//spi.p_reg->EVENTS_END = 0;
//uint8_t tx_buffer[CPU_BUF_SIZE];
uint8_t tx_buffer[3] = {0};
/*NRF_SPIM1->RXD.MAXCNT = 3;
NRF_SPIM1->RXD.PTR = (int32_t)rx_ptr;
NRF_SPIM1->RXD.LIST = SPIM_RXD_LIST_LIST_ArrayList;*/
nrfx_spim_xfer_desc_t xfer_desc;
xfer_desc.p_tx_buffer = NULL;
xfer_desc.tx_length = 0;
xfer_desc.rx_length = BYTES_PER_SAMPLE;
xfer_desc.p_rx_buffer = rx_ptr;
//nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_XFER_TRX(tx_buffer,3,rx_ptr, 3);
nrfx_err_t err = (nrfx_spim_xfer(&spi, &xfer_desc, flags));
//nrfx_err_t err = (nrfx_spim_xfer(&spi, &xfer, flags)); // ne startuje se odmah!
if (err != NRFX_SUCCESS) {
printk("SPIM transfer error: %d\n", err);
}
else {
LOG_INF("zapoceo citanje!\n");
}
/*while (spi.p_reg->EVENTS_END == 0) {
// optional: dodaj timeout da ne zapne zauvek
}*/
spi.p_reg->EVENTS_END = 0;
}
void reg_citanje_conf(void)
{
//spi.p_reg->EVENTS_END = 0;
uint8_t tx_buff = DEVICE_ADDRESS | ADCDATA | FLAG_STATIC_READ;
nrfx_spim_xfer_desc_t xfer_desc;
xfer_desc.p_tx_buffer = &tx_buff;
xfer_desc.tx_length = 1;
xfer_desc.rx_length = 0;
xfer_desc.p_rx_buffer = NULL;
nrfx_err_t err = (nrfx_spim_xfer(&spi, &xfer_desc, NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER)); // ne startuje se odmah!
if (err != NRFX_SUCCESS) {
printk("SPIM transfer error: %d\n", err);
}
else{
LOG_INF("reg konfigurisan!\n");
}
/*while (spi.p_reg->EVENTS_END == 0) {
// optional: dodaj timeout da ne zapne zauvek
}*/
spi.p_reg->EVENTS_END = 0;
}
void counter_handler(nrf_timer_event_t event_type, void *p_context)
{
//processing_ready = true;
if (event_type == NRF_TIMER_EVENT_COMPARE0)
{
// Ovde CPU preuzima prethodni bafer
processing_ready = true;
gpio_pin_toggle_dt(&led);
// Prebaci DMA na drugi bafer
using_buf_a = !using_buf_a;
uint8_t *next_buffer = using_buf_a ? (uint8_t *)p_rx_buffer_a : (uint8_t *)p_rx_buffer_b;
// Samo zameni RX buffer
//NRF_SPIM1->EVENTS_END = 0;
//NRF_SPIM1->RXD.PTR = (uint32_t)next_buffer;
//NRF_SPIM1->RXD.MAXCNT = BYTES_PER_SAMPLE;
spi_ping_pong_transfer_rx(next_buffer);
nrfx_timer_clear(&counter_timer);
nrfx_timer_enable(&counter_timer);
//nrfx_spim_abort(&spi);
}
}
void timer_counter_init(void)
{
nrfx_timer_config_t cfg = NRFX_TIMER_DEFAULT_CONFIG(NRFX_MHZ_TO_HZ(16));
cfg.mode = NRF_TIMER_MODE_COUNTER;
cfg.bit_width = NRF_TIMER_BIT_WIDTH_32;
nrfx_err_t err = nrfx_timer_init(&counter_timer, &cfg, counter_handler);
if (err != NRFX_SUCCESS) {
printk("Timer error: %d\n", err);
}
else {
LOG_INF("spreman timer!\n");
}
nrfx_timer_extended_compare(
&counter_timer,
NRF_TIMER_CC_CHANNEL0,
MAX_SAMPLES,
NRF_TIMER_SHORT_COMPARE0_STOP_MASK,
true
);
nrfx_timer_enable(&counter_timer);
NRF_PPI->CHENCLR = (1U << PPI_CH_T);
NRF_GPIOTE->EVENTS_IN[0] = 0;
uint32_t evt_end = (uint32_t)&NRF_GPIOTE->EVENTS_IN[0];
uint32_t task_count = nrfx_timer_task_address_get(&counter_timer, NRF_TIMER_TASK_COUNT);
NRF_PPI->CH[PPI_CH_T].EEP = evt_end;
NRF_PPI->CH[PPI_CH_T].TEP = task_count;
NRF_PPI->CHENSET = (1U << PPI_CH_T);
NVIC_ClearPendingIRQ(TIMER2_IRQn); //ovo je radilo reset (ponovo pozivajuci main)
NVIC_EnableIRQ(TIMER2_IRQn);
}
void TIMER2_IRQHandler(void)
{
nrfx_timer_irq_handler(&counter_timer);
}
int main(void)
{
uint8_t timer_count_value;
pin_initialization();
gpio_pin_configure_dt(&led, GPIO_OUTPUT_INACTIVE);
spi_init((uint8_t *)p_rx_buffer_a);
mcp3562_conf();
nrf_gpio_pin_set(CS_PIN);
nrf_gpio_pin_clear(CS_PIN);
reg_citanje_conf();
spi_ping_pong_transfer_rx((uint8_t *)p_rx_buffer_a);
gpiote_init();
timer_counter_init();
ppi_init();
gpio_pin_toggle_dt(&led);
communication_init();
while(1){
if (processing_ready){
processing_ready = false;
nrf_gpio_pin_set(CS_PIN);
k_msleep(3);
}
NRF_TIMER2->TASKS_CAPTURE[0] = 1;
timer_count_value = NRF_TIMER2->CC[0];
NRF_TIMER2->TASKS_CAPTURE[0] = 0;
printf("count = %d\n", timer_count_value);
k_msleep(5000);
//__WFI();
}
}