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

UART access functions now working

parent f2acacc5
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
#################################################################### ####################################################################
DEVICE = EFM32GG330F1024 DEVICE = EFM32GG330F1024
PROJECTNAME = freertos_blink PROJECTNAME = uart_test
# Name of interface configuration file used by OpenOCD # Name of interface configuration file used by OpenOCD
OOCD_IFACE ?= stlink-v2-1 OOCD_IFACE ?= stlink-v2-1
...@@ -131,7 +131,8 @@ C_SRC += \ ...@@ -131,7 +131,8 @@ C_SRC += \
../../common/emlib/src/em_rmu.c \ ../../common/emlib/src/em_rmu.c \
../../common/emlib/src/em_rtc.c \ ../../common/emlib/src/em_rtc.c \
../../common/emlib/src/em_system.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 \ ../../common/emdrv/sleep/src/sleep.c \
../uart/uart.c \ ../uart/uart.c \
../main.c ../main.c
......
...@@ -32,16 +32,18 @@ ...@@ -32,16 +32,18 @@
* last changes: * last changes:
* 2014-07-07 Theodor Stana t.stana@cern.ch File created * 2014-07-07 Theodor Stana t.stana@cern.ch File created
*============================================================================== *==============================================================================
* TODO: - * TODO: -
*============================================================================== *==============================================================================
*/ */
#include "uart.h" #include "uart.h"
#include "em_device.h" #include "em_device.h"
#include "em_cmu.h" #include "em_cmu.h"
#include "em_gpio.h"
uint32_t msticks = 0; uint32_t msticks = 0;
char str[32];
void SysTick_Handler() void SysTick_Handler()
{ {
...@@ -58,16 +60,21 @@ void delay(uint32_t n) ...@@ -58,16 +60,21 @@ void delay(uint32_t n)
int main() int main()
{ {
uart_init();
/* Setup SysTick Timer for 1 msec interrupts */ /* Setup SysTick Timer for 1 msec interrupts */
if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1); if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 1000)) while (1);
CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_HFPER, true);
uart_init(4800, 8, "n", "2");
GPIO_PinModeSet(gpioPortD, 1, gpioModePushPull, 0);
while (1) while (1)
{ {
uart_puts("supercalifrageristic\n"); if (uart_gets(str))
uart_puts(str);
// uart_puts("supercalifrageristic\r\n");
GPIO_PinOutToggle(gpioPortD, 1);
delay(500); delay(500);
} }
} }
...@@ -36,15 +36,31 @@ ...@@ -36,15 +36,31 @@
*============================================================================== *==============================================================================
*/ */
#include <string.h>
#include "uart.h" #include "uart.h"
#include "em_cmu.h" #include "em_cmu.h"
#include "em_int.h"
#include "em_gpio.h" #include "em_gpio.h"
#if defined(UART_USE_USART)
#include "em_usart.h" #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: * params:
* * none * * none
...@@ -53,12 +69,98 @@ ...@@ -53,12 +69,98 @@
* * none * * none
* *
* comments: * 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 * 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 */ /* Configure GPIO pins */
CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_GPIO, true);
...@@ -66,19 +168,16 @@ void uart_init() ...@@ -66,19 +168,16 @@ void uart_init()
GPIO_PinModeSet(UART_TXPORT, UART_TXPIN, gpioModePushPull, 1); GPIO_PinModeSet(UART_TXPORT, UART_TXPIN, gpioModePushPull, 1);
GPIO_PinModeSet(UART_RXPORT, UART_RXPIN, gpioModeInput, 0); GPIO_PinModeSet(UART_RXPORT, UART_RXPIN, gpioModeInput, 0);
USART_TypeDef *usart = UART_PORT;
USART_InitAsync_TypeDef init = USART_INITASYNC_DEFAULT;
/* Enable peripheral clocks */ /* Enable peripheral clocks */
CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(cmuClock_HFPER, true);
CMU_ClockEnable(UART_CLK, true); CMU_ClockEnable(UART_CLK, true);
/* Configure USART for basic async operation */ /* Configure USART for basic async operation */
init.enable = usartDisable; init.enable = usartDisable;
USART_InitAsync(usart, &init); USART_InitAsync(UART_PORT, &init);
/* Enable pins at UART1 location #2 */ /* 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 */ /* Clear previous RX interrupts */
USART_IntClear(UART_PORT, USART_IF_RXDATAV); USART_IntClear(UART_PORT, USART_IF_RXDATAV);
...@@ -89,7 +188,37 @@ void uart_init() ...@@ -89,7 +188,37 @@ void uart_init()
NVIC_EnableIRQ(UART_IRQN); NVIC_EnableIRQ(UART_IRQN);
/* Finally enable it */ /* 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() ...@@ -110,7 +239,7 @@ void uart_init()
*/ */
void uart_putc(char c) void uart_putc(char c)
{ {
USART_Tx(UART_PORT, c); UART_TX(UART_PORT, c);
} }
/* /*
...@@ -133,7 +262,7 @@ void uart_putc(char c) ...@@ -133,7 +262,7 @@ void uart_putc(char c)
int uart_puts(char *s) int uart_puts(char *s)
{ {
int nc = 0; int nc = 0;
for (; *s == '\0'; *s++) for ( ; *s != '\0'; *s++)
{ {
uart_putc(*s); uart_putc(*s);
nc++; nc++;
...@@ -141,3 +270,71 @@ int uart_puts(char *s) ...@@ -141,3 +270,71 @@ int uart_puts(char *s)
return nc; 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 @@ ...@@ -46,23 +46,48 @@
/*============================================================================*/ /*============================================================================*/
/* Defines */ /* Defines */
/*============================================================================*/ /*============================================================================*/
#define UART_IRQ_NAME USART0_RX_IRQHandler /* Use USART/LEUART definition; no UART for EFM32GG330, thus not supported */
#define UART_CLK cmuClock_USART1 /* Should be mutually exclusive, else compilation error */
#define UART_IRQN USART0_RX_IRQn #define UART_USE_USART
#define UART_PORT USART0 //#define UART_USE_LEUART
#define UART_TX USART_Tx
#define UART_RX USART_Rx /* Change the definition files below according to the port you use */
#define UART_LOC USART_ROUTE_LOCATION_LOC0 #if defined(UART_USE_USART)
#define UART_TXPORT gpioPortE #define UART_PORT USART0
#define UART_TXPIN 10 #define UART_IRQ_NAME USART0_RX_IRQHandler
#define UART_RXPORT gpioPortE #define UART_CLK cmuClock_USART0
#define UART_RXPIN 11 #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 */ /* Function prototypes */
/*============================================================================*/ /*============================================================================*/
void uart_init(); void uart_init(int baud, int databits, char *parity, char *stopbits);
void uart_putc(char c); void uart_putc(char c);
int uart_puts(char *s); 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