parent
3903d9e7f4
commit
718e16a46d
|
@ -0,0 +1,126 @@
|
|||
// Generated register defines for spi
|
||||
|
||||
// Copyright information found in source file:
|
||||
// Copyright lowRISC contributors.
|
||||
|
||||
// Licensing information found in source file:
|
||||
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#ifndef _SPI_REG_DEFS_
|
||||
#define _SPI_REG_DEFS_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
// Register width
|
||||
#define SPI_PARAM_REG_WIDTH 32
|
||||
|
||||
#define SPI0_BASE_ADDR (0x07000000)
|
||||
#define SPI0_REG(offset) (*((volatile uint32_t *)(SPI0_BASE_ADDR + offset)))
|
||||
|
||||
#define SPI0_TX_FIFO_LEN (8)
|
||||
#define SPI0_RX_FIFO_LEN SPI0_TX_FIFO_LEN
|
||||
|
||||
typedef enum {
|
||||
SPI_ROLE_MODE_MASTER = 0,
|
||||
SPI_ROLE_MODE_SLAVE
|
||||
} spi_role_mode_e;
|
||||
|
||||
typedef enum {
|
||||
SPI_CPOL_0_CPHA_0 = 0,
|
||||
SPI_CPOL_0_CPHA_1,
|
||||
SPI_CPOL_1_CPHA_0,
|
||||
SPI_CPOL_1_CPHA_1
|
||||
} spi_cp_mode_e;
|
||||
|
||||
typedef enum {
|
||||
SPI_MODE_STANDARD = 0,
|
||||
SPI_MODE_DUAL,
|
||||
SPI_MODE_QUAD
|
||||
} spi_spi_mode_e;
|
||||
|
||||
void spi0_set_clk_div(uint16_t div);
|
||||
void spi0_set_role_mode(spi_role_mode_e mode);
|
||||
void spi0_set_spi_mode(spi_spi_mode_e mode);
|
||||
void spi0_set_cp_mode(spi_cp_mode_e mode);
|
||||
void spi0_set_enable(uint8_t en);
|
||||
void spi0_set_interrupt_enable(uint8_t en);
|
||||
void spi0_set_msb_first();
|
||||
void spi0_set_lsb_first();
|
||||
void spi0_set_txdata(uint8_t data);
|
||||
uint8_t spi0_get_rxdata();
|
||||
uint8_t spi0_reset_rxfifo();
|
||||
uint8_t spi0_tx_fifo_full();
|
||||
uint8_t spi0_tx_fifo_empty();
|
||||
uint8_t spi0_rx_fifo_full();
|
||||
uint8_t spi0_rx_fifo_empty();
|
||||
void spi0_set_ss_ctrl_by_sw(uint8_t yes);
|
||||
void spi0_set_ss_level(uint8_t level);
|
||||
uint8_t spi0_get_interrupt_pending();
|
||||
void spi0_clear_interrupt_pending();
|
||||
void spi0_master_set_read();
|
||||
void spi0_master_set_write();
|
||||
void spi0_master_set_ss_delay(uint8_t clk_num);
|
||||
uint8_t spi0_master_transmiting();
|
||||
void spi0_master_write_bytes(uint8_t write_data[], uint32_t count);
|
||||
void spi0_master_read_bytes(uint8_t read_data[], uint32_t count);
|
||||
|
||||
// SPI control 0 register
|
||||
#define SPI_CTRL0_REG_OFFSET 0x0
|
||||
#define SPI_CTRL0_REG_RESVAL 0x0
|
||||
#define SPI_CTRL0_ENABLE_BIT 0
|
||||
#define SPI_CTRL0_INT_EN_BIT 1
|
||||
#define SPI_CTRL0_INT_PENDING_BIT 2
|
||||
#define SPI_CTRL0_ROLE_MODE_BIT 3
|
||||
#define SPI_CTRL0_CP_MODE_MASK 0x3
|
||||
#define SPI_CTRL0_CP_MODE_OFFSET 4
|
||||
#define SPI_CTRL0_CP_MODE_FIELD \
|
||||
((bitfield_field32_t) { .mask = SPI_CTRL0_CP_MODE_MASK, .index = SPI_CTRL0_CP_MODE_OFFSET })
|
||||
#define SPI_CTRL0_SPI_MODE_MASK 0x3
|
||||
#define SPI_CTRL0_SPI_MODE_OFFSET 6
|
||||
#define SPI_CTRL0_SPI_MODE_FIELD \
|
||||
((bitfield_field32_t) { .mask = SPI_CTRL0_SPI_MODE_MASK, .index = SPI_CTRL0_SPI_MODE_OFFSET })
|
||||
#define SPI_CTRL0_READ_BIT 8
|
||||
#define SPI_CTRL0_MSB_FIRST_BIT 9
|
||||
#define SPI_CTRL0_SS_SW_CTRL_BIT 10
|
||||
#define SPI_CTRL0_SS_LEVEL_BIT 11
|
||||
#define SPI_CTRL0_SS_DELAY_MASK 0xf
|
||||
#define SPI_CTRL0_SS_DELAY_OFFSET 12
|
||||
#define SPI_CTRL0_SS_DELAY_FIELD \
|
||||
((bitfield_field32_t) { .mask = SPI_CTRL0_SS_DELAY_MASK, .index = SPI_CTRL0_SS_DELAY_OFFSET })
|
||||
#define SPI_CTRL0_CLK_DIV_MASK 0x7
|
||||
#define SPI_CTRL0_CLK_DIV_OFFSET 29
|
||||
#define SPI_CTRL0_CLK_DIV_FIELD \
|
||||
((bitfield_field32_t) { .mask = SPI_CTRL0_CLK_DIV_MASK, .index = SPI_CTRL0_CLK_DIV_OFFSET })
|
||||
|
||||
// SPI status register
|
||||
#define SPI_STATUS_REG_OFFSET 0x4
|
||||
#define SPI_STATUS_REG_RESVAL 0x0
|
||||
#define SPI_STATUS_TX_FIFO_FULL_BIT 0
|
||||
#define SPI_STATUS_TX_FIFO_EMPTY_BIT 1
|
||||
#define SPI_STATUS_RX_FIFO_FULL_BIT 2
|
||||
#define SPI_STATUS_RX_FIFO_EMPTY_BIT 3
|
||||
#define SPI_STATUS_BUSY_BIT 4
|
||||
|
||||
// SPI TX data register
|
||||
#define SPI_TXDATA_REG_OFFSET 0x8
|
||||
#define SPI_TXDATA_REG_RESVAL 0x0
|
||||
#define SPI_TXDATA_TXDATA_MASK 0xff
|
||||
#define SPI_TXDATA_TXDATA_OFFSET 0
|
||||
#define SPI_TXDATA_TXDATA_FIELD \
|
||||
((bitfield_field32_t) { .mask = SPI_TXDATA_TXDATA_MASK, .index = SPI_TXDATA_TXDATA_OFFSET })
|
||||
|
||||
// SPI RX data register
|
||||
#define SPI_RXDATA_REG_OFFSET 0xc
|
||||
#define SPI_RXDATA_REG_RESVAL 0x0
|
||||
#define SPI_RXDATA_RXDATA_MASK 0xff
|
||||
#define SPI_RXDATA_RXDATA_OFFSET 0
|
||||
#define SPI_RXDATA_RXDATA_FIELD \
|
||||
((bitfield_field32_t) { .mask = SPI_RXDATA_RXDATA_MASK, .index = SPI_RXDATA_RXDATA_OFFSET })
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
#endif // _SPI_REG_DEFS_
|
||||
// End generated register defines for spi
|
|
@ -0,0 +1,219 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "../include/spi.h"
|
||||
|
||||
|
||||
void spi0_set_clk_div(uint16_t div)
|
||||
{
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(SPI_CTRL0_CLK_DIV_MASK << SPI_CTRL0_CLK_DIV_OFFSET);
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= div << SPI_CTRL0_CLK_DIV_OFFSET;
|
||||
}
|
||||
|
||||
void spi0_set_role_mode(spi_role_mode_e mode)
|
||||
{
|
||||
if (mode == SPI_ROLE_MODE_MASTER)
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(1 << SPI_CTRL0_ROLE_MODE_BIT);
|
||||
else
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 1 << SPI_CTRL0_ROLE_MODE_BIT;
|
||||
}
|
||||
|
||||
void spi0_set_spi_mode(spi_spi_mode_e mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case SPI_MODE_STANDARD:
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(SPI_CTRL0_SPI_MODE_MASK << SPI_CTRL0_SPI_MODE_OFFSET);
|
||||
break;
|
||||
|
||||
case SPI_MODE_DUAL:
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(SPI_CTRL0_SPI_MODE_MASK << SPI_CTRL0_SPI_MODE_OFFSET);
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 1 << SPI_CTRL0_SPI_MODE_OFFSET;
|
||||
break;
|
||||
|
||||
case SPI_MODE_QUAD:
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(SPI_CTRL0_SPI_MODE_MASK << SPI_CTRL0_SPI_MODE_OFFSET);
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 2 << SPI_CTRL0_SPI_MODE_OFFSET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void spi0_set_cp_mode(spi_cp_mode_e mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case SPI_CPOL_0_CPHA_0:
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(SPI_CTRL0_CP_MODE_MASK << SPI_CTRL0_CP_MODE_OFFSET);
|
||||
break;
|
||||
|
||||
case SPI_CPOL_0_CPHA_1:
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(SPI_CTRL0_CP_MODE_MASK << SPI_CTRL0_CP_MODE_OFFSET);
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 1 << SPI_CTRL0_CP_MODE_OFFSET;
|
||||
break;
|
||||
|
||||
case SPI_CPOL_1_CPHA_0:
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(SPI_CTRL0_CP_MODE_MASK << SPI_CTRL0_CP_MODE_OFFSET);
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 2 << SPI_CTRL0_CP_MODE_OFFSET;
|
||||
break;
|
||||
|
||||
case SPI_CPOL_1_CPHA_1:
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 3 << SPI_CTRL0_CP_MODE_OFFSET;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void spi0_set_enable(uint8_t en)
|
||||
{
|
||||
if (en)
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 1 << SPI_CTRL0_ENABLE_BIT;
|
||||
else
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(1 << SPI_CTRL0_ENABLE_BIT);
|
||||
}
|
||||
|
||||
void spi0_set_interrupt_enable(uint8_t en)
|
||||
{
|
||||
if (en)
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 1 << SPI_CTRL0_INT_EN_BIT;
|
||||
else
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(1 << SPI_CTRL0_INT_EN_BIT);
|
||||
}
|
||||
|
||||
void spi0_set_msb_first()
|
||||
{
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 1 << SPI_CTRL0_MSB_FIRST_BIT;
|
||||
}
|
||||
|
||||
void spi0_set_lsb_first()
|
||||
{
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(1 << SPI_CTRL0_MSB_FIRST_BIT);
|
||||
}
|
||||
|
||||
void spi0_set_txdata(uint8_t data)
|
||||
{
|
||||
SPI0_REG(SPI_TXDATA_REG_OFFSET) |= data;
|
||||
}
|
||||
|
||||
uint8_t spi0_get_rxdata()
|
||||
{
|
||||
return (SPI0_REG(SPI_RXDATA_REG_OFFSET));
|
||||
}
|
||||
|
||||
uint8_t spi0_reset_rxfifo()
|
||||
{
|
||||
uint8_t data;
|
||||
|
||||
data = 0;
|
||||
|
||||
while (!(SPI0_REG(SPI_STATUS_REG_OFFSET) & (1 << SPI_STATUS_RX_FIFO_EMPTY_BIT))) {
|
||||
data = SPI0_REG(SPI_RXDATA_REG_OFFSET);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void spi0_set_ss_ctrl_by_sw(uint8_t yes)
|
||||
{
|
||||
if (yes)
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 1 << SPI_CTRL0_SS_SW_CTRL_BIT;
|
||||
else
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(1 << SPI_CTRL0_SS_SW_CTRL_BIT);
|
||||
}
|
||||
|
||||
void spi0_set_ss_level(uint8_t level)
|
||||
{
|
||||
if (level)
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 1 << SPI_CTRL0_SS_LEVEL_BIT;
|
||||
else
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(1 << SPI_CTRL0_SS_LEVEL_BIT);
|
||||
}
|
||||
|
||||
uint8_t spi0_tx_fifo_full()
|
||||
{
|
||||
if (SPI0_REG(SPI_STATUS_REG_OFFSET) & (1 << SPI_STATUS_TX_FIFO_FULL_BIT))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t spi0_tx_fifo_empty()
|
||||
{
|
||||
if (SPI0_REG(SPI_STATUS_REG_OFFSET) & (1 << SPI_STATUS_TX_FIFO_EMPTY_BIT))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t spi0_rx_fifo_full()
|
||||
{
|
||||
if (SPI0_REG(SPI_STATUS_REG_OFFSET) & (1 << SPI_STATUS_RX_FIFO_FULL_BIT))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t spi0_rx_fifo_empty()
|
||||
{
|
||||
if (SPI0_REG(SPI_STATUS_REG_OFFSET) & (1 << SPI_STATUS_RX_FIFO_EMPTY_BIT))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t spi0_get_interrupt_pending()
|
||||
{
|
||||
if (SPI0_REG(SPI_CTRL0_REG_OFFSET) & (1 << SPI_CTRL0_INT_PENDING_BIT))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spi0_clear_interrupt_pending()
|
||||
{
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= (1 << SPI_CTRL0_INT_PENDING_BIT);
|
||||
}
|
||||
|
||||
void spi0_master_set_read()
|
||||
{
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= 1 << SPI_CTRL0_READ_BIT;
|
||||
}
|
||||
|
||||
void spi0_master_set_write()
|
||||
{
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(1 << SPI_CTRL0_READ_BIT);
|
||||
}
|
||||
|
||||
void spi0_master_set_ss_delay(uint8_t clk_num)
|
||||
{
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) &= ~(SPI_CTRL0_SS_DELAY_MASK << SPI_CTRL0_SS_DELAY_OFFSET);
|
||||
SPI0_REG(SPI_CTRL0_REG_OFFSET) |= (clk_num & SPI_CTRL0_SS_DELAY_MASK) << SPI_CTRL0_SS_DELAY_OFFSET;
|
||||
}
|
||||
|
||||
uint8_t spi0_master_transmiting()
|
||||
{
|
||||
if (SPI0_REG(SPI_STATUS_REG_OFFSET) & (1 << SPI_STATUS_BUSY_BIT))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spi0_master_write_bytes(uint8_t write_data[], uint32_t count)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
spi0_master_set_write();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
spi0_set_txdata(write_data[i]);
|
||||
while (spi0_master_transmiting());
|
||||
}
|
||||
}
|
||||
|
||||
void spi0_master_read_bytes(uint8_t read_data[], uint32_t count)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
spi0_master_set_read();
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
spi0_set_txdata(0xff);
|
||||
while (spi0_master_transmiting());
|
||||
read_data[i] = spi0_get_rxdata();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue