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 memory_barrier()
00067 }
00068 }
00069
00070
00071
00072
00073 static void _ILI9488_Spi_Tx_CB(void)
00074 {
00075 uint32_t i;
00076 if( ili9488DmaCtlInSpiMode.cmdOrDataFlag){
00077 PIO_Set(&lcd_spi_cds_pin);
00078 for(i = 0; i<0xFF; i++);
00079 ili9488DmaCtlInSpiMode.cmdOrDataFlag = 0;
00080 }
00081 ili9488DmaCtlInSpiMode.txDoneFlag = 1;
00082 }
00083
00084
00085
00086
00087
00088 static void _ILI9488_SpiDmaInitialize(sXdmad * dmad)
00089 {
00090 ili9488DmaCtlInSpiMode.cmdOrDataFlag = 1;
00091 ili9488DmaCtlInSpiMode.rxDoneFlag = 0;
00092 ili9488DmaCtlInSpiMode.txDoneFlag = 1;
00093
00094 ili9488DmaSpiMode.xdmaD = dmad;
00095 ili9488DmaSpiMode.xdmaD->pXdmacs = XDMAC;
00096 ili9488DmaSpiMode.ili9488DmaTxChannel = 0;
00097 ili9488DmaSpiMode.ili9488DmaRxChannel = 0;
00098 ili9488DmaSpiMode.xdmaInt = 0;
00099 ili9488DmaSpiMode.pSpiHw = ILI9488_SPI;
00100 ili9488DmaSpiMode.spiId = ILI9488_SPI_ID;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 static uint8_t _ILI9488_SpiDmaConfigChannels(void)
00111 {
00112 uint32_t srcType,dstType;
00113
00114
00115 XDMAD_Initialize( ili9488DmaSpiMode.xdmaD, 0 );
00116
00117 XDMAD_FreeChannel( ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaTxChannel);
00118 XDMAD_FreeChannel( ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaRxChannel);
00119
00120 srcType = XDMAD_TRANSFER_MEMORY;
00121 dstType = ili9488DmaSpiMode.spiId;
00122
00123
00124 ili9488DmaSpiMode.ili9488DmaTxChannel
00125 = XDMAD_AllocateChannel( ili9488DmaSpiMode.xdmaD, srcType, dstType);
00126
00127 if ( ili9488DmaSpiMode.ili9488DmaTxChannel == XDMAD_ALLOC_FAILED ) {
00128 return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00129 }
00130
00131
00132 ili9488DmaSpiMode.ili9488DmaRxChannel
00133 = XDMAD_AllocateChannel( ili9488DmaSpiMode.xdmaD, dstType, srcType);
00134
00135 if ( ili9488DmaSpiMode.ili9488DmaRxChannel == XDMAD_ALLOC_FAILED ) {
00136 return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00137 }
00138
00139
00140 XDMAD_SetCallback(ili9488DmaSpiMode.xdmaD,
00141 ili9488DmaSpiMode.ili9488DmaRxChannel,
00142 (XdmadTransferCallback)_ILI9488_Spi_Rx_CB,
00143 &ili9488DmaSpiMode);
00144 if (XDMAD_PrepareChannel(
00145 ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaRxChannel ))
00146 return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00147
00148
00149 XDMAD_SetCallback(ili9488DmaSpiMode.xdmaD,
00150 ili9488DmaSpiMode.ili9488DmaTxChannel,
00151 (XdmadTransferCallback)_ILI9488_Spi_Tx_CB,
00152 &ili9488DmaSpiMode);
00153 if ( XDMAD_PrepareChannel(
00154 ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaTxChannel ))
00155 return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00156
00157
00158 if(!(NVIC_GetActive(XDMAC_IRQn))) {
00159 NVIC_SetPriority( XDMAC_IRQn ,1);
00160
00161 NVIC_EnableIRQ(XDMAC_IRQn);
00162 }
00163 return 0;
00164 }
00165
00166
00167
00168
00169
00170
00171 static uint8_t _ILI9488_SpiDmaConfigureRxTx(void)
00172 {
00173 uint32_t txAddress,rxAddress;
00174 sXdmad *pXdmad;
00175 pXdmad = ili9488DmaSpiMode.xdmaD;
00176
00177 txAddress = (uint32_t)&ILI9488_SPI->SPI_TDR;
00178 rxAddress = (uint32_t)&ILI9488_SPI->SPI_RDR;
00179
00180
00181 ili9488DmaSpiMode.xdmadTxCfg.mbr_sa = 0;
00182 ili9488DmaSpiMode.xdmadTxCfg.mbr_da = txAddress;
00183 ili9488DmaSpiMode.xdmadTxCfg.mbr_ubc = 0;
00184
00185 ili9488DmaSpiMode.xdmadTxCfg.mbr_cfg
00186 = XDMAC_CC_TYPE_PER_TRAN
00187 | XDMAC_CC_MBSIZE_SINGLE
00188 | XDMAC_CC_DSYNC_MEM2PER
00189 | XDMAC_CC_DWIDTH_BYTE
00190 | XDMAC_CC_CSIZE_CHK_1
00191 | XDMAC_CC_SIF_AHB_IF0
00192 | XDMAC_CC_DIF_AHB_IF1
00193 | XDMAC_CC_SAM_INCREMENTED_AM
00194 | XDMAC_CC_DAM_FIXED_AM
00195 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00196 (ili9488DmaSpiMode.spiId, XDMAD_TRANSFER_TX ));
00197
00198 ili9488DmaSpiMode.xdmadTxCfg.mbr_bc = 0;
00199 ili9488DmaSpiMode.xdmadTxCfg.mbr_sus = 0;
00200 ili9488DmaSpiMode.xdmadTxCfg.mbr_dus = 0;
00201
00202
00203 ili9488DmaSpiMode.xdmadRxCfg.mbr_ubc = 0;
00204 ili9488DmaSpiMode.xdmadRxCfg.mbr_da = 0;
00205 ili9488DmaSpiMode.xdmadRxCfg.mbr_sa = rxAddress;
00206
00207 ili9488DmaSpiMode.xdmadRxCfg.mbr_cfg =
00208 XDMAC_CC_TYPE_PER_TRAN
00209 | XDMAC_CC_MBSIZE_SINGLE
00210 | XDMAC_CC_DSYNC_PER2MEM
00211 | XDMAC_CC_CSIZE_CHK_1
00212 | XDMAC_CC_DWIDTH_WORD
00213 | XDMAC_CC_SIF_AHB_IF1
00214 | XDMAC_CC_DIF_AHB_IF0
00215 | XDMAC_CC_SAM_FIXED_AM
00216 | XDMAC_CC_DAM_INCREMENTED_AM
00217 | XDMAC_CC_PERID(XDMAIF_Get_ChannelNumber
00218 (ili9488DmaSpiMode.spiId, XDMAD_TRANSFER_RX ));
00219 ili9488DmaSpiMode.xdmadRxCfg.mbr_bc = 0;
00220 ili9488DmaSpiMode.xdmadRxCfg.mbr_sus = 0;
00221 ili9488DmaSpiMode.xdmadRxCfg.mbr_dus =0;
00222
00223
00224 ili9488DmaSpiMode.xdmaInt = (XDMAC_CIE_BIE
00225 | XDMAC_CIE_RBIE
00226 | XDMAC_CIE_WBIE
00227 | XDMAC_CIE_ROIE);
00228
00229 if (XDMAD_ConfigureTransfer( pXdmad, ili9488DmaSpiMode.ili9488DmaRxChannel,
00230 &ili9488DmaSpiMode.xdmadRxCfg, 0, 0, ili9488DmaSpiMode.xdmaInt))
00231 return ILI9488_ERROR_DMA_CONFIGURE;
00232
00233 if (XDMAD_ConfigureTransfer( pXdmad, ili9488DmaSpiMode.ili9488DmaTxChannel,
00234 &ili9488DmaSpiMode.xdmadTxCfg, 0, 0, ili9488DmaSpiMode.xdmaInt))
00235 return ILI9488_ERROR_DMA_CONFIGURE;
00236 return 0;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 static uint8_t _ILI9488_SpiDmaUpdateBuffer(uint8_t *pTxBuffer,uint32_t wTxSize,
00249 uint32_t *pRxBuffer,uint32_t wRxSize)
00250 {
00251 sXdmad *pXdmad;
00252 pXdmad = ili9488DmaSpiMode.xdmaD;
00253
00254 ili9488DmaSpiMode.xdmadTxCfg.mbr_sa = (uint32_t)pTxBuffer;
00255 ili9488DmaSpiMode.xdmadTxCfg.mbr_ubc = wTxSize;
00256 if (wRxSize) {
00257 ili9488DmaSpiMode.xdmadRxCfg.mbr_da = (uint32_t)pRxBuffer;
00258 ili9488DmaSpiMode.xdmadRxCfg.mbr_ubc = wRxSize;
00259 if (XDMAD_ConfigureTransfer( pXdmad, ili9488DmaSpiMode.ili9488DmaRxChannel,
00260 &ili9488DmaSpiMode.xdmadRxCfg, 0, 0, ili9488DmaSpiMode.xdmaInt))
00261 return ILI9488_ERROR_DMA_CONFIGURE;
00262 }
00263 if (XDMAD_ConfigureTransfer( pXdmad, ili9488DmaSpiMode.ili9488DmaTxChannel,
00264 &ili9488DmaSpiMode.xdmadTxCfg, 0, 0, ili9488DmaSpiMode.xdmaInt))
00265 return ILI9488_ERROR_DMA_CONFIGURE;
00266 return 0;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277 uint8_t ILI9488_SpiInitializeWithDma(sXdmad * dmad)
00278 {
00279 _ILI9488_SpiDmaInitialize(dmad);
00280 if (_ILI9488_SpiDmaConfigChannels()) return ILI9488_ERROR_DMA_ALLOCATE_CHANNEL;
00281 if(_ILI9488_SpiDmaConfigureRxTx()) return ILI9488_ERROR_DMA_CONFIGURE;
00282 return 0;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292 uint8_t ILI9488_SpiDmaTxTransfer( uint8_t *pTxBuffer, uint32_t wTxSize)
00293 {
00294 while(!ili9488DmaCtlInSpiMode.txDoneFlag);
00295 _ILI9488_SpiDmaUpdateBuffer(pTxBuffer, wTxSize, 0, 0);
00296 SCB_CleanInvalidateDCache();
00297 ili9488DmaCtlInSpiMode.txDoneFlag = 0;
00298 if (XDMAD_StartTransfer(
00299 ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaTxChannel))
00300 return ILI9488_ERROR_DMA_TRANSFER;
00301 while(!ili9488DmaCtlInSpiMode.txDoneFlag);
00302 return 0;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312 uint8_t ILI9488_SpiDmaRxTransfer(uint32_t *pRxBuffer,uint32_t wRxSize)
00313 {
00314
00315 _ILI9488_SpiDmaUpdateBuffer((uint8_t*)pRxBuffer,wRxSize, (uint32_t*)pRxBuffer, wRxSize);
00316 SCB_CleanInvalidateDCache();
00317 if (XDMAD_StartTransfer( ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaRxChannel))
00318 return ILI9488_ERROR_DMA_TRANSFER;
00319
00320 if (XDMAD_StartTransfer( ili9488DmaSpiMode.xdmaD, ili9488DmaSpiMode.ili9488DmaTxChannel))
00321 return ILI9488_ERROR_DMA_TRANSFER;
00322 return 0;
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 uint8_t ILI9488_SpiSendCommand(uint8_t Instr, uint8_t *pTxData,
00335 uint32_t *pRxData, AccessIli_t ReadWrite, uint32_t size)
00336 {
00337 if(ReadWrite == AccessInst) {
00338 PIO_Clear(&lcd_spi_cds_pin);
00339 ili9488DmaCtlInSpiMode.cmdOrDataFlag = 1;
00340 return ILI9488_SpiDmaTxTransfer( &Instr, 1 );
00341 } else if (ReadWrite == AccessWrite) {
00342 PIO_Clear(&lcd_spi_cds_pin);
00343 ili9488DmaCtlInSpiMode.cmdOrDataFlag = 1;
00344 ILI9488_SpiDmaTxTransfer( &Instr, 1 );
00345 if(size == 0) return 0;
00346 ILI9488_SpiDmaTxTransfer( pTxData, size);
00347 return 0;
00348 } else {
00349 ili9488DmaCtlInSpiMode.rxDoneFlag = 0;
00350 ILI9488_SpiDmaRxTransfer( pRxData, size);
00351 while(!ili9488DmaCtlInSpiMode.rxDoneFlag);
00352 }
00353 return 0;
00354 }
00355
00356 #endif //BOARD_LCD_ILI9488