for Arduino TFT LCD Screen 160x128

Dependents:   TFTLCDSCREEN Pong_ILI9163C

Fork of TFT_ILI9163C by _ peu605

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TFT_ILI9163C_F411RE_DMA_IT.cpp Source File

TFT_ILI9163C_F411RE_DMA_IT.cpp

00001 #include "TFT_ILI9163C.h"
00002 #if defined(__F411RE_DMA_IT__)
00003 
00004 /**
00005  * TFT_ILI9163C library for ST Nucleo F411RE DMA Interrupt
00006  * 
00007  * @author Copyright (c) 2014, .S.U.M.O.T.O.Y., coded by Max MC Costa
00008  * https://github.com/sumotoy/TFT_ILI9163C
00009  *
00010  * @author modified by masuda, Masuda Naika
00011  */
00012 
00013 //Serial pc(SERIAL_TX, SERIAL_RX);
00014 
00015 //constructors
00016 TFT_ILI9163C::TFT_ILI9163C(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc, PinName reset) 
00017     : TFT_ILI9163C_BASE(mosi, miso, sclk, cs, dc, reset) {
00018         
00019         _resetPinName = reset;
00020         init(cs, dc);
00021 }
00022 
00023 TFT_ILI9163C::TFT_ILI9163C(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc) 
00024     : TFT_ILI9163C_BASE(mosi, miso, sclk, cs, dc) {
00025         
00026         _resetPinName = NC;
00027         init(cs, dc);
00028 }
00029 
00030 
00031 void DmaIrqHandler1() {
00032     tftPtr[0]->dmaIrqHandler();
00033 }
00034 
00035 void DmaIrqHandler2() {
00036     tftPtr[1]->dmaIrqHandler();
00037 }
00038 
00039 void DmaIrqHandler3() {
00040     tftPtr[2]->dmaIrqHandler();
00041 }
00042 
00043 void DmaIrqHandler4() {
00044     tftPtr[3]->dmaIrqHandler();
00045 }
00046 
00047 void DmaIrqHandler5() {
00048     tftPtr[4]->dmaIrqHandler();
00049 }
00050 
00051 void TFT_ILI9163C::dmaIrqHandler() {
00052 //    if(__HAL_DMA_GET_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma)) != RESET) {
00053 //        if(__HAL_DMA_GET_IT_SOURCE(&hdma, DMA_IT_TC) != RESET) {
00054     if ((*dma_state_reg & dma_tc_flag_mask) != RESET) {
00055         if ((hdma.Instance->CR & DMA_IT_TC) != RESET) {
00056             // disable SPI-DMA
00057             *bb_spi_txdmaen = 0;
00058             // disable DMA
00059             *bb_dma_sxcr_en = 0;
00060             while (*bb_dma_sxcr_en);
00061             // Disable the transfer complete interrupt
00062 //            __HAL_DMA_DISABLE_IT(&hdma, DMA_IT_TC);
00063 //            hdma.Instance->CR &= ~(DMA_IT_TC);
00064             *bb_dma_tcie = 0;
00065             
00066             waitSpiFree();
00067             deselectSlave();
00068         }
00069     }
00070 }
00071 
00072 inline void TFT_ILI9163C::waitCsFree() {
00073     while ((cs_port_reg->IDR & cs_reg_mask) == 0);
00074 }
00075 
00076 void TFT_ILI9163C::init(PinName cs, PinName dc){
00077     
00078     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00079         
00080     uint32_t cs_port_index = (uint32_t) cs >> 4;
00081     uint32_t dc_port_index = (uint32_t) dc >> 4;
00082     
00083      //set cs/dc port addresses and masks
00084     cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10));
00085     cs_reg_mask = 1 << ((uint32_t) cs & 0xf);
00086     dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10));
00087     dc_reg_mask = 1 << ((uint32_t) dc & 0xf);
00088     
00089     // set bit band addresses
00090 //  GPIO_TypeDef *cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10));
00091 //  GPIO_TypeDef *dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10));
00092 //  uint8_t cs_port_bit = (uint32_t) cs & 0xf;
00093 //  uint8_t dc_port_bit = (uint32_t) dc & 0xf;
00094 //  bb_cs_port = BITBAND_PERIPH(&cs_port_reg->ODR, cs_port_bit);
00095 //  bb_dc_port = BITBAND_PERIPH(&dc_port_reg->ODR, dc_port_bit);
00096 
00097     bb_spi_txe = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_TXE));
00098     bb_spi_bsy = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_BSY));
00099     bb_spi_spe = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_SPE));
00100     bb_spi_dff = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_DFF));
00101     bb_spi_txdmaen = BITBAND_PERIPH(&spi_ptr->CR2, MASK_TO_BITNUM(SPI_CR2_TXDMAEN));
00102 
00103     // init DMA
00104     hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
00105     hdma.Init.PeriphInc = DMA_PINC_DISABLE;
00106     hdma.Init.MemInc = DMA_MINC_DISABLE;
00107     hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
00108     hdma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
00109     hdma.Init.Mode = DMA_NORMAL;
00110     hdma.Init.Priority = DMA_PRIORITY_MEDIUM;
00111     hdma.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
00112     hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
00113     hdma.Init.MemBurst = DMA_MBURST_SINGLE;
00114     hdma.Init.PeriphBurst = DMA_PBURST_SINGLE;
00115     
00116     if(_spi.spi == SPI_1){
00117         hdma.Instance = DMA2_Stream3;       // DMA2_Stream2
00118         hdma.Init.Channel = DMA_CHANNEL_3;  // DMA_CHANNEL_2
00119         dma_tc_flag_mask = DMA_LISR_TCIF3;
00120         dma_state_reg = &DMA2->LISR;
00121         dma_tc_clear_mask = DMA_LIFCR_CTCIF3;
00122         dma_state_clear_reg = &DMA2->LIFCR;
00123         NVIC_SetPriority(DMA2_Stream3_IRQn, 0);
00124         NVIC_SetVector(DMA2_Stream3_IRQn, (uint32_t) &DmaIrqHandler1);
00125         NVIC_EnableIRQ(DMA2_Stream3_IRQn);
00126         __DMA2_CLK_ENABLE();
00127         tftPtr[0] = this;
00128     } else if(_spi.spi == SPI_2){
00129         hdma.Instance = DMA1_Stream4;
00130         hdma.Init.Channel = DMA_CHANNEL_0;
00131         dma_tc_flag_mask = DMA_HISR_TCIF4;
00132         dma_state_reg = &DMA1->HISR;
00133         dma_tc_clear_mask = DMA_HIFCR_CTCIF4;
00134         dma_state_clear_reg = &DMA1->HIFCR;
00135         NVIC_SetPriority(DMA1_Stream4_IRQn, 0);
00136         NVIC_SetVector(DMA1_Stream4_IRQn, (uint32_t) &DmaIrqHandler2);
00137         NVIC_EnableIRQ(DMA1_Stream4_IRQn);
00138         __DMA1_CLK_ENABLE();
00139         tftPtr[1] = this;
00140     } else if(_spi.spi == SPI_3){
00141         hdma.Instance = DMA1_Stream5;       // DMA1_Stream7
00142         hdma.Init.Channel = DMA_CHANNEL_0;  // DMA_CHANNEL0
00143         dma_tc_flag_mask = DMA_HISR_TCIF5;
00144         dma_state_reg = &DMA1->HISR;
00145         dma_tc_clear_mask = DMA_HIFCR_CTCIF5;
00146         dma_state_clear_reg = &DMA1->HIFCR;
00147         NVIC_SetPriority(DMA1_Stream5_IRQn, 0);
00148         NVIC_SetVector(DMA1_Stream5_IRQn, (uint32_t) &DmaIrqHandler3);
00149         NVIC_EnableIRQ(DMA1_Stream5_IRQn);
00150         __DMA1_CLK_ENABLE();
00151         tftPtr[2] = this;
00152     } else if(_spi.spi == SPI_4){
00153         hdma.Instance = DMA2_Stream1;       // DMA2_Stream4
00154         hdma.Init.Channel = DMA_CHANNEL_4;  // DMA_CHANNEL_5
00155         dma_tc_flag_mask = DMA_LISR_TCIF1;
00156         dma_state_reg = &DMA2->LISR;
00157         dma_tc_clear_mask = DMA_LIFCR_CTCIF1;
00158         dma_state_clear_reg = &DMA1->LIFCR;
00159         NVIC_SetPriority(DMA2_Stream1_IRQn, 0);
00160         NVIC_SetVector(DMA2_Stream1_IRQn, (uint32_t) &DmaIrqHandler4);
00161         NVIC_EnableIRQ(DMA2_Stream1_IRQn);
00162         __DMA2_CLK_ENABLE();
00163         tftPtr[3] = this;
00164     } else if(_spi.spi == SPI_5){
00165         hdma.Instance = DMA2_Stream4;       // DMA2_Stream5, DMA2_Stream6
00166         hdma.Init.Channel = DMA_CHANNEL_2;  // DMA_CHANNEL5, DMA_CHANNEL7
00167         dma_tc_flag_mask = DMA_HISR_TCIF4;
00168         dma_state_reg = &DMA2->HISR;
00169         dma_tc_clear_mask = DMA_HIFCR_CTCIF4;
00170         dma_state_clear_reg = &DMA2->HIFCR;
00171         NVIC_SetPriority(DMA2_Stream4_IRQn, 0);
00172         NVIC_SetVector(DMA2_Stream4_IRQn, (uint32_t) &DmaIrqHandler5);
00173         NVIC_EnableIRQ(DMA2_Stream4_IRQn);
00174         __DMA2_CLK_ENABLE();
00175         tftPtr[4] = this;
00176     }
00177     
00178     HAL_DMA_Init(&hdma);
00179 
00180     // set SPI DR
00181     hdma.Instance->PAR = (uint32_t) &spi_ptr->DR;
00182     // set SPI MAR
00183     hdma.Instance->M0AR = (uint32_t) &dmaBuff;
00184 
00185     // set bit band addresses
00186     bb_dma_sxcr_en = BITBAND_PERIPH(&hdma.Instance->CR, MASK_TO_BITNUM(DMA_SxCR_EN));
00187     bb_dma_tcie = BITBAND_PERIPH(&hdma.Instance->CR, MASK_TO_BITNUM(DMA_SxCR_TCIE));
00188 }
00189 
00190 inline void TFT_ILI9163C::selectSlave() {
00191     cs_port_reg->BSRRH = cs_reg_mask;   // Use BSRR register
00192 }
00193 
00194 inline void TFT_ILI9163C::deselectSlave() {
00195     cs_port_reg->BSRRL = cs_reg_mask;
00196 }
00197 
00198 inline void TFT_ILI9163C::setCommandMode() {
00199     dc_port_reg->BSRRH = dc_reg_mask;
00200 }
00201 
00202 inline void TFT_ILI9163C::setDataMode() {
00203     dc_port_reg->BSRRL = dc_reg_mask;
00204 }
00205 
00206 inline void TFT_ILI9163C::waitSpiFree() {
00207     while (*bb_spi_txe == 0);
00208     while (*bb_spi_bsy != 0);
00209 }
00210 
00211 inline void TFT_ILI9163C::waitBufferFree() {
00212     while (*bb_spi_txe == 0);
00213 }
00214 
00215 inline void TFT_ILI9163C::set8bitMode() {
00216     *bb_spi_spe = 0;
00217     *bb_spi_dff = 0;
00218     *bb_spi_spe = 1;
00219 }
00220 
00221 inline void TFT_ILI9163C::set16bitMode() {
00222     *bb_spi_spe = 0;
00223     *bb_spi_dff = 1;
00224     *bb_spi_spe = 1;
00225 }
00226 
00227 void TFT_ILI9163C::writecommand(uint8_t c){
00228     
00229     waitCsFree();
00230     
00231     set8bitMode();
00232     setCommandMode();
00233     selectSlave();
00234     
00235     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00236     spi_ptr->DR = c;
00237     
00238     waitSpiFree();
00239     deselectSlave();
00240 }
00241 
00242 void TFT_ILI9163C::writedata(uint8_t c){
00243     
00244     waitCsFree();
00245     
00246     set8bitMode();
00247     setDataMode();
00248     selectSlave();
00249     
00250     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00251     spi_ptr->DR = c;
00252     
00253     waitSpiFree();
00254     deselectSlave();
00255 } 
00256 
00257 void TFT_ILI9163C::writedata16(uint16_t d){
00258     
00259     waitCsFree();
00260     
00261     set16bitMode();
00262     setDataMode();
00263     selectSlave();
00264     
00265     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00266     spi_ptr->DR = d;
00267     
00268     waitSpiFree();
00269     deselectSlave();
00270 }
00271 
00272 
00273 void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){
00274     
00275     waitCsFree();
00276     
00277     set16bitMode();
00278     setDataMode();
00279     selectSlave();
00280     
00281     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00282     spi_ptr->DR = d1;
00283     waitBufferFree();
00284     spi_ptr->DR = d2;
00285     
00286     waitSpiFree();
00287     deselectSlave();
00288 }
00289 
00290 // use DMA, Interrupt
00291 void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
00292     
00293     len = len < 0 ? -len : len;
00294     
00295     if (len > 0) {
00296         waitCsFree();
00297         set16bitMode();
00298         setDataMode();
00299         selectSlave();
00300     
00301         // clear DMA flags
00302 //        __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma));
00303         *dma_state_clear_reg = dma_tc_clear_mask;
00304         
00305         dmaBuff = d;
00306         hdma.Instance->NDTR = len;
00307         
00308         /* Enable the transfer complete interrupt */
00309 //        __HAL_DMA_ENABLE_IT(&hdma, DMA_IT_TC);
00310 //        hdma.Instance->CR |= DMA_IT_TC;
00311         *bb_dma_tcie = 1;
00312         
00313         // enable DMA
00314         *bb_dma_sxcr_en = 1;
00315         // enable DMA request from SPI
00316         *bb_spi_txdmaen = 1;
00317     }
00318 }
00319 
00320 #endif