#include "nrf_delay.h"
#include "nrf_gpio.h"
#define SETB(x,y) (x|=(1<<y)) //for o/p
#define CLRB(x,y) (x&=(~(1<<y))) //for o/p
#define TGLB(x,y) (x^=(1<<y)) //for o/p
#define CHECKB(x,y) (x&(1<<y)) //for i/p
#define SERIAL_FLOAT_PRECISION 4
#define SERIAL_BUFFER_SIZE 64
typedef struct
{
unsigned char buffer[SERIAL_BUFFER_SIZE];
volatile unsigned int head;
volatile unsigned int tail;
}ring_buffer;
ring_buffer rx_buffer;
ring_buffer tx_buffer;
void UARTE0_UART0_IRQHandler(void)
{
unsigned char tx,rx;
unsigned int i;
if(NRF_UART0->EVENTS_TXDRDY == 1)
{
NRF_UART0->EVENTS_TXDRDY=0;
if (tx_buffer.head == tx_buffer.tail)
{
SETB(NRF_UART0->INTENCLR,7);
}
else
{
tx = tx_buffer.buffer[tx_buffer.tail];
tx_buffer.tail = (tx_buffer.tail + 1) % SERIAL_BUFFER_SIZE;
NRF_UART0->TXD = tx;
}
}
if(NRF_UART0->EVENTS_RXDRDY == 1)
{
NRF_UART0->EVENTS_RXDRDY = 0;
i = (unsigned int)(rx_buffer.head + 1) % SERIAL_BUFFER_SIZE;
if(CHECKB(NRF_UART0->ERRORSRC,1)==0)
{
rx = NRF_UART0->RXD;
if (i != rx_buffer.tail)
{
rx_buffer.buffer[rx_buffer.head] = rx;
rx_buffer.head = i;
}
}
else
{
rx = NRF_UART0->RXD;
}
}
}
void uart_init()
{
NRF_UART0->BAUDRATE = 0x01D7E000;
//NRF_UART0->CONFIG = 0x00000001;
NRF_UART0->PSELRTS = 5;
NRF_UART0->PSELTXD = 6;
NRF_UART0->PSELCTS = 7;
NRF_UART0->PSELRXD = 8;
nrf_gpio_cfg_output(6);
nrf_gpio_cfg_input(8, GPIO_PIN_CNF_PULL_Disabled);
nrf_gpio_cfg_output(5);
nrf_gpio_cfg_input(7, GPIO_PIN_CNF_PULL_Disabled);
NRF_UART0->TASKS_STARTTX = 1;
NRF_UART0->TASKS_STARTRX = 1;
NRF_UART0->ENABLE = 0x00000004;
NRF_UART0->INTENSET=0x84;
NVIC_EnableIRQ(UARTE0_UART0_IRQn);
}
int serial_available(void)
{
return (unsigned int)(SERIAL_BUFFER_SIZE + rx_buffer.head - rx_buffer.tail) % SERIAL_BUFFER_SIZE;
}
unsigned char serial_read(void)
{
unsigned char c;
if (rx_buffer.head == rx_buffer.tail)
{
return -1;
}
else
{
c = rx_buffer.buffer[rx_buffer.tail];
rx_buffer.tail = (unsigned int)(rx_buffer.tail + 1) % SERIAL_BUFFER_SIZE;
return c;
}
}
void serial_write(unsigned char c)
{
int i = (tx_buffer.head + 1) % SERIAL_BUFFER_SIZE;
while (i == tx_buffer.tail){ NRF_P0->OUT^=0x00020000; }
tx_buffer.buffer[tx_buffer.head] = c;
tx_buffer.head = i;
SETB(NRF_UART0->INTENSET,7);
NRF_UART0->EVENTS_TXDRDY = 0;
}
void serial_write_string(char *pointer)
{
while(*pointer!='\0')
{
serial_write(*pointer);
pointer++;
}
}
int main(void)
{
NRF_P0->DIR |= 0x000E0000;
NRF_P0->OUTSET |= 0x000E0000;
uart_init();
unsigned int i=0;
while(1)
{
NRF_P0->OUT^=0x00040000;
//NRF_UART0->TXD = '$'; // after comment out this line, code works normally !!!!
serial_write_string("Hello World i=");
serial_no(i++);
serial_write_string("\n\r");
nrf_delay_ms(50);
}
}
/NRF_UART0->TXD = '$'; // after comment out this line, code works normally !!!! When I comment out this line from main function only then code prints "Hello World" on serial terminal.
This is arduino logic. I think due to unavailability of interrupt for "uart tx data register ready" it is behaving like this. I have implement same logic on STM32F407 & there it works smoothly.