1 /* 2 * Copyright (c) 2006-2023, RT-Thread Development Team 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 * 6 * Change Logs: 7 * Date Author Notes 8 * 2022-07-30 Emuzit first version 9 */ 10 #ifndef __CH56X_SPI_H__ 11 #define __CH56X_SPI_H__ 12 13 #include "soc.h" 14 #include "ch56x_gpio.h" 15 16 #ifdef __cplusplus 17 extern "C" { 18 #endif 19 20 #define SPI0_BUS_NAME "spi0" 21 #define SPI1_BUS_NAME "spi1" 22 23 #ifndef SPI0_SCS_PIN 24 #define SPI0_SCS_PIN GET_PIN(A, 12) 25 #endif 26 #define SPI0_SCK_PIN GET_PIN(A, 13) 27 #define SPI0_MOSI_PIN GET_PIN(A, 14) 28 #define SPI0_MISO_PIN GET_PIN(A, 15) 29 30 #ifdef SOC_SERIES_CH569 31 #ifndef SPI1_SCS_PIN 32 #define SPI1_SCS_PIN GET_PIN(B, 11) 33 #endif 34 #define SPI1_SCK_PIN GET_PIN(B, 12) 35 #define SPI1_MOSI_PIN GET_PIN(B, 13) 36 #define SPI1_MISO_PIN GET_PIN(B, 14) 37 38 #else 39 #define SPI1_SCK_PIN GET_PIN(A, 0) 40 #define SPI1_MOSI_PIN GET_PIN(A, 1) 41 #define SPI1_MISO_PIN GET_PIN(A, 2) 42 #endif 43 44 #define SPI_FIFO_SIZE 8 45 46 union _spi_ctrl_mod 47 { 48 uint8_t reg; 49 struct 50 { 51 uint8_t mode_slave : 1; // RW, SPI master/slave (0/1) mode select 52 uint8_t all_clear : 1; // RW, clear FIFO/count/int-flag 53 uint8_t two_wire : 1; // RW, 2/3-wire mode (0/1), SPI slave 54 uint8_t mst_sck_mod : 1; // RW, mode0/mode3 (0/1) for SCK idle L/H 55 uint8_t fifo_dir : 1; // RW, FIFO direction is output/input (0/1) 56 uint8_t sck_oe : 1; // RW, SCK pin output enable 57 uint8_t mosi_oe : 1; // RW, MOSI pin output enable 58 uint8_t miso_oe : 1; // RW, MISO pin output enable 59 }; 60 struct 61 { 62 uint8_t stuff_0 : 3; 63 uint8_t slv_cmd_mod : 1; // RW, 1st byte is data/cmd (0/1), SPI slave 64 uint8_t stuff_4 : 4; 65 }; 66 }; 67 #define RB_SPI_MODE_SLAVE 0x01 68 #define RB_SPI_ALL_CLEAR 0x02 69 #define RB_SPI_2WIRE_MOD 0x04 70 #define RB_SPI_MST_SCK_MOD 0x08 71 #define RB_SPI_SLV_CMD_MOD 0x08 72 #define RB_SPI_FIFO_DIR 0x10 73 #define RB_SPI_SCK_OE 0x20 74 #define RB_SPI_MOSI_OE 0x40 75 #define RB_SPI_MISO_OE 0x80 76 77 #define MST_SCK_MOD_0 0 78 #define MST_SCK_MOD_3 1 79 80 #define SPI_FIFO_DIR_OUTPUT 0 81 #define SPI_FIFO_DIR_INPUT 1 82 83 union _spi_ctrl_cfg 84 { 85 uint8_t reg; 86 struct 87 { 88 uint8_t dma_enable : 1; // RW, enable DMA function 89 uint8_t resv_1 : 1; 90 uint8_t dma_loop : 1; // RW, enable DMA loop mode (0 => single) 91 uint8_t resv_3 : 1; 92 uint8_t auto_if : 1; // RW, enable auto clear RB_SPI_IF_BYTE_END 93 uint8_t bit_order : 1; // RW, data bit ordering, LSB/MSB first (0/1) 94 uint8_t resv_6 : 2; 95 }; 96 }; 97 #define RB_SPI_DMA_ENABLE 0x01 98 #define RB_SPI_DMA_LOOP 0x04 99 #define RB_SPI_AUTO_IF 0x10 100 #define RB_SPI_BIT_ORDER 0x20 101 102 #define SPI_BIT_ORDER_MSB 0 103 #define SPI_BIT_ORDER_LSB 1 104 105 union _spi_inter_en 106 { 107 uint8_t reg; 108 struct 109 { 110 uint8_t cnt_end : 1; // RW, IE for all bytes transfered 111 uint8_t byte_end : 1; // RW, IE for single byte transfered 112 uint8_t fifo_hf : 1; // RW, IE for FIFO half full 113 uint8_t dma_end : 1; // RW, IE for end of DMA 114 uint8_t fifo_ov : 1; // RW, IE for FIFO full or empty 115 uint8_t resv_5 : 2; 116 uint8_t fst_byte : 1; // RW, IE for 1st byte received, SPI slave 117 }; 118 }; 119 #define RB_SPI_IE_CNT_END 0x01 120 #define RB_SPI_IE_BYTE_END 0x02 121 #define RB_SPI_IE_FIFO_HF 0x04 122 #define RB_SPI_IE_DMA_END 0x08 123 #define RB_SPI_IE_FIFO_OV 0x10 124 #define RB_SPI_IE_FST_BYTE 0x80 125 126 union _spi_run_flag 127 { 128 uint8_t reg; 129 struct 130 { 131 uint8_t resv_0 : 4; 132 uint8_t slv_cmd_act : 1; // RO, SPI slave cmd received 133 uint8_t fifo_ready : 1; // RO, SPI FIFO ready to transfer 134 uint8_t slv_cs_load : 1; // RO, SPI slave is loading R8_SPIx_SLAVE_PRE 135 uint8_t slv_select : 1; // RO, SPI slave CS active (selected) 136 }; 137 }; 138 #define RB_SPI_SLV_CMD_ACT 0x10 139 #define RB_SPI_FIFO_READY 0x20 140 #define RB_SPI_SLV_CS_LOAD 0x40 141 #define RB_SPI_SLV_SELECT 0x80 142 143 union _spi_int_flag 144 { 145 uint8_t reg; 146 struct 147 { 148 uint8_t cnt_end : 1; // RW1, IF for all bytes transfered 149 uint8_t byte_end : 1; // RW1, IF for single byte transfered 150 uint8_t fifo_hf : 1; // RW1, IF for FIFO half full 151 uint8_t dma_end : 1; // RW1, IF for end of DMA 152 uint8_t fifo_ov : 1; // RW1, IF for FIFO full or empty 153 uint8_t resv_5 : 1; 154 uint8_t free : 1; // RO, current SPI state is free 155 uint8_t fst_byte : 1; // RW1, IF for 1st byte received, SPI slave 156 }; 157 }; 158 #define RB_SPI_IF_CNT_END 0x01 159 #define RB_SPI_IF_BYTE_END 0x02 160 #define RB_SPI_IF_FIFO_HF 0x04 161 #define RB_SPI_IF_DMA_END 0x08 162 #define RB_SPI_IF_FIFO_OV 0x10 163 #define RB_SPI_FREE 0x40 164 #define RB_SPI_IF_FST_BYTE 0x80 165 166 /* 167 * 0x00 R8_SPIx_CTRL_MOD: SPI mode setting register 168 * 0x01 R8_SPIx_CTRL_CFG: SPI configuration register 169 * 0x02 R8_SPIx_INTER_EN: SPI interrupt enable register 170 * 0x03 R8_SPIx_CLOCK_DIV: SPI master clock divisor, minimum 2 171 * 0x03 R8_SPIx_SLAVE_PRE: SPI slave preset data (reset as 10h) 172 * 0x04 R8_SPIx_BUFFER: SPI data buffer 173 * 0x05 R8_SPIx_RUN_FLAG: SPI working state register 174 * 0x06 R8_SPIx_INT_FLAG: SPI interrupt flags register 175 * 0x07 R8_SPIx_FIFO_COUNT: SPI FIFO data count 176 * 0x0c R16_SPIx_TOTAL_CNT: SPI total data length to transfer 177 * 0x10 R8_SPIx_FIFO: SPI FIFO 178 * 0x13 R8_SPIx_FIFO_COUNT1: SPI FIFO data count 179 * 0x14 R32_SPIx_DMA_NOW: SPI DMA current address 180 * 0x18 R32_SPIx_DMA_BEG: SPI DMA start address 181 * 0x1c R32_SPIx_DMA_END: SPI DMA end address 182 */ 183 struct spi_registers 184 { 185 union _spi_ctrl_mod CTRL_MOD; 186 union _spi_ctrl_cfg CTRL_CFG; 187 union _spi_inter_en INTER_EN; 188 union 189 { 190 uint8_t CLOCK_DIV; 191 uint8_t SLAVE_PRE; 192 }; 193 uint8_t BUFFER; 194 union _spi_run_flag RUN_FLAG; 195 union _spi_int_flag INT_FLAG; 196 uint8_t FIFO_COUNT; 197 uint32_t resv_8; 198 uint16_t TOTAL_COUNT; 199 uint16_t resv_0e; 200 uint8_t FIFO; 201 uint8_t resv_11[2]; 202 uint8_t FIFO_COUNT1; 203 uint32_t DMA_NOW; 204 uint32_t DMA_BIG; 205 uint32_t DMA_END; 206 }; 207 CHECK_STRUCT_SIZE(struct spi_registers, 0x20); 208 209 rt_err_t spi_cs_pin_assign(int spi_n, rt_base_t cs_pin); 210 211 #ifdef __cplusplus 212 } 213 #endif 214 215 #endif 216