Microsemi RISC-V project:

Reorganize project to separate Microsemi code into its own directory.
    Add many more demo and tests.
This commit is contained in:
Richard Barry 2018-12-10 20:55:32 +00:00
parent 6b37800ade
commit 866635d2ad
41 changed files with 128 additions and 52 deletions

View file

@ -0,0 +1,582 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* IP core registers definitions. This file contains the definitions required
* for accessing the IP core through the hardware abstraction layer (HAL).
* This file was automatically generated, using "get_header.exe" version 0.4.0,
* from the IP-XACT description for:
*
* Core16550 version: 2.0.0
*
* SVN $Revision: 7963 $
* SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $
*
*******************************************************************************/
#ifndef CORE_16550_REGISTERS_H_
#define CORE_16550_REGISTERS_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* RBR register:
*------------------------------------------------------------------------------
* Receive Buffer Register
*/
#define RBR_REG_OFFSET 0x00U
/*******************************************************************************
* THR register:
*------------------------------------------------------------------------------
* Transmit Holding Register
*/
#define THR_REG_OFFSET 0x00U
/*******************************************************************************
* DLR register:
*------------------------------------------------------------------------------
* Divisor Latch(LSB) Register
*/
#define DLR_REG_OFFSET 0x00U
/*******************************************************************************
* DMR register:
*------------------------------------------------------------------------------
* Divisor Latch(MSB) Register
*/
#define DMR_REG_OFFSET 0x04U
/*******************************************************************************
* IER register:
*------------------------------------------------------------------------------
* Interrupt Enable Register
*/
#define IER_REG_OFFSET 0x04U
/*------------------------------------------------------------------------------
* IER_ERBFI:
* ERBFI field of register IER.
*------------------------------------------------------------------------------
* Enables Received Data Available Interrupt. 0 - Disabled; 1 - Enabled
*/
#define IER_ERBFI_OFFSET 0x04U
#define IER_ERBFI_MASK 0x01U
#define IER_ERBFI_SHIFT 0U
/*------------------------------------------------------------------------------
* IER_ETBEI:
* ETBEI field of register IER.
*------------------------------------------------------------------------------
* Enables the Transmitter Holding Register Empty Interrupt. 0 - Disabled; 1 -
* Enabled
*/
#define IER_ETBEI_OFFSET 0x04U
#define IER_ETBEI_MASK 0x02U
#define IER_ETBEI_SHIFT 1U
/*------------------------------------------------------------------------------
* IER_ELSI:
* ELSI field of register IER.
*------------------------------------------------------------------------------
* Enables the Receiver Line Status Interrupt. 0 - Disabled; 1 - Enabled
*/
#define IER_ELSI_OFFSET 0x04U
#define IER_ELSI_MASK 0x04U
#define IER_ELSI_SHIFT 2U
/*------------------------------------------------------------------------------
* IER_EDSSI:
* EDSSI field of register IER.
*------------------------------------------------------------------------------
* Enables the Modem Status Interrupt 0 - Disabled; 1 - Enabled
*/
#define IER_EDSSI_OFFSET 0x04U
#define IER_EDSSI_MASK 0x08U
#define IER_EDSSI_SHIFT 3U
/*******************************************************************************
* IIR register:
*------------------------------------------------------------------------------
* Interrupt Identification
*/
#define IIR_REG_OFFSET 0x08U
/*------------------------------------------------------------------------------
* IIR_IIR:
* IIR field of register IIR.
*------------------------------------------------------------------------------
* Interrupt Identification bits.
*/
#define IIR_IIR_OFFSET 0x08U
#define IIR_IIR_MASK 0x0FU
#define IIR_IIR_SHIFT 0U
/*------------------------------------------------------------------------------
* IIR_IIR:
* IIR field of register IIR.
*------------------------------------------------------------------------------
* Interrupt Identification bits.
*/
/*------------------------------------------------------------------------------
* IIR_Mode:
* Mode field of register IIR.
*------------------------------------------------------------------------------
* 11 - FIFO mode
*/
#define IIR_MODE_OFFSET 0x08U
#define IIR_MODE_MASK 0xC0U
#define IIR_MODE_SHIFT 6U
/*******************************************************************************
* FCR register:
*------------------------------------------------------------------------------
* FIFO Control Register
*/
#define FCR_REG_OFFSET 0x08
/*------------------------------------------------------------------------------
* FCR_Bit0:
* Bit0 field of register FCR.
*------------------------------------------------------------------------------
* This bit enables both the TX and RX FIFOs.
*/
#define FCR_BIT0_OFFSET 0x08U
#define FCR_BIT0_MASK 0x01U
#define FCR_BIT0_SHIFT 0U
#define FCR_ENABLE_OFFSET 0x08U
#define FCR_ENABLE_MASK 0x01U
#define FCR_ENABLE_SHIFT 0U
/*------------------------------------------------------------------------------
* FCR_Bit1:
* Bit1 field of register FCR.
*------------------------------------------------------------------------------
* Clears all bytes in the RX FIFO and resets its counter logic. The shift
* register is not cleared. 0 - Disabled; 1 - Enabled
*/
#define FCR_BIT1_OFFSET 0x08U
#define FCR_BIT1_MASK 0x02U
#define FCR_BIT1_SHIFT 1U
#define FCR_CLEAR_RX_OFFSET 0x08U
#define FCR_CLEAR_RX_MASK 0x02U
#define FCR_CLEAR_RX_SHIFT 1U
/*------------------------------------------------------------------------------
* FCR_Bit2:
* Bit2 field of register FCR.
*------------------------------------------------------------------------------
* Clears all bytes in the TX FIFO and resets its counter logic. The shift
* register is not cleared. 0 - Disabled; 1 - Enabled
*/
#define FCR_BIT2_OFFSET 0x08U
#define FCR_BIT2_MASK 0x04U
#define FCR_BIT2_SHIFT 2U
#define FCR_CLEAR_TX_OFFSET 0x08U
#define FCR_CLEAR_TX_MASK 0x04U
#define FCR_CLEAR_TX_SHIFT 2U
/*------------------------------------------------------------------------------
* FCR_Bit3:
* Bit3 field of register FCR.
*------------------------------------------------------------------------------
* Enables RXRDYN and TXRDYN pins when set to 1. Otherwise, they are disabled.
*/
#define FCR_BIT3_OFFSET 0x08U
#define FCR_BIT3_MASK 0x08U
#define FCR_BIT3_SHIFT 3U
#define FCR_RDYN_EN_OFFSET 0x08U
#define FCR_RDYN_EN_MASK 0x08U
#define FCR_RDYN_EN_SHIFT 3U
/*------------------------------------------------------------------------------
* FCR_Bit6:
* Bit6 field of register FCR.
*------------------------------------------------------------------------------
* These bits are used to set the trigger level for the RX FIFO interrupt. RX
* FIFO Trigger Level: 0 - 1; 1 - 4; 2 - 8; 3 - 14
*/
#define FCR_BIT6_OFFSET 0x08U
#define FCR_BIT6_MASK 0xC0U
#define FCR_BIT6_SHIFT 6U
#define FCR_TRIG_LEVEL_OFFSET 0x08U
#define FCR_TRIG_LEVEL_MASK 0xC0U
#define FCR_TRIG_LEVEL_SHIFT 6U
/*******************************************************************************
* LCR register:
*------------------------------------------------------------------------------
* Line Control Register
*/
#define LCR_REG_OFFSET 0x0CU
/*------------------------------------------------------------------------------
* LCR_WLS:
* WLS field of register LCR.
*------------------------------------------------------------------------------
* Word Length Select: 00 - 5 bits; 01 - 6 bits; 10 - 7 bits; 11 - 8 bits
*/
#define LCR_WLS_OFFSET 0x0CU
#define LCR_WLS_MASK 0x03U
#define LCR_WLS_SHIFT 0U
/*------------------------------------------------------------------------------
* LCR_STB:
* STB field of register LCR.
*------------------------------------------------------------------------------
* Number of Stop Bits: 0 - 1 stop bit; 1 - 1½ stop bits when WLS = 00, 2 stop
* bits in other cases
*/
#define LCR_STB_OFFSET 0x0CU
#define LCR_STB_MASK 0x04U
#define LCR_STB_SHIFT 2U
/*------------------------------------------------------------------------------
* LCR_PEN:
* PEN field of register LCR.
*------------------------------------------------------------------------------
* Parity Enable 0 - Disabled; 1 - Enabled. Parity is added in transmission and
* checked in receiving.
*/
#define LCR_PEN_OFFSET 0x0CU
#define LCR_PEN_MASK 0x08U
#define LCR_PEN_SHIFT 3U
/*------------------------------------------------------------------------------
* LCR_EPS:
* EPS field of register LCR.
*------------------------------------------------------------------------------
* Even Parity Select 0 - Odd parity; 1 - Even parity
*/
#define LCR_EPS_OFFSET 0x0CU
#define LCR_EPS_MASK 0x10U
#define LCR_EPS_SHIFT 4U
/*------------------------------------------------------------------------------
* LCR_SP:
* SP field of register LCR.
*------------------------------------------------------------------------------
* Stick Parity 0 - Disabled; 1 - Enabled When stick parity is enabled, it
* works as follows: Bits 4..3, 11 - 0 will be sent as a parity bit, and
* checked in receiving. 01 - 1 will be sent as a parity bit, and checked in
* receiving.
*/
#define LCR_SP_OFFSET 0x0CU
#define LCR_SP_MASK 0x20U
#define LCR_SP_SHIFT 5U
/*------------------------------------------------------------------------------
* LCR_SB:
* SB field of register LCR.
*------------------------------------------------------------------------------
* Set Break 0 - Disabled 1 - Set break. SOUT is forced to 0. This does not
* have any effect on transmitter logic. The break is disabled by setting the
* bit to 0.
*/
#define LCR_SB_OFFSET 0x0CU
#define LCR_SB_MASK 0x40U
#define LCR_SB_SHIFT 6U
/*------------------------------------------------------------------------------
* LCR_DLAB:
* DLAB field of register LCR.
*------------------------------------------------------------------------------
* Divisor Latch Access Bit 0 - Disabled. Normal addressing mode in use 1 -
* Enabled. Enables access to the Divisor Latch registers during read or write
* operation to addresses 0 and 1.
*/
#define LCR_DLAB_OFFSET 0x0CU
#define LCR_DLAB_MASK 0x80U
#define LCR_DLAB_SHIFT 7U
/*******************************************************************************
* MCR register:
*------------------------------------------------------------------------------
* Modem Control Register
*/
#define MCR_REG_OFFSET 0x10U
/*------------------------------------------------------------------------------
* MCR_DTR:
* DTR field of register MCR.
*------------------------------------------------------------------------------
* Controls the Data Terminal Ready (DTRn) output. 0 - DTRn <= 1; 1 - DTRn <= 0
*/
#define MCR_DTR_OFFSET 0x10U
#define MCR_DTR_MASK 0x01U
#define MCR_DTR_SHIFT 0U
/*------------------------------------------------------------------------------
* MCR_RTS:
* RTS field of register MCR.
*------------------------------------------------------------------------------
* Controls the Request to Send (RTSn) output. 0 - RTSn <= 1; 1 - RTSn <= 0
*/
#define MCR_RTS_OFFSET 0x10U
#define MCR_RTS_MASK 0x02U
#define MCR_RTS_SHIFT 1U
/*------------------------------------------------------------------------------
* MCR_Out1:
* Out1 field of register MCR.
*------------------------------------------------------------------------------
* Controls the Output1 (OUT1n) signal. 0 - OUT1n <= 1; 1 - OUT1n <= 0
*/
#define MCR_OUT1_OFFSET 0x10U
#define MCR_OUT1_MASK 0x04U
#define MCR_OUT1_SHIFT 2U
/*------------------------------------------------------------------------------
* MCR_Out2:
* Out2 field of register MCR.
*------------------------------------------------------------------------------
* Controls the Output2 (OUT2n) signal. 0 - OUT2n <=1; 1 - OUT2n <=0
*/
#define MCR_OUT2_OFFSET 0x10U
#define MCR_OUT2_MASK 0x08U
#define MCR_OUT2_SHIFT 3U
/*------------------------------------------------------------------------------
* MCR_Loop:
* Loop field of register MCR.
*------------------------------------------------------------------------------
* Loop enable bit 0 - Disabled; 1 - Enabled. The following happens in loop
* mode: SOUT is set to 1. The SIN, DSRn, CTSn, RIn, and DCDn inputs are
* disconnected. The output of the Transmitter Shift Register is looped back
* into the Receiver Shift Register. The modem control outputs (DTRn, RTSn,
* OUT1n, and OUT2n) are connected internally to the modem control inputs, and
* the modem control output pins are set at 1. In loopback mode, the
* transmitted data is immediately received, allowing the CPU to check the
* operation of the UART. The interrupts are operating in loop mode.
*/
#define MCR_LOOP_OFFSET 0x10U
#define MCR_LOOP_MASK 0x10U
#define MCR_LOOP_SHIFT 4U
/*******************************************************************************
* LSR register:
*------------------------------------------------------------------------------
* Line Status Register
*/
#define LSR_REG_OFFSET 0x14U
/*------------------------------------------------------------------------------
* LSR_DR:
* DR field of register LSR.
*------------------------------------------------------------------------------
* Data Ready indicator 1 when a data byte has been received and stored in the
* FIFO. DR is cleared to 0 when the CPU reads the data from the FIFO.
*/
#define LSR_DR_OFFSET 0x14U
#define LSR_DR_MASK 0x01U
#define LSR_DR_SHIFT 0U
/*------------------------------------------------------------------------------
* LSR_OE:
* OE field of register LSR.
*------------------------------------------------------------------------------
* Overrun Error indicator Indicates that the new byte was received before the
* CPU read the byte from the receive buffer, and that the earlier data byte
* was destroyed. OE is cleared when the CPU reads the Line Status Register. If
* the data continues to fill the FIFO beyond the trigger level, an overrun
* error will occur once the FIFO is full and the next character has been
* completely received in the shift register. The character in the shift
* register is overwritten, but it is not transferred to the FIFO.
*/
#define LSR_OE_OFFSET 0x14U
#define LSR_OE_MASK 0x02U
#define LSR_OE_SHIFT 1U
/*------------------------------------------------------------------------------
* LSR_PE:
* PE field of register LSR.
*------------------------------------------------------------------------------
* Parity Error indicator Indicates that the received byte had a parity error.
* PE is cleared when the CPU reads the Line Status Register. This error is
* revealed to the CPU when its associated character is at the top of the FIFO.
*/
#define LSR_PE_OFFSET 0x14U
#define LSR_PE_MASK 0x04U
#define LSR_PE_SHIFT 2U
/*------------------------------------------------------------------------------
* LSR_FE:
* FE field of register LSR.
*------------------------------------------------------------------------------
* Framing Error indicator Indicates that the received byte did not have a
* valid Stop bit. FE is cleared when the CPU reads the Line Status Register.
* The UART will try to re-synchronize after a framing error. To do this, it
* assumes that the framing error was due to the next start bit, so it samples
* this start bit twice, and then starts receiving the data. This error is
* revealed to the CPU when its associated character is at the top of the FIFO.
*/
#define LSR_FE_OFFSET 0x14U
#define LSR_FE_MASK 0x08U
#define LSR_FE_SHIFT 3U
/*------------------------------------------------------------------------------
* LSR_BI:
* BI field of register LSR.
*------------------------------------------------------------------------------
* Break Interrupt indicator Indicates that the received data is at 0 longer
* than a full word transmission time (start bit + data bits + parity + stop
* bits). BI is cleared when the CPU reads the Line Status Register. This error
* is revealed to the CPU when its associated character is at the top of the
* FIFO. When break occurs, only one zero character is loaded into the FIFO.
*/
#define LSR_BI_OFFSET 0x14U
#define LSR_BI_MASK 0x10U
#define LSR_BI_SHIFT 4U
/*------------------------------------------------------------------------------
* LSR_THRE:
* THRE field of register LSR.
*------------------------------------------------------------------------------
* Transmitter Holding Register Empty indicator Indicates that the UART is
* ready to transmit a new data byte. THRE causes an interrupt to the CPU when
* bit 1 (ETBEI) in the Interrupt Enable Register is 1. This bit is set when
* the TX FIFO is empty. It is cleared when at least one byte is written to the
* TX FIFO.
*/
#define LSR_THRE_OFFSET 0x14U
#define LSR_THRE_MASK 0x20U
#define LSR_THRE_SHIFT 5U
/*------------------------------------------------------------------------------
* LSR_TEMT:
* TEMT field of register LSR.
*------------------------------------------------------------------------------
* Transmitter Empty indicator This bit is set to 1 when both the transmitter
* FIFO and shift registers are empty.
*/
#define LSR_TEMT_OFFSET 0x14U
#define LSR_TEMT_MASK 0x40U
#define LSR_TEMT_SHIFT 6U
/*------------------------------------------------------------------------------
* LSR_FIER:
* FIER field of register LSR.
*------------------------------------------------------------------------------
* This bit is set when there is at least one parity error, framing error, or
* break indication in the FIFO. FIER is cleared when the CPU reads the LSR if
* there are no subsequent errors in the FIFO.
*/
#define LSR_FIER_OFFSET 0x14U
#define LSR_FIER_MASK 0x80U
#define LSR_FIER_SHIFT 7U
/*******************************************************************************
* MSR register:
*------------------------------------------------------------------------------
* Modem Status Register
*/
#define MSR_REG_OFFSET 0x18U
/*------------------------------------------------------------------------------
* MSR_DCTS:
* DCTS field of register MSR.
*------------------------------------------------------------------------------
* Delta Clear to Send indicator. Indicates that the CTSn input has changed
* state since the last time it was read by the CPU.
*/
#define MSR_DCTS_OFFSET 0x18U
#define MSR_DCTS_MASK 0x01U
#define MSR_DCTS_SHIFT 0U
/*------------------------------------------------------------------------------
* MSR_DDSR:
* DDSR field of register MSR.
*------------------------------------------------------------------------------
* Delta Data Set Ready indicator Indicates that the DSRn input has changed
* state since the last time it was read by the CPU.
*/
#define MSR_DDSR_OFFSET 0x18U
#define MSR_DDSR_MASK 0x02U
#define MSR_DDSR_SHIFT 1U
/*------------------------------------------------------------------------------
* MSR_TERI:
* TERI field of register MSR.
*------------------------------------------------------------------------------
* Trailing Edge of Ring Indicator detector. Indicates that RI input has
* changed from 0 to 1.
*/
#define MSR_TERI_OFFSET 0x18U
#define MSR_TERI_MASK 0x04U
#define MSR_TERI_SHIFT 2U
/*------------------------------------------------------------------------------
* MSR_DDCD:
* DDCD field of register MSR.
*------------------------------------------------------------------------------
* Delta Data Carrier Detect indicator Indicates that DCD input has changed
* state. NOTE: Whenever bit 0, 1, 2, or 3 is set to 1, a Modem Status
* Interrupt is generated.
*/
#define MSR_DDCD_OFFSET 0x18U
#define MSR_DDCD_MASK 0x08U
#define MSR_DDCD_SHIFT 3U
/*------------------------------------------------------------------------------
* MSR_CTS:
* CTS field of register MSR.
*------------------------------------------------------------------------------
* Clear to Send The complement of the CTSn input. When bit 4 of the Modem
* Control Register (MCR) is set to 1 (loop), this bit is equivalent to DTR in
* the MCR.
*/
#define MSR_CTS_OFFSET 0x18U
#define MSR_CTS_MASK 0x10U
#define MSR_CTS_SHIFT 4U
/*------------------------------------------------------------------------------
* MSR_DSR:
* DSR field of register MSR.
*------------------------------------------------------------------------------
* Data Set Ready The complement of the DSR input. When bit 4 of the MCR is set
* to 1 (loop), this bit is equivalent to RTSn in the MCR.
*/
#define MSR_DSR_OFFSET 0x18U
#define MSR_DSR_MASK 0x20U
#define MSR_DSR_SHIFT 5U
/*------------------------------------------------------------------------------
* MSR_RI:
* RI field of register MSR.
*------------------------------------------------------------------------------
* Ring Indicator The complement of the RIn input. When bit 4 of the MCR is set
* to 1 (loop), this bit is equivalent to OUT1 in the MCR.
*/
#define MSR_RI_OFFSET 0x18U
#define MSR_RI_MASK 0x40U
#define MSR_RI_SHIFT 6U
/*------------------------------------------------------------------------------
* MSR_DCD:
* DCD field of register MSR.
*------------------------------------------------------------------------------
* Data Carrier Detect The complement of DCDn input. When bit 4 of the MCR is
* set to 1 (loop), this bit is equivalent to OUT2 in the MCR.
*/
#define MSR_DCD_OFFSET 0x18U
#define MSR_DCD_MASK 0x80U
#define MSR_DCD_SHIFT 7U
/*******************************************************************************
* SR register:
*------------------------------------------------------------------------------
* Scratch Register
*/
#define SR_REG_OFFSET 0x1CU
#ifdef __cplusplus
}
#endif
#endif /* CORE_16550_REGISTERS_H_*/

View file

@ -0,0 +1,865 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* Core16550 driver implementation. See file "core_16550.h" for a
* description of the functions implemented in this file.
*
* SVN $Revision: 7963 $
* SVN $Date: 2015-10-09 17:58:21 +0530 (Fri, 09 Oct 2015) $
*/
#include "hal.h"
#include "core_16550.h"
#include "core16550_regs.h"
#include "hal_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/*******************************************************************************
* Definitions for transmitter states
*/
#define TX_COMPLETE 0x00U
/*******************************************************************************
* Definition for transmitter FIFO size
*/
#define TX_FIFO_SIZE 16U
/*******************************************************************************
* Default receive interrupt trigger level
*/
#define DEFAULT_RX_TRIG_LEVEL ((uint8_t)UART_16550_FIFO_SINGLE_BYTE)
/*******************************************************************************
* Receiver error status mask and shift offset
*/
#define STATUS_ERROR_MASK ( LSR_OE_MASK | LSR_PE_MASK | \
LSR_FE_MASK | LSR_BI_MASK | LSR_FIER_MASK)
/*******************************************************************************
* Definitions for invalid parameters with proper type
*/
#define INVALID_INTERRUPT 0U
#define INVALID_IRQ_HANDLER ( (uart_16550_irq_handler_t) 0 )
/*******************************************************************************
* Possible values for Interrupt Identification Register Field.
*/
#define IIRF_MODEM_STATUS 0x00U
#define IIRF_THRE 0x02U
#define IIRF_RX_DATA 0x04U
#define IIRF_RX_LINE_STATUS 0x06U
#define IIRF_DATA_TIMEOUT 0x0CU
/*******************************************************************************
* Null parameters with appropriate type definitions
*/
#define NULL_ADDR ( ( addr_t ) 0 )
#define NULL_INSTANCE ( ( uart_16550_instance_t * ) 0 )
#define NULL_BUFF ( ( uint8_t * ) 0 )
/*******************************************************************************
* Possible states for different register bit fields
*/
enum {
DISABLE = 0U,
ENABLE = 1U
};
/*******************************************************************************
* Static function declarations
*/
static void default_tx_handler(uart_16550_instance_t * this_uart);
/*******************************************************************************
* Public function definitions
*/
/***************************************************************************//**
* UART_16550_init.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_init
(
uart_16550_instance_t* this_uart,
addr_t base_addr,
uint16_t baud_value,
uint8_t line_config
)
{
#ifndef NDEBUG
uint8_t dbg1;
uint8_t dbg2;
#endif
uint8_t fifo_config;
uint8_t temp;
HAL_ASSERT( base_addr != NULL_ADDR );
HAL_ASSERT( this_uart != NULL_INSTANCE );
if( ( base_addr != NULL_ADDR ) && ( this_uart != NULL_INSTANCE ) )
{
/* disable interrupts */
HAL_set_8bit_reg(base_addr, IER, DISABLE);
/* reset divisor latch */
HAL_set_8bit_reg_field(base_addr, LCR_DLAB, ENABLE);
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg_field(base_addr, LCR_DLAB );
HAL_ASSERT( dbg1 == ENABLE );
#endif
/* MSB of baud value */
temp = (uint8_t)(baud_value >> 8);
HAL_set_8bit_reg(base_addr, DMR, temp );
/* LSB of baud value */
HAL_set_8bit_reg(base_addr, DLR, ( (uint8_t)baud_value ) );
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg(base_addr, DMR );
dbg2 = HAL_get_8bit_reg(base_addr, DLR );
HAL_ASSERT( ( ( ( (uint16_t) dbg1 ) << 8 ) | dbg2 ) == baud_value );
#endif
/* reset divisor latch */
HAL_set_8bit_reg_field(base_addr, LCR_DLAB, DISABLE);
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg_field(base_addr, LCR_DLAB );
HAL_ASSERT( dbg1 == DISABLE );
#endif
/* set the line control register (bit length, stop bits, parity) */
HAL_set_8bit_reg( base_addr, LCR, line_config );
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg(base_addr, LCR );
HAL_ASSERT( dbg1 == line_config)
#endif
/* Enable and configure the RX and TX FIFOs. */
fifo_config = ((uint8_t)(DEFAULT_RX_TRIG_LEVEL << FCR_TRIG_LEVEL_SHIFT) |
FCR_RDYN_EN_MASK | FCR_CLEAR_RX_MASK |
FCR_CLEAR_TX_MASK | FCR_ENABLE_MASK );
HAL_set_8bit_reg( base_addr, FCR, fifo_config );
/* disable loopback */
HAL_set_8bit_reg_field( base_addr, MCR_LOOP, DISABLE );
#ifndef NDEBUG
dbg1 = HAL_get_8bit_reg_field(base_addr, MCR_LOOP);
HAL_ASSERT( dbg1 == DISABLE );
#endif
/* Instance setup */
this_uart->base_address = base_addr;
this_uart->tx_buffer = NULL_BUFF;
this_uart->tx_buff_size = TX_COMPLETE;
this_uart->tx_idx = 0U;
this_uart->tx_handler = default_tx_handler;
this_uart->rx_handler = ( (uart_16550_irq_handler_t) 0 );
this_uart->linests_handler = ( (uart_16550_irq_handler_t) 0 );
this_uart->modemsts_handler = ( (uart_16550_irq_handler_t) 0 );
this_uart->status = 0U;
}
}
/***************************************************************************//**
* UART_16550_polled_tx.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_polled_tx
(
uart_16550_instance_t * this_uart,
const uint8_t * pbuff,
uint32_t tx_size
)
{
uint32_t char_idx = 0U;
uint32_t size_sent;
uint8_t status;
HAL_ASSERT( this_uart != NULL_INSTANCE );
HAL_ASSERT( pbuff != NULL_BUFF );
HAL_ASSERT( tx_size > 0U );
if( ( this_uart != NULL_INSTANCE ) &&
( pbuff != NULL_BUFF ) &&
( tx_size > 0U ) )
{
/* Remain in this loop until the entire input buffer
* has been transferred to the UART.
*/
do {
/* Read the Line Status Register and update the sticky record */
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
/* Check if TX FIFO is empty. */
if( status & LSR_THRE_MASK )
{
uint32_t fill_size = TX_FIFO_SIZE;
/* Calculate the number of bytes to transmit. */
if ( tx_size < TX_FIFO_SIZE )
{
fill_size = tx_size;
}
/* Fill the TX FIFO with the calculated the number of bytes. */
for ( size_sent = 0U; size_sent < fill_size; ++size_sent )
{
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, THR,
(uint_fast8_t)pbuff[char_idx++]);
}
/* Calculate the number of untransmitted bytes remaining. */
tx_size -= size_sent;
}
} while ( tx_size );
}
}
/***************************************************************************//**
* UART_16550_polled_tx_string.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_polled_tx_string
(
uart_16550_instance_t * this_uart,
const uint8_t * p_sz_string
)
{
uint32_t char_idx = 0U;
uint32_t fill_size;
uint_fast8_t data_byte;
uint8_t status;
HAL_ASSERT( this_uart != NULL_INSTANCE );
HAL_ASSERT( p_sz_string != NULL_BUFF );
if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFF ) )
{
char_idx = 0U;
/* Get the first data byte from the input buffer */
data_byte = (uint_fast8_t)p_sz_string[char_idx];
/* First check for the NULL terminator byte.
* Then remain in this loop until the entire string in the input buffer
* has been transferred to the UART.
*/
while ( 0U != data_byte )
{
/* Wait until TX FIFO is empty. */
do {
status = HAL_get_8bit_reg( this_uart->base_address,LSR);
this_uart->status |= status;
} while ( !( status & LSR_THRE_MASK ) );
/* Send bytes from the input buffer until the TX FIFO is full
* or we reach the NULL terminator byte.
*/
fill_size = 0U;
while ( (0U != data_byte) && (fill_size < TX_FIFO_SIZE) )
{
/* Send the data byte */
HAL_set_8bit_reg( this_uart->base_address, THR, data_byte );
++fill_size;
char_idx++;
/* Get the next data byte from the input buffer */
data_byte = (uint_fast8_t)p_sz_string[char_idx];
}
}
}
}
/***************************************************************************//**
* UART_16550_irq_tx.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_irq_tx
(
uart_16550_instance_t * this_uart,
const uint8_t * pbuff,
uint32_t tx_size
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( pbuff != NULL_BUFF )
HAL_ASSERT( tx_size > 0U )
if( ( this_uart != NULL_INSTANCE ) &&
( pbuff != NULL_BUFF ) &&
( tx_size > 0U ) )
{
/*Initialize the UART instance with
parameters required for transmission.*/
this_uart->tx_buffer = pbuff;
this_uart->tx_buff_size = tx_size;
/* char_idx; */
this_uart->tx_idx = 0U;
/* assign handler for default data transmission */
this_uart->tx_handler = default_tx_handler;
/* enables TX interrupt */
HAL_set_8bit_reg_field(this_uart->base_address, IER_ETBEI, ENABLE);
}
}
/***************************************************************************//**
* UART_16550_tx_complete.
* See core_16550.h for details of how to use this function.
*/
int8_t
UART_16550_tx_complete
(
uart_16550_instance_t * this_uart
)
{
int8_t returnvalue = 0;
uint8_t status = 0U;
HAL_ASSERT( this_uart != NULL_INSTANCE )
if( this_uart != NULL_INSTANCE )
{
status = HAL_get_8bit_reg(this_uart->base_address,LSR);
this_uart->status |= status;
if( ( this_uart->tx_buff_size == TX_COMPLETE ) &&
( status & LSR_TEMT_MASK ) )
{
returnvalue = (int8_t)1;
}
}
return returnvalue;
}
/***************************************************************************//**
* UART_16550_get_rx.
* See core_16550.h for details of how to use this function.
*/
size_t
UART_16550_get_rx
(
uart_16550_instance_t * this_uart,
uint8_t * rx_buff,
size_t buff_size
)
{
uint8_t status;
size_t rx_size = 0U;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( rx_buff != (uint8_t *)0 )
HAL_ASSERT( buff_size > 0U )
if( ( this_uart != NULL_INSTANCE ) &&
( rx_buff != (uint8_t *)0 ) &&
( buff_size > 0U ) )
{
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
while ( ((status & LSR_DR_MASK) != 0U) && ( rx_size < buff_size ) )
{
rx_buff[rx_size] = HAL_get_8bit_reg( this_uart->base_address, RBR );
rx_size++;
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
}
}
return rx_size;
}
/***************************************************************************//**
* UART_16550_isr.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_isr
(
uart_16550_instance_t * this_uart
)
{
uint8_t iirf;
HAL_ASSERT( this_uart != NULL_INSTANCE )
if(this_uart != NULL_INSTANCE )
{
iirf = HAL_get_8bit_reg_field( this_uart->base_address, IIR_IIR );
switch ( iirf )
{
/* Modem status interrupt */
case IIRF_MODEM_STATUS:
{
if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler )
{
HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->modemsts_handler );
if( INVALID_IRQ_HANDLER != this_uart->modemsts_handler )
{
(*(this_uart->modemsts_handler))(this_uart);
}
}
}
break;
/* Transmitter Holding Register Empty interrupt */
case IIRF_THRE:
{
HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->tx_handler );
if ( INVALID_IRQ_HANDLER != this_uart->tx_handler )
{
(*(this_uart->tx_handler))(this_uart);
}
}
break;
/* Received Data Available interrupt */
case IIRF_RX_DATA:
case IIRF_DATA_TIMEOUT:
{
HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->rx_handler );
if ( INVALID_IRQ_HANDLER != this_uart->rx_handler )
{
(*(this_uart->rx_handler))(this_uart);
}
}
break;
/* Line status interrupt */
case IIRF_RX_LINE_STATUS:
{
HAL_ASSERT( INVALID_IRQ_HANDLER != this_uart->linests_handler );
if ( INVALID_IRQ_HANDLER != this_uart->linests_handler )
{
(*(this_uart->linests_handler))(this_uart);
}
}
break;
/* Unidentified interrupt */
default:
{
HAL_ASSERT( INVALID_INTERRUPT )
}
}
}
}
/***************************************************************************//**
* UART_16550_set_rx_handler.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_rx_handler
(
uart_16550_instance_t * this_uart,
uart_16550_irq_handler_t handler,
uart_16550_rx_trig_level_t trigger_level
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
HAL_ASSERT( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL)
if( ( this_uart != NULL_INSTANCE ) &&
( handler != INVALID_IRQ_HANDLER) &&
( trigger_level < UART_16550_FIFO_INVALID_TRIG_LEVEL) )
{
this_uart->rx_handler = handler;
/* Set the receive interrupt trigger level. */
HAL_set_8bit_reg_field( this_uart->base_address,
FCR_TRIG_LEVEL, trigger_level );
/* Enable receive interrupt. */
HAL_set_8bit_reg_field( this_uart->base_address, IER_ERBFI, ENABLE );
}
}
/***************************************************************************//**
* UART_16550_set_loopback.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_loopback
(
uart_16550_instance_t * this_uart,
uart_16550_loopback_t loopback
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE );
HAL_ASSERT( loopback < UART_16550_INVALID_LOOPBACK );
if( ( this_uart != NULL_INSTANCE ) &&
( loopback < UART_16550_INVALID_LOOPBACK ) )
{
if ( loopback == UART_16550_LOOPBACK_OFF )
{
HAL_set_8bit_reg_field( this_uart->base_address,
MCR_LOOP,
DISABLE );
}
else
{
HAL_set_8bit_reg_field( this_uart->base_address,
MCR_LOOP,
ENABLE );
}
}
}
/***************************************************************************//**
* UART_16550_get_rx_status.
* See core_16550.h for details of how to use this function.
*/
uint8_t
UART_16550_get_rx_status
(
uart_16550_instance_t * this_uart
)
{
uint8_t status = UART_16550_INVALID_PARAM;
HAL_ASSERT( this_uart != NULL_INSTANCE );
if( ( this_uart != NULL_INSTANCE ) )
{
/*
* Bit 1 - Overflow error status
* Bit 2 - Parity error status
* Bit 3 - Frame error status
* Bit 4 - Break interrupt indicator
* Bit 7 - FIFO data error status
*/
this_uart->status |= HAL_get_8bit_reg( this_uart->base_address, LSR );
status = ( this_uart->status & STATUS_ERROR_MASK );
/*
* Clear the sticky status for this instance.
*/
this_uart->status = (uint8_t)0;
}
return status;
}
/***************************************************************************//**
* UART_16550_get_modem_status.
* See core_16550.h for details of how to use this function.
*/
uint8_t
UART_16550_get_modem_status
(
uart_16550_instance_t * this_uart
)
{
uint8_t status = UART_16550_NO_ERROR;
HAL_ASSERT( this_uart != NULL_INSTANCE )
if( ( this_uart != NULL_INSTANCE ) )
{
/*
* Extract UART error status and place in lower bits of "status".
* Bit 0 - Delta Clear to Send Indicator
* Bit 1 - Delta Clear to Receive Indicator
* Bit 2 - Trailing edge of Ring Indicator detector
* Bit 3 - Delta Data Carrier Detect indicator
* Bit 4 - Clear To Send
* Bit 5 - Data Set Ready
* Bit 6 - Ring Indicator
* Bit 7 - Data Carrier Detect
*/
status = HAL_get_8bit_reg( this_uart->base_address, MSR );
}
return status;
}
/***************************************************************************//**
* Default TX interrupt handler to automatically transmit data from
* user assgined TX buffer.
*/
static void
default_tx_handler
(
uart_16550_instance_t * this_uart
)
{
uint8_t status;
HAL_ASSERT( NULL_INSTANCE != this_uart )
if ( this_uart != NULL_INSTANCE )
{
HAL_ASSERT( NULL_BUFF != this_uart->tx_buffer )
HAL_ASSERT( 0U != this_uart->tx_buff_size )
if ( ( this_uart->tx_buffer != NULL_BUFF ) &&
( 0U != this_uart->tx_buff_size ) )
{
/* Read the Line Status Register and update the sticky record. */
status = HAL_get_8bit_reg( this_uart->base_address,LSR);
this_uart->status |= status;
/*
* This function should only be called as a result of a THRE interrupt.
* Verify that this is true before proceeding to transmit data.
*/
if ( status & LSR_THRE_MASK )
{
uint32_t size_sent = 0U;
uint32_t fill_size = TX_FIFO_SIZE;
uint32_t tx_remain = this_uart->tx_buff_size - this_uart->tx_idx;
/* Calculate the number of bytes to transmit. */
if ( tx_remain < TX_FIFO_SIZE )
{
fill_size = tx_remain;
}
/* Fill the TX FIFO with the calculated the number of bytes. */
for ( size_sent = 0U; size_sent < fill_size; ++size_sent )
{
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, THR,
(uint_fast8_t)this_uart->tx_buffer[this_uart->tx_idx]);
++this_uart->tx_idx;
}
}
/* Flag Tx as complete if all data has been pushed into the Tx FIFO. */
if ( this_uart->tx_idx == this_uart->tx_buff_size )
{
this_uart->tx_buff_size = TX_COMPLETE;
/* disables TX interrupt */
HAL_set_8bit_reg_field( this_uart->base_address,
IER_ETBEI, DISABLE);
}
}
}
}
/***************************************************************************//**
* UART_16550_enable_irq.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_enable_irq
(
uart_16550_instance_t * this_uart,
uint8_t irq_mask
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
if( this_uart != NULL_INSTANCE )
{
/* irq_mask encoding: 1- enable
* bit 0 - Receive Data Available Interrupt
* bit 1 - Transmitter Holding Register Empty Interrupt
* bit 2 - Receiver Line Status Interrupt
* bit 3 - Modem Status Interrupt
*/
/* read present interrupts for enabled ones*/
irq_mask |= HAL_get_8bit_reg( this_uart->base_address, IER );
/* Enable interrupts */
HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );
}
}
/***************************************************************************//**
* UART_16550_disable_irq.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_disable_irq
(
uart_16550_instance_t * this_uart,
uint8_t irq_mask
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
if( this_uart != NULL_INSTANCE )
{
/* irq_mask encoding: 1 - disable
* bit 0 - Receive Data Available Interrupt
* bit 1 - Transmitter Holding Register Empty Interrupt
* bit 2 - Receiver Line Status Interrupt
* bit 3 - Modem Status Interrupt
*/
/* read present interrupts for enabled ones */
irq_mask = (( (uint8_t)~irq_mask ) &
HAL_get_8bit_reg( this_uart->base_address, IER ));
/* Disable interrupts */
HAL_set_8bit_reg( this_uart->base_address, IER, irq_mask );
}
}
/***************************************************************************//**
* UART_16550_set_rxstatus_handler.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_rxstatus_handler
(
uart_16550_instance_t * this_uart,
uart_16550_irq_handler_t handler
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
if( ( this_uart != NULL_INSTANCE ) &&
( handler != INVALID_IRQ_HANDLER) )
{
this_uart->linests_handler = handler;
/* Enable receiver line status interrupt. */
HAL_set_8bit_reg_field( this_uart->base_address, IER_ELSI, ENABLE );
}
}
/***************************************************************************//**
* UART_16550_set_tx_handler.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_tx_handler
(
uart_16550_instance_t * this_uart,
uart_16550_irq_handler_t handler
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
if( ( this_uart != NULL_INSTANCE ) &&
( handler != INVALID_IRQ_HANDLER) )
{
this_uart->tx_handler = handler;
/* Make TX buffer info invalid */
this_uart->tx_buffer = NULL_BUFF;
this_uart->tx_buff_size = 0U;
/* Enable transmitter holding register Empty interrupt. */
HAL_set_8bit_reg_field( this_uart->base_address, IER_ETBEI, ENABLE );
}
}
/***************************************************************************//**
* UART_16550_set_modemstatus_handler.
* See core_16550.h for details of how to use this function.
*/
void
UART_16550_set_modemstatus_handler
(
uart_16550_instance_t * this_uart,
uart_16550_irq_handler_t handler
)
{
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( handler != INVALID_IRQ_HANDLER)
if( ( this_uart != NULL_INSTANCE ) &&
( handler != INVALID_IRQ_HANDLER) )
{
this_uart->modemsts_handler = handler;
/* Enable modem status interrupt. */
HAL_set_8bit_reg_field( this_uart->base_address, IER_EDSSI, ENABLE );
}
}
/***************************************************************************//**
* UART_16550_fill_tx_fifo.
* See core_16550.h for details of how to use this function.
*/
size_t
UART_16550_fill_tx_fifo
(
uart_16550_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
)
{
uint8_t status;
size_t size_sent = 0U;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( tx_buffer != NULL_BUFF )
HAL_ASSERT( tx_size > 0U )
/* Fill the UART's Tx FIFO until the FIFO is full or the complete input
* buffer has been written. */
if( (this_uart != NULL_INSTANCE) &&
(tx_buffer != NULL_BUFF) &&
(tx_size > 0U) )
{
/* Read the Line Status Register and update the sticky record. */
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
/* Check if TX FIFO is empty. */
if( status & LSR_THRE_MASK )
{
uint32_t fill_size = TX_FIFO_SIZE;
/* Calculate the number of bytes to transmit. */
if ( tx_size < TX_FIFO_SIZE )
{
fill_size = tx_size;
}
/* Fill the TX FIFO with the calculated the number of bytes. */
for ( size_sent = 0U; size_sent < fill_size; ++size_sent )
{
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, THR,
(uint_fast8_t)tx_buffer[size_sent]);
}
}
}
return size_sent;
}
/***************************************************************************//**
* UART_16550_get_tx_status.
* See core_16550.h for details of how to use this function.
*/
uint8_t
UART_16550_get_tx_status
(
uart_16550_instance_t * this_uart
)
{
uint8_t status = UART_16550_TX_BUSY;
HAL_ASSERT( this_uart != NULL_INSTANCE );
if( ( this_uart != NULL_INSTANCE ) )
{
/* Read the Line Status Register and update the sticky record. */
status = HAL_get_8bit_reg( this_uart->base_address, LSR );
this_uart->status |= status;
/*
* Extract the transmit status bits from the UART's Line Status Register.
* Bit 5 - Transmitter Holding Register/FIFO Empty (THRE) status. (If = 1, TX FIFO is empty)
* Bit 6 - Transmitter Empty (TEMT) status. (If = 1, both TX FIFO and shift register are empty)
*/
status &= ( LSR_THRE_MASK | LSR_TEMT_MASK );
}
return status;
}
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,461 @@
/*******************************************************************************
* (c) Copyright 2008-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreGPIO bare metal driver implementation.
*
* SVN $Revision: 7964 $
* SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $
*/
#include "core_gpio.h"
#include "hal.h"
#include "hal_assert.h"
#include "coregpio_regs.h"
/*-------------------------------------------------------------------------*//**
*
*/
#define GPIO_INT_ENABLE_MASK (uint32_t)0x00000008UL
#define OUTPUT_BUFFER_ENABLE_MASK 0x00000004UL
#define NB_OF_GPIO 32
#define CLEAR_ALL_IRQ32 (uint32_t)0xFFFFFFFF
#define CLEAR_ALL_IRQ16 (uint16_t)0xFFFF
#define CLEAR_ALL_IRQ8 (uint8_t)0xFF
/*-------------------------------------------------------------------------*//**
* GPIO_init()
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_init
(
gpio_instance_t * this_gpio,
addr_t base_addr,
gpio_apb_width_t bus_width
)
{
uint8_t i = 0;
addr_t cfg_reg_addr = base_addr;
this_gpio->base_addr = base_addr;
this_gpio->apb_bus_width = bus_width;
/* Clear configuration. */
for( i = 0, cfg_reg_addr = base_addr; i < NB_OF_GPIO; ++i )
{
HW_set_8bit_reg( cfg_reg_addr, 0 );
cfg_reg_addr += 4;
}
/* Clear any pending interrupts */
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
HAL_set_32bit_reg( this_gpio->base_addr, IRQ, CLEAR_ALL_IRQ32 );
break;
case GPIO_APB_16_BITS_BUS:
HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, (uint16_t)CLEAR_ALL_IRQ16 );
HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, (uint16_t)CLEAR_ALL_IRQ16 );
break;
case GPIO_APB_8_BITS_BUS:
HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, (uint8_t)CLEAR_ALL_IRQ8 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, (uint8_t)CLEAR_ALL_IRQ8 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, (uint8_t)CLEAR_ALL_IRQ8 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, (uint8_t)CLEAR_ALL_IRQ8 );
break;
default:
HAL_ASSERT(0);
break;
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_config
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_config
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
uint32_t config
)
{
HAL_ASSERT( port_id < NB_OF_GPIO );
if ( port_id < NB_OF_GPIO )
{
uint32_t cfg_reg_addr = this_gpio->base_addr;
cfg_reg_addr += (port_id * 4);
HW_set_32bit_reg( cfg_reg_addr, config );
/*
* Verify that the configuration was correctly written. Failure to read
* back the expected value may indicate that the GPIO port was configured
* as part of the hardware flow and cannot be modified through software.
* It may also indicate that the base address passed as parameter to
* GPIO_init() was incorrect.
*/
HAL_ASSERT( HW_get_32bit_reg( cfg_reg_addr ) == config );
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_set_outputs
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_set_outputs
(
gpio_instance_t * this_gpio,
uint32_t value
)
{
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, value );
break;
case GPIO_APB_16_BITS_BUS:
HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint16_t)value );
HAL_set_16bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint16_t)(value >> 16) );
break;
case GPIO_APB_8_BITS_BUS:
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT0, (uint8_t)value );
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT1, (uint8_t)(value >> 8) );
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT2, (uint8_t)(value >> 16) );
HAL_set_8bit_reg( this_gpio->base_addr, GPIO_OUT3, (uint8_t)(value >> 24) );
break;
default:
HAL_ASSERT(0);
break;
}
/*
* Verify that the output register was correctly written. Failure to read back
* the expected value may indicate that some of the GPIOs may not exist due to
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
* It may also indicate that the base address or APB bus width passed as
* parameter to the GPIO_init() function do not match the hardware design.
*/
HAL_ASSERT( GPIO_get_outputs( this_gpio ) == value );
}
/*-------------------------------------------------------------------------*//**
* GPIO_get_inputs
* See "core_gpio.h" for details of how to use this function.
*/
uint32_t GPIO_get_inputs
(
gpio_instance_t * this_gpio
)
{
uint32_t gpio_in = 0;
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
gpio_in = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_IN );
break;
case GPIO_APB_16_BITS_BUS:
gpio_in |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN0 );
gpio_in |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 16);
break;
case GPIO_APB_8_BITS_BUS:
gpio_in |= HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN0 );
gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN1 ) << 8);
gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN2 ) << 16);
gpio_in |= (HAL_get_8bit_reg( this_gpio->base_addr, GPIO_IN3 ) << 24);
break;
default:
HAL_ASSERT(0);
break;
}
return gpio_in;
}
/*-------------------------------------------------------------------------*//**
* GPIO_get_outputs
* See "core_gpio.h" for details of how to use this function.
*/
uint32_t GPIO_get_outputs
(
gpio_instance_t * this_gpio
)
{
uint32_t gpio_out = 0;
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
gpio_out = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );
break;
case GPIO_APB_16_BITS_BUS:
gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 16);
break;
case GPIO_APB_8_BITS_BUS:
gpio_out |= HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT0 );
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT1 ) << 8);
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT2 ) << 16);
gpio_out |= (HAL_get_16bit_reg( this_gpio->base_addr, GPIO_OUT3 ) << 24);
break;
default:
HAL_ASSERT(0);
break;
}
return gpio_out;
}
/*-------------------------------------------------------------------------*//**
* GPIO_set_output
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_set_output
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
uint8_t value
)
{
HAL_ASSERT( port_id < NB_OF_GPIO );
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
{
uint32_t outputs_state;
outputs_state = HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT );
if ( 0 == value )
{
outputs_state &= ~(1 << port_id);
}
else
{
outputs_state |= 1 << port_id;
}
HAL_set_32bit_reg( this_gpio->base_addr, GPIO_OUT, outputs_state );
/*
* Verify that the output register was correctly written. Failure to read back
* the expected value may indicate that some of the GPIOs may not exist due to
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
* It may also indicate that the base address or APB bus width passed as
* parameter to the GPIO_init() function do not match the hardware design.
*/
HAL_ASSERT( HAL_get_32bit_reg( this_gpio->base_addr, GPIO_OUT ) == outputs_state );
}
break;
case GPIO_APB_16_BITS_BUS:
{
uint16_t outputs_state;
uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 4) * 4);
outputs_state = HW_get_16bit_reg( gpio_out_reg_addr );
if ( 0 == value )
{
outputs_state &= ~(1 << (port_id & 0x0F));
}
else
{
outputs_state |= 1 << (port_id & 0x0F);
}
HW_set_16bit_reg( gpio_out_reg_addr, outputs_state );
/*
* Verify that the output register was correctly written. Failure to read back
* the expected value may indicate that some of the GPIOs may not exist due to
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
* It may also indicate that the base address or APB bus width passed as
* parameter to the GPIO_init() function do not match the hardware design.
*/
HAL_ASSERT( HW_get_16bit_reg( gpio_out_reg_addr ) == outputs_state );
}
break;
case GPIO_APB_8_BITS_BUS:
{
uint8_t outputs_state;
uint32_t gpio_out_reg_addr = this_gpio->base_addr + GPIO_OUT_REG_OFFSET + ((port_id >> 3) * 4);
outputs_state = HW_get_8bit_reg( gpio_out_reg_addr );
if ( 0 == value )
{
outputs_state &= ~(1 << (port_id & 0x07));
}
else
{
outputs_state |= 1 << (port_id & 0x07);
}
HW_set_8bit_reg( gpio_out_reg_addr, outputs_state );
/*
* Verify that the output register was correctly written. Failure to read back
* the expected value may indicate that some of the GPIOs may not exist due to
* the number of GPIOs selected in the CoreGPIO hardware flow configuration.
* It may also indicate that the base address or APB bus width passed as
* parameter to the GPIO_init() function do not match the hardware design.
*/
HAL_ASSERT( HW_get_8bit_reg( gpio_out_reg_addr ) == outputs_state );
}
break;
default:
HAL_ASSERT(0);
break;
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_drive_inout
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_drive_inout
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
gpio_inout_state_t inout_state
)
{
uint32_t config;
uint32_t cfg_reg_addr = this_gpio->base_addr;
HAL_ASSERT( port_id < NB_OF_GPIO );
switch( inout_state )
{
case GPIO_DRIVE_HIGH:
/* Set output high */
GPIO_set_output( this_gpio, port_id, 1 );
/* Enable output buffer */
cfg_reg_addr = this_gpio->base_addr + (port_id * 4);
config = HW_get_8bit_reg( cfg_reg_addr );
config |= OUTPUT_BUFFER_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, config );
break;
case GPIO_DRIVE_LOW:
/* Set output low */
GPIO_set_output( this_gpio, port_id, 0 );
/* Enable output buffer */
cfg_reg_addr = this_gpio->base_addr + (port_id * 4);
config = HW_get_8bit_reg( cfg_reg_addr );
config |= OUTPUT_BUFFER_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, config );
break;
case GPIO_HIGH_Z:
/* Disable output buffer */
cfg_reg_addr = this_gpio->base_addr + (port_id * 4);
config = HW_get_8bit_reg( cfg_reg_addr );
config &= ~OUTPUT_BUFFER_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, config );
break;
default:
HAL_ASSERT(0);
break;
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_enable_irq
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_enable_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
)
{
uint32_t cfg_value;
uint32_t cfg_reg_addr = this_gpio->base_addr;
HAL_ASSERT( port_id < NB_OF_GPIO );
if ( port_id < NB_OF_GPIO )
{
cfg_reg_addr += (port_id * 4);
cfg_value = HW_get_8bit_reg( cfg_reg_addr );
cfg_value |= GPIO_INT_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, cfg_value );
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_disable_irq
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_disable_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
)
{
uint32_t cfg_value;
uint32_t cfg_reg_addr = this_gpio->base_addr;
HAL_ASSERT( port_id < NB_OF_GPIO );
if ( port_id < NB_OF_GPIO )
{
cfg_reg_addr += (port_id * 4);
cfg_value = HW_get_8bit_reg( cfg_reg_addr );
cfg_value &= ~GPIO_INT_ENABLE_MASK;
HW_set_8bit_reg( cfg_reg_addr, cfg_value );
}
}
/*-------------------------------------------------------------------------*//**
* GPIO_clear_irq
* See "core_gpio.h" for details of how to use this function.
*/
void GPIO_clear_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
)
{
uint32_t irq_clr_value = ((uint32_t)1) << ((uint32_t)port_id);
switch( this_gpio->apb_bus_width )
{
case GPIO_APB_32_BITS_BUS:
HAL_set_32bit_reg( this_gpio->base_addr, IRQ, irq_clr_value );
break;
case GPIO_APB_16_BITS_BUS:
HAL_set_16bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );
HAL_set_16bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 16 );
break;
case GPIO_APB_8_BITS_BUS:
HAL_set_8bit_reg( this_gpio->base_addr, IRQ0, irq_clr_value );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ1, irq_clr_value >> 8 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ2, irq_clr_value >> 16 );
HAL_set_8bit_reg( this_gpio->base_addr, IRQ3, irq_clr_value >> 24 );
break;
default:
HAL_ASSERT(0);
break;
}
}

View file

@ -0,0 +1,552 @@
/*******************************************************************************
* (c) Copyright 2008-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreGPIO bare metal driver public API.
*
* SVN $Revision: 7964 $
* SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $
*/
/*=========================================================================*//**
@mainpage CoreGPIO Bare Metal Driver.
@section intro_sec Introduction
The CoreGPIO hardware IP includes up to 32 general purpose input output GPIOs.
This driver provides a set of functions for controlling the GPIOs as part of a
bare metal system where no operating system is available. These drivers
can be adapted for use as part of an operating system but the implementation
of the adaptation layer between this driver and the operating system's driver
model is outside the scope of this driver.
@section driver_configuration Driver Configuration
The CoreGPIO individual IOs can be configured either in the hardware flow or
as part of the software application through calls to the GPIO_config() function.
GPIOs configured as as part of the hardware is fixed and cannot be modified
using a call to the GPI_config() function.
@section theory_op Theory of Operation
The CoreGPIO driver uses the Actel Hardware Abstraction Layer (HAL) to access
hardware registers. You must ensure that the Actel HAL is included as part of
your software project. The Actel HAL is available through the Actel Firmware
Catalog.
The CoreGPIO driver functions are logically grouped into the following groups:
- Initiliazation
- Configuration
- Reading and writing GPIO state
- Interrupt control
The CoreGPIO driver is initialized through a call to the GPIO_init() function.
The GPIO_init() function must be called before any other GPIO driver functions
can be called.
Each GPIO port is individually configured through a call to the
GPIO_config() function. Configuration includes deciding if a GPIO port
will be used as input, output or both. GPIO ports configured as inputs can be
further configured to generate interrupts based on the input's state.
Interrupts can be level or edge sensitive.
Please note that a CoreGPIO hardware instance can be generated, as part of the
hardware flow, with a fixed configuration for some or all of its IOs. Attempting
to modify the configuration of such a hardware configured IO using the
GPIO_config() function has no effect.
The state of the GPIO ports can be read and written using the following
functions:
- GPIO_get_inputs()
- GPIO_get_outputs()
- GPIO_set_outputs()
- GPIO_drive_inout()
Interrupts generated by GPIO ports configured as inputs are controlled using
the following functions:
- GPIO_enable_irq()
- GPIO_disable_irq()
- GPIO_clear_irq()
*//*=========================================================================*/
#ifndef CORE_GPIO_H_
#define CORE_GPIO_H_
#include <stdint.h>
#include "cpu_types.h"
/*-------------------------------------------------------------------------*//**
The gpio_id_t enumeration is used to identify GPIOs as part of the
parameter to functions:
- GPIO_config(),
- GPIO_drive_inout(),
- GPIO_enable_int(),
- GPIO_disable_int(),
- GPIO_clear_int()
*/
typedef enum __gpio_id_t
{
GPIO_0 = 0,
GPIO_1 = 1,
GPIO_2 = 2,
GPIO_3 = 3,
GPIO_4 = 4,
GPIO_5 = 5,
GPIO_6 = 6,
GPIO_7 = 7,
GPIO_8 = 8,
GPIO_9 = 9,
GPIO_10 = 10,
GPIO_11 = 11,
GPIO_12 = 12,
GPIO_13 = 13,
GPIO_14 = 14,
GPIO_15 = 15,
GPIO_16 = 16,
GPIO_17 = 17,
GPIO_18 = 18,
GPIO_19 = 19,
GPIO_20 = 20,
GPIO_21 = 21,
GPIO_22 = 22,
GPIO_23 = 23,
GPIO_24 = 24,
GPIO_25 = 25,
GPIO_26 = 26,
GPIO_27 = 27,
GPIO_28 = 28,
GPIO_29 = 29,
GPIO_30 = 30,
GPIO_31 = 31
} gpio_id_t;
typedef enum __gpio_apb_width_t
{
GPIO_APB_8_BITS_BUS = 0,
GPIO_APB_16_BITS_BUS = 1,
GPIO_APB_32_BITS_BUS = 2,
GPIO_APB_UNKNOWN_BUS_WIDTH = 3
} gpio_apb_width_t;
/*-------------------------------------------------------------------------*//**
*/
typedef struct __gpio_instance_t
{
addr_t base_addr;
gpio_apb_width_t apb_bus_width;
} gpio_instance_t;
/*-------------------------------------------------------------------------*//**
GPIO ports definitions used to identify GPIOs as part of the parameter to
function GPIO_set_outputs().
These definitions can also be used to identity GPIO through logical
operations on the return value of function GPIO_get_inputs().
*/
#define GPIO_0_MASK 0x00000001UL
#define GPIO_1_MASK 0x00000002UL
#define GPIO_2_MASK 0x00000004UL
#define GPIO_3_MASK 0x00000008UL
#define GPIO_4_MASK 0x00000010UL
#define GPIO_5_MASK 0x00000020UL
#define GPIO_6_MASK 0x00000040UL
#define GPIO_7_MASK 0x00000080UL
#define GPIO_8_MASK 0x00000100UL
#define GPIO_9_MASK 0x00000200UL
#define GPIO_10_MASK 0x00000400UL
#define GPIO_11_MASK 0x00000800UL
#define GPIO_12_MASK 0x00001000UL
#define GPIO_13_MASK 0x00002000UL
#define GPIO_14_MASK 0x00004000UL
#define GPIO_15_MASK 0x00008000UL
#define GPIO_16_MASK 0x00010000UL
#define GPIO_17_MASK 0x00020000UL
#define GPIO_18_MASK 0x00040000UL
#define GPIO_19_MASK 0x00080000UL
#define GPIO_20_MASK 0x00100000UL
#define GPIO_21_MASK 0x00200000UL
#define GPIO_22_MASK 0x00400000UL
#define GPIO_23_MASK 0x00800000UL
#define GPIO_24_MASK 0x01000000UL
#define GPIO_25_MASK 0x02000000UL
#define GPIO_26_MASK 0x04000000UL
#define GPIO_27_MASK 0x08000000UL
#define GPIO_28_MASK 0x10000000UL
#define GPIO_29_MASK 0x20000000UL
#define GPIO_30_MASK 0x40000000UL
#define GPIO_31_MASK 0x80000000UL
/*-------------------------------------------------------------------------*//**
* GPIO modes
*/
#define GPIO_INPUT_MODE 0x0000000002UL
#define GPIO_OUTPUT_MODE 0x0000000005UL
#define GPIO_INOUT_MODE 0x0000000003UL
/*-------------------------------------------------------------------------*//**
* Possible GPIO inputs interrupt configurations.
*/
#define GPIO_IRQ_LEVEL_HIGH 0x0000000000UL
#define GPIO_IRQ_LEVEL_LOW 0x0000000020UL
#define GPIO_IRQ_EDGE_POSITIVE 0x0000000040UL
#define GPIO_IRQ_EDGE_NEGATIVE 0x0000000060UL
#define GPIO_IRQ_EDGE_BOTH 0x0000000080UL
/*-------------------------------------------------------------------------*//**
* Possible states for GPIO configured as INOUT.
*/
typedef enum gpio_inout_state
{
GPIO_DRIVE_LOW = 0,
GPIO_DRIVE_HIGH,
GPIO_HIGH_Z
} gpio_inout_state_t;
/*-------------------------------------------------------------------------*//**
The GPIO_init() function initialises a CoreGPIO hardware instance and the data
structure associated with the CoreGPIO hardware instance.
Please note that a CoreGPIO hardware instance can be generated with a fixed
configuration for some or all of its IOs as part of the hardware flow. Attempting
to modify the configuration of such a hardware configured IO using the
GPIO_config() function has no effect.
@param this_gpio
Pointer to the gpio_instance_t data structure instance holding all data
regarding the CoreGPIO hardware instance being initialized. A pointer to the
same data structure will be used in subsequent calls to the CoreGPIO driver
functions in order to identify the CoreGPIO instance that should perform the
operation implemented by the called driver function.
@param base_addr
The base_addr parameter is the base address in the processor's memory map for
the registers of the GPIO instance being initialized.
@param bus_width
The bus_width parameter informs the driver of the APB bus width selected during
the hardware flow configuration of the CoreGPIO hardware instance. It indicates
to the driver whether the CoreGPIO hardware registers will be visible as 8, 16
or 32 bits registers. Allowed value are:
- GPIO_APB_8_BITS_BUS
- GPIO_APB_16_BITS_BUS
- GPIO_APB_32_BITS_BUS
@return
none.
Example:
@code
#define COREGPIO_BASE_ADDR 0xC2000000
gpio_instance_t g_gpio;
void system_init( void )
{
GPIO_init( &g_gpio, COREGPIO_BASE_ADDR, GPIO_APB_32_BITS_BUS );
}
@endcode
*/
void GPIO_init
(
gpio_instance_t * this_gpio,
addr_t base_addr,
gpio_apb_width_t bus_width
);
/*-------------------------------------------------------------------------*//**
The GPIO_config() function is used to configure an individual GPIO port.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO port to be configured.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@param config
The config parameter specifies the configuration to be applied to the GPIO
port identified by the first parameter. It is a logical OR of GPIO mode and
the interrupt mode. The interrupt mode is only relevant if the GPIO is
configured as input.
Possible modes are:
- GPIO_INPUT_MODE,
- GPIO_OUTPUT_MODE,
- GPIO_INOUT_MODE.
Possible interrupt modes are:
- GPIO_IRQ_LEVEL_HIGH,
- GPIO_IRQ_LEVEL_LOW,
- GPIO_IRQ_EDGE_POSITIVE,
- GPIO_IRQ_EDGE_NEGATIVE,
- GPIO_IRQ_EDGE_BOTH
@return
none.
For example the following call will configure GPIO 4 as an input generating
interrupts on a low to high transition of the input:
@code
GPIO_config( &g_gpio, GPIO_4, GPIO_INPUT_MODE | GPIO_IRQ_EDGE_POSITIVE );
@endcode
*/
void GPIO_config
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
uint32_t config
);
/*-------------------------------------------------------------------------*//**
The GPIO_set_outputs() function is used to set the state of the GPIO ports
configured as outputs.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param value
The value parameter specifies the state of the GPIO ports configured as
outputs. It is a bit mask of the form (GPIO_n_MASK | GPIO_m_MASK) where n
and m are numbers identifying GPIOs.
For example (GPIO_0_MASK | GPIO_1_MASK | GPIO_2_MASK ) specifies that the
first, second and third GPIOs' must be set high and all other outputs set
low.
@return
none.
Example 1:
Set GPIOs outputs 0 and 8 high and all other GPIO outputs low.
@code
GPIO_set_outputs( &g_gpio, GPIO_0_MASK | GPIO_8_MASK );
@endcode
Example 2:
Set GPIOs outputs 2 and 4 low without affecting other GPIO outputs.
@code
uint32_t gpio_outputs;
gpio_outputs = GPIO_get_outputs( &g_gpio );
gpio_outputs &= ~( GPIO_2_MASK | GPIO_4_MASK );
GPIO_set_outputs( &g_gpio, gpio_outputs );
@endcode
@see GPIO_get_outputs()
*/
void GPIO_set_outputs
(
gpio_instance_t * this_gpio,
uint32_t value
);
/*-------------------------------------------------------------------------*//**
The GPIO_set_output() function is used to set the state of a single GPIO
port configured as output.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter specifies the GPIO port that will have its output set
by a call to this function.
@param value
The value parameter specifies the desired state for the GPIO output. A value
of 0 will set the output low and a value of 1 will set the port high.
@return
none.
*/
void GPIO_set_output
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
uint8_t value
);
/*-------------------------------------------------------------------------*//**
The GPIO_get_inputs() function is used to read the state of all GPIOs
confgured as inputs.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@return
This function returns a 32 bit unsigned integer where each bit represents
the state of an input. The least significant bit representing the state of
GPIO 0 and the most significant bit the state of GPIO 31.
*/
uint32_t GPIO_get_inputs
(
gpio_instance_t * this_gpio
);
/*-------------------------------------------------------------------------*//**
The GPIO_get_outputs() function is used to read the current state of all
GPIO outputs.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@return
This function returns a 32 bit unsigned integer where each bit represents
the state of an output. The least significant bit representing the state
of GPIO 0 and the most significant bit the state of GPIO 31.
*/
uint32_t GPIO_get_outputs
(
gpio_instance_t * this_gpio
);
/*-------------------------------------------------------------------------*//**
The GPIO_drive_inout() function is used to set the output state of a
GPIO configured as INOUT. An INOUT GPIO can be in one of three states:
- high
- low
- high impedance
An INOUT output would typically be used where several devices can drive the
state of a signal. The high and low states are equivalent to the high and low
states of a GPIO configured as output. The high impedance state is used to
prevent the GPIO from driving the state of the output and therefore allow
reading the state of the GPIO as an input.
Please note that the GPIO port you wish to use as INOUT through this function
must be configurable through software. Therefore the GPIO ports used as INOUT
must not have a fixed configuration selected as part of the hardware flow.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO for whcih this function will
change the output state.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@param inout_state
The inout_state parameter specifies the state of the I/O identified by the
first parameter. Possible states are:
- GPIO_DRIVE_HIGH,
- GPIO_DRIVE_LOW,
- GPIO_HIGH_Z (high impedance)
@return
none.
Example:
The call to GPIO_drive_inout() below will set the GPIO 7 output to
high impedance state.
@code
GPIO_drive_inout( &g_gpio, GPIO_7, GPIO_HIGH_Z );
@endcode
*/
void GPIO_drive_inout
(
gpio_instance_t * this_gpio,
gpio_id_t port_id,
gpio_inout_state_t inout_state
);
/*-------------------------------------------------------------------------*//**
The GPIO_enable_irq() function is used to enable an interrupt to be
generated based on the state of the input identified as parameter.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO input the call to
GPIO_enable_irq() will enable to generate interrupts.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@return
none.
Example:
The call to GPIO_enable_irq() below will allow GPIO 8 to generate
interrupts.
@code
GPIO_enable_irq( &g_gpio, GPIO_8 );
@endcode
*/
void GPIO_enable_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
);
/*-------------------------------------------------------------------------*//**
The GPIO_disable_irq() function is used to disable interrupt from being
generated based on the state of the input specified as parameter.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO input the call to
GPIO_disable_irq() will disable from generating interrupts.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@return
none.
Example:
The call to GPIO_disable_irq() below will prevent GPIO 8 from generating
interrupts.
@code
GPIO_disable_irq( &g_gpio, GPIO_8 );
@endcode
*/
void GPIO_disable_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
);
/*-------------------------------------------------------------------------*//**
The GPIO_clear_irq() function is used to clear the interrupt generated by
the GPIO specified as parameter. The GPIO_clear_irq() function must be
called as part of a GPIO interrupt service routine (ISR) in order to prevent
the same interrupt event retriggering a call to the GPIO ISR.
Please note that interrupts may also need to be cleared in the processor's
interrupt controller.
@param this_gpio
The this_gpio parameter is a pointer to the gpio_instance_t structure holding
all data regarding the CoreGPIO instance controlled through this function call.
@param port_id
The port_id parameter identifies the GPIO input for which to clear the
interrupt.
An enumeration item of the form GPIO_n where n is the number of the GPIO
port is used to identify the GPIO port. For example GPIO_0 identifies the
first GPIO port and GPIO_31 the last one.
@return
none.
Example:
The example below demonstrates the use of the GPIO_clear_irq() function as
part of the GPIO 9 interrupt service routine on a Cortex-M processor.
@code
void GPIO9_IRQHandler( void )
{
do_interrupt_processing();
GPIO_clear_irq( &g_gpio, GPIO_9 );
NVIC_ClearPendingIRQ( GPIO9_IRQn );
}
@endcode
*/
void GPIO_clear_irq
(
gpio_instance_t * this_gpio,
gpio_id_t port_id
);
#endif /* CORE_GPIO_H_ */

View file

@ -0,0 +1,40 @@
/*******************************************************************************
* (c) Copyright 2009-2015 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 7964 $
* SVN $Date: 2015-10-09 18:26:53 +0530 (Fri, 09 Oct 2015) $
*/
#ifndef __CORE_GPIO_REGISTERS_H
#define __CORE_GPIO_REGISTERS_H 1
/*------------------------------------------------------------------------------
*
*/
#define IRQ_REG_OFFSET 0x80
#define IRQ0_REG_OFFSET 0x80
#define IRQ1_REG_OFFSET 0x84
#define IRQ2_REG_OFFSET 0x88
#define IRQ3_REG_OFFSET 0x8C
/*------------------------------------------------------------------------------
*
*/
#define GPIO_IN_REG_OFFSET 0x90
#define GPIO_IN0_REG_OFFSET 0x90
#define GPIO_IN1_REG_OFFSET 0x94
#define GPIO_IN2_REG_OFFSET 0x98
#define GPIO_IN3_REG_OFFSET 0x9C
/*------------------------------------------------------------------------------
*
*/
#define GPIO_OUT_REG_OFFSET 0xA0
#define GPIO_OUT0_REG_OFFSET 0xA0
#define GPIO_OUT1_REG_OFFSET 0xA4
#define GPIO_OUT2_REG_OFFSET 0xA8
#define GPIO_OUT3_REG_OFFSET 0xAC
#endif /* __CORE_GPIO_REGISTERS_H */

View file

@ -0,0 +1,190 @@
/*******************************************************************************
* (c) Copyright 2009-2015 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 7984 $
* SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $
*/
#ifndef __CORE_SMBUS_REGISTERS
#define __CORE_SMBUS_REGISTERS 1
/*------------------------------------------------------------------------------
* CONTROL register details
*/
#define CONTROL_REG_OFFSET 0x00u
/*
* CR0 bits.
*/
#define CR0_OFFSET 0x00u
#define CR0_MASK 0x01u
#define CR0_SHIFT 0u
/*
* CR1 bits.
*/
#define CR1_OFFSET 0x00u
#define CR1_MASK 0x02u
#define CR1_SHIFT 1u
/*
* AA bits.
*/
#define AA_OFFSET 0x00u
#define AA_MASK 0x04u
#define AA_SHIFT 2u
/*
* SI bits.
*/
#define SI_OFFSET 0x00u
#define SI_MASK 0x08u
#define SI_SHIFT 3u
/*
* STO bits.
*/
#define STO_OFFSET 0x00u
#define STO_MASK 0x10u
#define STO_SHIFT 4u
/*
* STA bits.
*/
#define STA_OFFSET 0x00u
#define STA_MASK 0x20u
#define STA_SHIFT 5u
/*
* ENS1 bits.
*/
#define ENS1_OFFSET 0x00u
#define ENS1_MASK 0x40u
#define ENS1_SHIFT 6u
/*
* CR2 bits.
*/
#define CR2_OFFSET 0x00u
#define CR2_MASK 0x80u
#define CR2_SHIFT 7u
/*------------------------------------------------------------------------------
* STATUS register details
*/
#define STATUS_REG_OFFSET 0x04u
/*------------------------------------------------------------------------------
* DATA register details
*/
#define DATA_REG_OFFSET 0x08u
/*
* TARGET_ADDR bits.
*/
#define TARGET_ADDR_OFFSET 0x08u
#define TARGET_ADDR_MASK 0xFEu
#define TARGET_ADDR_SHIFT 1u
/*
* DIR bit.
*/
#define DIR_OFFSET 0x08u
#define DIR_MASK 0x01u
#define DIR_SHIFT 0u
/*------------------------------------------------------------------------------
* ADDRESS register details
*/
#define ADDRESS_REG_OFFSET 0x0Cu
/*
* GC bits.
*/
#define GC_OFFSET 0x0Cu
#define GC_MASK 0x01u
#define GC_SHIFT 0u
/*
* ADR bits.
*/
#define OWN_SLAVE_ADDR_OFFSET 0x0Cu
#define OWN_SLAVE_ADDR_MASK 0xFEu
#define OWN_SLAVE_ADDR_SHIFT 1u
/*------------------------------------------------------------------------------
* SMBUS register details
*/
#define SMBUS_REG_OFFSET 0x10u
/*
* SMBALERT_IE bits.
*/
#define SMBALERT_IE_OFFSET 0x10u
#define SMBALERT_IE_MASK 0x01u
#define SMBALERT_IE_SHIFT 0u
/*
* SMBSUS_IE bits.
*/
#define SMBSUS_IE_OFFSET 0x10u
#define SMBSUS_IE_MASK 0x02u
#define SMBSUS_IE_SHIFT 1u
/*
* SMB_IPMI_EN bits.
*/
#define SMB_IPMI_EN_OFFSET 0x10u
#define SMB_IPMI_EN_MASK 0x04u
#define SMB_IPMI_EN_SHIFT 2u
/*
* SMBALERT_NI_STATUS bits.
*/
#define SMBALERT_NI_STATUS_OFFSET 0x10u
#define SMBALERT_NI_STATUS_MASK 0x08u
#define SMBALERT_NI_STATUS_SHIFT 3u
/*
* SMBALERT_NO_CONTROL bits.
*/
#define SMBALERT_NO_CONTROL_OFFSET 0x10u
#define SMBALERT_NO_CONTROL_MASK 0x10u
#define SMBALERT_NO_CONTROL_SHIFT 4u
/*
* SMBSUS_NI_STATUS bits.
*/
#define SMBSUS_NI_STATUS_OFFSET 0x10u
#define SMBSUS_NI_STATUS_MASK 0x20u
#define SMBSUS_NI_STATUS_SHIFT 5u
/*
* SMBSUS_NO_CONTROL bits.
*/
#define SMBSUS_NO_CONTROL_OFFSET 0x10u
#define SMBSUS_NO_CONTROL_MASK 0x40u
#define SMBSUS_NO_CONTROL_SHIFT 6u
/*
* SMBUS_MST_RESET bits.
*/
#define SMBUS_MST_RESET_OFFSET 0x10u
#define SMBUS_MST_RESET_MASK 0x80u
#define SMBUS_MST_RESET_SHIFT 7u
/*------------------------------------------------------------------------------
* SLAVE ADDRESS 1 register details
*/
#define ADDRESS1_REG_OFFSET 0x1Cu
/*
* SLAVE1_EN bit of Slave Address 1 .
*/
#define SLAVE1_EN_OFFSET 0x1Cu
#define SLAVE1_EN_MASK 0x01u
#define SLAVE1_EN_SHIFT 0u
#endif /* __CORE_SMBUS_REGISTERS */

View file

@ -0,0 +1,35 @@
/*******************************************************************************
* (c) Copyright 2009-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreI2C driver interrupt control.
*
* SVN $Revision: 7984 $
* SVN $Date: 2015-10-12 12:07:40 +0530 (Mon, 12 Oct 2015) $
*/
#include "hal.h"
#include "hal_assert.h"
#include "core_i2c.h"
#include "riscv_hal.h"
#define I2C_IRQn External_29_IRQn
/*------------------------------------------------------------------------------
* This function must be modified to enable interrupts generated from the
* CoreI2C instance identified as parameter.
*/
void I2C_enable_irq( i2c_instance_t * this_i2c )
{
PLIC_EnableIRQ(I2C_IRQn);
// HAL_ASSERT(0)
}
/*------------------------------------------------------------------------------
* This function must be modified to disable interrupts generated from the
* CoreI2C instance identified as parameter.
*/
void I2C_disable_irq( i2c_instance_t * this_i2c )
{
PLIC_DisableIRQ(I2C_IRQn);
// HAL_ASSERT(0)
}

View file

@ -0,0 +1,158 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreTimer driver implementation.
*
* SVN $Revision: 7967 $
* SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $
*/
#include "core_timer.h"
#include "coretimer_regs.h"
#include "hal.h"
#include "hal_assert.h"
#ifndef NDEBUG
static timer_instance_t* NULL_timer_instance;
#endif
/***************************************************************************//**
* TMR_init()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_init
(
timer_instance_t * this_timer,
addr_t address,
uint8_t mode,
uint32_t prescale,
uint32_t load_value
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_ASSERT( prescale <= PRESCALER_DIV_1024 )
HAL_ASSERT( load_value != 0 )
this_timer->base_address = address;
/* Disable interrupts. */
HAL_set_32bit_reg_field( address, InterruptEnable,0 );
/* Disable timer. */
HAL_set_32bit_reg_field( address, TimerEnable, 0 );
/* Clear pending interrupt. */
HAL_set_32bit_reg( address, TimerIntClr, 1 );
/* Configure prescaler and load value. */
HAL_set_32bit_reg( address, TimerPrescale, prescale );
HAL_set_32bit_reg( address, TimerLoad, load_value );
/* Set the interrupt mode. */
if ( mode == TMR_CONTINUOUS_MODE )
{
HAL_set_32bit_reg_field( address, TimerMode, 0 );
}
else
{
/* TMR_ONE_SHOT_MODE */
HAL_set_32bit_reg_field( address, TimerMode, 1 );
}
}
/***************************************************************************//**
* TMR_start()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_start
(
timer_instance_t * this_timer
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_set_32bit_reg_field( this_timer->base_address, TimerEnable, 1 );
}
/***************************************************************************//**
* TMR_stop()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_stop
(
timer_instance_t * this_timer
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_set_32bit_reg_field( this_timer->base_address, TimerEnable, 0 );
}
/***************************************************************************//**
* TMR_enable_int()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_enable_int
(
timer_instance_t * this_timer
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_set_32bit_reg_field( this_timer->base_address, InterruptEnable, 1 );
}
/***************************************************************************//**
* TMR_clear_int()
* See "core_timer.h" for details of how to use this function.
*/
void
TMR_clear_int
(
timer_instance_t * this_timer
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_set_32bit_reg( this_timer->base_address, TimerIntClr, 0x01 );
}
/***************************************************************************//**
* TMR_current_value()
* See "core_timer.h" for details of how to use this function.
*/
uint32_t
TMR_current_value
(
timer_instance_t * this_timer
)
{
uint32_t value = 0;
HAL_ASSERT( this_timer != NULL_timer_instance )
value = HAL_get_32bit_reg( this_timer->base_address, TimerValue );
return value;
}
/***************************************************************************//**
* TMR_reload()
* See "core_timer.h" for details of how to use this function.
*/
void TMR_reload
(
timer_instance_t * this_timer,
uint32_t load_value
)
{
HAL_ASSERT( this_timer != NULL_timer_instance )
HAL_ASSERT( load_value != 0 )
HAL_set_32bit_reg(this_timer->base_address, TimerLoad, load_value );
}

View file

@ -0,0 +1,206 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* CoreTimer public API.
*
* SVN $Revision: 7967 $
* SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $
*/
#ifndef CORE_TIMER_H_
#define CORE_TIMER_H_
#include "cpu_types.h"
/***************************************************************************//**
* The following definitions are used to select the CoreTimer driver operating
* mode. They allow selecting continuous or one-shot mode.
* 1. Continuous Mode
* In continuous mode the timer's counter is decremented from the load value
* until it reaches zero. The timer counter is automatically reloaded, with the
* load value, upon reaching zero. An interrupt is generated every time the
* counter reaches zero if interrupt is enabled.
* This mode is typically used to generate an interrupt at constant time
* intervals.
* 2. One-shot mode:
* In one-shot mode, the counter decrements from the load value and until it
* reaches zero. An interrupt can be generated, if enabled, when the counter
* reaches zero. The timer's counter must be reloaded to begin counting down
* again.
*/
#define TMR_CONTINUOUS_MODE 0
#define TMR_ONE_SHOT_MODE 1
/***************************************************************************//**
* The following definitions are used to configure the CoreTimer prescaler.
* The prescaler is used to divide down the clock used to decrement the
* CoreTimer counter. It can be configure to divide the clock by 2, 4, 8,
* 16, 32, 64, 128, 256, 512, or 1024.
*/
#define PRESCALER_DIV_2 0
#define PRESCALER_DIV_4 1
#define PRESCALER_DIV_8 2
#define PRESCALER_DIV_16 3
#define PRESCALER_DIV_32 4
#define PRESCALER_DIV_64 5
#define PRESCALER_DIV_128 6
#define PRESCALER_DIV_256 7
#define PRESCALER_DIV_512 8
#define PRESCALER_DIV_1024 9
/***************************************************************************//**
* There should be one instance of this structure for each instance of CoreTimer
* in your system. The function TMR_init() initializes this structure. It is
* used to identify the various CoreTimer hardware instances in your system.
* An initialized timer instance structure should be passed as first parameter to
* CoreTimer driver functions to identify which CoreTimer instance should perform
* the requested operation.
* Software using this driver should only need to create one single instance of
* this data structure for each hardware timer instance in the system.
*/
typedef struct __timer_instance_t
{
addr_t base_address;
} timer_instance_t;
/***************************************************************************//**
* The function TMR_init() initializes the data structures and sets relevant
* CoreTimer registers. This function will prepare the Timer for use in a given
* hardware/software configuration. It should be called before any other Timer
* API functions.
* The timer will not start counting down immediately after this function is
* called. It is necessary to call TMR_start() to start the timer decrementing.
* The CoreTimer interrupt is disabled as part of this function.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer will be used to identify the
* target CoreTimer hardware instance in subsequent calls
* to the CoreTimer functions.
* @param address Base address in the processor's memory map of the
* registers of the CoreTimer instance being initialized.
* @param mode This parameter is used to select the operating mode of
* the timer driver. This can be either TMR_CONTINUOUS_MODE
* or TMR_ONE_SHOT_MODE.
* @param prescale This parameter is used to select the prescaler divider
* used to divide down the clock used to decrement the
* timers counter. This can be set using one of the
* PRESCALER_DIV_<n> definitions, where <n> is the
* dividers value.
* @param load_value This parameter is used to set the timers load value
* from which the CoreTimer counter will decrement.
* In Continuous mode, this value will be used to reload
* the timers counter whenever it reaches zero.
*/
void
TMR_init
(
timer_instance_t * this_timer,
addr_t address,
uint8_t mode,
uint32_t prescale,
uint32_t load_value
);
/***************************************************************************//**
* The function TMR_start() enables the timer to start counting down.
* This function only needs to be called once after the timer has been
* initialized through a call to TMR_init(). It does not need to be called after
* each call to TMR_reload() when the timer is used in one-shot mode.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*/
void
TMR_start
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The function TMR_stop() stops the timer counting down. It can be used to
* stop interrupts from being generated when continuous mode is used and
* interrupts must be paused from being generated.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*/
void
TMR_stop
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The function TMR_enable_int() enables the timer interrupt. A call to this
* function will allow the interrupt signal coming out of CoreTimer to be
* asserted.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*/
void
TMR_enable_int
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The function TMR_clear_int() clears the timer interrupt. This function should
* be called within the interrupt handler servicing interrupts from the timer.
* Failure to clear the timer interrupt will result in the interrupt signal
* generating from CoreTimer to remain asserted. This assertion may cause the
* interrupt service routine to be continuously called, causing the system to
* lock up.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*/
void
TMR_clear_int
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The TMR_current_value() function returns the current value of the counter.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
*
* @return Returns the current value of the timer counter value.
*/
uint32_t
TMR_current_value
(
timer_instance_t * this_timer
);
/***************************************************************************//**
* The TMR_reload() function is used in one-shot mode. It reloads the timer
* counter with the values passed as parameter. This will result in an interrupt
* being generated when the timer counter reaches 0 if interrupt is enabled.
*
* @param this_timer Pointer to a timer_instance_t structure holding all
* relevant data associated with the target timer hardware
* instance. This pointer is used to identify the target
* CoreTimer hardware instance.
* @param load_value This parameter sets the value from which the CoreTimer
* counter will decrement.
*/
void TMR_reload
(
timer_instance_t * this_timer,
uint32_t load_value
);
#endif /* CORE_TIMER_H_ */

View file

@ -0,0 +1,109 @@
/*******************************************************************************
* (c) Copyright 2007-2015 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 7967 $
* SVN $Date: 2015-10-09 18:48:26 +0530 (Fri, 09 Oct 2015) $
*/
#ifndef __CORE_TIMER_REGISTERS
#define __CORE_TIMER_REGISTERS 1
/*------------------------------------------------------------------------------
* TimerLoad register details
*/
#define TimerLoad_REG_OFFSET 0x00
/*
* LoadValue bits.
*/
#define LoadValue_OFFSET 0x00
#define LoadValue_MASK 0xFFFFFFFF
#define LoadValue_SHIFT 0
/*------------------------------------------------------------------------------
* TimerValue register details
*/
#define TimerValue_REG_OFFSET 0x04
/*
* CurrentValue bits.
*/
#define CurrentValue_OFFSET 0x04
#define CurrentValue_MASK 0xFFFFFFFF
#define CurrentValue_SHIFT 0
/*------------------------------------------------------------------------------
* TimerControl register details
*/
#define TimerControl_REG_OFFSET 0x08
/*
* TimerEnable bits.
*/
#define TimerEnable_OFFSET 0x08
#define TimerEnable_MASK 0x00000001
#define TimerEnable_SHIFT 0
/*
* InterruptEnable bits.
*/
#define InterruptEnable_OFFSET 0x08
#define InterruptEnable_MASK 0x00000002
#define InterruptEnable_SHIFT 1
/*
* TimerMode bits.
*/
#define TimerMode_OFFSET 0x08
#define TimerMode_MASK 0x00000004
#define TimerMode_SHIFT 2
/*------------------------------------------------------------------------------
* TimerPrescale register details
*/
#define TimerPrescale_REG_OFFSET 0x0C
/*
* Prescale bits.
*/
#define Prescale_OFFSET 0x0C
#define Prescale_MASK 0x0000000F
#define Prescale_SHIFT 0
/*------------------------------------------------------------------------------
* TimerIntClr register details
*/
#define TimerIntClr_REG_OFFSET 0x10
/*
* TimerIntClr bits.
*/
#define TimerIntClr_OFFSET 0x10
#define TimerIntClr_MASK 0xFFFFFFFF
#define TimerIntClr_SHIFT 0
/*------------------------------------------------------------------------------
* TimerRIS register details
*/
#define TimerRIS_REG_OFFSET 0x14
/*
* RawTimerInterrupt bits.
*/
#define RawTimerInterrupt_OFFSET 0x14
#define RawTimerInterrupt_MASK 0x00000001
#define RawTimerInterrupt_SHIFT 0
/*------------------------------------------------------------------------------
* TimerMIS register details
*/
#define TimerMIS_REG_OFFSET 0x18
/*
* TimerInterrupt bits.
*/
#define TimerInterrupt_OFFSET 0x18
#define TimerInterrupt_MASK 0x00000001
#define TimerInterrupt_SHIFT 0
#endif /* __CORE_TIMER_REGISTERS */

View file

@ -0,0 +1,296 @@
/*******************************************************************************
* (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.
*
* CoreUARTapb driver implementation. See file "core_uart_apb.h" for a
* description of the functions implemented in this file.
*
* SVN $Revision: 9082 $
* SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $
*/
#include "hal.h"
#include "coreuartapb_regs.h"
#include "core_uart_apb.h"
#include "hal_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
#define NULL_INSTANCE ( ( UART_instance_t* ) 0 )
#define NULL_BUFFER ( ( uint8_t* ) 0 )
#define MAX_LINE_CONFIG ( ( uint8_t )( DATA_8_BITS | ODD_PARITY ) )
#define MAX_BAUD_VALUE ( ( uint16_t )( 0x1FFF ) )
#define STATUS_ERROR_MASK ( ( uint8_t )( STATUS_PARITYERR_MASK | \
STATUS_OVERFLOW_MASK | \
STATUS_FRAMERR_MASK ) )
#define BAUDVALUE_LSB ( (uint16_t) (0x00FF) )
#define BAUDVALUE_MSB ( (uint16_t) (0xFF00) )
#define BAUDVALUE_SHIFT ( (uint8_t) (5) )
#define STATUS_ERROR_OFFSET STATUS_PARITYERR_SHIFT
/***************************************************************************//**
* UART_init()
* See "core_uart_apb.h" for details of how to use this function.
*/
void
UART_init
(
UART_instance_t * this_uart,
addr_t base_addr,
uint16_t baud_value,
uint8_t line_config
)
{
uint8_t rx_full;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( line_config <= MAX_LINE_CONFIG )
HAL_ASSERT( baud_value <= MAX_BAUD_VALUE )
if( ( this_uart != NULL_INSTANCE ) &&
( line_config <= MAX_LINE_CONFIG ) &&
( baud_value <= MAX_BAUD_VALUE ) )
{
/*
* Store lower 8-bits of baud value in CTRL1.
*/
HAL_set_8bit_reg( base_addr, CTRL1, (uint_fast8_t)(baud_value &
BAUDVALUE_LSB ) );
/*
* Extract higher 5-bits of baud value and store in higher 5-bits
* of CTRL2, along with line configuration in lower 3 three bits.
*/
HAL_set_8bit_reg( base_addr, CTRL2, (uint_fast8_t)line_config |
(uint_fast8_t)((baud_value &
BAUDVALUE_MSB) >> BAUDVALUE_SHIFT ) );
this_uart->base_address = base_addr;
#ifndef NDEBUG
{
uint8_t config;
uint8_t temp;
uint16_t baud_val;
baud_val = HAL_get_8bit_reg( this_uart->base_address, CTRL1 );
config = HAL_get_8bit_reg( this_uart->base_address, CTRL2 );
/*
* To resolve operator precedence between & and <<
*/
temp = ( config & (uint8_t)(CTRL2_BAUDVALUE_MASK ) );
baud_val |= (uint16_t)( (uint16_t)(temp) << BAUDVALUE_SHIFT );
config &= (uint8_t)(~CTRL2_BAUDVALUE_MASK);
HAL_ASSERT( baud_val == baud_value );
HAL_ASSERT( config == line_config );
}
#endif
/*
* Flush the receive FIFO of data that may have been received before the
* driver was initialized.
*/
rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_RXFULL_MASK;
while ( rx_full )
{
HAL_get_8bit_reg( this_uart->base_address, RXDATA );
rx_full = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_RXFULL_MASK;
}
/*
* Clear status of the UART instance.
*/
this_uart->status = (uint8_t)0;
}
}
/***************************************************************************//**
* UART_send()
* See "core_uart_apb.h" for details of how to use this function.
*/
void
UART_send
(
UART_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
)
{
size_t char_idx;
uint8_t tx_ready;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( tx_buffer != NULL_BUFFER )
HAL_ASSERT( tx_size > 0 )
if( (this_uart != NULL_INSTANCE) &&
(tx_buffer != NULL_BUFFER) &&
(tx_size > (size_t)0) )
{
for ( char_idx = (size_t)0; char_idx < tx_size; char_idx++ )
{
/* Wait for UART to become ready to transmit. */
do {
tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_TXRDY_MASK;
} while ( !tx_ready );
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, TXDATA,
(uint_fast8_t)tx_buffer[char_idx] );
}
}
}
/***************************************************************************//**
* UART_fill_tx_fifo()
* See "core_uart_apb.h" for details of how to use this function.
*/
size_t
UART_fill_tx_fifo
(
UART_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
)
{
uint8_t tx_ready;
size_t size_sent = 0u;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( tx_buffer != NULL_BUFFER )
HAL_ASSERT( tx_size > 0 )
/* Fill the UART's Tx FIFO until the FIFO is full or the complete input
* buffer has been written. */
if( (this_uart != NULL_INSTANCE) &&
(tx_buffer != NULL_BUFFER) &&
(tx_size > 0u) )
{
tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_TXRDY_MASK;
if ( tx_ready )
{
do {
HAL_set_8bit_reg( this_uart->base_address, TXDATA,
(uint_fast8_t)tx_buffer[size_sent] );
size_sent++;
tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_TXRDY_MASK;
} while ( (tx_ready) && ( size_sent < tx_size ) );
}
}
return size_sent;
}
/***************************************************************************//**
* UART_get_rx()
* See "core_uart_apb.h" for details of how to use this function.
*/
size_t
UART_get_rx
(
UART_instance_t * this_uart,
uint8_t * rx_buffer,
size_t buff_size
)
{
uint8_t new_status;
uint8_t rx_full;
size_t rx_idx = 0u;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( rx_buffer != NULL_BUFFER )
HAL_ASSERT( buff_size > 0 )
if( (this_uart != NULL_INSTANCE) &&
(rx_buffer != NULL_BUFFER) &&
(buff_size > 0u) )
{
rx_idx = 0u;
new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );
this_uart->status |= new_status;
rx_full = new_status & STATUS_RXFULL_MASK;
while ( ( rx_full ) && ( rx_idx < buff_size ) )
{
rx_buffer[rx_idx] = HAL_get_8bit_reg( this_uart->base_address,
RXDATA );
rx_idx++;
new_status = HAL_get_8bit_reg( this_uart->base_address, STATUS );
this_uart->status |= new_status;
rx_full = new_status & STATUS_RXFULL_MASK;
}
}
return rx_idx;
}
/***************************************************************************//**
* UART_polled_tx_string()
* See "core_uart_apb.h" for details of how to use this function.
*/
void
UART_polled_tx_string
(
UART_instance_t * this_uart,
const uint8_t * p_sz_string
)
{
uint32_t char_idx;
uint8_t tx_ready;
HAL_ASSERT( this_uart != NULL_INSTANCE )
HAL_ASSERT( p_sz_string != NULL_BUFFER )
if( ( this_uart != NULL_INSTANCE ) && ( p_sz_string != NULL_BUFFER ) )
{
char_idx = 0U;
while( 0U != p_sz_string[char_idx] )
{
/* Wait for UART to become ready to transmit. */
do {
tx_ready = HAL_get_8bit_reg( this_uart->base_address, STATUS ) &
STATUS_TXRDY_MASK;
} while ( !tx_ready );
/* Send next character in the buffer. */
HAL_set_8bit_reg( this_uart->base_address, TXDATA,
(uint_fast8_t)p_sz_string[char_idx] );
char_idx++;
}
}
}
/***************************************************************************//**
* UART_get_rx_status()
* See "core_uart_apb.h" for details of how to use this function.
*/
uint8_t
UART_get_rx_status
(
UART_instance_t * this_uart
)
{
uint8_t status = UART_APB_INVALID_PARAM;
HAL_ASSERT( this_uart != NULL_INSTANCE )
/*
* Extract UART error status and place in lower bits of "status".
* Bit 0 - Parity error status
* Bit 1 - Overflow error status
* Bit 2 - Frame error status
*/
if( this_uart != NULL_INSTANCE )
{
status = ( ( this_uart->status & STATUS_ERROR_MASK ) >>
STATUS_ERROR_OFFSET );
/*
* Clear the sticky status for this instance.
*/
this_uart->status = (uint8_t)0;
}
return status;
}
#ifdef __cplusplus
}
#endif

View file

@ -0,0 +1,407 @@
/*******************************************************************************
* (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.
*
* This file contains the application programming interface for the CoreUARTapb
* bare metal driver.
*
* SVN $Revision: 9082 $
* SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $
*/
/*=========================================================================*//**
@mainpage CoreUARTapb Bare Metal Driver.
@section intro_sec Introduction
CoreUARTapb is an implementation of the Universal Asynchronous
Receiver/Transmitter aimed at a minimal FPGA tile usage within an Microsemi
FPGA. The CoreUARTapb bare metal software driver is designed for use in
systems with no operating system.
The CoreUARTapb driver provides functions for basic polled transmitting and
receiving operations. It also provides functions allowing use of the
CoreUARTapb in interrupt-driven mode, but leaves the management of interrupts
to the calling application, as interrupt enabling and disabling cannot be
controlled through the CoreUARTapb registers. The CoreUARTapb driver is
provided as C source code.
@section driver_configuration Driver Configuration
Your application software should configure the CoreUARTapb driver, through
calls to the UART_init() function for each CoreUARTapb instance in the
hardware design. The configuration parameters include the CoreUARTapb
hardware instance base address and other runtime parameters, such as baud
rate, bit width, and parity. No CoreUARTapb hardware configuration parameters
are needed by the driver, apart from the CoreUARTapb hardware instance base
address. Hence, no additional configuration files are required to use the driver.
A CoreUARTapb hardware instance can be generated with fixed baud value,
character size and parity configuration settings as part of the hardware flow.
The baud_value and line_config parameter values passed to the UART_init()
function will not have any effect if fixed values were selected for the
baud value, character size and parity in the hardware configuration of
CoreUARTapb. When fixed values are selected for these hardware configuration
parameters, the driver cannot overwrite the fixed values in the CoreUARTapb
control registers, CTRL1 and CTRL2.
@section theory_op Theory of Operation
The CoreUARTapb software driver is designed to allow the control of multiple
instances of CoreUARTapb. Each instance of CoreUARTapb in the hardware design
is associated with a single instance of the UART_instance_t structure in the
software. You need to allocate memory for one unique UART_instance_t
structure instance for each CoreUARTapb hardware instance. The contents of
these data structures are initialized during calls to function UART_init().
A pointer to the structure is passed to subsequent driver functions in order
to identify the CoreUARTapb hardware instance you wish to perform the
requested operation on.
Note: Do not attempt to directly manipulate the content of UART_instance_t
structures. This structure is only intended to be modified by the driver
function.
The driver can be used to transmit and receive data once initialized.
Transmit can be performed using the UART_send() function. This function
is blocking, meaning that it will only return once the data passed to
the function has been sent to the CoreUARTapb hardware. Data received
by the CoreUARTapb hardware can be read by the user application using
the UART_get_rx() function.
The function UART_fill_tx_fifo() is also provided to be used as part of
interrupt-driven transmit. This function fills the CoreUARTapb hardware
transmit FIFO with the content of a data buffer passed as a parameter before
returning. The control of the interrupts must be implemented outside the
driver as the CoreUARTapb hardware does not provide the ability to enable
or disable its interrupt sources.
The function UART_polled_tx_string() is provided to transmit a NULL
terminated string in polled mode. This function is blocking, meaning that it
will only return once the data passed to the function has been sent to the
CoreUARTapb hardware.
The function UART_get_rx_status() returns the error status of the CoreUARTapb
receiver. This can be used by applications to take appropriate action in case
of receiver errors.
*//*=========================================================================*/
#ifndef __CORE_UART_APB_H
#define __CORE_UART_APB_H 1
#include "cpu_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/***************************************************************************//**
* Data bits length defines:
*/
#define DATA_7_BITS 0x00u
#define DATA_8_BITS 0x01u
/***************************************************************************//**
* Parity defines:
*/
#define NO_PARITY 0x00u
#define EVEN_PARITY 0x02u
#define ODD_PARITY 0x06u
/***************************************************************************//**
* Error Status definitions:
*/
#define UART_APB_PARITY_ERROR 0x01u
#define UART_APB_OVERFLOW_ERROR 0x02u
#define UART_APB_FRAMING_ERROR 0x04u
#define UART_APB_NO_ERROR 0x00u
#define UART_APB_INVALID_PARAM 0xFFu
/***************************************************************************//**
* UART_instance_t
*
* There should be one instance of this structure for each instance of CoreUARTapb
* in your system. This structure instance is used to identify the various UARTs
* in a system and should be passed as first parameter to UART functions to
* identify which UART should perform the requested operation. The 'status'
* element in the structure is used to provide sticky status information.
*/
typedef struct
{
addr_t base_address;
uint8_t status;
} UART_instance_t;
/***************************************************************************//**
* The function UART_init() initializes the UART with the configuration passed
* as parameters. The configuration parameters are the baud_value used to
* generate the baud rate and the line configuration (bit length and parity).
*
* @param this_uart The this_uart parameter is a pointer to a UART_instance_t
* structure which holds all data regarding this instance of
* the CoreUARTapb. This pointer will be used to identify
* the target CoreUARTapb hardware instance in subsequent
* calls to the CoreUARTapb functions.
* @param base_addr The base_address parameter is the base address in the
* processor's memory map for the registers of the
* CoreUARTapb instance being initialized.
* @param baud_value The baud_value parameter is used to select the baud rate
* for the UART. The baud value is calculated from the
* frequency of the system clock in hertz and the desired
* baud rate using the following equation:
*
* baud_value = (clock /(baud_rate * 16)) - 1.
*
* The baud_value parameter must be a value in the range 0
* to 8191 (or 0x0000 to 0x1FFF).
* @param line_config This parameter is the line configuration specifying the
* bit length and parity settings. This is a logical OR of:
* - DATA_7_BITS
* - DATA_8_BITS
* - NO_PARITY
* - EVEN_PARITY
* - ODD_PARITY
* For example, 8 bits even parity would be specified as
* (DATA_8_BITS | EVEN_PARITY).
* @return This function does not return a value.
* Example:
* @code
* #define BAUD_VALUE_57600 25
*
* #define COREUARTAPB0_BASE_ADDR 0xC3000000UL
*
* UART_instance_t g_uart;
* int main()
* {
* UART_init(&g_uart, COREUARTAPB0_BASE_ADDR,
BAUD_VALUE_57600, (DATA_8_BITS | EVEN_PARITY));
* }
* @endcode
*/
void
UART_init
(
UART_instance_t * this_uart,
addr_t base_addr,
uint16_t baud_value,
uint8_t line_config
);
/***************************************************************************//**
* The function UART_send() is used to transmit data. It transfers the contents
* of the transmitter data buffer, passed as a function parameter, into the
* UART's hardware transmitter FIFO. It returns when the full content of the
* transmitter data buffer has been transferred to the UART's transmitter FIFO.
*
* Note: you cannot assume that the data you are sending using this function has
* been received at the other end by the time this function returns. The actual
* transmit over the serial connection will still be taking place at the time of
* the function return. It is safe to release or reuse the memory used as the
* transmit buffer once this function returns.
*
* @param this_uart The this_uart parameter is a pointer to a
* UART_instance_t structure which holds all data regarding
* this instance of the CoreUARTapbUART.
* @param tx_buffer The tx_buffer parameter is a pointer to a buffer
* containing the data to be transmitted.
* @param tx_size The tx_size parameter is the size, in bytes, of
* the data to be transmitted.
*
* @return This function does not return a value.
*
* Example:
* @code
* uint8_t testmsg1[] = {"\n\r\n\r\n\rUART_send() test message 1"};
* UART_send(&g_uart,(const uint8_t *)&testmsg1,sizeof(testmsg1));
* @endcode
*/
void
UART_send
(
UART_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
);
/***************************************************************************//**
* The function UART_fill_tx_fifo() fills the UART's transmitter hardware FIFO
* with the data found in the transmitter buffer that is passed in as a
* function parameter. The function returns either when the FIFO is full or
* when the complete contents of the transmitter buffer have been copied into
* the FIFO. It returns the number of bytes copied into the UART's transmitter
* hardware FIFO. This function is intended to be used as part of
* interrupt-driven transmission.
*
* Note: You cannot assume that the data you transmit using this function has
* been received at the other end by the time this function returns.
* The actual transmission over the serial connection will still be
* taking place at the time of the function return.
*
* @param this_uart The this_uart parameter is a pointer to a UART_instance_t
* structure which holds all data regarding this instance of
* the UART.
* @param tx_buffer The tx_buffer parameter is a pointer to a buffer
* containing the data to be transmitted.
* @param tx_size The tx_size parameter is the size in bytes, of the data
* to be transmitted.
* @return This function returns the number of bytes copied
* into the UART's transmitter hardware FIFO.
*
* Example:
* @code
* void send_using_interrupt
* (
* uint8_t * pbuff,
* size_t tx_size
* )
* {
* size_t size_in_fifo;
* size_in_fifo = UART_fill_tx_fifo( &g_uart, pbuff, tx_size );
* }
* @endcode
*/
size_t
UART_fill_tx_fifo
(
UART_instance_t * this_uart,
const uint8_t * tx_buffer,
size_t tx_size
);
/***************************************************************************//**
* The function UART_get_rx() reads the content of the UART's receiver hardware
* FIFO and stores it in the receiver buffer that is passed in as a function
* parameter. It copies either the full contents of the FIFO into the receiver
* buffer, or just enough data from the FIFO to fill the receiver buffer,
* dependent upon the size of the receiver buffer. The size of the receiver
* buffer is passed in as a function parameter. UART_get_rx() returns the number
* of bytes copied into the receiver buffer. If no data was received at the time
* the function is called, the function returns 0.
*
* Note: This function reads and accumulates the receiver status of the
* CoreUARTapb instance before reading each byte from the receiver's
* data register/FIFO. This allows the driver to maintain a sticky
* record of any receiver errors that occur as the UART receives each
* data byte; receiver errors would otherwise be lost after each read
* from the receiver's data register. A call to the UART_get_rx_status()
* function returns any receiver errors accumulated during the execution
* of the UART_get_rx() function.
* Note: When FIFO mode is disabled in the CoreUARTapb hardware configuration,
* the driver accumulates a sticky record of any parity errors, framing
* errors or overflow errors. When FIFO mode is enabled, the driver
* accumulates a sticky record of overflow errors only; in this case
* interrupts must be used to handle parity errors or framing errors.
*
* @param this_uart The this_uart parameter is a pointer to a UART_instance_t
* structure which holds all data regarding this instance of
* the UART.
* @param rx_buffer The rx_buffer parameter is a pointer to a buffer where the
* received data will be copied.
* @param buff_size The buff_size parameter is the size of the receive buffer
* in bytes.
* @return This function returns the number of bytes copied into the
* receive buffer.
*
* Example:
* @code
* #define MAX_RX_DATA_SIZE 256
*
* uint8_t rx_data[MAX_RX_DATA_SIZE];
* uint8_t rx_size = 0;
*
* rx_size = UART_get_rx( &g_uart, rx_data, sizeof(rx_data) );
* @endcode
*/
size_t
UART_get_rx
(
UART_instance_t * this_uart,
uint8_t * rx_buffer,
size_t buff_size
);
/***************************************************************************//**
* The function UART_polled_tx_string() is used to transmit a NULL ('\0')
* terminated string. Internally, it polls for the transmit ready status and
* transfers the text starting at the address pointed to by p_sz_string into
* the UART's hardware transmitter FIFO. It is a blocking function and returns
* only when the complete string has been transferred to the UART's transmit
* FIFO.
*
* Note: You cannot assume that the data you transmit using this function
* has been received at the other end by the time this function
* returns. The actual transmission over the serial connection will
* still be taking place at the time of the function return.
*
* @param this_uart The this_uart parameter is a pointer to a
* UART_instance_t structure which holds
* all data regarding this instance of the UART.
* @param p_sz_string The p_sz_string parameter is a pointer to a buffer
* containing the NULL ('\0') terminated string to be
* transmitted.
* @return This function does not return a value.
*
* Example:
* @code
* uint8_t testmsg1[] = {"\r\n\r\nUART_polled_tx_string() test message 1\0"};
* UART_polled_tx_string(&g_uart,(const uint8_t *)&testmsg1);
* @endcode
*/
void
UART_polled_tx_string
(
UART_instance_t * this_uart,
const uint8_t * p_sz_string
);
/***************************************************************************//**
* The UART_get_rx_status() function returns the receiver error status of the
* CoreUARTapb instance. It reads both the current error status of the receiver
* and the accumulated error status from preceding calls to the UART_get_rx()
* function and combines them using a bitwise OR. It returns the cumulative
* parity, framing and overflow error status of the receiver, since the
* previous call to UART_get_rx_status(), as an 8-bit encoded value.
*
* Note: The UART_get_rx() function reads and accumulates the receiver status
* of the CoreUARTapb instance before reading each byte from the
* receiver's data register/FIFO. The driver maintains a sticky record
* of the cumulative error status, which persists after the
* UART_get_rx() function returns. The UART_get_rx_status() function
* clears this accumulated record of receiver errors before returning.
*
* @param this_uart The this_uart parameter is a pointer to a UART_instance_t
* structure which holds all data regarding this instance
* of the UART.
* @return This function returns the UART receiver error status as
* an 8-bit encoded value. The returned value is 0 if no
* receiver errors occurred. The driver provides a set of
* bit mask constants which should be compared with and/or
* used to mask the returned value to determine the
* receiver error status.
* When the return value is compared to the following bit
* masks, a non-zero result indicates that the
* corresponding error occurred:
* UART_APB_PARITY_ERROR (bit mask = 0x01)
* UART_APB_OVERFLOW_ERROR (bit mask = 0x02)
* UART_APB_FRAMING_ERROR (bit mask = 0x04)
* When the return value is compared to the following bit
* mask, a non-zero result indicates that no error occurred:
* UART_APB_NO_ERROR (0x00)
*
* Example:
* @code
* UART_instance_t g_uart;
* uint8_t rx_data[MAX_RX_DATA_SIZE];
* uint8_t err_status;
* err_status = UART_get_err_status(&g_uart);
*
* if(UART_APB_NO_ERROR == err_status )
* {
* rx_size = UART_get_rx( &g_uart, rx_data, MAX_RX_DATA_SIZE );
* }
* @endcode
*/
uint8_t
UART_get_rx_status
(
UART_instance_t * this_uart
);
#ifdef __cplusplus
}
#endif
#endif /* __CORE_UART_APB_H */

View file

@ -0,0 +1,130 @@
/*******************************************************************************
* (c) Copyright 2007-2017 Microsemi SoC Products Group. All rights reserved.
*
* SVN $Revision: 9082 $
* SVN $Date: 2017-04-28 11:51:36 +0530 (Fri, 28 Apr 2017) $
*/
#ifndef __CORE_UART_APB_REGISTERS
#define __CORE_UART_APB_REGISTERS 1
#ifdef __cplusplus
extern "C" {
#endif
/*------------------------------------------------------------------------------
* TxData register details
*/
#define TXDATA_REG_OFFSET 0x0u
/*
* TxData bits.
*/
#define TXDATA_OFFSET 0x0u
#define TXDATA_MASK 0xFFu
#define TXDATA_SHIFT 0u
/*------------------------------------------------------------------------------
* RxData register details
*/
#define RXDATA_REG_OFFSET 0x4u
/*
* RxData bits.
*/
#define RXDATA_OFFSET 0x4u
#define RXDATA_MASK 0xFFu
#define RXDATA_SHIFT 0u
/*------------------------------------------------------------------------------
* ControReg1 register details
*/
#define CTRL1_REG_OFFSET 0x8u
/*
* Baud value (Lower 8-bits)
*/
#define CTRL1_BAUDVALUE_OFFSET 0x8u
#define CTRL1_BAUDVALUE_MASK 0xFFu
#define CTRL1_BAUDVALUE_SHIFT 0u
/*------------------------------------------------------------------------------
* ControReg2 register details
*/
#define CTRL2_REG_OFFSET 0xCu
/*
* Bit length
*/
#define CTRL2_BIT_LENGTH_OFFSET 0xCu
#define CTRL2_BIT_LENGTH_MASK 0x01u
#define CTRL2_BIT_LENGTH_SHIFT 0u
/*
* Parity enable.
*/
#define CTRL2_PARITY_EN_OFFSET 0xCu
#define CTRL2_PARITY_EN_MASK 0x02u
#define CTRL2_PARITY_EN_SHIFT 1u
/*
* Odd/even parity selection.
*/
#define CTRL2_ODD_EVEN_OFFSET 0xCu
#define CTRL2_ODD_EVEN_MASK 0x04u
#define CTRL2_ODD_EVEN_SHIFT 2u
/*
* Baud value (Higher 5-bits)
*/
#define CTRL2_BAUDVALUE_OFFSET 0xCu
#define CTRL2_BAUDVALUE_MASK 0xF8u
#define CTRL2_BAUDVALUE_SHIFT 3u
/*------------------------------------------------------------------------------
* StatusReg register details
*/
#define StatusReg_REG_OFFSET 0x10u
#define STATUS_REG_OFFSET 0x10u
/*
* Transmit ready.
*/
#define STATUS_TXRDY_OFFSET 0x10u
#define STATUS_TXRDY_MASK 0x01u
#define STATUS_TXRDY_SHIFT 0u
/*
* Receive full.
*/
#define STATUS_RXFULL_OFFSET 0x10u
#define STATUS_RXFULL_MASK 0x02u
#define STATUS_RXFULL_SHIFT 1u
/*
* Parity error.
*/
#define STATUS_PARITYERR_OFFSET 0x10u
#define STATUS_PARITYERR_MASK 0x04u
#define STATUS_PARITYERR_SHIFT 2u
/*
* Overflow.
*/
#define STATUS_OVERFLOW_OFFSET 0x10u
#define STATUS_OVERFLOW_MASK 0x08u
#define STATUS_OVERFLOW_SHIFT 3u
/*
* Frame Error.
*/
#define STATUS_FRAMERR_OFFSET 0x10u
#define STATUS_FRAMERR_MASK 0x10u
#define STATUS_FRAMERR_SHIFT 4u
#ifdef __cplusplus
}
#endif
#endif /* __CORE_UART_APB_REGISTERS */