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_F302R8_DMA.cpp Source File

TFT_ILI9163C_F302R8_DMA.cpp

00001 #include "TFT_ILI9163C.h"
00002 #if defined(__F302R8_DMA__)
00003 
00004 /**
00005  * TFT_ILI9163C library for ST Nucleo F411RE
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 TFT_ILI9163C::init(PinName cs, PinName dc){
00032     
00033     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00034         
00035     uint32_t cs_port_index = (uint32_t) cs >> 4;
00036     uint32_t dc_port_index = (uint32_t) dc >> 4;
00037     
00038      //set cs/dc port addresses and masks
00039     cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10));
00040     cs_reg_mask = 1 << ((uint32_t) cs & 0xf);
00041     dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10));
00042     dc_reg_mask = 1 << ((uint32_t) dc & 0xf);
00043     
00044     // set bit band addresses
00045 //  GPIO_TypeDef *cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10));
00046 //  GPIO_TypeDef *dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10));
00047 //  uint8_t cs_port_bit = (uint32_t) cs & 0xf;
00048 //  uint8_t dc_port_bit = (uint32_t) dc & 0xf;
00049 //  bb_cs_port = BITBAND_PERIPH(&cs_port_reg->ODR, cs_port_bit);
00050 //  bb_dc_port = BITBAND_PERIPH(&dc_port_reg->ODR, dc_port_bit);
00051 
00052     bb_spi_txe = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_TXE));
00053     bb_spi_bsy = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_BSY));
00054     bb_spi_spe = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_SPE));
00055 
00056     // init DMA
00057     hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
00058     hdma.Init.PeriphInc = DMA_PINC_DISABLE;
00059     hdma.Init.MemInc = DMA_MINC_DISABLE;
00060     hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
00061     hdma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
00062     hdma.Init.Mode = DMA_NORMAL;
00063     hdma.Init.Priority = DMA_PRIORITY_MEDIUM;
00064     
00065     if(_spi.spi == SPI_2){
00066         hdma.Instance = DMA1_Channel5;
00067         __DMA1_CLK_ENABLE();
00068     } else if(_spi.spi == SPI_3){
00069         hdma.Instance = DMA1_Channel3;
00070         __DMA1_CLK_ENABLE();
00071     }
00072     
00073     HAL_DMA_Init(&hdma);
00074 
00075     // set SPI DR
00076     hdma.Instance->CPAR = (uint32_t) &spi_ptr->DR;
00077     // set SPI MAR
00078     hdma.Instance->CMAR = (uint32_t) &dmaBuff;
00079     
00080     // set bit band addresses
00081     bb_spi_txdmaen = BITBAND_PERIPH(&spi_ptr->CR2, MASK_TO_BITNUM(SPI_CR2_TXDMAEN));
00082     bb_dma_sxcr_en = BITBAND_PERIPH(&hdma.Instance->CCR, MASK_TO_BITNUM(DMA_CCR_EN));
00083 }
00084 
00085 inline void TFT_ILI9163C::selectSlave() {
00086     cs_port_reg->BSRRH = cs_reg_mask;   // Use BSRR register
00087 }
00088 
00089 inline void TFT_ILI9163C::deselectSlave() {
00090     cs_port_reg->BSRRL = cs_reg_mask;
00091 }
00092 
00093 inline void TFT_ILI9163C::setCommandMode() {
00094     dc_port_reg->BSRRH = dc_reg_mask;
00095 }
00096 
00097 inline void TFT_ILI9163C::setDataMode() {
00098     dc_port_reg->BSRRL = dc_reg_mask;
00099 }
00100 
00101 inline void TFT_ILI9163C::waitSpiFree() {
00102     while (*bb_spi_txe == 0);
00103     while (*bb_spi_bsy != 0);
00104 }
00105 
00106 inline void TFT_ILI9163C::waitBufferFree() {
00107     while (*bb_spi_txe == 0);
00108 }
00109 
00110 inline void TFT_ILI9163C::set8bitMode() {
00111 
00112     *bb_spi_spe = 0;
00113     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00114 
00115     uint16_t tmp = spi_ptr->CR2;
00116     tmp &= ~SPI_CR2_DS;
00117     tmp |= SPI_DATASIZE_8BIT;
00118     spi_ptr->CR2 = tmp;
00119 
00120     *bb_spi_spe = 1;
00121 }
00122 
00123 inline void TFT_ILI9163C::set16bitMode() {
00124 
00125     *bb_spi_spe = 0;
00126     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00127     
00128     uint16_t tmp = spi_ptr->CR2;
00129     tmp &= ~SPI_CR2_DS;
00130     tmp |= SPI_DATASIZE_16BIT;
00131     spi_ptr->CR2 = tmp;
00132 
00133     *bb_spi_spe = 1;
00134 }
00135 
00136 void TFT_ILI9163C::writecommand(uint8_t c){
00137     
00138     set8bitMode();
00139     setCommandMode();
00140     selectSlave();
00141     
00142     // Strange behavior :-(
00143     // Data packing RM0365 P.816
00144     // When the data frame size fits into one byte (less than or equal to 8 bits), data packing is
00145     // used automatically when any read or write 16-bit access is performed on the SPIx_DR register.
00146     
00147     // Force 8-bit access to the data register
00148     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00149     uint8_t *p_spi_dr = (uint8_t*) &spi_ptr->DR;
00150     *p_spi_dr = (uint8_t) c;
00151     
00152     waitSpiFree();
00153     deselectSlave();
00154 }
00155 
00156 
00157 void TFT_ILI9163C::writedata(uint8_t c){
00158     
00159     set8bitMode();
00160     setDataMode();
00161     selectSlave();
00162     
00163     // Force 8-bit access to the data register
00164     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00165     uint8_t *p_spi_dr = (uint8_t*) &spi_ptr->DR;
00166     *p_spi_dr = (uint8_t) c;
00167     
00168     waitSpiFree();
00169     deselectSlave();
00170 } 
00171 
00172 
00173 void TFT_ILI9163C::writedata16(uint16_t d){
00174 
00175     set16bitMode();
00176     setDataMode();
00177     selectSlave();
00178     
00179     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00180     spi_ptr->DR = d;
00181     
00182     waitSpiFree();
00183     deselectSlave();
00184 }
00185 
00186 
00187 void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){
00188 
00189     set16bitMode();
00190     setDataMode();
00191     selectSlave();
00192     
00193     SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
00194     spi_ptr->DR = d1;
00195     waitBufferFree();
00196     spi_ptr->DR = d2;
00197     
00198     waitSpiFree();
00199     deselectSlave();
00200 }
00201 
00202 void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
00203     
00204     len = len < 0 ? -len : len;
00205     
00206     if (len > 0) {
00207         set16bitMode();
00208         setDataMode();
00209         selectSlave();
00210     
00211         // clear DMA flags
00212         __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma));
00213         
00214         dmaBuff = d;
00215         hdma.Instance->CNDTR = len;
00216         
00217         // enable DMA
00218         *bb_dma_sxcr_en = 1;
00219         // enable DMA request from SPI
00220         *bb_spi_txdmaen = 1;
00221         // wait DMA complete
00222         while (hdma.Instance->CNDTR);
00223         // disable SPI-DMA
00224         *bb_spi_txdmaen = 0;
00225         // disable DMA
00226         *bb_dma_sxcr_en = 0;
00227         while (*bb_dma_sxcr_en);
00228         
00229         waitSpiFree();
00230         deselectSlave();
00231     }
00232 }
00233 
00234 #endif