mirror of
https://github.com/kelvinlawson/atomthreads.git
synced 2026-01-11 18:33:16 +01:00
112 lines
2.5 KiB
C
112 lines
2.5 KiB
C
/*
|
|
* ----------------------------------------------------------------------------
|
|
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
* <joerg@FreeBSD.ORG> wrote this file. As long as you retain this notice you
|
|
* can do whatever you want with this stuff. If we meet some day, and you think
|
|
* this stuff is worth it, you can buy me a beer in return. Joerg Wunsch
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* Stdio demo, UART implementation
|
|
*
|
|
* $Id: uart.c,v 1.1 2005/12/28 21:38:59 joerg_wunsch Exp $
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
#include <avr/io.h>
|
|
|
|
#include "atom.h"
|
|
#include "atommutex.h"
|
|
#include "atomport-private.h"
|
|
#include "uart.h"
|
|
|
|
/*
|
|
* Set register-access macros for the first UART across various Atmega devices.
|
|
*/
|
|
#ifdef UCSRA
|
|
/* Device with single UART */
|
|
#define REG_UCSRA UCSRA
|
|
#define REG_UCSRB UCSRB
|
|
#define REG_UBRRL UBRRL
|
|
#define REG_UDR UDR
|
|
#define BIT_TXEN TXEN
|
|
#define BIT_RXEN RXEN
|
|
#define BIT_UDRE UDRE
|
|
#else
|
|
/* Device with multiple UARTs */
|
|
#define REG_UCSRA UCSR0A
|
|
#define REG_UCSRB UCSR0B
|
|
#define REG_UBRRL UBRR0L
|
|
#define REG_UDR UDR0
|
|
#define BIT_TXEN TXEN0
|
|
#define BIT_RXEN RXEN0
|
|
#define BIT_UDRE UDRE0
|
|
#endif
|
|
|
|
|
|
/* Local data */
|
|
|
|
/*
|
|
* Semaphore for single-threaded access to UART device
|
|
*/
|
|
static ATOM_MUTEX uart_mutex;
|
|
|
|
|
|
/*
|
|
* Initialize the UART to requested baudrate, tx/rx, 8N1.
|
|
*/
|
|
int
|
|
uart_init(uint32_t baudrate)
|
|
{
|
|
int status;
|
|
|
|
/* Set up the UART device with the selected baudrate */
|
|
#if AVR_CPU_HZ < 2000000UL && defined(U2X)
|
|
REG_UCSRA = _BV(U2X); /* improve baud rate error by using 2x clk */
|
|
REG_UBRRL = (AVR_CPU_HZ / (8UL * baudrate)) - 1;
|
|
#else
|
|
REG_UBRRL = (AVR_CPU_HZ / (16UL * baudrate)) - 1;
|
|
#endif
|
|
REG_UCSRB = _BV(BIT_TXEN) | _BV(BIT_RXEN); /* tx/rx enable */
|
|
|
|
/* Create a mutex for single-threaded putchar() access */
|
|
if (atomMutexCreate (&uart_mutex) != ATOM_OK)
|
|
{
|
|
status = -1;
|
|
}
|
|
else
|
|
{
|
|
status = 0;
|
|
}
|
|
|
|
/* Finished */
|
|
return (status);
|
|
}
|
|
|
|
/*
|
|
* Send character c down the UART Tx, wait until tx holding register
|
|
* is empty.
|
|
*/
|
|
int
|
|
uart_putchar(char c, FILE *stream)
|
|
{
|
|
|
|
/* Block on private access to the UART */
|
|
if (atomMutexGet(&uart_mutex, 0) == ATOM_OK)
|
|
{
|
|
/* Convert \n to \r\n */
|
|
if (c == '\n')
|
|
uart_putchar('\r', stream);
|
|
|
|
/* Wait until the UART is ready then send the character out */
|
|
loop_until_bit_is_set(REG_UCSRA, BIT_UDRE);
|
|
REG_UDR = c;
|
|
|
|
/* Return mutex access */
|
|
atomMutexPut(&uart_mutex);
|
|
}
|
|
|
|
return 0;
|
|
}
|