Commit 44b8f4ba authored by Theodor-Adrian Stana's avatar Theodor-Adrian Stana

UART access functions now working

parent f2acacc5
......@@ -10,7 +10,7 @@
####################################################################
DEVICE = EFM32GG330F1024
PROJECTNAME = freertos_blink
PROJECTNAME = uart_test
# Name of interface configuration file used by OpenOCD
OOCD_IFACE ?= stlink-v2-1
......@@ -131,7 +131,8 @@ C_SRC += \
../../common/emlib/src/em_rmu.c \
../../common/emlib/src/em_rtc.c \
../../common/emlib/src/em_system.c \
../.../common/emlib/src/em_usart.c \
../../common/emlib/src/em_usart.c \
../../common/emlib/src/em_leuart.c \
../../common/emdrv/sleep/src/sleep.c \
../uart/uart.c \
../main.c
......
......@@ -32,16 +32,18 @@
* last changes:
* 2014-07-07 Theodor Stana t.stana@cern.ch File created
*==============================================================================
* TODO: -
* TODO: -
*==============================================================================
*/
#include "uart.h"
#include "em_device.h"
#include "em_cmu.h"
#include "em_gpio.h"
uint32_t msticks = 0;
char str[32];
void SysTick_Handler()
{
......@@ -58,16 +60,21 @@ void delay(uint32_t n)
int main()
{
uart_init();
/* Setup SysTick Timer for 1 msec interrupts */
if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1);
CMU_ClockEnable(cmuClock_HFPER, true);
uart_init(4800, 8, "n", "2");
GPIO_PinModeSet(gpioPortD, 1, gpioModePushPull, 0);
while (1)
{
uart_puts("supercalifrageristic\n");
if (uart_gets(str))
uart_puts(str);
// uart_puts("supercalifrageristic\r\n");
GPIO_PinOutToggle(gpioPortD, 1);
delay(500);
}
}
......@@ -36,15 +36,31 @@
*==============================================================================
*/
#include <string.h>
#include "uart.h"
#include "em_cmu.h"
#include "em_int.h"
#include "em_gpio.h"
#if defined(UART_USE_USART)
#include "em_usart.h"
#else
#include "em_leuart.h"
#endif
#define RXBUFSIZE 32
static volatile uint8_t rxbuf[RXBUFSIZE];
static volatile int widx = 0;
static volatile int ridx = 0;
static volatile int rxcnt = 0;
static volatile int rxovf = 0;
/*
*==============================================================================
* UART initialization
* UART IRQ for data reception
*
* params:
* * none
......@@ -53,12 +69,98 @@
* * none
*
* comments:
* Receives data and stores it in a buffer for later readout
*
*==============================================================================
*/
void UART_IRQ_NAME()
{
#if defined(UART_USE_USART)
if (UART_PORT->STATUS & USART_STATUS_RXDATAV)
#else
if (UART_PORT->IF & LEUART_IF_RXDATAV)
#endif
{
if (rxovf == 0)
{
rxbuf[widx] = UART_RX(UART_PORT);
widx++;
rxcnt++;
if (widx == RXBUFSIZE)
{
widx = 0;
}
if (rxcnt > RXBUFSIZE)
{
rxovf = 1;
}
}
}
}
/*
*==============================================================================
* UART initialization
*
* params:
* * baud -- integer baud rate
* * databits -- integer number of data bits
* USART: 4-16
* LEUART: 8 or 9
* * parity -- "n" == none
* "e" == even
* "o" == odd
* * stopbits -- "0.5"/"1"/"1.5"/"2"
*
* returns:
* * none
*
* comments:
* Initializes UART library for selected UART
*
*==============================================================================
*/
void uart_init()
void uart_init(int baud, int databits, char *parity, char *stopbits)
{
/* First, adjust the init struct according to params */
#if defined(UART_USE_USART)
USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
init.baudrate = baud;
init.databits = databits - 3;
if (strcmp(parity, "n") == 0)
init.parity = usartNoParity;
else if (strcmp(parity, "e") == 0)
init.parity = usartEvenParity;
else if (strcmp(parity, "o") == 0)
init.parity = usartOddParity;
if (strcmp(stopbits, "0.5") == 0)
init.stopbits = usartStopbits0p5;
else if (strcmp(stopbits, "1") == 0)
init.stopbits = usartStopbits1;
else if (strcmp(stopbits, "1.5") == 0)
init.stopbits = usartStopbits1p5;
else if (strcmp(stopbits, "2") == 0)
init.stopbits = usartStopbits2;
#else
LEUART_Init_TypeDef init = LEUART_INIT_DEFAULT;
//
//
//
//
//
// SAME AS ABOVE FOR LEUART
//
//
//
//
//
#endif
/* Now, the rest of the init sequence */
#if defined(UART_USE_USART)
/* Configure GPIO pins */
CMU_ClockEnable(cmuClock_GPIO, true);
......@@ -66,19 +168,16 @@ void uart_init()
GPIO_PinModeSet(UART_TXPORT, UART_TXPIN, gpioModePushPull, 1);
GPIO_PinModeSet(UART_RXPORT, UART_RXPIN, gpioModeInput, 0);
USART_TypeDef *usart = UART_PORT;
USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
/* Enable peripheral clocks */
CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(UART_CLK, true);
/* Configure USART for basic async operation */
init.enable = usartDisable;
USART_InitAsync(usart, &init);
USART_InitAsync(UART_PORT, &init);
/* Enable pins at UART1 location #2 */
usart->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | UART_LOC;
UART_PORT->ROUTE = USART_ROUTE_RXPEN | USART_ROUTE_TXPEN | UART_LOC;
/* Clear previous RX interrupts */
USART_IntClear(UART_PORT, USART_IF_RXDATAV);
......@@ -89,7 +188,37 @@ void uart_init()
NVIC_EnableIRQ(UART_IRQN);
/* Finally enable it */
USART_Enable(usart, usartEnable);
USART_Enable(UART_PORT, usartEnable);
#else
/* Enable CORE LE clock in order to access LE modules */
CMU_ClockEnable(cmuClock_CORELE, true);
/* Select LFXO for LEUARTs (and wait for it to stabilize) */
CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
CMU_ClockEnable(UART_CLK, true);
/* Do not prescale clock */
CMU_ClockDivSet(UART_CLK, cmuClkDiv_1);
/* Configure LEUART */
init.enable = leuartDisable;
LEUART_Init(UART_PORT, &init);
/* Enable pins at default location */
UART_PORT->ROUTE = LEUART_ROUTE_RXPEN | LEUART_ROUTE_TXPEN | UART_LOC;
/* Clear previous RX interrupts */
LEUART_IntClear(UART_PORT, LEUART_IF_RXDATAV);
NVIC_ClearPendingIRQ(UART_IRQN);
/* Enable RX interrupts */
LEUART_IntEnable(UART_PORT, LEUART_IF_RXDATAV);
NVIC_EnableIRQ(UART_IRQN);
/* Finally enable it */
LEUART_Enable(UART_PORT, leuartEnable);
#endif
}
/*
......@@ -110,7 +239,7 @@ void uart_init()
*/
void uart_putc(char c)
{
USART_Tx(UART_PORT, c);
UART_TX(UART_PORT, c);
}
/*
......@@ -133,7 +262,7 @@ void uart_putc(char c)
int uart_puts(char *s)
{
int nc = 0;
for (; *s == '\0'; *s++)
for ( ; *s != '\0'; *s++)
{
uart_putc(*s);
nc++;
......@@ -141,3 +270,71 @@ int uart_puts(char *s)
return nc;
}
/*
*==============================================================================
* Receive character
*
* params:
* * none
*
* returns:
* * character in buffer
*
* comments:
* Retrieves data from the receive buffer, which is filled in the ISR above
*
*==============================================================================
*/
char uart_getc()
{
char c = '\0';
INT_Disable();
if (rxcnt > 0)
{
c = rxbuf[ridx++];
if (ridx == RXBUFSIZE)
{
ridx = 0;
}
rxcnt--;
rxovf = 0;
}
INT_Enable();
return c;
}
/*
*==============================================================================
* Read a set of characters from UART buffer
*
* params:
* * buffer to write to
*
* returns:
* * number of characters read
*
* comments:
* Replica of stdlib gets. Returns characters from the UART buffers until
* the null character or a line break character is encountered. The latter,
* if encountered, is replaced with a null character.
*
*==============================================================================
*/
int uart_gets(char *s)
{
uint32_t nc = 0;
do {
*s = uart_getc();
if (*s == '\n')
*s = '\0';
if (*s == '\0')
break;
nc++;
*s++;
} while (1);
return nc;
}
......@@ -46,23 +46,48 @@
/*============================================================================*/
/* Defines */
/*============================================================================*/
#define UART_IRQ_NAME USART0_RX_IRQHandler
#define UART_CLK cmuClock_USART1
#define UART_IRQN USART0_RX_IRQn
#define UART_PORT USART0
#define UART_TX USART_Tx
#define UART_RX USART_Rx
#define UART_LOC USART_ROUTE_LOCATION_LOC0
#define UART_TXPORT gpioPortE
#define UART_TXPIN 10
#define UART_RXPORT gpioPortE
#define UART_RXPIN 11
/* Use USART/LEUART definition; no UART for EFM32GG330, thus not supported */
/* Should be mutually exclusive, else compilation error */
#define UART_USE_USART
//#define UART_USE_LEUART
/* Change the definition files below according to the port you use */
#if defined(UART_USE_USART)
#define UART_PORT USART0
#define UART_IRQ_NAME USART0_RX_IRQHandler
#define UART_CLK cmuClock_USART0
#define UART_IRQN USART0_RX_IRQn
#define UART_TX USART_Tx
#define UART_RX USART_Rx
#define UART_TXPORT gpioPortE
#define UART_TXPIN 10
#define UART_RXPORT gpioPortE
#define UART_RXPIN 11
#define UART_LOC USART_ROUTE_LOCATION_LOC0
#endif
#if defined(UART_USE_LEUART)
#define UART_PORT LEUART1
#define UART_IRQ_NAME LEUART1_IRQHandler
#define UART_CLK cmuClock_LEUART1
#define UART_IRQN LEUART1_IRQn
#define UART_UART LEUART1
#define UART_TX LEUART_Tx
#define UART_RX LEUART_Rx
#define UART_TXPORT gpioPortC
#define UART_TXPIN 6
#define UART_RXPORT gpioPortC
#define UART_RXPIN 7
#define UART_LOC LEUART_ROUTE_LOCATION_LOC0
#endif
/*============================================================================*/
/* Function prototypes */
/*============================================================================*/
void uart_init();
void uart_init(int baud, int databits, char *parity, char *stopbits);
void uart_putc(char c);
int uart_puts(char *s);
char uart_getc();
int uart_gets(char *s);
#endif // __FRW_UART_H_
#endif // __UART_H_
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment