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.

Parents Reply Children
No Data
Related