| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161 |
- /*
- * Copyright (c) 2022 OpenLuat & AirM2M
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
- #include "user.h"
- #define HSPIM_CR0_CLEAR_MASK ((uint32_t)~0xFFEEFFFF)
- #define HSPIM_CR0_MODE_SELECT_CLEAR_MASK ((uint32_t)~0x1C00)
- #define HSPIM_CR1_CLEAR_MASK ((uint32_t)~0xFFFFF)
- #define HSPIM_FCR_CLEAR_MASK ((uint32_t)~0x3F3F3F00)
- #define HSPIM_DCR_RECEIVE_LEVEL_CLEAR_MASK ((uint32_t)~0x3F80)
- #define HSPIM_DCR_TRANSMIT_LEVEL_CLEAR_MASK ((uint32_t)~0x7F)
- #define HSPIM_CR0_PARAM_ENABLE_POS (0x18)
- #define HSPIM_CR0_PARAM_DMA_RECEIVE_ENABLE_POS (0x14)
- #define HSPIM_CR0_PARAM_DMA_TRANSMIT_ENABLE_POS (0x10)
- #define HSPIM_CR0_PARAM_INTERRPUT_RX_POS (0x0F)
- #define HSPIM_CR0_PARAM_INTERRPUT_TX_POS (0x0E)
- #define HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS (0x0D)
- #define HSPIM_CR0_PARAM_MODEL_SELECT_POS (0x0A)
- #define HSPIM_CR0_PARAM_FIRST_BIT_POS (0x09)
- #define HSPIM_CR0_PARAM_CPOL_POS (0x08)
- #define HSPIM_CR0_PARAM_CPHA_POS (0x07)
- #define HSPIM_CR0_PARAM_DIVIDE_ENABLE_POS (0x02)
- #define HSPIM_CR0_PARAM_TRANSMIT_ENABLE_POS (0x01)
- #define HSPIM_CR0_PARAM_BUSY_POS (0x00)
- #define HSPIM_CR1_PARAM_BAUDRATE_POS (0x0A)
- #define HSPIM_CR1_PARAM_RECEIVE_DATA_LENGTH_POS (0x00)
- #define HSPIM_DCR_PARAM_DMA_RECEIVE_LEVEL_POS (0x07)
- #define HSPIM_DCR_PARAM_DMA_TRANSMIT_LEVEL_POS (0x00)
- #define HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS (0x08)
- #define HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS (0x10)
- #define HSPIM_SR_PUSH_FULL_TX (1 << 4)
- #define HSPIM_SR_POP_EMPTY_RX (1 << 10)
- #define HSPIM_FIFO_TX_NUM (64)
- #define HSPIM_FIFO_RX_NUM (64)
- #define HSPIM_FIFO_LEVEL (48)
- #define SPIM_FIFO_TX_NUM (16)
- #define SPIM_FIFO_RX_NUM (16)
- #define SPIM_FIFO_RX_LEVEL (7)
- #define SPIM_FIFO_TX_LEVEL (8)
- typedef struct
- {
- const volatile void *RegBase;
- const int32_t IrqLine;
- const uint16_t DMATxChannel;
- const uint16_t DMARxChannel;
- CBFuncEx_t Callback;
- void *pParam;
- HANDLE Sem;
- Buffer_Struct TxBuf;
- Buffer_Struct RxBuf;
- uint32_t Speed;
- uint8_t DMATxStream;
- uint8_t DMARxStream;
- uint8_t Is16Bit;
- uint8_t IsOnlyTx;
- uint8_t IsBusy;
- uint8_t IsBlockMode;
- }SPI_ResourceStruct;
- static SPI_ResourceStruct prvSPI[SPI_MAX] = {
- {
- HSPIM,
- SPI5_IRQn,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_HSPI_TX,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_HSPI_RX,
- },
- {
- SPIM0,
- SPI0_IRQn,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_TX,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_RX,
- },
- {
- SPIM1,
- SPI1_IRQn,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI1_TX,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI1_RX,
- },
- {
- SPIM2,
- SPI2_IRQn,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI2_TX,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI2_RX,
- },
- {
- SPIS0,
- SPI0_IRQn,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_TX,
- SYSCTRL_PHER_CTRL_DMA_CHx_IF_SPI0_RX,
- },
- };
- static void HSPI_IrqHandle(int32_t IrqLine, void *pData)
- {
- uint32_t SpiID = HSPI_ID0;
- uint32_t RxLevel, i, TxLen;
- HSPIM_TypeDef *SPI = HSPIM;
- volatile uint32_t DummyData;
- if (!prvSPI[SpiID].IsBusy)
- {
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- return;
- }
- if (prvSPI[SpiID].RxBuf.Data)
- {
- while (prvSPI[SpiID].RxBuf.Pos < prvSPI[SpiID].RxBuf.MaxLen)
- {
- if (SPI->SR & HSPIM_SR_POP_EMPTY_RX)
- {
- break;
- }
- else
- {
- prvSPI[SpiID].RxBuf.Data[prvSPI[SpiID].RxBuf.Pos] = SPI->RDR;
- prvSPI[SpiID].RxBuf.Pos++;
- }
- }
- }
- else
- {
- while (prvSPI[SpiID].RxBuf.Pos < prvSPI[SpiID].RxBuf.MaxLen)
- {
- if (SPI->SR & HSPIM_SR_POP_EMPTY_RX)
- {
- break;
- }
- else
- {
- DummyData = SPI->RDR;
- prvSPI[SpiID].RxBuf.Pos++;
- }
- }
- }
- if (prvSPI[SpiID].RxBuf.Pos >= prvSPI[SpiID].RxBuf.MaxLen)
- {
- SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- prvSPI[SpiID].IsBusy = 0;
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- if ((prvSPI[SpiID].TxBuf.Pos != prvSPI[SpiID].RxBuf.Pos) || (prvSPI[SpiID].RxBuf.Pos != prvSPI[SpiID].RxBuf.MaxLen))
- {
- DBG("%u, %u", prvSPI[SpiID].TxBuf.Pos, prvSPI[SpiID].RxBuf.Pos);
- }
- #ifdef __BUILD_OS__
- if (prvSPI[SpiID].IsBlockMode)
- {
- OS_MutexRelease(prvSPI[SpiID].Sem);
- }
- #endif
- PM_SetHardwareRunFlag(PM_HW_HSPI, 0);
- prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
- return;
- }
- if (prvSPI[SpiID].TxBuf.Pos < prvSPI[SpiID].TxBuf.MaxLen)
- {
- i = 0;
- TxLen = (HSPIM_FIFO_TX_NUM - (SPI->FSR & 0x0000003f));
- if (TxLen > (prvSPI[SpiID].TxBuf.MaxLen -prvSPI[SpiID].TxBuf.Pos))
- {
- TxLen = prvSPI[SpiID].TxBuf.MaxLen - prvSPI[SpiID].TxBuf.Pos;
- }
- while((i < TxLen))
- {
- SPI->WDR = prvSPI[SpiID].TxBuf.Data[prvSPI[SpiID].TxBuf.Pos + i];
- i++;
- }
- prvSPI[SpiID].TxBuf.Pos += TxLen;
- if (prvSPI[SpiID].TxBuf.Pos >= prvSPI[SpiID].TxBuf.MaxLen)
- {
- SPI->FCR = (63 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(0 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(63);
- SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- SPI->CR0 |= (5 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- }
- }
- else
- {
- SPI->FCR = (63 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(0 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(63);
- SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- SPI->CR0 |= (5 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- }
- }
- static int32_t SPI_DMADoneCB(void *pData, void *pParam)
- {
- uint32_t SpiID = (uint32_t)pData;
- uint32_t RxLevel;
- if (prvSPI[SpiID].RxBuf.MaxLen > prvSPI[SpiID].RxBuf.Pos)
- {
- RxLevel = ((prvSPI[SpiID].RxBuf.MaxLen - prvSPI[SpiID].RxBuf.Pos) > 4080)?4000:(prvSPI[SpiID].RxBuf.MaxLen - prvSPI[SpiID].RxBuf.Pos);
- DMA_ClearStreamFlag(prvSPI[SpiID].DMATxStream);
- DMA_ClearStreamFlag(prvSPI[SpiID].DMARxStream);
- if (prvSPI[SpiID].IsOnlyTx)
- {
- DMA_ForceStartStream(prvSPI[SpiID].DMATxStream, &prvSPI[SpiID].TxBuf.Data[prvSPI[SpiID].TxBuf.Pos], RxLevel, SPI_DMADoneCB, (void *)SpiID, 1);
- // DMA_ForceStartStream(prvSPI[SpiID].DMARxStream, &prvSPI[SpiID].RxBuf.Data[prvSPI[SpiID].RxBuf.Pos], RxLevel, NULL, NULL, 0);
- }
- else
- {
- DMA_ForceStartStream(prvSPI[SpiID].DMATxStream, &prvSPI[SpiID].TxBuf.Data[prvSPI[SpiID].TxBuf.Pos], RxLevel, NULL, NULL, 0);
- DMA_ForceStartStream(prvSPI[SpiID].DMARxStream, &prvSPI[SpiID].RxBuf.Data[prvSPI[SpiID].RxBuf.Pos], RxLevel, SPI_DMADoneCB, (void *)SpiID, 1);
- }
- prvSPI[SpiID].RxBuf.Pos += RxLevel;
- prvSPI[SpiID].TxBuf.Pos += RxLevel;
- }
- else
- {
- prvSPI[SpiID].IsBusy = 0;
- if ((prvSPI[SpiID].TxBuf.Pos != prvSPI[SpiID].RxBuf.Pos) || (prvSPI[SpiID].RxBuf.Pos != prvSPI[SpiID].RxBuf.MaxLen))
- {
- DBG("%u, %u", prvSPI[SpiID].TxBuf.Pos, prvSPI[SpiID].RxBuf.Pos);
- }
- #ifdef __BUILD_OS__
- if (prvSPI[SpiID].IsBlockMode)
- {
- OS_MutexRelease(prvSPI[SpiID].Sem);
- }
- #endif
- if (SpiID)
- {
- PM_SetHardwareRunFlag(PM_HW_HSPI, 0);
- }
- else
- {
- PM_SetHardwareRunFlag(PM_HW_SPI_0 + SpiID - 1, 0);
- }
- prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
- }
- }
- static void SPI_IrqHandle(int32_t IrqLine, void *pData)
- {
- uint32_t SpiID = (uint32_t)pData;
- volatile uint32_t DummyData;
- uint32_t RxLevel, SR, i, TxLen;
- SPI_TypeDef *SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
- if (!prvSPI[SpiID].IsBusy)
- {
- SR = SPI->ICR;
- SPI->IMR = 0;
- SPI->SER = 0;
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- return;
- }
- TxLen = SPIM_FIFO_TX_NUM - SPI->TXFLR;
- SR = SPI->ICR;
- if (prvSPI[SpiID].RxBuf.Data)
- {
- while(SPI->RXFLR)
- {
- prvSPI[SpiID].RxBuf.Data[prvSPI[SpiID].RxBuf.Pos] = SPI->DR;
- prvSPI[SpiID].RxBuf.Pos++;
- }
- }
- else
- {
- while(SPI->RXFLR)
- {
- DummyData = SPI->DR;
- prvSPI[SpiID].RxBuf.Pos++;
- }
- }
- if (prvSPI[SpiID].RxBuf.Pos >= prvSPI[SpiID].RxBuf.MaxLen)
- {
- SR = SPI->ICR;
- SPI->IMR = 0;
- SPI->SER = 0;
- prvSPI[SpiID].IsBusy = 0;
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- if (prvSPI[SpiID].TxBuf.Pos != prvSPI[SpiID].RxBuf.Pos)
- {
- DBG("%u, %u", prvSPI[SpiID].TxBuf.Pos, prvSPI[SpiID].RxBuf.Pos);
- }
- #ifdef __BUILD_OS__
- if (prvSPI[SpiID].IsBlockMode)
- {
- OS_MutexRelease(prvSPI[SpiID].Sem);
- }
- #endif
- PM_SetHardwareRunFlag(PM_HW_SPI_0 + SpiID - 1, 0);
- prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
- return;
- }
- if (prvSPI[SpiID].TxBuf.Pos < prvSPI[SpiID].TxBuf.MaxLen)
- {
- i = 0;
- if (TxLen > (prvSPI[SpiID].TxBuf.MaxLen -prvSPI[SpiID].TxBuf.Pos))
- {
- TxLen = prvSPI[SpiID].TxBuf.MaxLen - prvSPI[SpiID].TxBuf.Pos;
- }
- while((i < TxLen))
- {
- SPI->DR = prvSPI[SpiID].TxBuf.Data[prvSPI[SpiID].TxBuf.Pos + i];
- i++;
- }
- prvSPI[SpiID].TxBuf.Pos += i;
- }
- else
- {
- if ((prvSPI[SpiID].RxBuf.MaxLen - prvSPI[SpiID].RxBuf.Pos) >= SPIM_FIFO_RX_NUM)
- {
- SPI->RXFTLR = (SPIM_FIFO_RX_NUM - 1);
- }
- else
- {
- SPI->RXFTLR = prvSPI[SpiID].RxBuf.MaxLen - prvSPI[SpiID].RxBuf.Pos - 1;
- }
- SPI->IMR = SPI_IMR_RXOIM|SPI_IMR_RXFIM;
- }
- }
- static int32_t SPI_DummyCB(void *pData, void *pParam)
- {
- return 0;
- }
- static void HSPI_MasterInit(uint8_t SpiID, uint8_t Mode, uint32_t Speed)
- {
- HSPIM_TypeDef *SPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
- uint32_t div = (SystemCoreClock / Speed) >> 1;
- uint32_t ctrl = (1 << 24) | (1 << 10) | (1 << 2) | (1 << 1);
- switch(Mode)
- {
- case SPI_MODE_0:
- break;
- case SPI_MODE_1:
- ctrl |= (1 << HSPIM_CR0_PARAM_CPHA_POS);
- break;
- case SPI_MODE_2:
- ctrl |= (1 << HSPIM_CR0_PARAM_CPOL_POS);
- break;
- case SPI_MODE_3:
- ctrl |= (1 << HSPIM_CR0_PARAM_CPOL_POS)|(1 << HSPIM_CR0_PARAM_CPHA_POS);
- break;
- }
- SPI->CR1 = (div << HSPIM_CR1_PARAM_BAUDRATE_POS) + 1;
- SPI->CR0 = ctrl;
- SPI->DCR = 30|(1 << 7);
- prvSPI[SpiID].Speed = (SystemCoreClock >> 1) / div;
- ISR_SetHandler(prvSPI[SpiID].IrqLine, HSPI_IrqHandle, (uint32_t)SpiID);
- #ifdef __BUILD_OS__
- ISR_SetPriority(prvSPI[SpiID].IrqLine, IRQ_MAX_PRIORITY + 1);
- #else
- ISR_SetPriority(prvSPI[SpiID].IrqLine, 3);
- #endif
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- }
- void SPI_MasterInit(uint8_t SpiID, uint8_t DataBit, uint8_t Mode, uint32_t Speed, CBFuncEx_t CB, void *pUserData)
- {
- SPI_TypeDef *SPI;
- uint32_t ctrl;
- uint32_t div;
- switch(SpiID)
- {
- case HSPI_ID0:
- HSPI_MasterInit(SpiID, Mode, Speed);
- break;
- case SPI_ID0:
- SYSCTRL->PHER_CTRL &= ~SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
- case SPI_ID1:
- case SPI_ID2:
- SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
- SPI->SSIENR = 0;
- SPI->SER = 0;
- SPI->IMR = 0;
- SPI->DMACR = 0;
- ctrl = DataBit - 1;
- switch(Mode)
- {
- case SPI_MODE_0:
- break;
- case SPI_MODE_1:
- ctrl |= SPI_CTRLR0_SCPH;
- break;
- case SPI_MODE_2:
- ctrl |= SPI_CTRLR0_SCPOL;
- break;
- case SPI_MODE_3:
- ctrl |= SPI_CTRLR0_SCPOL|SPI_CTRLR0_SCPH;
- break;
- }
- div = (SystemCoreClock >> 2) / Speed;
- if (div % 2) div++;
- prvSPI[SpiID].Speed = (SystemCoreClock >> 2) / div;
- SPI->CTRLR0 = ctrl;
- SPI->BAUDR = div;
- SPI->TXFTLR = 0;
- SPI->RXFTLR = 0;
- SPI->DMATDLR = 7;
- SPI->DMARDLR = 0;
- ISR_SetHandler(prvSPI[SpiID].IrqLine, SPI_IrqHandle, (uint32_t)SpiID);
- #ifdef __BUILD_OS__
- ISR_SetPriority(prvSPI[SpiID].IrqLine, IRQ_LOWEST_PRIORITY - 2);
- #else
- ISR_SetPriority(prvSPI[SpiID].IrqLine, 5);
- #endif
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- SPI->SSIENR = 1;
- break;
- // case SPI_ID3:
- // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
- // break;
- default:
- return;
- }
- prvSPI[SpiID].DMATxStream = 0xff;
- prvSPI[SpiID].DMARxStream = 0xff;
- if (CB)
- {
- prvSPI[SpiID].Callback = CB;
- }
- else
- {
- prvSPI[SpiID].Callback = SPI_DummyCB;
- }
- prvSPI[SpiID].pParam = pUserData;
- #ifdef __BUILD_OS__
- if (!prvSPI[SpiID].Sem)
- {
- prvSPI[SpiID].Sem = OS_MutexCreate();
- }
- #endif
- }
- void SPI_SetTxOnlyFlag(uint8_t SpiID, uint8_t OnOff)
- {
- prvSPI[SpiID].IsOnlyTx = OnOff;
- }
- void SPI_SetCallbackFun(uint8_t SpiID, CBFuncEx_t CB, void *pUserData)
- {
- if (CB)
- {
- prvSPI[SpiID].Callback = CB;
- }
- else
- {
- prvSPI[SpiID].Callback = SPI_DummyCB;
- }
- prvSPI[SpiID].pParam = pUserData;
- }
- static void SPI_DMATransfer(uint8_t SpiID, uint8_t UseDMA)
- {
- uint32_t RxLevel;
- RxLevel = (prvSPI[SpiID].RxBuf.MaxLen > 4080)?4000:prvSPI[SpiID].RxBuf.MaxLen;
- prvSPI[SpiID].RxBuf.Pos += RxLevel;
- prvSPI[SpiID].TxBuf.Pos += RxLevel;
- DMA_StopStream(prvSPI[SpiID].DMATxStream);
- DMA_StopStream(prvSPI[SpiID].DMARxStream);
- if (prvSPI[SpiID].IsOnlyTx)
- {
- DMA_ForceStartStream(prvSPI[SpiID].DMATxStream, prvSPI[SpiID].TxBuf.Data, RxLevel, SPI_DMADoneCB, (void *)SpiID, 1);
- // DMA_ForceStartStream(prvSPI[SpiID].DMARxStream, prvSPI[SpiID].RxBuf.Data, RxLevel, NULL, NULL, 0);
- }
- else
- {
- DMA_ForceStartStream(prvSPI[SpiID].DMATxStream, prvSPI[SpiID].TxBuf.Data, RxLevel, NULL, NULL, 0);
- DMA_ForceStartStream(prvSPI[SpiID].DMARxStream, prvSPI[SpiID].RxBuf.Data, RxLevel, SPI_DMADoneCB, (void *)SpiID, 1);
- }
- }
- static int32_t HSPI_Transfer(uint8_t SpiID, uint8_t UseDMA)
- {
- HSPIM_TypeDef *SPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
- uint32_t TxLen, i;
- PM_SetHardwareRunFlag(PM_HW_HSPI, 1);
- if (UseDMA)
- {
- SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- SPI->CR0 |= (1 << HSPIM_CR0_PARAM_DMA_TRANSMIT_ENABLE_POS)|(1 << HSPIM_CR0_PARAM_DMA_RECEIVE_ENABLE_POS);
- SPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(0 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
- SPI->FCR &= ~(3 << 6);
- SPI_DMATransfer(SpiID, UseDMA);
- }
- else
- {
- SPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- // SPI->CR0 &= ~(1 << 10);
- SPI->CR0 &= ~((1 << HSPIM_CR0_PARAM_DMA_TRANSMIT_ENABLE_POS)|(1 << HSPIM_CR0_PARAM_DMA_RECEIVE_ENABLE_POS));
- if (prvSPI[SpiID].TxBuf.MaxLen <= HSPIM_FIFO_TX_NUM)
- {
- TxLen = prvSPI[SpiID].TxBuf.MaxLen;
- SPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|((TxLen - 1) << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
- SPI->CR0 |= (5 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- }
- else
- {
- TxLen = HSPIM_FIFO_TX_NUM;
- SPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(63 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
- SPI->CR0 |= (3 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- }
- SPI->FCR &= ~(3 << 6);
- for(i = 0; i < TxLen; i++)
- {
- SPI->WDR = prvSPI[SpiID].TxBuf.Data[i];
- }
- prvSPI[SpiID].TxBuf.Pos += TxLen;
- // SPI->CR0 |= (1 << 10);
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 1);
- return ERROR_NONE;
- }
- return ERROR_NONE;
- }
- int32_t SPI_Transfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint32_t Len, uint8_t UseDMA)
- {
- uint32_t SR;
- SPI_TypeDef *SPI;
- if (prvSPI[SpiID].IsBusy)
- {
- return -ERROR_DEVICE_BUSY;
- }
- prvSPI[SpiID].IsBusy = 1;
- uint32_t RxLevel, i, TxLen;
- Buffer_StaticInit(&prvSPI[SpiID].TxBuf, TxData, Len);
- Buffer_StaticInit(&prvSPI[SpiID].RxBuf, RxData, Len);
- switch(SpiID)
- {
- case HSPI_ID0:
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- return HSPI_Transfer(SpiID, UseDMA);
- case SPI_ID0:
- SYSCTRL->PHER_CTRL &= ~SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
- case SPI_ID1:
- case SPI_ID2:
- break;
- // case SPI_ID3:
- // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
- // break;
- default:
- return -ERROR_ID_INVALID;
- }
- PM_SetHardwareRunFlag(PM_HW_SPI_0 + SpiID - 1, 1);
- SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
- SPI->SER = 0;
- if (UseDMA)
- {
- SR = SPI->ICR;
- SPI->IMR = 0;
- SPI->DMACR = SPI_DMACR_RDMAE|SPI_DMACR_TDMAE;
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- SPI->SER = 1;
- SPI_DMATransfer(SpiID, 1);
- }
- else
- {
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- if (prvSPI[SpiID].RxBuf.MaxLen <= SPIM_FIFO_RX_NUM)
- {
- SPI->RXFTLR = prvSPI[SpiID].RxBuf.MaxLen - 1;
- TxLen = prvSPI[SpiID].RxBuf.MaxLen;
- SPI->IMR = SPI_IMR_RXOIM|SPI_IMR_RXFIM;
- }
- else
- {
- SPI->IMR = SPI_IMR_TXEIM;
- SPI->RXFTLR = SPIM_FIFO_RX_LEVEL;
- SPI->TXFTLR = SPIM_FIFO_TX_LEVEL;
- TxLen = SPIM_FIFO_TX_NUM;
- }
- for(i = 0; i < TxLen; i++)
- {
- SPI->DR = prvSPI[SpiID].TxBuf.Data[i];
- }
- prvSPI[SpiID].TxBuf.Pos += TxLen;
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 1);
- }
- SPI->SER = 1;
- return ERROR_NONE;
- }
- static int32_t prvSPI_BlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint32_t Len)
- {
- volatile uint32_t DummyData;
- uint32_t TxLen, RxLen, i, To;
- HSPIM_TypeDef *HSPI;
- SPI_TypeDef *SPI;
- prvSPI[SpiID].IsBusy = 1;
- switch(SpiID)
- {
- case HSPI_ID0:
- HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- HSPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(32 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
- HSPI->FCR &= ~(3 << 6);
- HSPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- if (Len <= HSPIM_FIFO_TX_NUM)
- {
- TxLen = Len;
- }
- else
- {
- TxLen = HSPIM_FIFO_TX_NUM;
- }
- for(i = 0; i < TxLen; i++)
- {
- HSPI->WDR = TxData[i];
- }
- if (RxData)
- {
- for(RxLen = 0; RxLen < Len; RxLen++)
- {
- while (HSPI->SR & HSPIM_SR_POP_EMPTY_RX)
- {
- ;
- }
- RxData[RxLen] = HSPI->RDR;
- if (TxLen < Len)
- {
- HSPI->WDR = TxData[TxLen];
- TxLen++;
- }
- }
- }
- else
- {
- while(TxLen < Len)
- {
- while ((HSPI->FSR & 0x7f) > 16)
- {
- ;
- }
- HSPI->WDR = TxData[TxLen];
- TxLen++;
- }
- while ((HSPI->FSR & 0x7f))
- {
- ;
- }
- // for(RxLen = 0; RxLen < Len; RxLen++)
- // {
- // while (HSPI->SR & HSPIM_SR_POP_EMPTY_RX)
- // {
- // ;
- // }
- // DummyData = HSPI->RDR;
- // if (TxLen < Len)
- // {
- // HSPI->WDR = TxData[TxLen];
- // TxLen++;
- // }
- // }
- }
- break;
- case SPI_ID0:
- case SPI_ID1:
- case SPI_ID2:
- SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- SPI->SER = 0;
- if (Len <= SPIM_FIFO_TX_NUM)
- {
- TxLen = Len;
- }
- else
- {
- TxLen = SPIM_FIFO_TX_NUM;
- }
- for(i = 0; i < TxLen; i++)
- {
- SPI->DR = TxData[i];
- }
- SPI->SER = 1;
- if (RxData)
- {
- for(RxLen = 0; RxLen < Len; RxLen++)
- {
- while (!SPI->RXFLR)
- {
- ;
- }
- RxData[RxLen] = SPI->DR;
- if (TxLen < Len)
- {
- SPI->DR = TxData[TxLen];
- TxLen++;
- }
- }
- }
- else
- {
- for(RxLen = 0; RxLen < Len; RxLen++)
- {
- while (!SPI->RXFLR)
- {
- ;
- }
- DummyData = SPI->DR;
- if (TxLen < Len)
- {
- SPI->DR = TxData[TxLen];
- TxLen++;
- }
- }
- }
- SPI->SER = 0;
- break;
- }
- prvSPI[SpiID].IsBusy = 0;
- prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
- return 0;
- }
- int32_t SPI_BlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint8_t *RxData, uint32_t Len)
- {
- #ifdef __BUILD_OS__
- if ( (prvSPI[SpiID].DMARxStream == 0xff) || (prvSPI[SpiID].DMATxStream == 0xff) || OS_CheckInIrq() || ((prvSPI[SpiID].Speed >> 3) >= (Len * 100000)))
- {
- prvSPI[SpiID].IsBlockMode = 0;
- #endif
- return prvSPI_BlockTransfer(SpiID, TxData, RxData, Len);
- #ifdef __BUILD_OS__
- }
- int32_t Result;
- uint32_t Time = (Len * 1000) / (prvSPI[SpiID].Speed >> 3);
- prvSPI[SpiID].IsBlockMode = 1;
- if (TxData)
- {
- Result = SPI_Transfer(SpiID, TxData, RxData, Len, 1);
- }
- else
- {
- Result = SPI_Transfer(SpiID, RxData, RxData, Len, 1);
- }
- if (Result)
- {
- prvSPI[SpiID].IsBlockMode = 0;
- DBG("!");
- return Result;
- }
- if (OS_MutexLockWtihTime(prvSPI[SpiID].Sem, Time + 10))
- {
- DBG("!!!");
- SPI_TransferStop(SpiID);
- prvSPI[SpiID].IsBlockMode = 0;
- return -1;
- }
- prvSPI[SpiID].IsBlockMode = 0;
- return 0;
- #endif
- }
- static int32_t prvSPI_FlashBlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint32_t WLen, uint8_t *RxData, uint32_t RLen)
- {
- volatile uint32_t DummyData;
- uint32_t TxLen, RxLen, i;
- HSPIM_TypeDef *HSPI;
- SPI_TypeDef *SPI;
- prvSPI[SpiID].IsBusy = 1;
- switch(SpiID)
- {
- case HSPI_ID0:
- HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
- HSPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(32 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
- HSPI->FCR &= ~(3 << 6);
- HSPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- if (WLen <= HSPIM_FIFO_TX_NUM)
- {
- TxLen = WLen;
- }
- else
- {
- TxLen = HSPIM_FIFO_TX_NUM;
- }
- for(i = 0; i < TxLen; i++)
- {
- HSPI->WDR = TxData[i];
- }
- for(RxLen = 0; RxLen < WLen; RxLen++)
- {
- while (HSPI->SR & HSPIM_SR_POP_EMPTY_RX)
- {
- ;
- }
- DummyData = HSPI->RDR;
- if (TxLen < WLen)
- {
- HSPI->WDR = TxData[TxLen];
- TxLen++;
- }
- }
- if (RLen <= HSPIM_FIFO_TX_NUM)
- {
- TxLen = RLen;
- }
- else
- {
- TxLen = HSPIM_FIFO_TX_NUM;
- }
- for(i = 0; i < TxLen; i++)
- {
- HSPI->WDR = TxData[i];
- }
- for(RxLen = 0; RxLen < RLen; RxLen++)
- {
- while (HSPI->SR & HSPIM_SR_POP_EMPTY_RX)
- {
- ;
- }
- RxData[RxLen] = HSPI->RDR;
- if (TxLen < RLen)
- {
- HSPI->WDR = 0xff;
- TxLen++;
- }
- }
- break;
- case SPI_ID0:
- case SPI_ID1:
- case SPI_ID2:
- SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- SPI->SER = 0;
- if (WLen <= SPIM_FIFO_TX_NUM)
- {
- TxLen = WLen;
- }
- else
- {
- TxLen = SPIM_FIFO_TX_NUM;
- }
- for(i = 0; i < TxLen; i++)
- {
- SPI->DR = TxData[i];
- }
- SPI->SER = 1;
- for(RxLen = 0; RxLen < WLen; RxLen++)
- {
- while (!SPI->RXFLR)
- {
- ;
- }
- DummyData = SPI->DR;
- if (TxLen < WLen)
- {
- SPI->DR = TxData[TxLen];
- TxLen++;
- }
- }
- if (RLen <= SPIM_FIFO_TX_NUM)
- {
- TxLen = RLen;
- }
- else
- {
- TxLen = SPIM_FIFO_TX_NUM;
- }
- for(i = 0; i < TxLen; i++)
- {
- SPI->DR = TxData[i];
- }
- for(RxLen = 0; RxLen < RLen; RxLen++)
- {
- while (!SPI->RXFLR)
- {
- ;
- }
- RxData[RxLen] = SPI->DR;
- if (TxLen < RLen)
- {
- SPI->DR = 0xff;
- TxLen++;
- }
- }
- SPI->SER = 0;
- break;
- }
- prvSPI[SpiID].IsBusy = 0;
- prvSPI[SpiID].Callback((void *)SpiID, prvSPI[SpiID].pParam);
- return 0;
- }
- int32_t SPI_FlashBlockTransfer(uint8_t SpiID, const uint8_t *TxData, uint32_t WLen, uint8_t *RxData, uint32_t RLen)
- {
- #ifdef __BUILD_OS__
- if ( (prvSPI[SpiID].DMARxStream == 0xff) || (prvSPI[SpiID].DMATxStream == 0xff) || OS_CheckInIrq() || ((prvSPI[SpiID].Speed >> 3) >= ((WLen + RLen) * 100000)))
- {
- prvSPI[SpiID].IsBlockMode = 0;
- #endif
- return prvSPI_FlashBlockTransfer(SpiID, TxData, WLen, RxData, RLen);
- #ifdef __BUILD_OS__
- }
- int32_t Result;
- uint32_t Time = ((WLen + RLen) * 1000) / (prvSPI[SpiID].Speed >> 3);
- uint8_t *Temp = malloc(WLen + RLen);
- memcpy(Temp, TxData, WLen);
- prvSPI[SpiID].IsBlockMode = 1;
- if (TxData)
- {
- Result = SPI_Transfer(SpiID, Temp, Temp, WLen + RLen, 1);
- }
- else
- {
- Result = SPI_Transfer(SpiID, Temp, Temp, WLen + RLen, 1);
- }
- if (Result)
- {
- prvSPI[SpiID].IsBlockMode = 0;
- free(Temp);
- return Result;
- }
- if (OS_MutexLockWtihTime(prvSPI[SpiID].Sem, Time + 10))
- {
- free(Temp);
- DBG("!!!");
- SPI_TransferStop(SpiID);
- prvSPI[SpiID].IsBlockMode = 0;
- return -1;
- }
- memcpy(RxData, Temp + WLen, RLen);
- prvSPI[SpiID].IsBlockMode = 0;
- free(Temp);
- return 0;
- #endif
- }
- void SPI_DMATxInit(uint8_t SpiID, uint8_t Stream, uint32_t Channel)
- {
- SPI_TypeDef *SPI;
- HSPIM_TypeDef *HSPI;
- DMA_InitTypeDef DMA_InitStruct;
- DMA_BaseConfig(&DMA_InitStruct);
- DMA_InitStruct.DMA_Peripheral = prvSPI[SpiID].DMATxChannel;
- DMA_InitStruct.DMA_Priority = DMA_Priority_3;
- prvSPI[SpiID].DMATxStream = Stream;
- switch(SpiID)
- {
- case HSPI_ID0:
- HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
- if (prvSPI[SpiID].IsOnlyTx)
- {
- DMA_InitStruct.DMA_Priority = DMA_Priority_0;
- }
- DMA_InitStruct.DMA_PeripheralBurstSize = DMA_BurstSize_32;
- DMA_InitStruct.DMA_MemoryBurstSize = DMA_BurstSize_32;
- DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&HSPI->WDR;
- break;
- case SPI_ID0:
- case SPI_ID1:
- case SPI_ID2:
- SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
- DMA_InitStruct.DMA_PeripheralBurstSize = DMA_BurstSize_8;
- DMA_InitStruct.DMA_MemoryBurstSize = DMA_BurstSize_8;
- DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&SPI->DR;
- break;
- // case SPI_ID3:
- // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
- // break;
- default:
- return;
- }
- DMA_ConfigStream(Stream, &DMA_InitStruct);
- }
- void SPI_DMARxInit(uint8_t SpiID, uint8_t Stream, uint32_t Channel)
- {
- SPI_TypeDef *SPI;
- HSPIM_TypeDef *HSPI;
- DMA_InitTypeDef DMA_InitStruct;
- DMA_BaseConfig(&DMA_InitStruct);
- DMA_InitStruct.DMA_Peripheral = prvSPI[SpiID].DMARxChannel;
- DMA_InitStruct.DMA_Priority = DMA_Priority_2;
- prvSPI[SpiID].DMARxStream = Stream;
- switch(SpiID)
- {
- case HSPI_ID0:
- HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
- DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&HSPI->RDR;
- break;
- case SPI_ID0:
- case SPI_ID1:
- case SPI_ID2:
- SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
- DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&SPI->DR;
- break;
- // case SPI_ID3:
- // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
- // break;
- default:
- return;
- }
- DMA_ConfigStream(Stream, &DMA_InitStruct);
- }
- void SPI_TransferStop(uint8_t SpiID)
- {
- uint16_t Data;
- ISR_Clear(prvSPI[SpiID].IrqLine);
- ISR_OnOff(prvSPI[SpiID].IrqLine, 0);
- SPI_TypeDef *SPI;
- HSPIM_TypeDef *HSPI;
- uint32_t TxLen, i;
- DMA_StopStream(prvSPI[SpiID].DMATxStream);
- DMA_StopStream(prvSPI[SpiID].DMARxStream);
- switch(SpiID)
- {
- case HSPI_ID0:
- HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
- HSPI->CR0 &= ~(7 << HSPIM_CR0_PARAM_INTERRPUT_ENABLE_POS);
- HSPI->FCR = (32 << HSPIM_FCR_PARAM_TRANSIMIT_FIFO_EMPTY_THRESHOULD_POS)|(32 << HSPIM_FCR_PARAM_RECEIVE_FIFO_FULL_THRESHOULD_POS)|(3 << 6)|(63);
- HSPI->FCR &= ~(3 << 6);
- PM_SetHardwareRunFlag(PM_HW_HSPI, 0);
- break;
- case SPI_ID0:
- SYSCTRL->PHER_CTRL &= ~SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
- case SPI_ID1:
- case SPI_ID2:
- SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
- while(SPI->TXFLR){;}
- while(SPI->RXFLR){Data = SPI->DR;}
- SPI->SER = 0;
- break;
- // case SPI_ID3:
- // SYSCTRL->PHER_CTRL |= SYSCTRL_PHER_CTRL_SPI0_SLV_EN;
- // break;
- default:
- return ;
- }
- PM_SetHardwareRunFlag(PM_HW_SPI_0 + SpiID - 1, 0);
- prvSPI[SpiID].IsBusy = 0;
- }
- uint8_t SPI_IsTransferBusy(uint8_t SpiID)
- {
- return prvSPI[SpiID].IsBusy;
- }
- void SPI_SetNewConfig(uint8_t SpiID, uint32_t Speed, uint8_t NewMode)
- {
- HSPIM_TypeDef *HSPI;
- SPI_TypeDef *SPI;
- uint32_t div;
- if (prvSPI[SpiID].IsBusy) return;
- switch(SpiID)
- {
- case HSPI_ID0:
- HSPI = (HSPIM_TypeDef *)prvSPI[SpiID].RegBase;
- div = (SystemCoreClock / Speed) >> 1;
- HSPI->CR1 = (div << HSPIM_CR1_PARAM_BAUDRATE_POS) + 1;
- prvSPI[SpiID].Speed = (SystemCoreClock >> 1) / div;
- HSPI->CR0 &= ~((1 << HSPIM_CR0_PARAM_CPOL_POS)|(1 << HSPIM_CR0_PARAM_CPHA_POS));
- switch(NewMode)
- {
- case SPI_MODE_0:
- break;
- case SPI_MODE_1:
- HSPI->CR0 |= (1 << HSPIM_CR0_PARAM_CPHA_POS);
- break;
- case SPI_MODE_2:
- HSPI->CR0 |= (1 << HSPIM_CR0_PARAM_CPOL_POS);
- break;
- case SPI_MODE_3:
- HSPI->CR0 |= (1 << HSPIM_CR0_PARAM_CPOL_POS)|(1 << HSPIM_CR0_PARAM_CPHA_POS);
- break;
- }
- break;
- case SPI_ID0:
- case SPI_ID1:
- case SPI_ID2:
- SPI = (SPI_TypeDef *)prvSPI[SpiID].RegBase;
- SPI->SSIENR = 0;
- div = (SystemCoreClock >> 2) / Speed;
- if (div % 2) div++;
- prvSPI[SpiID].Speed = (SystemCoreClock >> 2) / div;
- SPI->BAUDR = div;
- SPI->CTRLR0 &= ~(SPI_CTRLR0_SCPOL|SPI_CTRLR0_SCPH);
- switch(NewMode)
- {
- case SPI_MODE_0:
- break;
- case SPI_MODE_1:
- SPI->CTRLR0 |= SPI_CTRLR0_SCPH;
- break;
- case SPI_MODE_2:
- SPI->CTRLR0 |= SPI_CTRLR0_SCPOL;
- break;
- case SPI_MODE_3:
- SPI->CTRLR0 |= SPI_CTRLR0_SCPOL|SPI_CTRLR0_SCPH;
- break;
- }
- SPI->SSIENR = 1;
- break;
- }
- }
|