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.

  • This is answer to my own Question. This working code for UARTE.

    #include "nrf_delay.h"
    #include "nrf_gpio.h"
    #include "nrf_uart.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)
    {
      /*
      if(NRF_UARTE0->EVENTS_TXDRDY == 1)
      {
        NRF_UARTE0->EVENTS_TXDRDY=0;
        
      }
      */
    
      
      if(NRF_UARTE0->EVENTS_ENDTX == 1)
      {
        NRF_UARTE0->EVENTS_ENDTX = 0;
        NRF_UARTE0->TASKS_STOPTX = 1;
      }
      
     
      /*
      if(NRF_UARTE0->EVENTS_TXSTARTED == 1)
      {
        NRF_UARTE0->EVENTS_TXSTARTED = 0;
      }
      */
      
      /*
      if(NRF_UARTE0->EVENTS_TXSTOPPED == 1)
      {
        //NRF_UARTE0->EVENTS_TXSTOPPED = 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 |= (0<<22)|(0<<20)|(1<<8)|(0<<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->EVENTS_ENDTX=0;
      NRF_UARTE0->EVENTS_TXSTOPPED = 0;
    
      NRF_UARTE0->TXD.PTR=(uint32_t)&tx_buffer.buffer[0];
      NRF_UARTE0->TXD.MAXCNT=tx_buffer.head;
    
      NRF_UARTE0->TASKS_STARTTX = 1;
     
      while(NRF_UARTE0->EVENTS_ENDTX == 0 && NRF_UARTE0->EVENTS_TXSTOPPED == 0){}
    
    }
    
    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(50);
    
        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);
    
    }
    
Related