Master Thesis  V1.0
Research and Design of Sensor Node for NMSD Treatment
uart.c File Reference

UART communication with BLE. More...

#include <uart.h>
#include "em_usart.h"
#include "pinout.h"
#include "em_cmu.h"
#include "em_gpio.h"
#include "ble.h"
#include <stdint.h>
#include "em_device.h"
#include "em_chip.h"
#include "em_emu.h"
#include "bsp.h"
#include "debug_dbprint.h"
Include dependency graph for uart.c:

Go to the source code of this file.

Data Structures

struct  circularBuffer
 

Macros

#define BUFFERSIZE   256
 

Functions

void uart_Init ()
 UART init. More...
 
uint8_t uartGetChar ()
 uartGetChar function More...
 
void uartPutChar (uint8_t ch)
 uartPutChar function More...
 
void uartPutData (uint8_t *dataPtr, uint32_t dataLen)
 uartPutData function More...
 
uint32_t uartGetData (uint8_t *dataPtr, uint32_t dataLen)
 uartGetData function More...
 
void USART1_RX_IRQHandler (void)
 UART1 RX IRQ Handler. More...
 
void USART1_TX_IRQHandler (void)
 UART1 TX IRQ Handler. More...
 

Variables

volatile struct circularBuffer rxBuf
 
volatile struct circularBuffer txBuf = { {0}, 0, 0, 0, false }
 

Detailed Description

UART communication with BLE.

Version
1.0
Author
Jona Cappelle

Definition in file uart.c.

Macro Definition Documentation

◆ BUFFERSIZE

#define BUFFERSIZE   256

Definition at line 35 of file uart.c.

Function Documentation

◆ uart_Init()

void uart_Init ( )

UART init.

Inspired by Silabs demo code

Definition at line 57 of file uart.c.

58 {
59 
60  // Enable oscillator to GPIO and USART1 modules
61  CMU_ClockEnable(cmuClock_HFPER, true);
62  CMU_ClockEnable(cmuClock_GPIO, true);
63  CMU_ClockEnable(cmuClock_USART1, true);
64 
65  // set pin modes for UART TX and RX pins
66  GPIO_PinModeSet(BLE_PORT, BLE_PIN_RX, gpioModeInput, 0);
67  GPIO_PinModeSet(BLE_PORT, BLE_PIN_TX, gpioModePushPull, 1);
68 
69  // Initialize USART asynchronous mode and route pins
70  USART_InitAsync(BLE_USART, &init);
71 
72  /* Prepare UART Rx and Tx interrupts */
73  USART_IntClear(BLE_USART, _USART_IFC_MASK);
74  USART_IntEnable(BLE_USART, USART_IEN_RXDATAV);
75  NVIC_ClearPendingIRQ(USART1_RX_IRQn);
76  NVIC_ClearPendingIRQ(USART1_TX_IRQn);
77  NVIC_EnableIRQ(USART1_RX_IRQn);
78  NVIC_EnableIRQ(USART1_TX_IRQn);
79 
80  BLE_USART->ROUTE |= USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_LOCATION_LOC0;
81 
82  /* Enable UART */
83  USART_Enable(BLE_USART, usartEnable);
84 }

References BLE_PIN_RX, BLE_PIN_TX, BLE_PORT, and BLE_USART.

Referenced by BLE_Init().

◆ uartGetChar()

uint8_t uartGetChar ( )

uartGetChar function

Note that if there are no pending characters in the receive buffer, this function will hang until a character is received.

Definition at line 94 of file uart.c.

95 {
96  uint8_t ch;
97 
98  /* Check if there is a byte that is ready to be fetched. If no byte is ready, wait for incoming data */
99  if (rxBuf.pendingBytes < 1)
100  {
101  while (rxBuf.pendingBytes < 1) ;
102  }
103 
104  /* Copy data from buffer */
105  ch = rxBuf.data[rxBuf.rdI];
106  rxBuf.rdI = (rxBuf.rdI + 1) % BUFFERSIZE;
107 
108  /* Decrement pending byte counter */
110 
111  return ch;
112 }

References BUFFERSIZE, circularBuffer::data, circularBuffer::pendingBytes, circularBuffer::rdI, and rxBuf.

◆ uartGetData()

uint32_t uartGetData ( uint8_t *  dataPtr,
uint32_t  dataLen 
)

uartGetData function

Definition at line 185 of file uart.c.

186 {
187  uint32_t i = 0;
188 
189  /* Wait until the requested number of bytes are available */
190  if (rxBuf.pendingBytes < dataLen)
191  {
192  while (rxBuf.pendingBytes < dataLen) ;
193  }
194 
195  if (dataLen == 0)
196  {
197  dataLen = rxBuf.pendingBytes;
198  }
199 
200  /* Copy data from Rx buffer to dataPtr */
201  while (i < dataLen)
202  {
203  *(dataPtr + i) = rxBuf.data[rxBuf.rdI];
204  rxBuf.rdI = (rxBuf.rdI + 1) % BUFFERSIZE;
205  i++;
206  }
207 
208  /* Decrement pending byte counter */
209  rxBuf.pendingBytes -= dataLen;
210 
211  return i;
212 }

References BUFFERSIZE, circularBuffer::data, circularBuffer::pendingBytes, circularBuffer::rdI, and rxBuf.

Referenced by BLE_readData().

◆ uartPutChar()

void uartPutChar ( uint8_t  ch)

uartPutChar function

Definition at line 121 of file uart.c.

122 {
123  /* Check if Tx queue has room for new data */
124  if ((txBuf.pendingBytes + 1) > BUFFERSIZE)
125  {
126  /* Wait until there is room in queue */
127  while ((txBuf.pendingBytes + 1) > BUFFERSIZE) ;
128  }
129 
130  /* Copy ch into txBuffer */
131  txBuf.data[txBuf.wrI] = ch;
132  txBuf.wrI = (txBuf.wrI + 1) % BUFFERSIZE;
133 
134  /* Increment pending byte counter */
136 
137  /* Enable interrupt on USART TX Buffer*/
138  USART_IntEnable(BLE_USART, USART_IEN_TXBL);
139 }

References BLE_USART, BUFFERSIZE, circularBuffer::data, circularBuffer::pendingBytes, txBuf, and circularBuffer::wrI.

◆ uartPutData()

void uartPutData ( uint8_t *  dataPtr,
uint32_t  dataLen 
)

uartPutData function

Definition at line 148 of file uart.c.

149 {
150  uint32_t i = 0;
151 
152  /* Check if buffer is large enough for data */
153  if (dataLen > BUFFERSIZE)
154  {
155  /* Buffer can never fit the requested amount of data */
156  return;
157  }
158 
159  /* Check if buffer has room for new data */
160  if ((txBuf.pendingBytes + dataLen) > BUFFERSIZE)
161  {
162  /* Wait until room */
163  while ((txBuf.pendingBytes + dataLen) > BUFFERSIZE) ;
164  }
165 
166  /* Fill dataPtr[0:dataLen-1] into txBuffer */
167  while (i < dataLen)
168  {
169  txBuf.data[txBuf.wrI] = *(dataPtr + i);
170  txBuf.wrI = (txBuf.wrI + 1) % BUFFERSIZE;
171  i++;
172  }
173 
174  /* Increment pending byte counter */
175  txBuf.pendingBytes += dataLen;
176 
177  /* Enable interrupt on USART TX Buffer*/
178  USART_IntEnable(BLE_USART, USART_IEN_TXBL);
179 }

References BLE_USART, BUFFERSIZE, circularBuffer::data, circularBuffer::pendingBytes, txBuf, and circularBuffer::wrI.

Referenced by BLE_sendData(), and BLE_set_output_power().

◆ USART1_RX_IRQHandler()

void USART1_RX_IRQHandler ( void  )

UART1 RX IRQ Handler.

Set up the interrupt prior to use

Note that this function handles overflows in a very simple way.

Definition at line 223 of file uart.c.

224 {
225  /* Check for RX data valid interrupt */
226  if (BLE_USART->IF & USART_IF_RXDATAV)
227  {
228  /* Copy data into RX Buffer */
229  uint8_t rxData = USART_Rx(BLE_USART);
230  rxBuf.data[rxBuf.wrI] = rxData;
231  rxBuf.wrI = (rxBuf.wrI + 1) % BUFFERSIZE;
233 
234  /* Flag Rx overflow */
236  {
237  rxBuf.overflow = true;
238  }
239  }
240 }

References BLE_USART, BUFFERSIZE, circularBuffer::data, circularBuffer::overflow, circularBuffer::pendingBytes, rxBuf, and circularBuffer::wrI.

◆ USART1_TX_IRQHandler()

void USART1_TX_IRQHandler ( void  )

UART1 TX IRQ Handler.

Set up the interrupt prior to use

Definition at line 250 of file uart.c.

251 {
252  /* Check TX buffer level status */
253  if (BLE_USART->IF & USART_IF_TXBL)
254  {
255  if (txBuf.pendingBytes > 0)
256  {
257  /* Transmit pending character */
258  USART_Tx(BLE_USART, txBuf.data[txBuf.rdI]);
259  txBuf.rdI = (txBuf.rdI + 1) % BUFFERSIZE;
261  }
262 
263  /* Disable Tx interrupt if no more bytes in queue */
264  if (txBuf.pendingBytes == 0)
265  {
266  USART_IntDisable(BLE_USART, USART_IEN_TXBL);
267  }
268  }
269 }

References BLE_USART, BUFFERSIZE, circularBuffer::data, circularBuffer::pendingBytes, circularBuffer::rdI, and txBuf.

Variable Documentation

◆ rxBuf

volatile struct circularBuffer rxBuf

◆ txBuf

volatile struct circularBuffer txBuf = { {0}, 0, 0, 0, false }
txBuf
volatile struct circularBuffer txBuf
BLE_PIN_RX
#define BLE_PIN_RX
Definition: ble.h:34
circularBuffer::wrI
uint32_t wrI
Definition: uart.c:41
circularBuffer::rdI
uint32_t rdI
Definition: uart.c:40
rxBuf
volatile struct circularBuffer rxBuf
circularBuffer::overflow
bool overflow
Definition: uart.c:43
BLE_PORT
#define BLE_PORT
Definition: ble.h:35
BUFFERSIZE
#define BUFFERSIZE
Definition: uart.c:35
BLE_USART
#define BLE_USART
Definition: ble.h:36
circularBuffer::pendingBytes
uint32_t pendingBytes
Definition: uart.c:42
circularBuffer::data
uint8_t data[BUFFERSIZE]
Definition: uart.c:39
BLE_PIN_TX
#define BLE_PIN_TX
Definition: ble.h:33