[sw] update SPI HAL

This commit is contained in:
stnolting 2023-03-04 11:57:08 +01:00
parent 6f7fb6fea5
commit 3ffc84cb76
4 changed files with 96 additions and 90 deletions

View file

@ -1067,32 +1067,34 @@ typedef volatile struct __attribute__((packed,aligned(4))) {
/** SPI control register bits */
enum NEORV32_SPI_CTRL_enum {
SPI_CTRL_EN = 0, /**< SPI control register(0) (r/w): SPI unit enable */
SPI_CTRL_CPHA = 1, /**< SPI control register(1) (r/w): Clock phase */
SPI_CTRL_CPOL = 2, /**< SPI control register(2) (r/w): Clock polarity */
SPI_CTRL_SIZE0 = 3, /**< SPI control register(3) (r/w): Transfer data size lsb (00: 8-bit, 01: 16-bit, 10: 24-bit, 11: 32-bit) */
SPI_CTRL_SIZE1 = 4, /**< SPI control register(4) (r/w): Transfer data size msb (00: 8-bit, 01: 16-bit, 10: 24-bit, 11: 32-bit) */
SPI_CTRL_CS_SEL0 = 5, /**< SPI control register(5) (r/w): Direct chip select bit 1 */
SPI_CTRL_CS_SEL1 = 6, /**< SPI control register(6) (r/w): Direct chip select bit 2 */
SPI_CTRL_CS_SEL2 = 7, /**< SPI control register(7) (r/w): Direct chip select bit 2 */
SPI_CTRL_CS_EN = 8, /**< SPI control register(8) (r/w): Chip select enable (selected CS line output is low when set) */
SPI_CTRL_PRSC0 = 9, /**< SPI control register(9) (r/w): Clock prescaler select bit 0 */
SPI_CTRL_PRSC1 = 10, /**< SPI control register(10) (r/w): Clock prescaler select bit 1 */
SPI_CTRL_PRSC2 = 11, /**< SPI control register(11) (r/w): Clock prescaler select bit 2 */
SPI_CTRL_CDIV0 = 12, /**< SPI control register(12) (r/w): Clock divider bit 0 */
SPI_CTRL_CDIV1 = 13, /**< SPI control register(13) (r/w): Clock divider bit 1 */
SPI_CTRL_CDIV2 = 14, /**< SPI control register(14) (r/w): Clock divider bit 2 */
SPI_CTRL_CDIV3 = 15, /**< SPI control register(15) (r/w): Clock divider bit 3 */
SPI_CTRL_IRQ0 = 16, /**< SPI control register(16) (r/w): Interrupt configuration lsb (0-: PHY going idle) */
SPI_CTRL_IRQ1 = 17, /**< SPI control register(17) (r/w): Interrupt configuration lsb (10: TX fifo less than half full, 11: TX fifo empty) */
SPI_CTRL_EN = 0, /**< SPI control register(0) (r/w): SPI unit enable */
SPI_CTRL_CPHA = 1, /**< SPI control register(1) (r/w): Clock phase */
SPI_CTRL_CPOL = 2, /**< SPI control register(2) (r/w): Clock polarity */
SPI_CTRL_CS_SEL0 = 3, /**< SPI control register(3) (r/w): Direct chip select bit 1 */
SPI_CTRL_CS_SEL1 = 4, /**< SPI control register(4) (r/w): Direct chip select bit 2 */
SPI_CTRL_CS_SEL2 = 5, /**< SPI control register(5) (r/w): Direct chip select bit 2 */
SPI_CTRL_CS_EN = 6, /**< SPI control register(6) (r/w): Chip select enable (selected CS line output is low when set) */
SPI_CTRL_PRSC0 = 7, /**< SPI control register(7) (r/w): Clock prescaler select bit 0 */
SPI_CTRL_PRSC1 = 8, /**< SPI control register(8) (r/w): Clock prescaler select bit 1 */
SPI_CTRL_PRSC2 = 9, /**< SPI control register(9) (r/w): Clock prescaler select bit 2 */
SPI_CTRL_CDIV0 = 10, /**< SPI control register(10) (r/w): Clock divider bit 0 */
SPI_CTRL_CDIV1 = 11, /**< SPI control register(11) (r/w): Clock divider bit 1 */
SPI_CTRL_CDIV2 = 12, /**< SPI control register(12) (r/w): Clock divider bit 2 */
SPI_CTRL_CDIV3 = 13, /**< SPI control register(13) (r/w): Clock divider bit 3 */
SPI_CTRL_FIFO_LSB = 23, /**< SPI control register(23) (r/-): log2(FIFO size), lsb */
SPI_CTRL_FIFO_MSB = 26, /**< SPI control register(26) (r/-): log2(FIFO size), msb */
SPI_CTRL_RX_AVAIL = 27, /**< SPI control register(27) (r/-): RX FIFO data available (RX FIFO not empty) */
SPI_CTRL_TX_EMPTY = 28, /**< SPI control register(28) (r/-): TX FIFO empty */
SPI_CTRL_TX_HALF = 29, /**< SPI control register(29) (r/-): TX FIFO at least half full */
SPI_CTRL_TX_FULL = 30, /**< SPI control register(30) (r/-): TX FIFO full */
SPI_CTRL_BUSY = 31 /**< SPI control register(31) (r/-): SPI busy flag */
SPI_CTRL_RX_AVAIL = 15, /**< SPI control register(15) (r/-): RX FIFO data available (RX FIFO not empty) */
SPI_CTRL_TX_EMPTY = 16, /**< SPI control register(16) (r/-): TX FIFO empty */
SPI_CTRL_TX_NHALF = 17, /**< SPI control register(17) (r/-): TX FIFO not at least half full */
SPI_CTRL_TX_FULL = 18, /**< SPI control register(18) (r/-): TX FIFO full */
SPI_CTRL_IRQ_RX_AVAIL = 19, /**< SPI control register(19) (r/w): Fire IRQ if RX FIFO data available (RX FIFO not empty) */
SPI_CTRL_IRQ_TX_EMPTY = 20, /**< SPI control register(20) (r/w): Fire IRQ if TX FIFO empty */
SPI_CTRL_IRQ_TX_HALF = 21, /**< SPI control register(21) (r/w): Fire IRQ if TX FIFO not at least half full */
SPI_CTRL_FIFO_LSB = 23, /**< SPI control register(23) (r/-): log2(FIFO size), lsb */
SPI_CTRL_FIFO_MSB = 26, /**< SPI control register(26) (r/-): log2(FIFO size), msb */
SPI_CTRL_BUSY = 31 /**< SPI control register(31) (r/-): SPI busy flag */
};
/**@}*/

View file

@ -3,7 +3,7 @@
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2023, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
@ -44,16 +44,16 @@
#define neorv32_spi_h
// prototypes
int neorv32_spi_available(void);
void neorv32_spi_setup(int prsc, int cdiv, int clk_phase, int clk_polarity, int data_size, int irq_config);
void neorv32_spi_disable(void);
void neorv32_spi_enable(void);
int neorv32_spi_get_fifo_depth(void);
void neorv32_spi_cs_en(int cs);
void neorv32_spi_cs_dis(void);
uint32_t neorv32_spi_trans(uint32_t tx_data);
void neorv32_spi_put_nonblocking(uint32_t tx_data);
uint32_t neorv32_spi_get_nonblocking(void);
int neorv32_spi_busy(void);
int neorv32_spi_available(void);
void neorv32_spi_setup(int prsc, int cdiv, int clk_phase, int clk_polarity, uint32_t irq_mask);
void neorv32_spi_disable(void);
void neorv32_spi_enable(void);
int neorv32_spi_get_fifo_depth(void);
void neorv32_spi_cs_en(int cs);
void neorv32_spi_cs_dis(void);
uint8_t neorv32_spi_trans(uint8_t tx_data);
void neorv32_spi_put_nonblocking(uint8_t tx_data);
uint8_t neorv32_spi_get_nonblocking(void);
int neorv32_spi_busy(void);
#endif // neorv32_spi_h

View file

@ -3,7 +3,7 @@
// # ********************************************************************************************* #
// # BSD 3-Clause License #
// # #
// # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
// # Copyright (c) 2023, Stephan Nolting. All rights reserved. #
// # #
// # Redistribution and use in source and binary forms, with or without modification, are #
// # permitted provided that the following conditions are met: #
@ -67,10 +67,9 @@ int neorv32_spi_available(void) {
* @prama[in] cdiv Clock divider (0..15).
* @param[in] clk_phase Clock phase (0=sample on rising edge, 1=sample on falling edge).
* @param[in] clk_polarity Clock polarity (when idle).
* @param[in] data_size Data transfer size (0: 8-bit, 1: 16-bit, 2: 24-bit, 3: 32-bit).
* @param[in] irq_config Interrupt configuration (0,1: PHY transfer done, 2: TX FIFO becomes less than half full, 3: TX FIFO becomes empty).
* @param[in] irq_mask Interrupt configuration mask (CTRL's irq_* bits).
**************************************************************************/
void neorv32_spi_setup(int prsc, int cdiv, int clk_phase, int clk_polarity, int data_size, int irq_config) {
void neorv32_spi_setup(int prsc, int cdiv, int clk_phase, int clk_polarity, uint32_t irq_mask) {
NEORV32_SPI->CTRL = 0; // reset
@ -78,10 +77,9 @@ void neorv32_spi_setup(int prsc, int cdiv, int clk_phase, int clk_polarity, int
tmp |= (uint32_t)(1 & 0x01) << SPI_CTRL_EN;
tmp |= (uint32_t)(clk_phase & 0x01) << SPI_CTRL_CPHA;
tmp |= (uint32_t)(clk_polarity & 0x01) << SPI_CTRL_CPOL;
tmp |= (uint32_t)(data_size & 0x03) << SPI_CTRL_SIZE0;
tmp |= (uint32_t)(prsc & 0x07) << SPI_CTRL_PRSC0;
tmp |= (uint32_t)(cdiv & 0x0f) << SPI_CTRL_CDIV0;
tmp |= (uint32_t)(irq_config & 0x03) << SPI_CTRL_IRQ0;
tmp |= (uint32_t)(irq_mask & (0x07 << SPI_CTRL_IRQ_RX_AVAIL));
NEORV32_SPI->CTRL = tmp;
}
@ -157,6 +155,7 @@ void neorv32_spi_cs_en(int cs) {
* @note The SPI chip select output lines are HIGH when deactivated.
**************************************************************************/
void neorv32_spi_cs_dis(void) {
NEORV32_SPI->CTRL &= ~(1 << SPI_CTRL_CS_EN);
}
@ -166,37 +165,37 @@ void neorv32_spi_cs_dis(void) {
*
* @note This function is blocking.
*
* @param tx_data Transmit data (8/16/24/32-bit, LSB-aligned).
* @return Receive data (8/16/24/32-bit, LSB-aligned).
* @param tx_data Transmit data (8-bit, LSB-aligned).
* @return Receive data (8-bit, LSB-aligned).
**************************************************************************/
uint32_t neorv32_spi_trans(uint32_t tx_data) {
uint8_t neorv32_spi_trans(uint8_t tx_data) {
NEORV32_SPI->DATA = tx_data; // trigger transfer
NEORV32_SPI->DATA = (uint32_t)tx_data; // trigger transfer
while((NEORV32_SPI->CTRL & (1<<SPI_CTRL_BUSY)) != 0); // wait for current transfer to finish
return NEORV32_SPI->DATA;
return (uint8_t)NEORV32_SPI->DATA;
}
/**********************************************************************//**
* Initiate SPI TX transfer (non-blocking).
*
* @param tx_data Transmit data (8/16/24/32-bit, LSB-aligned).
* @param tx_data Transmit data (8-bit, LSB-aligned).
**************************************************************************/
void neorv32_spi_put_nonblocking(uint32_t tx_data) {
void neorv32_spi_put_nonblocking(uint8_t tx_data) {
NEORV32_SPI->DATA = tx_data; // trigger transfer
NEORV32_SPI->DATA = (uint32_t)tx_data; // trigger transfer
}
/**********************************************************************//**
* Get SPI RX data (non-blocking).
*
* @return Receive data (8/16/24/32-bit, LSB-aligned).
* @return Receive data (8-bit, LSB-aligned).
**************************************************************************/
uint32_t neorv32_spi_get_nonblocking(void) {
uint8_t neorv32_spi_get_nonblocking(void) {
return NEORV32_SPI->DATA;
return (uint8_t)NEORV32_SPI->DATA;
}

View file

@ -825,35 +825,64 @@
<bitRange>[2:2]</bitRange>
<description>Clock polarity</description>
</field>
<field>
<name>SPI_CTRL_SIZE</name>
<bitRange>[4:3]</bitRange>
<description>Data transfer size</description>
</field>
<field>
<name>SPI_CTRL_CS_SEL</name>
<bitRange>[7:5]</bitRange>
<bitRange>[5:3]</bitRange>
<description>CS select</description>
</field>
<field>
<name>SPI_CTRL_CS_EN</name>
<bitRange>[8:8]</bitRange>
<bitRange>[6:6]</bitRange>
<description>Enable selected CS line</description>
</field>
<field>
<name>SPI_CTRL_PRSC</name>
<bitRange>[11:9]</bitRange>
<bitRange>[9:7]</bitRange>
<description>Clock prescaler select</description>
</field>
<field>
<name>SPI_CTRL_CDIV</name>
<bitRange>[15:12]</bitRange>
<bitRange>[13:10]</bitRange>
<description>SPI clock divider</description>
</field>
<field>
<name>SPI_CTRL_IRQ</name>
<bitRange>[17:16]</bitRange>
<description>Interrupt configuration</description>
<name>SPI_CTRL_RX_AVAIL</name>
<bitRange>[15:15]</bitRange>
<access>read-only</access>
<description>RX FIFO data available (RX FIFO not empty)</description>
</field>
<field>
<name>SPI_CTRL_TX_EMPTY</name>
<bitRange>[16:16]</bitRange>
<access>read-only</access>
<description>TX FIFO is empty</description>
</field>
<field>
<name>SPI_CTRL_TX_NHALF</name>
<bitRange>[17:17]</bitRange>
<access>read-only</access>
<description>TX FIFO not at least half full</description>
</field>
<field>
<name>SPI_CTRL_TX_FULL</name>
<bitRange>[18:18]</bitRange>
<access>read-only</access>
<description>TX FIFO is full</description>
</field>
<field>
<name>SPI_CTRL_IRQ_RX_AVAIL</name>
<bitRange>[19:19]</bitRange>
<description>Fire interrupt if RX FIFO is not empty</description>
</field>
<field>
<name>SPI_CTRL_IRQ_TX_EMPTY</name>
<bitRange>[20:20]</bitRange>
<description>Fire interrupt if TX FIFO is empty</description>
</field>
<field>
<name>SPI_CTRL_IRQ_TX_NHALF</name>
<bitRange>[21:21]</bitRange>
<description>Fire interrupt if TX FIFO is not at least half full</description>
</field>
<field>
<name>SPI_CTRL_FIFO</name>
@ -861,30 +890,6 @@
<access>read-only</access>
<description>log2(FIFO size)</description>
</field>
<field>
<name>SPI_CTRL_RX_AVAIL</name>
<bitRange>[27:27]</bitRange>
<access>read-only</access>
<description>RX FIFO data available (RX FIFO not empty)</description>
</field>
<field>
<name>SPI_CTRL_TX_EMPTY</name>
<bitRange>[28:28]</bitRange>
<access>read-only</access>
<description>TX FIFO is empty</description>
</field>
<field>
<name>SPI_CTRL_TX_HALF</name>
<bitRange>[29:29]</bitRange>
<access>read-only</access>
<description>TX FIFO is at least half full</description>
</field>
<field>
<name>SPI_CTRL_TX_FULL</name>
<bitRange>[30:30]</bitRange>
<access>read-only</access>
<description>TX FIFO is full</description>
</field>
<field>
<name>SPI_CTRL_BUSY</name>
<bitRange>[31:31]</bitRange>