1 /*! 2 * @file apm32f4x_spi.h 3 * 4 * @brief This file contains all the functions prototypes for the SPI firmware library 5 * 6 * @version V1.0.2 7 * 8 * @date 2022-06-23 9 * 10 * @attention 11 * 12 * Copyright (C) 2021-2022 Geehy Semiconductor 13 * 14 * You may not use this file except in compliance with the 15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE). 16 * 17 * The program is only for reference, which is distributed in the hope 18 * that it will be usefull and instructional for customers to develop 19 * their software. Unless required by applicable law or agreed to in 20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT 21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied. 22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions 23 * and limitations under the License. 24 */ 25 26 /* Define to prevent recursive inclusion */ 27 #ifndef __APM32F4XX_SPI_H 28 #define __APM32F4XX_SPI_H 29 30 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 /* Includes */ 35 #include "apm32f4xx.h" 36 37 /** @addtogroup APM32F4xx_StdPeriphDriver 38 @{ 39 */ 40 41 /** @addtogroup SPI_Driver 42 @{ 43 */ 44 45 /** @defgroup SPI_Enumerations 46 @{ 47 */ 48 49 /** 50 * @brief SPI data direction mode 51 * 52 * @note BIT0 refer to 1 line or 2 lines 53 * BIT4 refer to Tx or Rx in 1 line 54 * BIT8 refer to receive only or full-duplex in 2 lines 55 */ 56 typedef enum 57 { 58 SPI_DIRECTION_2LINES_FULLDUPLEX = 0x0000, /*!< 2 lines full duplex */ 59 SPI_DIRECTION_2LINES_RXONLY = 0x0100, /*!< 2 lines but receive only */ 60 SPI_DIRECTION_1LINE_RX = 0x0001, /*!< 1 line receive only */ 61 SPI_DIRECTION_1LINE_TX = 0x0011 /*!< 1 line send only */ 62 } SPI_DIRECTION_T; 63 64 /** 65 * @brief SPI mode 66 */ 67 typedef enum 68 { 69 SPI_MODE_SLAVE, /*!< Slave mode */ 70 SPI_MODE_MASTER /*!< Master mode */ 71 } SPI_MODE_T; 72 73 /** 74 * @brief SPI Data length 75 */ 76 typedef enum 77 { 78 SPI_DATA_LENGTH_8B, /*!< Set data frame format to 8bit */ 79 SPI_DATA_LENGTH_16B /*!< Set data frame format to 16bit */ 80 } SPI_DATA_LENGTH_T; 81 82 /** 83 * @brief SPI Clock Polarity 84 */ 85 typedef enum 86 { 87 SPI_CLKPOL_LOW, /*!< Set SCK polarity to low in idle state */ 88 SPI_CLKPOL_HIGH /*!< Set SCK polarity to high in idle state */ 89 } SPI_CLKPOL_T; 90 91 /** 92 * @brief SPI Clock Phase 93 */ 94 typedef enum 95 { 96 SPI_CLKPHA_1EDGE, /*!< Sample value in the first clock edge */ 97 SPI_CLKPHA_2EDGE /*!< Sample value in the second clock edge */ 98 } SPI_CLKPHA_T; 99 100 /** 101 * @brief SPI Slave Select management 102 */ 103 typedef enum 104 { 105 SPI_NSS_HARD, /*!< Disable software NSS mode */ 106 SPI_NSS_SOFT /*!< Enable software NSS mode */ 107 } SPI_NSS_T; 108 109 /** 110 * @brief SPI BaudRate Prescaler 111 */ 112 typedef enum 113 { 114 SPI_BAUDRATE_DIV_2, /*!< BaudRate DIV = 2 */ 115 SPI_BAUDRATE_DIV_4, /*!< BaudRate DIV = 4 */ 116 SPI_BAUDRATE_DIV_8, /*!< BaudRate DIV = 8 */ 117 SPI_BAUDRATE_DIV_16, /*!< BaudRate DIV = 16 */ 118 SPI_BAUDRATE_DIV_32, /*!< BaudRate DIV = 32 */ 119 SPI_BAUDRATE_DIV_64, /*!< BaudRate DIV = 64 */ 120 SPI_BAUDRATE_DIV_128, /*!< BaudRate DIV = 128 */ 121 SPI_BAUDRATE_DIV_256, /*!< BaudRate DIV = 256 */ 122 } SPI_BAUDRATE_DIV_T; 123 124 /** 125 * @brief SPI MSB LSB transmission 126 */ 127 typedef enum 128 { 129 SPI_FIRSTBIT_MSB, /*!< MSB first */ 130 SPI_FIRSTBIT_LSB /*!< LSB first */ 131 } SPI_FIRSTBIT_T; 132 133 /** 134 * @brief I2S Mode 135 */ 136 typedef enum 137 { 138 I2S_MODE_SLAVE_TX, /*!< Slave transmit mode */ 139 I2S_MODE_SLAVE_RX, /*!< Slave receive mode */ 140 I2S_MODE_MASTER_TX, /*!< Master transmit mode */ 141 I2S_MODE_MASTER_RX /*!< Master receive mode */ 142 } I2S_MODE_T; 143 144 /** 145 * @brief I2S Standard 146 */ 147 typedef enum 148 { 149 I2S_STANDARD_PHILLIPS = 0x00, /*!< I2S phillips mode */ 150 I2S_STANDARD_MSB = 0x01, /*!< MSB alignment mode */ 151 I2S_STANDARD_LSB = 0x02, /*!< LSB alignment mode */ 152 I2S_STANDARD_PCMSHORT = 0x03, /*!< PCB short frame synchronization mode */ 153 I2S_STANDARD_PCMLONG = 0x13 /*!< PCB long frame synchronization mode */ 154 } I2S_STANDARD_T; 155 156 /** 157 * @brief I2S data length 158 */ 159 typedef enum 160 { 161 I2S_DATA_LENGHT_16B = 0x00, /*!< Set the length of data to 16-bit */ 162 I2S_DATA_LENGHT_16BEX = 0x01, /*!< Set the length of data to 16-bit extended */ 163 I2S_DATA_LENGHT_24B = 0x03, /*!< Set the length of data to 24-bit */ 164 I2S_DATA_LENGHT_32B = 0x05, /*!< Set the length of data to 32-bit */ 165 } I2S_DATA_LENGTH_T; 166 167 /** 168 * @brief I2S MCLK Output 169 */ 170 typedef enum 171 { 172 I2S_MCLK_OUTPUT_DISABLE, /*!< Disable I2S MCLK output */ 173 I2S_MCLK_OUTPUT_ENABLE /*!< Enable I2S MCLK output */ 174 } I2S_MCLK_OUTPUT_T; 175 176 /** 177 * @brief I2S Audio divider 178 */ 179 typedef enum 180 { 181 I2S_AUDIO_DIV_192K = 192000, /*!< Audio div = 192K */ 182 I2S_AUDIO_DIV_96K = 96000, /*!< Audio div = 96K */ 183 I2S_AUDIO_DIV_48K = 48000, /*!< Audio div = 48K */ 184 I2S_AUDIO_DIV_44K = 44100, /*!< Audio div = 44.1K */ 185 I2S_AUDIO_DIV_32K = 32000, /*!< Audio div = 32K */ 186 I2S_AUDIO_DIV_22K = 22050, /*!< Audio div = 22.05K */ 187 I2S_AUDIO_DIV_16K = 16000, /*!< Audio div = 16K */ 188 I2S_AUDIO_DIV_11K = 11025, /*!< Audio div = 11.025K */ 189 I2S_AUDIO_DIV_8K = 8000, /*!< Audio div = 8K */ 190 I2S_AUDIO_DIV_DEFAULT = 2 /*!< Audio div = 2 */ 191 } I2S_AUDIO_DIV_T; 192 193 /** 194 * @brief I2S Clock Polarity 195 */ 196 typedef enum 197 { 198 I2S_CLKPOL_LOW, /*!< Set clock polarity to low */ 199 I2S_CLKPOL_HIGH /*!< Set clock polarity to high */ 200 } I2S_CLKPOL_T; 201 202 /** 203 * @brief SPI I2S DMA requests 204 */ 205 typedef enum 206 { 207 SPI_I2S_DMA_REQ_TX, /*!< Tx buffer DMA transfer request */ 208 SPI_I2S_DMA_REQ_RX /*!< Rx buffer DMA transfer request */ 209 } SPI_I2S_DMA_REQ_T; 210 211 /** 212 * @brief SPI Direction select 213 */ 214 typedef enum 215 { 216 SPI_DIRECTION_RX, /*!< Selects Rx receive direction */ 217 SPI_DIRECTION_TX /*!< Selects Tx transmission direction */ 218 } SPI_DIRECTION_SELECT_T; 219 220 /** 221 * @brief SPI interrupts definition 222 */ 223 typedef enum 224 { 225 SPI_I2S_INT_TXBE = 0x8002, /*!< Tx buffer empty interrupt */ 226 SPI_I2S_INT_RXBNE = 0x4001, /*!< Rx buffer not empty interrupt */ 227 SPI_I2S_INT_ERR = 0x2000, /*!< Error interrupt */ 228 I2S_INT_UDR = 0x2008, /*!< Underrun Error interrupt flag */ 229 SPI_INT_CRCE = 0x2010, /*!< CRC Error interrupt flag */ 230 SPI_INT_ME = 0x2020, /*!< Mode Error interrupt flag */ 231 SPI_I2S_INT_OVR = 0x2040 /*!< Overrun interrupt flag */ 232 } SPI_I2S_INT_T; 233 234 /** 235 * @brief SPI flags definition 236 */ 237 typedef enum 238 { 239 SPI_FLAG_RXBNE = 0x0001, /*!< Receive buffer not empty flag */ 240 SPI_FLAG_TXBE = 0x0002, /*!< Transmit buffer empty flag */ 241 I2S_FLAG_SCHDIR = 0x0004, /*!< Side Channel flag */ 242 I2S_FLAG_UDR = 0x0008, /*!< Underrun Error flag */ 243 SPI_FLAG_CRCE = 0x0010, /*!< CRC Error flag */ 244 SPI_FLAG_ME = 0x0020, /*!< Mode Error flag */ 245 SPI_FLAG_OVR = 0x0040, /*!< Overrun flag */ 246 SPI_FLAG_BSY = 0x0080 /*!< Busy flag */ 247 } SPI_FLAG_T; 248 249 /**@} end of group SPI_Enumerations*/ 250 251 /** @addtogroup SPI_Structure Data Structure 252 @{ 253 */ 254 255 /** 256 * @brief SPI Config structure definition 257 */ 258 typedef struct 259 { 260 SPI_MODE_T mode; /*!< SPI mode selection */ 261 SPI_DATA_LENGTH_T length; /*!< SPI data length selection */ 262 SPI_CLKPHA_T phase; /*!< SPI clock phase selection */ 263 SPI_CLKPOL_T polarity; /*!< SPI clock polarity selection */ 264 SPI_NSS_T nss; /*!< Set SPI software NSS */ 265 SPI_FIRSTBIT_T firstBit; /*!< Set first bit */ 266 SPI_DIRECTION_T direction; /*!< SPI data direction mode selection */ 267 SPI_BAUDRATE_DIV_T baudrateDiv; /*!< SPI BaudRate Prescaler selection */ 268 uint16_t crcPolynomial; /*!< Setup CRC polynomial value */ 269 } SPI_Config_T; 270 271 /** 272 * @brief I2S Config structure definition 273 */ 274 typedef struct 275 { 276 I2S_MODE_T mode; /*!< I2S mode selection */ 277 I2S_STANDARD_T standard; /*!< I2S standard selection */ 278 I2S_DATA_LENGTH_T length; /*!< Set I2S data length */ 279 I2S_MCLK_OUTPUT_T MCLKOutput; /*!< Set I2S MCLK output */ 280 I2S_AUDIO_DIV_T audioDiv; /*!< I2S Audio divider selection */ 281 I2S_CLKPOL_T polarity; /*!< I2S Clock polarity selection */ 282 } I2S_Config_T; 283 284 /**@} end of group SPI_Structure*/ 285 286 /** @defgroup SPI_Functions 287 @{ 288 */ 289 290 /* Reset */ 291 void SPI_I2S_Reset(SPI_T* spi); 292 293 /* Initialization and Configuration */ 294 void SPI_Config(SPI_T* spi, SPI_Config_T* spiConfig); 295 void I2S_Config(SPI_T* spi, I2S_Config_T* i2sConfig); 296 void SPI_ConfigStructInit(SPI_Config_T* spiConfig); 297 void I2S_ConfigStructInit(I2S_Config_T* i2sConfig); 298 void SPI_Enable(SPI_T* spi); 299 void SPI_Disable(SPI_T* spi); 300 void I2S_Enable(SPI_T* spi); 301 void I2S_Disable(SPI_T* spi); 302 void SPI_ConfigDataSize(SPI_T* spi, SPI_DATA_LENGTH_T length); 303 304 void SPI_SetSoftwareNSS(SPI_T* spi); 305 void SPI_ResetSoftwareNSS(SPI_T* spi); 306 void SPI_EnableSSOutput(SPI_T* spi); 307 void SPI_DisableSSOutput(SPI_T* spi); 308 void SPI_ConfigBiDirectionalLine(SPI_T* spi, SPI_DIRECTION_SELECT_T direction); 309 310 void SPI_EnableTIMode(SPI_T* spi); 311 void SPI_DisableTIMode(SPI_T* spi); 312 void I2S_ConfigFullDuplex(SPI_T* spi, I2S_Config_T* i2sConfig); 313 314 /* Data transfers */ 315 void SPI_I2S_TxData(SPI_T* spi, uint16_t data); 316 uint16_t SPI_I2S_RxData(SPI_T* spi); 317 318 /* Hardware CRC Calculation */ 319 void SPI_EnableCRC(SPI_T* spi); 320 void SPI_DisableCRC(SPI_T* spi); 321 void SPI_TxCRC(SPI_T* spi); 322 uint16_t SPI_ReadTxCRC(SPI_T* spi); 323 uint16_t SPI_ReadRxCRC(SPI_T* spi); 324 uint16_t SPI_ReadCRCPolynomial(SPI_T* spi); 325 326 /* DMA transfers */ 327 void SPI_I2S_EnableDMA(SPI_T* spi, SPI_I2S_DMA_REQ_T dmaReq); 328 void SPI_I2S_DisableDMA(SPI_T* spi, SPI_I2S_DMA_REQ_T dmaReq); 329 330 /* Interrupts and flags */ 331 void SPI_I2S_EnableInterrupt(SPI_T* spi, uint32_t interrupt); 332 void SPI_I2S_DisableInterrupt(SPI_T* spi, uint32_t interrupt); 333 uint8_t SPI_I2S_ReadStatusFlag(SPI_T* spi, SPI_FLAG_T flag); 334 void SPI_I2S_ClearStatusFlag(SPI_T* spi, SPI_FLAG_T flag); 335 uint8_t SPI_I2S_ReadIntFlag(SPI_T* spi, SPI_I2S_INT_T flag); 336 void SPI_I2S_ClearIntFlag(SPI_T* spi, SPI_I2S_INT_T flag); 337 338 #ifdef __cplusplus 339 } 340 #endif 341 342 #endif /* __APM32F4XX_SPI_H */ 343 344 /**@} end of group SPI_Enumerations */ 345 /**@} end of group SPI_Driver */ 346 /**@} end of group APM32F4xx_StdPeriphDriver */ 347