00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "board.h"
00041
00042 #include <string.h>
00043 #include <stdio.h>
00044
00045 #ifdef BOARD_LCD_ILI9488
00046
00047
00048
00049
00050
00051 static const Pin lcd_spi_cds_pin = BOARD_SPI_LCD_PIN_CDS;
00052
00053 static sIli9488Dma ili9488DmaSpiMode;
00054 static sIli9488DmaCtl ili9488DmaCtlInSpiMode;
00055
00056
00057
00058
00059
00060
00061
00062 static void _ILI9488_Spi_Rx_CB(void)
00063 {
00064 if (!ili9488DmaCtlInSpiMode.cmdOrDataFlag) {
00065 ili9488DmaCtlInSpiMode.rxDoneFlag = 1;
00066 SCB_InvalidateDCache_by_Addr((uint32_t *)ili9488DmaSpiMode.xdmadRxCfg.mbr_da,
00067 ili9488DmaSpiMode.xdmadRxCfg.mbr_ubc);
00068 memory_barrier()
00069 }
00070 }
00071
00072
00073
00074
00075 static void _ILI9488_Spi_Tx_CB(void)
00076 {
00077 uint32_t i;
00078
00079 if (ili9488DmaCtlInSpiMode.cmdOrDataFlag) {
00080 PIO_Set(&lcd_spi_cds_pin);
00081
00082 for (i = 0; i < 0xFF; i++);
00083
00084 ili9488DmaCtlInSpiMode.cmdOrDataFlag = 0;
00085 }
00086
00087 ili9488DmaCtlInSpiMode.txDoneFlag = 1;
00088 }
00089
00090
00091
00092
00093
00094 static void _ILI9488_SpiDmaInitialize(sXdmad *dmad)
00095 {
00096 ili9488DmaCtlInSpiMode.cmdOrDataFlag = 1;
00097 ili9488DmaCtlInSpiMode.rxDoneFlag = 0;
00098 ili9488DmaCtlInSpiMode.txDoneFlag = 1;
00099
00100 ili9488DmaSpiMode.xdmaD = dmad;
00101 ili9488DmaSpiMode.xdmaD->pXdmacs = XDMAC;
00102 ili9488DmaSpiMode.ili9488DmaTxChannel = 0;
00103 ili9488DmaSpiMode.ili9488DmaRxChannel = 0;
00104 ili9488DmaSpiMode.xdmaInt = 0;
00105 ili9488DmaSpiMode.pSpiHw = ILI9488_SPI;
00106 ili9488DmaSpiMode.spiId = ILI9488_SPI_ID;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 static uint8_t _ILI9488_SpiDmaConfigChannels(void)
00117 {
00118 uint32_t srcType, dstType;
00119
00120
00121 XDMAD_Initialize(ili9488DmaSpiMode.xdmaD, 0);
00122
00123 XDMAD_FreeChannel(ili9488DmaSpiMode.xdmaD,
00124 ili9488DmaSpiMode.ili9488DmaTxChannel);
00125 XDMAD_FreeChannel(ili9488DmaSpiMode.xdmaD,
00126 ili9488DmaSpiMode.ili9488DmaRxChannel);
00127
00128 srcType = XDMAD_TRANSFER_MEMORY;
00129 dstType = ili9488DmaSpiMode.spiId;
00130
00131
00132 ili9488DmaSpiMode.ili9488DmaTxChannel
00133 = XDMAD_AllocateChannel(ili9488DmaSpiMode.xdmaD, srcType, dstType);
00134
00135 if (ili9488DmaSpiMode.ili9488DmaTxChannel == XDMAD_ALLOC_FAILED)
00136 return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00137
00138
00139 ili9488DmaSpiMode.ili9488DmaRxChannel
00140 = XDMAD_AllocateChannel(ili9488DmaSpiMode.xdmaD, dstType, srcType);
00141
00142 if (ili9488DmaSpiMode.ili9488DmaRxChannel == XDMAD_ALLOC_FAILED)
00143 return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00144
00145
00146 XDMAD_SetCallback(ili9488DmaSpiMode.xdmaD,
00147 ili9488DmaSpiMode.ili9488DmaRxChannel,
00148 (XdmadTransferCallback)_ILI9488_Spi_Rx_CB,
00149 &ili9488DmaSpiMode);
00150
00151 if (XDMAD_PrepareChannel(
00152 ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaRxChannel))
00153 return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00154
00155
00156 XDMAD_SetCallback(ili9488DmaSpiMode.xdmaD,
00157 ili9488DmaSpiMode.ili9488DmaTxChannel,
00158 (XdmadTransferCallback)_ILI9488_Spi_Tx_CB,
00159 &ili9488DmaSpiMode);
00160
00161 if (XDMAD_PrepareChannel(
00162 ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaTxChannel))
00163 return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00164
00165
00166 if (!(NVIC_GetActive(XDMAC_IRQn))) {
00167 NVIC_SetPriority(XDMAC_IRQn , 1);
00168
00169 NVIC_EnableIRQ(XDMAC_IRQn);
00170 }
00171
00172 return 0;
00173 }
00174
00175
00176
00177
00178
00179
00180 static uint8_t _ILI9488_SpiDmaConfigureRxTx(void)
00181 {
00182 uint32_t txAddress, rxAddress;
00183 sXdmad *pXdmad;
00184 pXdmad = ili9488DmaSpiMode.xdmaD;
00185
00186 txAddress = (uint32_t)&ILI9488_SPI->SPI_TDR;
00187 rxAddress = (uint32_t)&ILI9488_SPI->SPI_RDR;
00188
00189
00190 ili9488DmaSpiMode.xdmadTxCfg.mbr_sa = 0;
00191 ili9488DmaSpiMode.xdmadTxCfg.mbr_da = txAddress;
00192 ili9488DmaSpiMode.xdmadTxCfg.mbr_ubc = 0;
00193
00194 ili9488DmaSpiMode.xdmadTxCfg.mbr_cfg
00195 = XDMAC_CC_TYPE_PER_TRAN
00196 | XDMAC_CC_MBSIZE_SINGLE
00197 | XDMAC_CC_DSYNC_MEM2PER
00198 | XDMAC_CC_DWIDTH_BYTE
00199 | XDMAC_CC_CSIZE_CHK_1
00200 | XDMAC_CC_SIF_AHB_IF1
00201 | XDMAC_CC_DIF_AHB_IF1
00202 | XDMAC_CC_SAM_INCREMENTED_AM
00203 | XDMAC_CC_DAM_FIXED_AM
00204 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00205 (ili9488DmaSpiMode.spiId, XDMAD_TRANSFER_TX));
00206
00207 ili9488DmaSpiMode.xdmadTxCfg.mbr_bc = 0;
00208 ili9488DmaSpiMode.xdmadTxCfg.mbr_sus = 0;
00209 ili9488DmaSpiMode.xdmadTxCfg.mbr_dus = 0;
00210
00211
00212 ili9488DmaSpiMode.xdmadRxCfg.mbr_ubc = 0;
00213 ili9488DmaSpiMode.xdmadRxCfg.mbr_da = 0;
00214 ili9488DmaSpiMode.xdmadRxCfg.mbr_sa = rxAddress;
00215
00216 ili9488DmaSpiMode.xdmadRxCfg.mbr_cfg =
00217 XDMAC_CC_TYPE_PER_TRAN
00218 | XDMAC_CC_MBSIZE_SINGLE
00219 | XDMAC_CC_DSYNC_PER2MEM
00220 | XDMAC_CC_CSIZE_CHK_1
00221 | XDMAC_CC_DWIDTH_WORD
00222 | XDMAC_CC_SIF_AHB_IF1
00223 | XDMAC_CC_DIF_AHB_IF1
00224 | XDMAC_CC_SAM_FIXED_AM
00225 | XDMAC_CC_DAM_INCREMENTED_AM
00226 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00227 (ili9488DmaSpiMode.spiId, XDMAD_TRANSFER_RX));
00228 ili9488DmaSpiMode.xdmadRxCfg.mbr_bc = 0;
00229 ili9488DmaSpiMode.xdmadRxCfg.mbr_sus = 0;
00230 ili9488DmaSpiMode.xdmadRxCfg.mbr_dus = 0;
00231
00232
00233 ili9488DmaSpiMode.xdmaInt = (XDMAC_CIE_BIE
00234 | XDMAC_CIE_RBIE
00235 | XDMAC_CIE_WBIE
00236 | XDMAC_CIE_ROIE);
00237
00238 if (XDMAD_ConfigureTransfer(pXdmad, ili9488DmaSpiMode.ili9488DmaRxChannel,
00239 &ili9488DmaSpiMode.xdmadRxCfg, 0, 0, ili9488DmaSpiMode.xdmaInt))
00240 return ILI9488_ERROR_DMA_CONFIGURE;
00241
00242 if (XDMAD_ConfigureTransfer(pXdmad, ili9488DmaSpiMode.ili9488DmaTxChannel,
00243 &ili9488DmaSpiMode.xdmadTxCfg, 0, 0, ili9488DmaSpiMode.xdmaInt))
00244 return ILI9488_ERROR_DMA_CONFIGURE;
00245
00246 return 0;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 static uint8_t _ILI9488_SpiDmaUpdateBuffer(uint8_t *pTxBuffer, uint32_t wTxSize,
00259 uint32_t *pRxBuffer, uint32_t wRxSize)
00260 {
00261 sXdmad *pXdmad;
00262 pXdmad = ili9488DmaSpiMode.xdmaD;
00263
00264 ili9488DmaSpiMode.xdmadTxCfg.mbr_sa = (uint32_t)pTxBuffer;
00265 ili9488DmaSpiMode.xdmadTxCfg.mbr_ubc = wTxSize;
00266
00267 if (wRxSize) {
00268 ili9488DmaSpiMode.xdmadRxCfg.mbr_da = (uint32_t)pRxBuffer;
00269 ili9488DmaSpiMode.xdmadRxCfg.mbr_ubc = wRxSize;
00270
00271 if (XDMAD_ConfigureTransfer(pXdmad, ili9488DmaSpiMode.ili9488DmaRxChannel,
00272 &ili9488DmaSpiMode.xdmadRxCfg, 0, 0, ili9488DmaSpiMode.xdmaInt))
00273 return ILI9488_ERROR_DMA_CONFIGURE;
00274 }
00275
00276 if (XDMAD_ConfigureTransfer(pXdmad, ili9488DmaSpiMode.ili9488DmaTxChannel,
00277 &ili9488DmaSpiMode.xdmadTxCfg, 0, 0, ili9488DmaSpiMode.xdmaInt))
00278 return ILI9488_ERROR_DMA_CONFIGURE;
00279
00280 return 0;
00281 }
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 uint8_t ILI9488_SpiInitializeWithDma(sXdmad *dmad)
00292 {
00293 _ILI9488_SpiDmaInitialize(dmad);
00294
00295 if (_ILI9488_SpiDmaConfigChannels()) return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00296
00297 if (_ILI9488_SpiDmaConfigureRxTx()) return ILI9488_ERROR_DMA_CONFIGURE;
00298
00299 return 0;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309 uint8_t ILI9488_SpiDmaTxTransfer(uint8_t *pTxBuffer, uint32_t wTxSize)
00310 {
00311 while (!ili9488DmaCtlInSpiMode.txDoneFlag);
00312
00313 _ILI9488_SpiDmaUpdateBuffer(pTxBuffer, wTxSize, 0, 0);
00314 SCB_CleanDCache_by_Addr((uint32_t *)pTxBuffer, wTxSize);
00315 ili9488DmaCtlInSpiMode.txDoneFlag = 0;
00316
00317 if (XDMAD_StartTransfer(
00318 ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaTxChannel))
00319 return ILI9488_ERROR_DMA_TRANSFER;
00320
00321 while (!ili9488DmaCtlInSpiMode.txDoneFlag);
00322
00323 return 0;
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333 uint8_t ILI9488_SpiDmaRxTransfer(uint32_t *pRxBuffer, uint32_t wRxSize)
00334 {
00335 _ILI9488_SpiDmaUpdateBuffer((uint8_t *)pRxBuffer, wRxSize,
00336 (uint32_t *)pRxBuffer, wRxSize);
00337 SCB_CleanDCache_by_Addr((uint32_t *)pRxBuffer, wRxSize);
00338
00339 if (XDMAD_StartTransfer(ili9488DmaSpiMode.xdmaD,
00340 ili9488DmaSpiMode.ili9488DmaRxChannel))
00341 return ILI9488_ERROR_DMA_TRANSFER;
00342
00343 if (XDMAD_StartTransfer(ili9488DmaSpiMode.xdmaD,
00344 ili9488DmaSpiMode.ili9488DmaTxChannel))
00345 return ILI9488_ERROR_DMA_TRANSFER;
00346
00347 return 0;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359 uint8_t ILI9488_SpiSendCommand(uint8_t Instr, uint8_t *pTxData,
00360 uint32_t *pRxData, AccessIli_t ReadWrite, uint32_t size)
00361 {
00362 if (ReadWrite == AccessInst) {
00363 PIO_Clear(&lcd_spi_cds_pin);
00364 ili9488DmaCtlInSpiMode.cmdOrDataFlag = 1;
00365 return ILI9488_SpiDmaTxTransfer(&Instr, 1);
00366 } else if (ReadWrite == AccessWrite) {
00367 PIO_Clear(&lcd_spi_cds_pin);
00368 ili9488DmaCtlInSpiMode.cmdOrDataFlag = 1;
00369 ILI9488_SpiDmaTxTransfer(&Instr, 1);
00370
00371 if (size == 0) return 0;
00372
00373 ILI9488_SpiDmaTxTransfer(pTxData, size);
00374 return 0;
00375 } else {
00376 ili9488DmaCtlInSpiMode.rxDoneFlag = 0;
00377 ILI9488_SpiDmaRxTransfer(pRxData, size);
00378
00379 while (!ili9488DmaCtlInSpiMode.rxDoneFlag);
00380 }
00381
00382 return 0;
00383 }
00384
00385 #endif //BOARD_LCD_ILI9488