sipeed_spi.c
1 #include <stdio.h> 2 #include <fpioa.h> 3 #include <spi.h> 4 #include <sipeed_spi.h> 5 #include <sysctl.h> 6 #include <utils.h> 7 8 void sipeed_spi_init( 9 sipeed_spi_device_num_t spi_num, 10 sipeed_spi_device_num_t work_mode, 11 sipeed_spi_device_num_t frame_format, 12 sipeed_size_t data_bit_length, 13 sipeed_uint32_t endian) 14 { 15 spi_init(spi_num, work_mode, frame_format, data_bit_length, endian); 16 } 17 18 void sipeed_spi_init_non_standard(sipeed_spi_device_num_t spi_num, sipeed_uint32_t instruction_length, sipeed_uint32_t address_length, 19 sipeed_uint32_t wait_cycles, sipeed_spi_instruction_address_trans_mode_t instruction_address_trans_mode) 20 { 21 spi_init_non_standard(spi_num,instruction_length,address_length,wait_cycles, instruction_address_trans_mode); 22 } 23 24 void sipeed_spi_send_data_standard(sipeed_spi_device_num_t spi_num, sipeed_spi_chip_select_t chip_select, const sipeed_uint8_t *cmd_buff, 25 sipeed_size_t cmd_len, const sipeed_uint8_t *tx_buff, sipeed_size_t tx_len) 26 { 27 spi_send_data_standard( spi_num,chip_select,cmd_buff,cmd_len,tx_buff,tx_len); 28 } 29 void sipeed_spi_receive_data_standard(sipeed_spi_device_num_t spi_num, sipeed_spi_chip_select_t chip_select, const sipeed_uint8_t *cmd_buff, 30 sipeed_size_t cmd_len, sipeed_uint8_t *rx_buff, sipeed_size_t rx_len) 31 { 32 spi_receive_data_standard(spi_num,chip_select,cmd_buff,cmd_len,rx_buff,rx_len); 33 34 } 35 void sipeed_spi_receive_data_multiple(sipeed_spi_device_num_t spi_num, sipeed_spi_chip_select_t chip_select, const sipeed_uint32_t *cmd_buff, 36 sipeed_size_t cmd_len, sipeed_uint8_t *rx_buff, sipeed_size_t rx_len) 37 { 38 spi_receive_data_multiple( spi_num,chip_select,cmd_buff,cmd_len,rx_buff,rx_len); 39 } 40 41 void sipeed_spi_send_data_multiple(sipeed_spi_device_num_t spi_num, sipeed_spi_chip_select_t chip_select, const sipeed_uint32_t *cmd_buff, 42 sipeed_size_t cmd_len, const sipeed_uint8_t *tx_buff, sipeed_size_t tx_len) 43 { 44 spi_send_data_multiple( spi_num, chip_select,cmd_buff,cmd_len, tx_buff, tx_len); 45 } 46 47 void sipeed_spi_send_data_standard_dma(sipeed_dmac_channel_number_t channel_num, sipeed_spi_device_num_t spi_num, 48 sipeed_spi_chip_select_t chip_select, 49 const sipeed_uint8_t *cmd_buff, sipeed_size_t cmd_len, const sipeed_uint8_t *tx_buff, sipeed_size_t tx_len) 50 { 51 spi_send_data_standard_dma(channel_num, spi_num, chip_select, cmd_buff, cmd_len, tx_buff, tx_len); 52 } 53 54 void sipeed_spi_receive_data_standard_dma(sipeed_dmac_channel_number_t dma_send_channel_num, 55 sipeed_dmac_channel_number_t dma_receive_channel_num, 56 sipeed_spi_device_num_t spi_num, sipeed_spi_chip_select_t chip_select, const sipeed_uint8_t *cmd_buff, 57 sipeed_size_t cmd_len, sipeed_uint8_t *rx_buff, sipeed_size_t rx_len) 58 { 59 spi_receive_data_standard_dma(dma_send_channel_num, dma_receive_channel_num, spi_num, chip_select, cmd_buff, cmd_len, rx_buff, rx_len); 60 } 61 62 void sipeed_spi_send_data_multiple_dma(sipeed_dmac_channel_number_t channel_num, sipeed_spi_device_num_t spi_num, 63 sipeed_spi_chip_select_t chip_select, 64 const sipeed_uint32_t *cmd_buff, sipeed_size_t cmd_len, const sipeed_uint8_t *tx_buff, sipeed_size_t tx_len) 65 { 66 spi_send_data_multiple_dma(channel_num, spi_num,chip_select,cmd_buff,cmd_len,tx_buff,tx_len); 67 68 } 69 70 void sipeed_spi_receive_data_multiple_dma(sipeed_dmac_channel_number_t dma_send_channel_num, 71 sipeed_dmac_channel_number_t dma_receive_channel_num, 72 sipeed_spi_device_num_t spi_num, sipeed_spi_chip_select_t chip_select, const sipeed_uint32_t *cmd_buff, 73 sipeed_size_t cmd_len, sipeed_uint8_t *rx_buff, sipeed_size_t rx_len) 74 { 75 spi_receive_data_multiple_dma( dma_send_channel_num, dma_receive_channel_num, 76 spi_num, chip_select, cmd_buff, 77 cmd_len, rx_buff, rx_len); 78 } 79 80 void sipeed_spi_fill_data_dma(sipeed_dmac_channel_number_t channel_num, sipeed_spi_device_num_t spi_num, sipeed_spi_chip_select_t chip_select, 81 const sipeed_uint32_t *tx_buff, sipeed_size_t tx_len) 82 { 83 spi_fill_data_dma( channel_num, spi_num, chip_select, tx_buff, tx_len); 84 } 85 86 void sipeed_spi_send_data_normal_dma(sipeed_dmac_channel_number_t channel_num, sipeed_spi_device_num_t spi_num, 87 sipeed_spi_chip_select_t chip_select, 88 const void *tx_buff, sipeed_size_t tx_len, sipeed_spi_transfer_width_t spi_transfer_width) 89 { 90 spi_send_data_normal_dma( channel_num, spi_num, 91 chip_select, tx_buff, tx_len, spi_transfer_width); 92 93 } 94 95 sipeed_uint32_t sipeed_spi_set_clk_rate(sipeed_spi_device_num_t spi_num, sipeed_uint32_t spi_clk) 96 { 97 return spi_set_clk_rate( spi_num, spi_clk); 98 } 99 100 101 static spi_transfer_width_t sipeed_spi_get_frame_size(size_t data_bit_length) 102 { 103 if (data_bit_length < 8) 104 return SPI_TRANS_CHAR; 105 else if (data_bit_length < 16) 106 return SPI_TRANS_SHORT; 107 return SPI_TRANS_INT; 108 } 109 110 static void sipeed_spi_set_tmod(uint8_t spi_num, uint32_t tmod) 111 { 112 configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); 113 volatile spi_t *spi_handle = spi[spi_num]; 114 uint8_t tmod_offset = 0; 115 switch(spi_num) 116 { 117 case 0: 118 case 1: 119 tmod_offset = 8; 120 break; 121 case 2: 122 configASSERT(!"Spi Bus 2 Not Support!"); 123 break; 124 case 3: 125 default: 126 tmod_offset = 10; 127 break; 128 } 129 set_bit(&spi_handle->ctrlr0, 3 << tmod_offset, tmod << tmod_offset); 130 } 131 132 void sipeed_spi_transfer_data_standard(spi_device_num_t spi_num, spi_chip_select_t chip_select, const uint8_t *tx_buff,uint8_t *rx_buff, size_t tx_len, size_t rx_len) 133 { 134 configASSERT(spi_num < SPI_DEVICE_MAX && spi_num != 2); 135 configASSERT(tx_len > 0 && tx_len >= rx_len); 136 size_t index, fifo_len; 137 sipeed_spi_set_tmod(spi_num, SPI_TMOD_TRANS_RECV); 138 139 volatile spi_t *spi_handle = spi[spi_num]; 140 141 uint8_t dfs_offset; 142 switch(spi_num){ 143 case 0: 144 case 1: 145 dfs_offset = 16; 146 break; 147 case 2: 148 configASSERT(!"Spi Bus 2 Not Support!"); 149 break; 150 case 3: 151 default: 152 dfs_offset = 0; 153 break; 154 } 155 uint32_t data_bit_length = (spi_handle->ctrlr0 >> dfs_offset) & 0x1F; 156 spi_transfer_width_t frame_width = sipeed_spi_get_frame_size(data_bit_length); 157 spi_handle->ctrlr1 = (uint32_t)(tx_len/frame_width - 1); 158 spi_handle->ssienr = 0x01; 159 spi_handle->ser = 1U << chip_select; 160 uint32_t index_tx = 0, index_rx = 0; 161 while (tx_len) 162 { 163 fifo_len = 32 - spi_handle->txflr; 164 fifo_len = fifo_len < tx_len ? fifo_len : tx_len; 165 switch(frame_width) 166 { 167 case SPI_TRANS_INT: 168 fifo_len = fifo_len / 4 * 4; 169 for (index = 0; index < fifo_len / 4; index++) 170 spi_handle->dr[0] = ((uint32_t *)tx_buff)[index_tx++]; 171 break; 172 case SPI_TRANS_SHORT: 173 fifo_len = fifo_len / 2 * 2; 174 for (index = 0; index < fifo_len / 2; index++) 175 spi_handle->dr[0] = ((uint16_t *)tx_buff)[index_tx++]; 176 break; 177 default: 178 for (index = 0; index < fifo_len; index++) 179 spi_handle->dr[0] = tx_buff[index_tx++]; 180 break; 181 } 182 tx_len -= fifo_len; 183 while(rx_len) 184 { 185 fifo_len = spi_handle->rxflr; 186 if(fifo_len==0) 187 { 188 if(index_tx - index_rx < 32) 189 break; 190 } 191 fifo_len = fifo_len < rx_len ? fifo_len : rx_len; 192 switch(frame_width) 193 { 194 case SPI_TRANS_INT: 195 fifo_len = fifo_len / 4 * 4; 196 for (index = 0; index < fifo_len / 4; index++) 197 ((uint32_t *)rx_buff)[index_rx++] = spi_handle->dr[0]; 198 break; 199 case SPI_TRANS_SHORT: 200 fifo_len = fifo_len / 2 * 2; 201 for (index = 0; index < fifo_len / 2; index++) 202 ((uint16_t *)rx_buff)[index_rx++] = (uint16_t)spi_handle->dr[0]; 203 break; 204 default: 205 for (index = 0; index < fifo_len; index++) 206 rx_buff[index_rx++] = (uint8_t)spi_handle->dr[0]; 207 break; 208 } 209 210 rx_len -= fifo_len; 211 212 } 213 } 214 215 while ((spi_handle->sr & 0x05) != 0x04) 216 ; 217 while (rx_len) 218 { 219 fifo_len = spi_handle->rxflr; 220 fifo_len = fifo_len < rx_len ? fifo_len : rx_len; 221 switch(frame_width) 222 { 223 case SPI_TRANS_INT: 224 fifo_len = fifo_len / 4 * 4; 225 for (index = 0; index < fifo_len / 4; index++) 226 ((uint32_t *)rx_buff)[index_rx++] = spi_handle->dr[0]; 227 break; 228 case SPI_TRANS_SHORT: 229 fifo_len = fifo_len / 2 * 2; 230 for (index = 0; index < fifo_len / 2; index++) 231 ((uint16_t *)rx_buff)[index_rx++] = (uint16_t)spi_handle->dr[0]; 232 break; 233 default: 234 for (index = 0; index < fifo_len; index++) 235 rx_buff[index_rx++] = (uint8_t)spi_handle->dr[0]; 236 break; 237 } 238 239 rx_len -= fifo_len; 240 } 241 spi_handle->ser = 0x00; 242 spi_handle->ssienr = 0x00; 243 } 244 245 void sipeed_spi_deinit(spi_device_num_t spi_num) 246 { 247 volatile spi_t *spi_handle = spi[spi_num]; 248 spi_handle->ssienr = 0x00; 249 sysctl_clock_disable(SYSCTL_CLOCK_SPI0 + spi_num); 250 } 251