for Arduino TFT LCD Screen 160x128

Dependents:   TFTLCDSCREEN Pong_ILI9163C

Fork of TFT_ILI9163C by _ peu605

Committer:
billycorgan123
Date:
Fri Mar 04 08:55:32 2016 +0000
Revision:
12:f0799be044ff
Parent:
7:3dcb98ecf29f
first trial with Arduino TFT LCD Screen, ILI9163

Who changed what in which revision?

UserRevisionLine numberNew contents of line
peu605 7:3dcb98ecf29f 1 #include "TFT_ILI9163C.h"
peu605 7:3dcb98ecf29f 2 #if defined(__F302R8_DMA__)
peu605 7:3dcb98ecf29f 3
peu605 7:3dcb98ecf29f 4 /**
peu605 7:3dcb98ecf29f 5 * TFT_ILI9163C library for ST Nucleo F411RE
peu605 7:3dcb98ecf29f 6 *
peu605 7:3dcb98ecf29f 7 * @author Copyright (c) 2014, .S.U.M.O.T.O.Y., coded by Max MC Costa
peu605 7:3dcb98ecf29f 8 * https://github.com/sumotoy/TFT_ILI9163C
peu605 7:3dcb98ecf29f 9 *
peu605 7:3dcb98ecf29f 10 * @author modified by masuda, Masuda Naika
peu605 7:3dcb98ecf29f 11 */
peu605 7:3dcb98ecf29f 12
peu605 7:3dcb98ecf29f 13 //Serial pc(SERIAL_TX, SERIAL_RX);
peu605 7:3dcb98ecf29f 14
peu605 7:3dcb98ecf29f 15 //constructors
peu605 7:3dcb98ecf29f 16 TFT_ILI9163C::TFT_ILI9163C(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc, PinName reset)
peu605 7:3dcb98ecf29f 17 : TFT_ILI9163C_BASE(mosi, miso, sclk, cs, dc, reset) {
peu605 7:3dcb98ecf29f 18
peu605 7:3dcb98ecf29f 19 _resetPinName = reset;
peu605 7:3dcb98ecf29f 20 init(cs, dc);
peu605 7:3dcb98ecf29f 21 }
peu605 7:3dcb98ecf29f 22
peu605 7:3dcb98ecf29f 23 TFT_ILI9163C::TFT_ILI9163C(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc)
peu605 7:3dcb98ecf29f 24 : TFT_ILI9163C_BASE(mosi, miso, sclk, cs, dc) {
peu605 7:3dcb98ecf29f 25
peu605 7:3dcb98ecf29f 26 _resetPinName = NC;
peu605 7:3dcb98ecf29f 27 init(cs, dc);
peu605 7:3dcb98ecf29f 28 }
peu605 7:3dcb98ecf29f 29
peu605 7:3dcb98ecf29f 30
peu605 7:3dcb98ecf29f 31 void TFT_ILI9163C::init(PinName cs, PinName dc){
peu605 7:3dcb98ecf29f 32
peu605 7:3dcb98ecf29f 33 SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
peu605 7:3dcb98ecf29f 34
peu605 7:3dcb98ecf29f 35 uint32_t cs_port_index = (uint32_t) cs >> 4;
peu605 7:3dcb98ecf29f 36 uint32_t dc_port_index = (uint32_t) dc >> 4;
peu605 7:3dcb98ecf29f 37
peu605 7:3dcb98ecf29f 38 //set cs/dc port addresses and masks
peu605 7:3dcb98ecf29f 39 cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10));
peu605 7:3dcb98ecf29f 40 cs_reg_mask = 1 << ((uint32_t) cs & 0xf);
peu605 7:3dcb98ecf29f 41 dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10));
peu605 7:3dcb98ecf29f 42 dc_reg_mask = 1 << ((uint32_t) dc & 0xf);
peu605 7:3dcb98ecf29f 43
peu605 7:3dcb98ecf29f 44 // set bit band addresses
peu605 7:3dcb98ecf29f 45 // GPIO_TypeDef *cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10));
peu605 7:3dcb98ecf29f 46 // GPIO_TypeDef *dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10));
peu605 7:3dcb98ecf29f 47 // uint8_t cs_port_bit = (uint32_t) cs & 0xf;
peu605 7:3dcb98ecf29f 48 // uint8_t dc_port_bit = (uint32_t) dc & 0xf;
peu605 7:3dcb98ecf29f 49 // bb_cs_port = BITBAND_PERIPH(&cs_port_reg->ODR, cs_port_bit);
peu605 7:3dcb98ecf29f 50 // bb_dc_port = BITBAND_PERIPH(&dc_port_reg->ODR, dc_port_bit);
peu605 7:3dcb98ecf29f 51
peu605 7:3dcb98ecf29f 52 bb_spi_txe = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_TXE));
peu605 7:3dcb98ecf29f 53 bb_spi_bsy = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_BSY));
peu605 7:3dcb98ecf29f 54 bb_spi_spe = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_SPE));
peu605 7:3dcb98ecf29f 55
peu605 7:3dcb98ecf29f 56 // init DMA
peu605 7:3dcb98ecf29f 57 hdma.Init.Direction = DMA_MEMORY_TO_PERIPH;
peu605 7:3dcb98ecf29f 58 hdma.Init.PeriphInc = DMA_PINC_DISABLE;
peu605 7:3dcb98ecf29f 59 hdma.Init.MemInc = DMA_MINC_DISABLE;
peu605 7:3dcb98ecf29f 60 hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
peu605 7:3dcb98ecf29f 61 hdma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
peu605 7:3dcb98ecf29f 62 hdma.Init.Mode = DMA_NORMAL;
peu605 7:3dcb98ecf29f 63 hdma.Init.Priority = DMA_PRIORITY_MEDIUM;
peu605 7:3dcb98ecf29f 64
peu605 7:3dcb98ecf29f 65 if(_spi.spi == SPI_2){
peu605 7:3dcb98ecf29f 66 hdma.Instance = DMA1_Channel5;
peu605 7:3dcb98ecf29f 67 __DMA1_CLK_ENABLE();
peu605 7:3dcb98ecf29f 68 } else if(_spi.spi == SPI_3){
peu605 7:3dcb98ecf29f 69 hdma.Instance = DMA1_Channel3;
peu605 7:3dcb98ecf29f 70 __DMA1_CLK_ENABLE();
peu605 7:3dcb98ecf29f 71 }
peu605 7:3dcb98ecf29f 72
peu605 7:3dcb98ecf29f 73 HAL_DMA_Init(&hdma);
peu605 7:3dcb98ecf29f 74
peu605 7:3dcb98ecf29f 75 // set SPI DR
peu605 7:3dcb98ecf29f 76 hdma.Instance->CPAR = (uint32_t) &spi_ptr->DR;
peu605 7:3dcb98ecf29f 77 // set SPI MAR
peu605 7:3dcb98ecf29f 78 hdma.Instance->CMAR = (uint32_t) &dmaBuff;
peu605 7:3dcb98ecf29f 79
peu605 7:3dcb98ecf29f 80 // set bit band addresses
peu605 7:3dcb98ecf29f 81 bb_spi_txdmaen = BITBAND_PERIPH(&spi_ptr->CR2, MASK_TO_BITNUM(SPI_CR2_TXDMAEN));
peu605 7:3dcb98ecf29f 82 bb_dma_sxcr_en = BITBAND_PERIPH(&hdma.Instance->CCR, MASK_TO_BITNUM(DMA_CCR_EN));
peu605 7:3dcb98ecf29f 83 }
peu605 7:3dcb98ecf29f 84
peu605 7:3dcb98ecf29f 85 inline void TFT_ILI9163C::selectSlave() {
peu605 7:3dcb98ecf29f 86 cs_port_reg->BSRRH = cs_reg_mask; // Use BSRR register
peu605 7:3dcb98ecf29f 87 }
peu605 7:3dcb98ecf29f 88
peu605 7:3dcb98ecf29f 89 inline void TFT_ILI9163C::deselectSlave() {
peu605 7:3dcb98ecf29f 90 cs_port_reg->BSRRL = cs_reg_mask;
peu605 7:3dcb98ecf29f 91 }
peu605 7:3dcb98ecf29f 92
peu605 7:3dcb98ecf29f 93 inline void TFT_ILI9163C::setCommandMode() {
peu605 7:3dcb98ecf29f 94 dc_port_reg->BSRRH = dc_reg_mask;
peu605 7:3dcb98ecf29f 95 }
peu605 7:3dcb98ecf29f 96
peu605 7:3dcb98ecf29f 97 inline void TFT_ILI9163C::setDataMode() {
peu605 7:3dcb98ecf29f 98 dc_port_reg->BSRRL = dc_reg_mask;
peu605 7:3dcb98ecf29f 99 }
peu605 7:3dcb98ecf29f 100
peu605 7:3dcb98ecf29f 101 inline void TFT_ILI9163C::waitSpiFree() {
peu605 7:3dcb98ecf29f 102 while (*bb_spi_txe == 0);
peu605 7:3dcb98ecf29f 103 while (*bb_spi_bsy != 0);
peu605 7:3dcb98ecf29f 104 }
peu605 7:3dcb98ecf29f 105
peu605 7:3dcb98ecf29f 106 inline void TFT_ILI9163C::waitBufferFree() {
peu605 7:3dcb98ecf29f 107 while (*bb_spi_txe == 0);
peu605 7:3dcb98ecf29f 108 }
peu605 7:3dcb98ecf29f 109
peu605 7:3dcb98ecf29f 110 inline void TFT_ILI9163C::set8bitMode() {
peu605 7:3dcb98ecf29f 111
peu605 7:3dcb98ecf29f 112 *bb_spi_spe = 0;
peu605 7:3dcb98ecf29f 113 SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
peu605 7:3dcb98ecf29f 114
peu605 7:3dcb98ecf29f 115 uint16_t tmp = spi_ptr->CR2;
peu605 7:3dcb98ecf29f 116 tmp &= ~SPI_CR2_DS;
peu605 7:3dcb98ecf29f 117 tmp |= SPI_DATASIZE_8BIT;
peu605 7:3dcb98ecf29f 118 spi_ptr->CR2 = tmp;
peu605 7:3dcb98ecf29f 119
peu605 7:3dcb98ecf29f 120 *bb_spi_spe = 1;
peu605 7:3dcb98ecf29f 121 }
peu605 7:3dcb98ecf29f 122
peu605 7:3dcb98ecf29f 123 inline void TFT_ILI9163C::set16bitMode() {
peu605 7:3dcb98ecf29f 124
peu605 7:3dcb98ecf29f 125 *bb_spi_spe = 0;
peu605 7:3dcb98ecf29f 126 SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
peu605 7:3dcb98ecf29f 127
peu605 7:3dcb98ecf29f 128 uint16_t tmp = spi_ptr->CR2;
peu605 7:3dcb98ecf29f 129 tmp &= ~SPI_CR2_DS;
peu605 7:3dcb98ecf29f 130 tmp |= SPI_DATASIZE_16BIT;
peu605 7:3dcb98ecf29f 131 spi_ptr->CR2 = tmp;
peu605 7:3dcb98ecf29f 132
peu605 7:3dcb98ecf29f 133 *bb_spi_spe = 1;
peu605 7:3dcb98ecf29f 134 }
peu605 7:3dcb98ecf29f 135
peu605 7:3dcb98ecf29f 136 void TFT_ILI9163C::writecommand(uint8_t c){
peu605 7:3dcb98ecf29f 137
peu605 7:3dcb98ecf29f 138 set8bitMode();
peu605 7:3dcb98ecf29f 139 setCommandMode();
peu605 7:3dcb98ecf29f 140 selectSlave();
peu605 7:3dcb98ecf29f 141
peu605 7:3dcb98ecf29f 142 // Strange behavior :-(
peu605 7:3dcb98ecf29f 143 // Data packing RM0365 P.816
peu605 7:3dcb98ecf29f 144 // When the data frame size fits into one byte (less than or equal to 8 bits), data packing is
peu605 7:3dcb98ecf29f 145 // used automatically when any read or write 16-bit access is performed on the SPIx_DR register.
peu605 7:3dcb98ecf29f 146
peu605 7:3dcb98ecf29f 147 // Force 8-bit access to the data register
peu605 7:3dcb98ecf29f 148 SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
peu605 7:3dcb98ecf29f 149 uint8_t *p_spi_dr = (uint8_t*) &spi_ptr->DR;
peu605 7:3dcb98ecf29f 150 *p_spi_dr = (uint8_t) c;
peu605 7:3dcb98ecf29f 151
peu605 7:3dcb98ecf29f 152 waitSpiFree();
peu605 7:3dcb98ecf29f 153 deselectSlave();
peu605 7:3dcb98ecf29f 154 }
peu605 7:3dcb98ecf29f 155
peu605 7:3dcb98ecf29f 156
peu605 7:3dcb98ecf29f 157 void TFT_ILI9163C::writedata(uint8_t c){
peu605 7:3dcb98ecf29f 158
peu605 7:3dcb98ecf29f 159 set8bitMode();
peu605 7:3dcb98ecf29f 160 setDataMode();
peu605 7:3dcb98ecf29f 161 selectSlave();
peu605 7:3dcb98ecf29f 162
peu605 7:3dcb98ecf29f 163 // Force 8-bit access to the data register
peu605 7:3dcb98ecf29f 164 SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
peu605 7:3dcb98ecf29f 165 uint8_t *p_spi_dr = (uint8_t*) &spi_ptr->DR;
peu605 7:3dcb98ecf29f 166 *p_spi_dr = (uint8_t) c;
peu605 7:3dcb98ecf29f 167
peu605 7:3dcb98ecf29f 168 waitSpiFree();
peu605 7:3dcb98ecf29f 169 deselectSlave();
peu605 7:3dcb98ecf29f 170 }
peu605 7:3dcb98ecf29f 171
peu605 7:3dcb98ecf29f 172
peu605 7:3dcb98ecf29f 173 void TFT_ILI9163C::writedata16(uint16_t d){
peu605 7:3dcb98ecf29f 174
peu605 7:3dcb98ecf29f 175 set16bitMode();
peu605 7:3dcb98ecf29f 176 setDataMode();
peu605 7:3dcb98ecf29f 177 selectSlave();
peu605 7:3dcb98ecf29f 178
peu605 7:3dcb98ecf29f 179 SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
peu605 7:3dcb98ecf29f 180 spi_ptr->DR = d;
peu605 7:3dcb98ecf29f 181
peu605 7:3dcb98ecf29f 182 waitSpiFree();
peu605 7:3dcb98ecf29f 183 deselectSlave();
peu605 7:3dcb98ecf29f 184 }
peu605 7:3dcb98ecf29f 185
peu605 7:3dcb98ecf29f 186
peu605 7:3dcb98ecf29f 187 void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){
peu605 7:3dcb98ecf29f 188
peu605 7:3dcb98ecf29f 189 set16bitMode();
peu605 7:3dcb98ecf29f 190 setDataMode();
peu605 7:3dcb98ecf29f 191 selectSlave();
peu605 7:3dcb98ecf29f 192
peu605 7:3dcb98ecf29f 193 SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi;
peu605 7:3dcb98ecf29f 194 spi_ptr->DR = d1;
peu605 7:3dcb98ecf29f 195 waitBufferFree();
peu605 7:3dcb98ecf29f 196 spi_ptr->DR = d2;
peu605 7:3dcb98ecf29f 197
peu605 7:3dcb98ecf29f 198 waitSpiFree();
peu605 7:3dcb98ecf29f 199 deselectSlave();
peu605 7:3dcb98ecf29f 200 }
peu605 7:3dcb98ecf29f 201
peu605 7:3dcb98ecf29f 202 void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) {
peu605 7:3dcb98ecf29f 203
peu605 7:3dcb98ecf29f 204 len = len < 0 ? -len : len;
peu605 7:3dcb98ecf29f 205
peu605 7:3dcb98ecf29f 206 if (len > 0) {
peu605 7:3dcb98ecf29f 207 set16bitMode();
peu605 7:3dcb98ecf29f 208 setDataMode();
peu605 7:3dcb98ecf29f 209 selectSlave();
peu605 7:3dcb98ecf29f 210
peu605 7:3dcb98ecf29f 211 // clear DMA flags
peu605 7:3dcb98ecf29f 212 __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma));
peu605 7:3dcb98ecf29f 213
peu605 7:3dcb98ecf29f 214 dmaBuff = d;
peu605 7:3dcb98ecf29f 215 hdma.Instance->CNDTR = len;
peu605 7:3dcb98ecf29f 216
peu605 7:3dcb98ecf29f 217 // enable DMA
peu605 7:3dcb98ecf29f 218 *bb_dma_sxcr_en = 1;
peu605 7:3dcb98ecf29f 219 // enable DMA request from SPI
peu605 7:3dcb98ecf29f 220 *bb_spi_txdmaen = 1;
peu605 7:3dcb98ecf29f 221 // wait DMA complete
peu605 7:3dcb98ecf29f 222 while (hdma.Instance->CNDTR);
peu605 7:3dcb98ecf29f 223 // disable SPI-DMA
peu605 7:3dcb98ecf29f 224 *bb_spi_txdmaen = 0;
peu605 7:3dcb98ecf29f 225 // disable DMA
peu605 7:3dcb98ecf29f 226 *bb_dma_sxcr_en = 0;
peu605 7:3dcb98ecf29f 227 while (*bb_dma_sxcr_en);
peu605 7:3dcb98ecf29f 228
peu605 7:3dcb98ecf29f 229 waitSpiFree();
peu605 7:3dcb98ecf29f 230 deselectSlave();
peu605 7:3dcb98ecf29f 231 }
peu605 7:3dcb98ecf29f 232 }
peu605 7:3dcb98ecf29f 233
peu605 7:3dcb98ecf29f 234 #endif