pulp-runtime/include/hal/udma/uart/udma_uart_v1.h
2019-12-15 14:12:22 +01:00

151 lines
No EOL
5.5 KiB
C

/*
* Copyright (C) 2018 ETH Zurich and University of Bologna
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __HAL_UDMA_UDMA_UART_V1_H__
#define __HAL_UDMA_UDMA_UART_V1_H__
#include "archi/udma/uart/udma_uart_v1.h"
#define UDMA_UART_OFFSET(id) UDMA_PERIPH_OFFSET(ARCHI_UDMA_UART_ID(id))
#define UDMA_UART_RX_ADDR(id) (ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(id) + UDMA_CHANNEL_RX_OFFSET)
#define UDMA_UART_TX_ADDR(id) (ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(id) + UDMA_CHANNEL_TX_OFFSET)
#define UDMA_UART_CUSTOM_ADDR(id) (ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(id) + UDMA_CHANNEL_CUSTOM_OFFSET)
#define ARCHI_SOC_EVENT_UART_RX(id) (ARCHI_SOC_EVENT_PERIPH_FIRST_EVT(ARCHI_UDMA_UART_ID(id)) + ARCHI_UDMA_UART_RX_EVT)
#define ARCHI_SOC_EVENT_UART_TX(id) (ARCHI_SOC_EVENT_PERIPH_FIRST_EVT(ARCHI_UDMA_UART_ID(id)) + ARCHI_UDMA_UART_TX_EVT)
// UDMA RX/TX Channels HAL Registers Structure
typedef struct {
uint32_t rx_ch_saddr;
uint32_t rx_ch_size;
uint32_t rx_ch_cfg;
uint32_t rx_ch_initcfg_unused;
uint32_t tx_ch_saddr;
uint32_t tx_ch_size;
uint32_t tx_ch_cfg;
uint32_t tx_ch_initcfg_unused;
} plpUdmaRxTxChHandle3_t;
// UART HAL Registers Structure
typedef struct {
plpUdmaRxTxChHandle3_t udma_rxtx_ch_handle;
uint32_t status;
uint32_t setup;
} plpUdmaUartHandle_t;
// UART HAL Register Fields Structure
typedef struct {
uint32_t tx_oe:1;
uint32_t rx_oe:1;
uint32_t rx_pe:1;
uint32_t unused:29;
} __attribute__ ((packed)) plpUdmaUartStatus_t;
typedef struct {
uint32_t parity_en:1;
uint32_t char_length:2;
uint32_t stop_bit_length:1;
uint32_t unused0:4;
uint32_t tx_en:1;
uint32_t rx_en:1;
uint32_t unused1:6;
uint32_t clkdiv:16;
} __attribute__ ((packed)) plpUdmaUartSetup_t;
// UART HAL Register Union definition
typedef union {
plpUdmaUartStatus_t status;
plpUdmaUartSetup_t setup;
uint32_t raw;
} __attribute__ ((packed)) plpUdmaUartCustom_u;
// UART HAL Handle
#define UART_HANDLE(id) ((plpUdmaUartHandle_t *)(ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(id)))
// UART HAL functions prototype
static inline void plpUdmaUartSetupSet (plpUdmaUartHandle_t * const handle, uint32_t data);
static inline uint32_t plpUdmaUartSetupGet (plpUdmaUartHandle_t * const handle);
static inline uint32_t plpUdmaUartStatusGet (plpUdmaUartHandle_t * const handle);
// UART HAL functions definition
static inline void plpUdmaUartSetupSet (plpUdmaUartHandle_t * const handle, uint32_t data) {
handle->setup = data;
}
static inline uint32_t plpUdmaUartSetupGet (plpUdmaUartHandle_t * const handle) {
return handle->setup;
}
static inline uint32_t plpUdmaUartStatusGet (plpUdmaUartHandle_t * const handle) {
return handle->status;
}
///////////////////////////////////////////////////
// TODO Obsolete : to be removed cause deprecated
/**
* Setup UART. The UART defaults to 8 bit character mode with 1 stop bit.
*
* parity Enable/disable parity mode
* clk_counter Clock counter value that is used to derive the UART clock.
* There is a prescaler in place that already divides the SoC
* clock by 16. Since this is a counter, a value of 0 means that
* the SoC clock divided by 16 is used. A value of 31 would mean
* that we use the SoC clock divided by 16*32 = 512.
*/
static inline void plp_uart_setup(int channel, int parity, uint16_t clk_counter)
{
// [31:16]: clock divider (from SoC clock)
// [9]: RX enable
// [8]: TX enable
// [3]: stop bits 0 = 1 stop bit
// 1 = 2 stop bits
// [2:1]: bits 00 = 5 bits
// 01 = 6 bits
// 10 = 7 bits
// 11 = 8 bits
// [0]: parity
unsigned int val = 0x0306 | parity; // both tx and rx enabled; 8N1 configuration; 1 stop bits
val |= ((clk_counter) << 16);
pulp_write32(ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(channel) + UDMA_CHANNEL_CUSTOM_OFFSET + UART_SETUP_OFFSET, val);
}
static inline void plp_uart_disable(int channel) {
pulp_write32(ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(channel) + UDMA_CHANNEL_CUSTOM_OFFSET + UART_SETUP_OFFSET, 0x00500006);
}
static inline int plp_uart_tx_busy(int channel) {
return pulp_read32(ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(channel) + UDMA_CHANNEL_CUSTOM_OFFSET + UART_STATUS_OFFSET) & 1;
}
static inline int plp_uart_rx_busy(int channel) {
return (pulp_read32(ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(channel) + UDMA_CHANNEL_CUSTOM_OFFSET + UART_STATUS_OFFSET) >> 1) & 1;
}
static inline unsigned int plp_uart_reg_read(int channel, unsigned int addr)
{ //adr is an offset, expected UART_STATUS_OFFSET or UART_SETUP_OFFSET
return pulp_read32(ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(channel) + UDMA_CHANNEL_CUSTOM_OFFSET + addr);
}
static inline void plp_uart_reg_write(int channel, unsigned int addr, unsigned int cfg)
{ //adr is an offset, expected UART_STATUS_OFFSET or UART_SETUP_OFFSET
pulp_write32(ARCHI_UDMA_ADDR + UDMA_UART_OFFSET(channel) + UDMA_CHANNEL_CUSTOM_OFFSET + addr, cfg);
}
#endif