2022-08-02 10:36:49 +08:00
|
|
|
/*
|
2023-02-09 12:01:20 +08:00
|
|
|
* Copyright (c) 2006-2023, RT-Thread Development Team
|
2022-08-02 10:36:49 +08:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
|
|
*
|
|
|
|
* Change Logs:
|
|
|
|
* Date Author Notes
|
|
|
|
* 2022-07-30 Emuzit first version
|
|
|
|
*/
|
|
|
|
#ifndef __CH56X_SPI_H__
|
|
|
|
#define __CH56X_SPI_H__
|
|
|
|
|
|
|
|
#include "soc.h"
|
|
|
|
#include "ch56x_gpio.h"
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define SPI0_BUS_NAME "spi0"
|
|
|
|
#define SPI1_BUS_NAME "spi1"
|
|
|
|
|
|
|
|
#ifndef SPI0_SCS_PIN
|
|
|
|
#define SPI0_SCS_PIN GET_PIN(A, 12)
|
|
|
|
#endif
|
|
|
|
#define SPI0_SCK_PIN GET_PIN(A, 13)
|
|
|
|
#define SPI0_MOSI_PIN GET_PIN(A, 14)
|
|
|
|
#define SPI0_MISO_PIN GET_PIN(A, 15)
|
|
|
|
|
|
|
|
#ifdef SOC_SERIES_CH569
|
|
|
|
#ifndef SPI1_SCS_PIN
|
|
|
|
#define SPI1_SCS_PIN GET_PIN(B, 11)
|
|
|
|
#endif
|
|
|
|
#define SPI1_SCK_PIN GET_PIN(B, 12)
|
|
|
|
#define SPI1_MOSI_PIN GET_PIN(B, 13)
|
|
|
|
#define SPI1_MISO_PIN GET_PIN(B, 14)
|
|
|
|
|
|
|
|
#else
|
|
|
|
#define SPI1_SCK_PIN GET_PIN(A, 0)
|
|
|
|
#define SPI1_MOSI_PIN GET_PIN(A, 1)
|
|
|
|
#define SPI1_MISO_PIN GET_PIN(A, 2)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define SPI_FIFO_SIZE 8
|
|
|
|
|
|
|
|
union _spi_ctrl_mod
|
|
|
|
{
|
|
|
|
uint8_t reg;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint8_t mode_slave : 1; // RW, SPI master/slave (0/1) mode select
|
|
|
|
uint8_t all_clear : 1; // RW, clear FIFO/count/int-flag
|
|
|
|
uint8_t two_wire : 1; // RW, 2/3-wire mode (0/1), SPI slave
|
|
|
|
uint8_t mst_sck_mod : 1; // RW, mode0/mode3 (0/1) for SCK idle L/H
|
|
|
|
uint8_t fifo_dir : 1; // RW, FIFO direction is output/input (0/1)
|
|
|
|
uint8_t sck_oe : 1; // RW, SCK pin output enable
|
|
|
|
uint8_t mosi_oe : 1; // RW, MOSI pin output enable
|
|
|
|
uint8_t miso_oe : 1; // RW, MISO pin output enable
|
|
|
|
};
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint8_t stuff_0 : 3;
|
|
|
|
uint8_t slv_cmd_mod : 1; // RW, 1st byte is data/cmd (0/1), SPI slave
|
|
|
|
uint8_t stuff_4 : 4;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
#define RB_SPI_MODE_SLAVE 0x01
|
|
|
|
#define RB_SPI_ALL_CLEAR 0x02
|
|
|
|
#define RB_SPI_2WIRE_MOD 0x04
|
|
|
|
#define RB_SPI_MST_SCK_MOD 0x08
|
|
|
|
#define RB_SPI_SLV_CMD_MOD 0x08
|
|
|
|
#define RB_SPI_FIFO_DIR 0x10
|
|
|
|
#define RB_SPI_SCK_OE 0x20
|
|
|
|
#define RB_SPI_MOSI_OE 0x40
|
|
|
|
#define RB_SPI_MISO_OE 0x80
|
|
|
|
|
|
|
|
#define MST_SCK_MOD_0 0
|
|
|
|
#define MST_SCK_MOD_3 1
|
|
|
|
|
|
|
|
#define SPI_FIFO_DIR_OUTPUT 0
|
|
|
|
#define SPI_FIFO_DIR_INPUT 1
|
|
|
|
|
|
|
|
union _spi_ctrl_cfg
|
|
|
|
{
|
|
|
|
uint8_t reg;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint8_t dma_enable : 1; // RW, enable DMA function
|
|
|
|
uint8_t resv_1 : 1;
|
|
|
|
uint8_t dma_loop : 1; // RW, enable DMA loop mode (0 => single)
|
|
|
|
uint8_t resv_3 : 1;
|
|
|
|
uint8_t auto_if : 1; // RW, enable auto clear RB_SPI_IF_BYTE_END
|
|
|
|
uint8_t bit_order : 1; // RW, data bit ordering, LSB/MSB first (0/1)
|
|
|
|
uint8_t resv_6 : 2;
|
|
|
|
};
|
|
|
|
};
|
|
|
|
#define RB_SPI_DMA_ENABLE 0x01
|
|
|
|
#define RB_SPI_DMA_LOOP 0x04
|
|
|
|
#define RB_SPI_AUTO_IF 0x10
|
|
|
|
#define RB_SPI_BIT_ORDER 0x20
|
|
|
|
|
|
|
|
#define SPI_BIT_ORDER_MSB 0
|
|
|
|
#define SPI_BIT_ORDER_LSB 1
|
|
|
|
|
|
|
|
union _spi_inter_en
|
|
|
|
{
|
|
|
|
uint8_t reg;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint8_t cnt_end : 1; // RW, IE for all bytes transfered
|
|
|
|
uint8_t byte_end : 1; // RW, IE for single byte transfered
|
|
|
|
uint8_t fifo_hf : 1; // RW, IE for FIFO half full
|
|
|
|
uint8_t dma_end : 1; // RW, IE for end of DMA
|
|
|
|
uint8_t fifo_ov : 1; // RW, IE for FIFO full or empty
|
|
|
|
uint8_t resv_5 : 2;
|
|
|
|
uint8_t fst_byte : 1; // RW, IE for 1st byte received, SPI slave
|
|
|
|
};
|
|
|
|
};
|
|
|
|
#define RB_SPI_IE_CNT_END 0x01
|
|
|
|
#define RB_SPI_IE_BYTE_END 0x02
|
|
|
|
#define RB_SPI_IE_FIFO_HF 0x04
|
|
|
|
#define RB_SPI_IE_DMA_END 0x08
|
|
|
|
#define RB_SPI_IE_FIFO_OV 0x10
|
|
|
|
#define RB_SPI_IE_FST_BYTE 0x80
|
|
|
|
|
|
|
|
union _spi_run_flag
|
|
|
|
{
|
|
|
|
uint8_t reg;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint8_t resv_0 : 4;
|
|
|
|
uint8_t slv_cmd_act : 1; // RO, SPI slave cmd received
|
|
|
|
uint8_t fifo_ready : 1; // RO, SPI FIFO ready to transfer
|
|
|
|
uint8_t slv_cs_load : 1; // RO, SPI slave is loading R8_SPIx_SLAVE_PRE
|
|
|
|
uint8_t slv_select : 1; // RO, SPI slave CS active (selected)
|
|
|
|
};
|
|
|
|
};
|
|
|
|
#define RB_SPI_SLV_CMD_ACT 0x10
|
|
|
|
#define RB_SPI_FIFO_READY 0x20
|
|
|
|
#define RB_SPI_SLV_CS_LOAD 0x40
|
|
|
|
#define RB_SPI_SLV_SELECT 0x80
|
|
|
|
|
|
|
|
union _spi_int_flag
|
|
|
|
{
|
|
|
|
uint8_t reg;
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
uint8_t cnt_end : 1; // RW1, IF for all bytes transfered
|
|
|
|
uint8_t byte_end : 1; // RW1, IF for single byte transfered
|
|
|
|
uint8_t fifo_hf : 1; // RW1, IF for FIFO half full
|
|
|
|
uint8_t dma_end : 1; // RW1, IF for end of DMA
|
|
|
|
uint8_t fifo_ov : 1; // RW1, IF for FIFO full or empty
|
|
|
|
uint8_t resv_5 : 1;
|
|
|
|
uint8_t free : 1; // RO, current SPI state is free
|
|
|
|
uint8_t fst_byte : 1; // RW1, IF for 1st byte received, SPI slave
|
|
|
|
};
|
|
|
|
};
|
|
|
|
#define RB_SPI_IF_CNT_END 0x01
|
|
|
|
#define RB_SPI_IF_BYTE_END 0x02
|
|
|
|
#define RB_SPI_IF_FIFO_HF 0x04
|
|
|
|
#define RB_SPI_IF_DMA_END 0x08
|
|
|
|
#define RB_SPI_IF_FIFO_OV 0x10
|
|
|
|
#define RB_SPI_FREE 0x40
|
|
|
|
#define RB_SPI_IF_FST_BYTE 0x80
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 0x00 R8_SPIx_CTRL_MOD: SPI mode setting register
|
|
|
|
* 0x01 R8_SPIx_CTRL_CFG: SPI configuration register
|
|
|
|
* 0x02 R8_SPIx_INTER_EN: SPI interrupt enable register
|
|
|
|
* 0x03 R8_SPIx_CLOCK_DIV: SPI master clock divisor, minimum 2
|
|
|
|
* 0x03 R8_SPIx_SLAVE_PRE: SPI slave preset data (reset as 10h)
|
|
|
|
* 0x04 R8_SPIx_BUFFER: SPI data buffer
|
|
|
|
* 0x05 R8_SPIx_RUN_FLAG: SPI working state register
|
|
|
|
* 0x06 R8_SPIx_INT_FLAG: SPI interrupt flags register
|
|
|
|
* 0x07 R8_SPIx_FIFO_COUNT: SPI FIFO data count
|
|
|
|
* 0x0c R16_SPIx_TOTAL_CNT: SPI total data length to transfer
|
|
|
|
* 0x10 R8_SPIx_FIFO: SPI FIFO
|
|
|
|
* 0x13 R8_SPIx_FIFO_COUNT1: SPI FIFO data count
|
|
|
|
* 0x14 R32_SPIx_DMA_NOW: SPI DMA current address
|
|
|
|
* 0x18 R32_SPIx_DMA_BEG: SPI DMA start address
|
|
|
|
* 0x1c R32_SPIx_DMA_END: SPI DMA end address
|
|
|
|
*/
|
|
|
|
struct spi_registers
|
|
|
|
{
|
|
|
|
union _spi_ctrl_mod CTRL_MOD;
|
|
|
|
union _spi_ctrl_cfg CTRL_CFG;
|
|
|
|
union _spi_inter_en INTER_EN;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
uint8_t CLOCK_DIV;
|
|
|
|
uint8_t SLAVE_PRE;
|
|
|
|
};
|
|
|
|
uint8_t BUFFER;
|
|
|
|
union _spi_run_flag RUN_FLAG;
|
|
|
|
union _spi_int_flag INT_FLAG;
|
|
|
|
uint8_t FIFO_COUNT;
|
|
|
|
uint32_t resv_8;
|
|
|
|
uint16_t TOTAL_COUNT;
|
|
|
|
uint16_t resv_0e;
|
|
|
|
uint8_t FIFO;
|
|
|
|
uint8_t resv_11[2];
|
|
|
|
uint8_t FIFO_COUNT1;
|
|
|
|
uint32_t DMA_NOW;
|
|
|
|
uint32_t DMA_BIG;
|
|
|
|
uint32_t DMA_END;
|
|
|
|
};
|
|
|
|
CHECK_STRUCT_SIZE(struct spi_registers, 0x20);
|
|
|
|
|
|
|
|
rt_err_t spi_cs_pin_assign(int spi_n, rt_base_t cs_pin);
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|