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

problem because of absence of interrupt for "uart tx data register ready"

#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.

  • Thank YOu for help !!

    #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);
    
    }
    

    Now this is complete UARTE driver code using direct register access.

Related