1 /*! 2 * @file qpm32f10x_qspi.c 3 * 4 * @brief This file contains all the functions for the QSPI peripheral 5 * 6 * @version V1.0.1 7 * 8 * @date 2022-12-31 9 * 10 * @attention 11 * 12 * Copyright (C) 2022-2023 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 /* Includes */ 27 #include "apm32s10x_qspi.h" 28 29 /** @addtogroup APM32S10x_StdPeriphDriver 30 @{ 31 */ 32 33 /** @addtogroup QSPI_Driver QSPI Driver 34 @{ 35 */ 36 37 /** @defgroup QSPI_Functions Functions 38 @{ 39 */ 40 41 /*! 42 * @brief Reset QSPI peripheral registers to their default values 43 * 44 * @param None 45 * 46 * @retval None 47 */ QSPI_Reset(void)48void QSPI_Reset(void) 49 { 50 volatile uint32_t dummy = 0; 51 52 QSPI->IOSW = QSPI_IOSW_RESET_VALUE; 53 QSPI->SSIEN = QSPI_SSIEN_RESET_VALUE; 54 QSPI->INTEN = QSPI_INTEN_RESET_VALUE; 55 dummy = QSPI->ICF; 56 QSPI->CTRL1 = QSPI_CTRL1_RESET_VALUE; 57 QSPI->CTRL2 = QSPI_CTRL2_RESET_VALUE; 58 QSPI->CTRL3 = QSPI_CTRL3_RESET_VALUE; 59 QSPI->SLAEN = QSPI_SLAEN_RESET_VALUE; 60 QSPI->BR = QSPI_BR_RESET_VALUE; 61 QSPI->TFL = QSPI_TFL_RESET_VALUE; 62 QSPI->RFL = QSPI_RFL_RESET_VALUE; 63 QSPI->TFTL = QSPI_TFTL_RESET_VALUE; 64 QSPI->RFTL = QSPI_RFTL_RESET_VALUE; 65 QSPI->STS = QSPI_STS_RESET_VALUE; 66 QSPI->RSD = QSPI_RSD_RESET_VALUE; 67 } 68 69 /*! 70 * @brief Configure the QSPI peripheral according to the specified parameters in the qspiConfig 71 * 72 * @param qspiConfig: Pointer to a QSPI_Config_T structure that contains the configuration information 73 * 74 * @retval None 75 */ QSPI_Config(QSPI_Config_T * qspiConfig)76void QSPI_Config(QSPI_Config_T* qspiConfig) 77 { 78 QSPI->CTRL1_B.CPHA = qspiConfig->clockPhase; 79 QSPI->CTRL1_B.CPOL = qspiConfig->clockPolarity; 80 QSPI->CTRL1_B.FRF = qspiConfig->frameFormat; 81 QSPI->CTRL1_B.DFS = qspiConfig->dataFrameSize;; 82 QSPI->CTRL1_B.SSTEN = qspiConfig->selectSlaveToggle; 83 84 QSPI->BR = qspiConfig->clockDiv; 85 } 86 87 /*! 88 * @brief Fill each qspiConfig member with its default value 89 * 90 * @param qspiConfig: Pointer to a QSPI_Config_T structure which will be initialized 91 * 92 * @retval None 93 */ QSPI_ConfigStructInit(QSPI_Config_T * qspiConfig)94void QSPI_ConfigStructInit(QSPI_Config_T* qspiConfig) 95 { 96 qspiConfig->clockPhase = QSPI_CLKPHA_2EDGE; 97 qspiConfig->clockPolarity = QSPI_CLKPOL_LOW; 98 qspiConfig->clockDiv = 0; 99 100 qspiConfig->frameFormat = QSPI_FRF_STANDARD; 101 qspiConfig->dataFrameSize = QSPI_DFS_8BIT; 102 qspiConfig->selectSlaveToggle = QSPI_SST_DISABLE; 103 } 104 105 /*! 106 * @brief Configure frame number 107 * 108 * @param num: Configs a 16bit frame number 109 * 110 * @retval None 111 */ QSPI_ConfigFrameNum(uint16_t num)112void QSPI_ConfigFrameNum(uint16_t num) 113 { 114 QSPI->CTRL2_B.NDF = num; 115 } 116 117 /*! 118 * @brief Configure data frame size 119 * 120 * @param dfs: Specifies the data frame size 121 * The parameter can be one of following values: 122 * @arg QSPI_DFS_4BIT : Specifies data frame size to 4bit 123 * @arg QSPI_DFS_5BIT : Specifies data frame size to 5bit 124 * @arg QSPI_DFS_6BIT : Specifies data frame size to 6bit 125 * @arg QSPI_DFS_7BIT : Specifies data frame size to 7bit 126 * @arg QSPI_DFS_8BIT : Specifies data frame size to 8bit 127 * @arg QSPI_DFS_9BIT : Specifies data frame size to 9bit 128 * @arg QSPI_DFS_10BIT : Specifies data frame size to 10bit 129 * @arg QSPI_DFS_11BIT : Specifies data frame size to 11bit 130 * @arg QSPI_DFS_12BIT : Specifies data frame size to 12bit 131 * @arg QSPI_DFS_13BIT : Specifies data frame size to 13bit 132 * @arg QSPI_DFS_14BIT : Specifies data frame size to 14bit 133 * @arg QSPI_DFS_15BIT : Specifies data frame size to 15bit 134 * @arg QSPI_DFS_16BIT : Specifies data frame size to 16bit 135 * @arg QSPI_DFS_17BIT : Specifies data frame size to 17bit 136 * @arg QSPI_DFS_18BIT : Specifies data frame size to 18bit 137 * @arg QSPI_DFS_19BIT : Specifies data frame size to 19bit 138 * @arg QSPI_DFS_20BIT : Specifies data frame size to 20bit 139 * @arg QSPI_DFS_21BIT : Specifies data frame size to 21bit 140 * @arg QSPI_DFS_22BIT : Specifies data frame size to 22bit 141 * @arg QSPI_DFS_23BIT : Specifies data frame size to 23bit 142 * @arg QSPI_DFS_24BIT : Specifies data frame size to 24bit 143 * @arg QSPI_DFS_25BIT : Specifies data frame size to 25bit 144 * @arg QSPI_DFS_26BIT : Specifies data frame size to 26bit 145 * @arg QSPI_DFS_27BIT : Specifies data frame size to 27bit 146 * @arg QSPI_DFS_28BIT : Specifies data frame size to 28bit 147 * @arg QSPI_DFS_29BIT : Specifies data frame size to 29bit 148 * @arg QSPI_DFS_30BIT : Specifies data frame size to 30bit 149 * @arg QSPI_DFS_31BIT : Specifies data frame size to 31bit 150 * @arg QSPI_DFS_32BIT : Specifies data frame size to 32bit 151 * 152 * @retval None 153 */ QSPI_ConfigDataFrameSize(QSPI_DFS_T dfs)154void QSPI_ConfigDataFrameSize(QSPI_DFS_T dfs) 155 { 156 QSPI->CTRL1_B.DFS = dfs; 157 } 158 159 /*! 160 * @brief Configure frame format 161 * 162 * @param frameFormat 163 * 164 * @retval None 165 */ QSPI_ConfigFrameFormat(QSPI_FRF_T frameFormat)166void QSPI_ConfigFrameFormat(QSPI_FRF_T frameFormat) 167 { 168 QSPI->CTRL1_B.FRF = frameFormat; 169 } 170 171 /*! 172 * @brief Enable QSPI 173 * 174 * @param None 175 * 176 * @retval None 177 */ QSPI_Enable(void)178void QSPI_Enable(void) 179 { 180 QSPI->SSIEN_B.EN = BIT_SET; 181 } 182 183 /*! 184 * @brief Disable QSPI 185 * 186 * @param None 187 * 188 * @retval None 189 */ QSPI_Disable(void)190void QSPI_Disable(void) 191 { 192 QSPI->SSIEN_B.EN = BIT_RESET; 193 } 194 195 /*! 196 * @brief Read Tx FIFO number of data 197 * 198 * @param None 199 * 200 * @retval None 201 */ QSPI_ReadTxFifoDataNum(void)202uint8_t QSPI_ReadTxFifoDataNum(void) 203 { 204 return (uint8_t)QSPI->TFL_B.TFL; 205 } 206 207 /*! 208 * @brief Read Rx FIFO number of data 209 * 210 * @param None 211 * 212 * @retval Returns Rx FIFO number of data 213 */ QSPI_ReadRxFifoDataNum(void)214uint8_t QSPI_ReadRxFifoDataNum(void) 215 { 216 return (uint8_t)QSPI->RFL_B.RFL; 217 } 218 219 /*! 220 * @brief Configure rx FIFO threshold 221 * 222 * @param threshold: Speicifes rx FIFO threshold with a 3bit value 223 * 224 * @retval None 225 */ QSPI_ConfigRxFifoThreshold(uint8_t threshold)226void QSPI_ConfigRxFifoThreshold(uint8_t threshold) 227 { 228 QSPI->RFTL_B.RFT = threshold; 229 } 230 231 /*! 232 * @brief Congfigure Tx FIFO threshold 233 * 234 * @param threshold: Speicifes Tx FIFO threshold with a 3bit value 235 * 236 * @retval None 237 */ QSPI_ConfigTxFifoThreshold(uint8_t threshold)238void QSPI_ConfigTxFifoThreshold(uint8_t threshold) 239 { 240 QSPI->TFTL_B.TFTH = threshold; 241 } 242 243 /*! 244 * @brief Congfigure Tx FIFO empty threshold 245 * 246 * @param threshold: Speicifes Tx FIFO empty threshold with a 3bit value 247 * 248 * @retval None 249 */ QSPI_ConfigTxFifoEmptyThreshold(uint8_t threshold)250void QSPI_ConfigTxFifoEmptyThreshold(uint8_t threshold) 251 { 252 QSPI->TFTL_B.TFT = threshold; 253 } 254 255 /*! 256 * @brief Configure RX sample edge 257 * 258 * @param rse: Specifies the sample edge 259 * The parameter can be one of following values: 260 * @arg QSPI_RSE_RISING : rising edge sample 261 * @arg QSPI_RSE_FALLING: falling edge sample 262 * 263 * @retval None 264 */ QSPI_ConfigRxSampleEdge(QSPI_RSE_T rse)265void QSPI_ConfigRxSampleEdge(QSPI_RSE_T rse) 266 { 267 QSPI->RSD_B.RSE = rse; 268 } 269 270 /*! 271 * @brief Set RX sample delay 272 * 273 * @param delay: Specifies the sample delay with a 8-bit value 274 * 275 * @retval None 276 */ QSPI_ConfigRxSampleDelay(uint8_t delay)277void QSPI_ConfigRxSampleDelay(uint8_t delay) 278 { 279 QSPI->RSD_B.RSD = delay; 280 } 281 282 /*! 283 * @brief Clock stretch enable 284 * 285 * @param None 286 * 287 * @retval None 288 */ QSPI_EnableClockStretch(void)289void QSPI_EnableClockStretch(void) 290 { 291 QSPI->CTRL3_B.CSEN = BIT_SET; 292 } 293 294 /*! 295 * @brief Clock stretch disable 296 * 297 * @param None 298 * 299 * @retval None 300 */ QSPI_DisableClockStretch(void)301void QSPI_DisableClockStretch(void) 302 { 303 QSPI->CTRL3_B.CSEN = BIT_RESET; 304 } 305 306 /*! 307 * @brief Configure instruction length 308 * 309 * @param len: Specifies the length of instruction 310 * The parameter can be one of following values: 311 * @arg QSPI_INST_LEN_0 : no instruction 312 * @arg QSPI_INST_LEN_4BIT : 4-bit instruction 313 * @arg QSPI_INST_LEN_8BIT : 8-bit instruction 314 * @arg QSPI_INST_LEN_16BIT : 16-bit instruction 315 * 316 * @retval None 317 */ QSPI_ConfigInstLen(QSPI_INST_LEN_T len)318void QSPI_ConfigInstLen(QSPI_INST_LEN_T len) 319 { 320 QSPI->CTRL3_B.INSLEN = len; 321 } 322 323 /*! 324 * @brief Configure address length 325 * 326 * @param len: Specifies the address length 327 * The parameter can be one of following values: 328 * @arg QSPI_ADDR_LEN_0 : no address 329 * @arg QSPI_ADDR_LEN_4BIT : 4-bit address length 330 * @arg QSPI_ADDR_LEN_8BIT, : 8-bit address length 331 * @arg QSPI_ADDR_LEN_12BIT : 12-bit address length 332 * @arg QSPI_ADDR_LEN_16BIT : 16-bit address length 333 * @arg QSPI_ADDR_LEN_20BIT : 20-bit address length 334 * @arg QSPI_ADDR_LEN_24BIT : 24-bit address length 335 * @arg QSPI_ADDR_LEN_28BIT : 28-bit address length 336 * @arg QSPI_ADDR_LEN_32BIT : 32-bit address length 337 * @arg QSPI_ADDR_LEN_36BIT : 36-bit address length 338 * @arg QSPI_ADDR_LEN_40BIT : 40-bit address length 339 * @arg QSPI_ADDR_LEN_44BIT : 44-bit address length 340 * @arg QSPI_ADDR_LEN_48BIT : 48-bit address length 341 * @arg QSPI_ADDR_LEN_52BIT : 52-bit address length 342 * @arg QSPI_ADDR_LEN_56BIT : 56-bit address length 343 * @arg QSPI_ADDR_LEN_60BIT : 60-bit address length 344 * 345 * @retval None 346 */ QSPI_ConfigAddrLen(QSPI_ADDR_LEN_T len)347void QSPI_ConfigAddrLen(QSPI_ADDR_LEN_T len) 348 { 349 QSPI->CTRL3_B.ADDRLEN = len; 350 } 351 352 /*! 353 * @brief Configure instruction and address type 354 * 355 * @param type: Specifies the instruction and address type 356 * The parameter can be one of following values: 357 * @arg QSPI_INST_ADDR_TYPE_STANDARD : Tx instruction in standard SPI mode, 358 * Tx address in standard SPI mode 359 * @arg QSPI_INST_TYPE_STANDARD : Tx instruction in standard SPI mode, 360 * Tx address in mode of SPI_FRF 361 * @arg QSPI_INST_ADDR_TYPE_FRF : Tx instruction in mode of SPI_FRF, 362 * Tx address in mode of SPI_FRF 363 * 364 * @retval None 365 */ QSPI_ConfigInstAddrType(QSPI_INST_ADDR_TYPE_T type)366void QSPI_ConfigInstAddrType(QSPI_INST_ADDR_TYPE_T type) 367 { 368 QSPI->CTRL3_B.IAT = type; 369 } 370 371 /*! 372 * @brief Configure wait cycle number 373 * 374 * @param cycle: Specifies the wait cycle number with a 5-bit value 375 * 376 * @retval None 377 */ QSPI_ConfigWaitCycle(uint8_t cycle)378void QSPI_ConfigWaitCycle(uint8_t cycle) 379 { 380 QSPI->CTRL3_B.WAITCYC = cycle; 381 } 382 383 /*! 384 * @brief Open QSPI GPIO 385 * 386 * @param None 387 * 388 * @retval None 389 */ QSPI_OpenIO(void)390void QSPI_OpenIO(void) 391 { 392 QSPI->IOSW_B.IOSW = BIT_SET; 393 } 394 395 /*! 396 * @brief Close QSPI GPIO 397 * 398 * @param None 399 * 400 * @retval None 401 */ QSPI_CloseIO(void)402void QSPI_CloseIO(void) 403 { 404 QSPI->IOSW_B.IOSW = BIT_RESET; 405 } 406 407 /*! 408 * @brief Set transmission mode 409 * 410 * @param mode: Specifies the transmission mode 411 * The parameter can be one of following values: 412 * @arg QSPI_TRANS_MODE_TX_RX : TX and RX mode 413 * @arg QSPI_TRANS_MODE_TX : TX mode only 414 * @arg QSPI_TRANS_MODE_RX : RX mode only 415 * @arg QSPI_TRANS_MODE_EEPROM_READ : EEPROM read mode 416 * 417 * @retval None 418 */ QSPI_ConfigTansMode(QSPI_TRANS_MODE_T mode)419void QSPI_ConfigTansMode(QSPI_TRANS_MODE_T mode) 420 { 421 QSPI->CTRL1_B.TXMODE = mode; 422 } 423 424 /*! 425 * @brief Transmit data 426 * 427 * @param data: Data to be transmited 428 * 429 * @retval None 430 */ QSPI_TxData(uint32_t data)431void QSPI_TxData(uint32_t data) 432 { 433 QSPI->DATA = data; 434 } 435 436 /*! 437 * @brief Return the most recent received data 438 * 439 * @param None 440 * 441 * @retval The received data 442 */ QSPI_RxData(void)443uint32_t QSPI_RxData(void) 444 { 445 return (uint32_t)QSPI->DATA; 446 } 447 448 /*! 449 * @brief Enable Slave 450 * 451 * @param None 452 * 453 * @retval None 454 */ QSPI_EnableSlave(void)455void QSPI_EnableSlave(void) 456 { 457 QSPI->SLAEN_B.SLAEN = BIT_SET; 458 } 459 460 /*! 461 * @brief Disable slave 462 * 463 * @param None 464 * 465 * @retval None 466 */ QSPI_DisableSlave(void)467void QSPI_DisableSlave(void) 468 { 469 QSPI->SLAEN_B.SLAEN = BIT_RESET; 470 } 471 472 /*! 473 * @brief Enable the specified QSPI interrupts 474 * 475 * @param interrupt: Specifies the QSPI interrupt sources 476 * The parameter can be combination of following values: 477 * @arg QSPI_INT_TFE: TX FIFO empty interrupt 478 * @arg QSPI_INT_TFO: TX FIFO overflow interrupt 479 * @arg QSPI_INT_RFU: RX FIFO underflow interrupt 480 * @arg QSPI_INT_RFO: RX FIFO overflow interrupt 481 * @arg QSPI_INT_RFF: RX FIFO full interrupt 482 * @arg QSPI_INT_MST: Master interrupt 483 * 484 * @retval None 485 */ QSPI_EnableInterrupt(uint32_t interrupt)486void QSPI_EnableInterrupt(uint32_t interrupt) 487 { 488 QSPI->INTEN |= interrupt; 489 } 490 491 /*! 492 * @brief Disable the specified QSPI interrupts 493 * 494 * @param interrupt: Specifies the QSPI interrupt sources 495 * The parameter can be combination of following values: 496 * @arg QSPI_INT_TFE: TX FIFO empty interrupt 497 * @arg QSPI_INT_TFO: TX FIFO overflow interrupt 498 * @arg QSPI_INT_RFU: RX FIFO underflow interrupt 499 * @arg QSPI_INT_RFO: RX FIFO overflow interrupt 500 * @arg QSPI_INT_RFF: RX FIFO full interrupt 501 * @arg QSPI_INT_MST: Master interrupt 502 * 503 * @retval None 504 */ QSPI_DisableInterrupt(uint32_t interrupt)505void QSPI_DisableInterrupt(uint32_t interrupt) 506 { 507 QSPI->INTEN &= (uint32_t)~interrupt; 508 } 509 510 /*! 511 * @brief Read specified QSPI flag 512 * 513 * @param flag: Specifies the flag to be checked 514 * The parameter can be one of following values: 515 * @arg QSPI_FLAG_BUSY: Busy flag 516 * @arg QSPI_FLAG_TFNF: TX FIFO not full flag 517 * @arg QSPI_FLAG_TFE: TX FIFO empty flag 518 * @arg QSPI_FLAG_RFNE: RX FIFO not empty flag 519 * @arg QSPI_FLAG_RFF: RX FIFO full flag 520 * @arg QSPI_FLAG_DCE: Data collision error 521 * 522 * @retval The new state of flag (SET or RESET) 523 */ QSPI_ReadStatusFlag(QSPI_FLAG_T flag)524uint8_t QSPI_ReadStatusFlag(QSPI_FLAG_T flag) 525 { 526 uint8_t ret = RESET; 527 528 ret = QSPI->STS & flag ? SET : RESET; 529 530 return ret; 531 } 532 533 /*! 534 * @brief Clear specified QSPI flag 535 * 536 * @param None 537 * 538 * @retval None 539 * 540 * @note This funtion only clear Data collision error flag(QSPI_FLAG_DCE) 541 */ QSPI_ClearStatusFlag(void)542void QSPI_ClearStatusFlag(void) 543 { 544 volatile uint32_t dummy = 0; 545 546 dummy = QSPI->STS; 547 } 548 549 /*! 550 * @brief Read specified QSPI interrupt flag 551 * 552 * @param flag: Specifies the interrupt flag to be checked 553 * The parameter can be one of following values: 554 * @arg QSPI_INT_FLAG_TFE: TX FIFO empty interrupt flag 555 * @arg QSPI_INT_FLAG_TFO: TX FIFO overflow interrupt flag 556 * @arg QSPI_INT_FLAG_RFU: RX FIFO underflow interrupt flag 557 * @arg QSPI_INT_FLAG_RFO: RX FIFO overflow interrupt flag 558 * @arg QSPI_INT_FLAG_RFF: RX FIFO full interrupt flag 559 * @arg QSPI_INT_FLAG_MST: Master interrupt flag 560 * 561 * @retval The new state of flag (SET or RESET) 562 */ QSPI_ReadIntFlag(QSPI_INT_FLAG_T flag)563uint8_t QSPI_ReadIntFlag(QSPI_INT_FLAG_T flag) 564 { 565 uint8_t ret = RESET; 566 567 ret = QSPI->ISTS & flag ? SET : RESET; 568 569 return ret; 570 } 571 572 /*! 573 * @brief Clear specified QSPI interrupt flag 574 * 575 * @param flag: Specifies the interrupt flag to be checked 576 * The parameter can be one of following values: 577 * @arg QSPI_INT_FLAG_TFO: TX FIFO overflow interrupt flag 578 * @arg QSPI_INT_FLAG_RFU: RX FIFO underflow interrupt flag 579 * @arg QSPI_INT_FLAG_RFO: RX FIFO overflow interrupt flag 580 * @arg QSPI_INT_FLAG_MST: Master interrupt flag 581 * 582 * @retval None 583 */ QSPI_ClearIntFlag(uint32_t flag)584void QSPI_ClearIntFlag(uint32_t flag) 585 { 586 volatile uint32_t dummy = 0; 587 588 if (flag & QSPI_INT_FLAG_TFO) 589 { 590 dummy = QSPI->TFOIC; 591 } 592 else if (flag & QSPI_INT_FLAG_RFO) 593 { 594 dummy = QSPI->RFOIC; 595 } 596 else if (flag & QSPI_INT_FLAG_RFU) 597 { 598 dummy = QSPI->RFUIC; 599 } 600 else if (flag & QSPI_INT_FLAG_MST) 601 { 602 dummy = QSPI->MIC; 603 } 604 } 605 606 /**@} end of group QSPI_Functions */ 607 /**@} end of group QSPI_Driver */ 608 /**@} end of group APM32S10x_StdPeriphDriver */ 609