mirror of
https://github.com/saymrwulf/pulp-runtime.git
synced 2026-05-20 21:40:59 +00:00
151 lines
No EOL
5.5 KiB
C
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 |