This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

UARTE driver from scratch

#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_BUFFER_SIZE 256


typedef struct
{
  volatile unsigned char buffer[SERIAL_BUFFER_SIZE];
  volatile unsigned int head;
}ring_buffer;



ring_buffer rx_buffer;
ring_buffer tx_buffer;


void UARTE0_UART0_IRQHandler(void)
{
  int boo;

  if(NRF_UARTE0->EVENTS_ENDTX == 1)
  {
   NRF_UARTE0->EVENTS_ENDTX = 0;    
  }

  if(NRF_UARTE0->EVENTS_TXDRDY == 1)
  {

    NRF_UARTE0->EVENTS_TXDRDY=0;
  }

  if(NRF_UARTE0->EVENTS_TXSTARTED == 1)
  {
    NRF_UARTE0->EVENTS_TXSTARTED = 0;

    //NRF_UARTE0->TXD.PTR=(uint32_t)&tx_buffer.buffer[0];
 
  }

}


void uart_init()
{
   
    NRF_UARTE0->BAUDRATE = 0x01D60000;
    //NRF_UARTE0->CONFIG = 0x00000001;

    NRF_UARTE0->PSEL.RTS = 5;
    NRF_UARTE0->PSEL.TXD = 6;
    NRF_UARTE0->PSEL.CTS = 7;
    NRF_UARTE0->PSEL.RXD = 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_UARTE0->EVENTS_ENDTX=0;
    NRF_UARTE0->EVENTS_TXDRDY=0;
    NRF_UARTE0->EVENTS_TXSTARTED=0;

    //NRF_UARTE0->TASKS_STARTTX = 1;
    //NRF_UARTE0->TASKS_STARTRX = 1;

    NRF_UARTE0->INTENSET |= (1<<20)|(1<<8)|(1<<7)|(1<<2);
  
    NRF_UARTE0->ENABLE = 0x00000008;
    
    NVIC_EnableIRQ(UARTE0_UART0_IRQn);
    
}





void serial_write_irq(unsigned char c)
{
  int i = (tx_buffer.head + 1) % SERIAL_BUFFER_SIZE;
 
  tx_buffer.buffer[tx_buffer.head] = c;
  tx_buffer.head = i;

}

void serial_write_string(char *pointer)
{

  tx_buffer.head = 0;

  while(*pointer!='\0')
  {
    serial_write_irq(*pointer);
    pointer++;
  }

  NRF_UARTE0->TXD.PTR=(uint32_t)&tx_buffer.buffer[0];
  NRF_UARTE0->TXD.MAXCNT=tx_buffer.head;

  
  NRF_UARTE0->TASKS_STARTTX = 1;

  nrf_delay_ms(1);   // I am talking about this delay.
                                //If I removed this, serial terminal receives Garbage values.

}

void serial_no(long int n) 
{
  char c;
  char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
  char *str = &buf[sizeof(buf) - 1];
  unsigned long int m;

  *str = '\0';
  
  if(n<0)
  {
     n=-n;
     serial_write_string("-");
  }

  do 
  {
    m = n;
    n /= 10;
    c = m - 10 * n;
    
    *--str = c < 10 ? c + '0' : c + 'A' - 10;
    
  } while(n);

  serial_write_string(str);
}

int main(void)
{
  int foo=-1000;

  NRF_P0->DIR |= 0x0001E000;
  NRF_P0->OUTSET |= 0x0001E000;

  NRF_P0->PIN_CNF[11]=0x0000000C;

  uart_init();

  while(1) 
  {
 
    NRF_P0->OUT^=0x00002000;
 
    serial_write_string("Hello World ");
    serial_no(foo++);
    serial_write_string("\n\r");
    //nrf_delay_ms(100);

    if(CHECKB(NRF_P0->IN,11)==0)
    {
       
      serial_write_string("Button Pressed !!\n\r");

      NRF_P0->OUT &= ~(1<<16);

      while(CHECKB(NRF_P0->IN,11)==0){}

      NRF_P0->OUT |= (1<<16);

      foo=0;

    }

  }

  return(0);

}

This is working code for UARTE using interrupts. But I am not able to understand that if I removed nrf_delay_ms(1) from function serial_write_string() then this code does not work.

After removal of nrf_delay_ms(1), it sends garbage values on serial terminal.