1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00
RIOT/pkg/openwsn/contrib/uart.c
2023-07-18 12:24:10 +02:00

186 lines
3.7 KiB
C

/*
* Copyright (C) 2018 Hamburg University of Applied Sciences
* 2020 Inria
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup pkg_openwsn
* @{
*
* @file
* @brief RIOT adaption of the OpenWSN "uart" bsp module.
*
* @author Peter Kietzmann <peter.kietzmann@haw-hamburg.de>
* @author Francisco Molina <francois-xavier.molina@inria.fr>
*
* @}
*/
#include <stdint.h>
#include <stdatomic.h>
#include "board.h"
#include "periph/uart.h"
#ifdef MODULE_ZTIMER_USEC
#include "ztimer.h"
#endif
#include "openwsn_uart.h"
#define XOFF 0x13
#define XON 0x11
#define XONXOFF_ESCAPE 0x12
#define XONXOFF_MASK 0x10
typedef struct {
uart_tx_cbt txCb;
uart_rx_cbt rxCb;
atomic_bool fXonXoffEscaping;
atomic_char xonXoffEscapedByte;
} uart_vars_t;
static uart_vars_t _uart_vars;
static atomic_char _uart_rx_byte;
#ifdef MODULE_ZTIMER_USEC
static ztimer_t _ztimer_tx_uart;
#endif
static void _openwsn_uart_write(const uint8_t *data)
{
if (IS_USED(MODULE_OPENWSN_SERIAL)) {
uart_write(OPENWSN_UART_DEV, data, 1);
#ifdef MODULE_ZTIMER_USEC
ztimer_set(ZTIMER_USEC, &_ztimer_tx_uart, 0);
#endif
}
}
static void _riot_rx_cb(void *arg, uint8_t data)
{
(void)arg;
if (IS_USED(MODULE_OPENWSN_SERIAL)) {
_uart_rx_byte = data;
if (_uart_vars.rxCb) {
_uart_vars.rxCb();
}
}
else {
(void)data;
}
}
static void _riot_tx_cb(void *arg)
{
(void)arg;
if (IS_USED(MODULE_OPENWSN_SERIAL)) {
if (_uart_vars.fXonXoffEscaping == 0x01) {
_uart_vars.fXonXoffEscaping = 0x00;
_uart_vars.xonXoffEscapedByte ^= XONXOFF_MASK;
_openwsn_uart_write((uint8_t *)&(_uart_vars.xonXoffEscapedByte));
}
else {
if (_uart_vars.txCb) {
_uart_vars.txCb();
}
}
}
}
void uart_enableInterrupts(void)
{
/* unused in RIOT */
}
void uart_disableInterrupts(void)
{
/* unused in RIOT */
}
void uart_clearRxInterrupts(void)
{
/* unused in RIOT */
}
void uart_clearTxInterrupts(void)
{
/* unused in RIOT */
}
void uart_init_openwsn(void)
{
if (IS_USED(MODULE_OPENWSN_SERIAL)) {
uart_init(OPENWSN_UART_DEV, OPENWSN_UART_BAUDRATE, \
(uart_rx_cb_t)_riot_rx_cb, NULL);
#ifdef MODULE_ZTIMER_USEC
_ztimer_tx_uart.callback = &_riot_tx_cb;
#else
(void) _riot_tx_cb;
#endif
}
}
void uart_setCallbacks(uart_tx_cbt txCb, uart_rx_cbt rxCb)
{
if (IS_USED(MODULE_OPENWSN_SERIAL)) {
_uart_vars.txCb = txCb;
_uart_vars.rxCb = rxCb;
}
else {
(void)rxCb;
(void)txCb;
}
}
void uart_setCTS(bool state)
{
if (IS_USED(MODULE_OPENWSN_SERIAL)) {
uint8_t byte;
if (state == true) {
byte = XON;
}
else {
byte = XOFF;
}
_openwsn_uart_write(&byte);
}
else {
(void)state;
}
}
void uart_writeByte(uint8_t byteToWrite)
{
if (IS_USED(MODULE_OPENWSN_SERIAL)) {
if (byteToWrite == XON || byteToWrite == XOFF || \
byteToWrite == XONXOFF_ESCAPE) {
uint8_t byte = XONXOFF_ESCAPE;
_uart_vars.fXonXoffEscaping = 0x01;
_uart_vars.xonXoffEscapedByte = byteToWrite;
_openwsn_uart_write(&byte);
}
else {
_openwsn_uart_write(&byteToWrite);
}
}
else {
(void)byteToWrite;
}
}
inline uint8_t uart_readByte(void)
{
if (IS_USED(MODULE_OPENWSN_SERIAL)) {
return _uart_rx_byte;
}
else {
return 0x00;
}
}