Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TFTLCDSCREEN Pong_ILI9163C
Fork of TFT_ILI9163C by
TFT_ILI9163C.cpp@6:83f3605478ab, 2015-01-28 (annotated)
- Committer:
- peu605
- Date:
- Wed Jan 28 13:35:18 2015 +0000
- Revision:
- 6:83f3605478ab
- Parent:
- 5:836673938ba7
F302R8 support
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
peu605 | 0:f90a4405ef98 | 1 | #include "TFT_ILI9163C.h" |
peu605 | 0:f90a4405ef98 | 2 | #include "mbed.h" |
peu605 | 0:f90a4405ef98 | 3 | |
peu605 | 0:f90a4405ef98 | 4 | /** |
peu605 | 0:f90a4405ef98 | 5 | * TFT_ILI9163C library for ST Nucleo F411RE |
peu605 | 0:f90a4405ef98 | 6 | * |
peu605 | 0:f90a4405ef98 | 7 | * @author Copyright (c) 2014, .S.U.M.O.T.O.Y., coded by Max MC Costa |
peu605 | 0:f90a4405ef98 | 8 | * https://github.com/sumotoy/TFT_ILI9163C |
peu605 | 0:f90a4405ef98 | 9 | * |
peu605 | 0:f90a4405ef98 | 10 | * @author modified by masuda, Masuda Naika |
peu605 | 0:f90a4405ef98 | 11 | */ |
peu605 | 0:f90a4405ef98 | 12 | |
peu605 | 0:f90a4405ef98 | 13 | //constructors |
peu605 | 0:f90a4405ef98 | 14 | TFT_ILI9163C::TFT_ILI9163C(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc, PinName reset) |
peu605 | 0:f90a4405ef98 | 15 | : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT) , SPI(mosi,miso,sclk,NC), _cs(cs), _dc(dc) { |
peu605 | 0:f90a4405ef98 | 16 | |
peu605 | 0:f90a4405ef98 | 17 | _resetPinName = reset; |
peu605 | 2:6c1fadae252f | 18 | init(cs, dc); |
peu605 | 0:f90a4405ef98 | 19 | } |
peu605 | 0:f90a4405ef98 | 20 | |
peu605 | 0:f90a4405ef98 | 21 | TFT_ILI9163C::TFT_ILI9163C(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc) |
peu605 | 0:f90a4405ef98 | 22 | : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT) , SPI(mosi,miso,sclk,NC), _cs(cs), _dc(dc) { |
peu605 | 0:f90a4405ef98 | 23 | |
peu605 | 3:254e799c24ca | 24 | _resetPinName = NC; |
peu605 | 3:254e799c24ca | 25 | init(cs, dc); |
peu605 | 0:f90a4405ef98 | 26 | } |
peu605 | 0:f90a4405ef98 | 27 | |
peu605 | 0:f90a4405ef98 | 28 | //Serial pc(SERIAL_TX, SERIAL_RX); |
peu605 | 0:f90a4405ef98 | 29 | |
peu605 | 1:c271e7e2e330 | 30 | // F411RE specific |
peu605 | 6:83f3605478ab | 31 | #if defined(TARGET_NUCLEO_F411RE) | defined(TARGET_NUCLEO_F302R8) |
peu605 | 2:6c1fadae252f | 32 | void TFT_ILI9163C::init(PinName cs, PinName dc){ |
peu605 | 0:f90a4405ef98 | 33 | |
peu605 | 2:6c1fadae252f | 34 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 35 | |
peu605 | 2:6c1fadae252f | 36 | uint32_t cs_port_index = (uint32_t) cs >> 4; |
peu605 | 2:6c1fadae252f | 37 | uint32_t dc_port_index = (uint32_t) dc >> 4; |
peu605 | 2:6c1fadae252f | 38 | |
peu605 | 2:6c1fadae252f | 39 | //set cs/dc port addresses and masks |
peu605 | 2:6c1fadae252f | 40 | cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10)); |
peu605 | 2:6c1fadae252f | 41 | cs_reg_mask = 1 << ((uint32_t) cs & 0xf); |
peu605 | 2:6c1fadae252f | 42 | dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10)); |
peu605 | 2:6c1fadae252f | 43 | dc_reg_mask = 1 << ((uint32_t) dc & 0xf); |
peu605 | 2:6c1fadae252f | 44 | |
peu605 | 2:6c1fadae252f | 45 | // set bit band addresses |
peu605 | 2:6c1fadae252f | 46 | // GPIO_TypeDef *cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10)); |
peu605 | 2:6c1fadae252f | 47 | // GPIO_TypeDef *dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10)); |
peu605 | 2:6c1fadae252f | 48 | // uint8_t cs_port_bit = (uint32_t) cs & 0xf; |
peu605 | 2:6c1fadae252f | 49 | // uint8_t dc_port_bit = (uint32_t) dc & 0xf; |
peu605 | 2:6c1fadae252f | 50 | // bb_cs_port = BITBAND_PERIPH(&cs_port_reg->ODR, cs_port_bit); |
peu605 | 2:6c1fadae252f | 51 | // bb_dc_port = BITBAND_PERIPH(&dc_port_reg->ODR, dc_port_bit); |
peu605 | 6:83f3605478ab | 52 | |
peu605 | 2:6c1fadae252f | 53 | bb_spi_txe = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_TXE)); |
peu605 | 2:6c1fadae252f | 54 | bb_spi_bsy = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_BSY)); |
peu605 | 2:6c1fadae252f | 55 | bb_spi_spe = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_SPE)); |
peu605 | 6:83f3605478ab | 56 | #if defined(TARGET_NUCLEO_F411RE) |
peu605 | 2:6c1fadae252f | 57 | bb_spi_dff = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_DFF)); |
peu605 | 6:83f3605478ab | 58 | #endif |
peu605 | 6:83f3605478ab | 59 | |
peu605 | 6:83f3605478ab | 60 | #if defined(__NUCLEO_DMA__) & defined(TARGET_NUCLEO_F411RE) |
peu605 | 2:6c1fadae252f | 61 | // init DMA |
peu605 | 0:f90a4405ef98 | 62 | hdma.Init.Direction = DMA_MEMORY_TO_PERIPH; |
peu605 | 0:f90a4405ef98 | 63 | hdma.Init.PeriphInc = DMA_PINC_DISABLE; |
peu605 | 0:f90a4405ef98 | 64 | hdma.Init.MemInc = DMA_MINC_DISABLE; |
peu605 | 0:f90a4405ef98 | 65 | hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; |
peu605 | 0:f90a4405ef98 | 66 | hdma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; |
peu605 | 0:f90a4405ef98 | 67 | hdma.Init.Mode = DMA_NORMAL; |
peu605 | 0:f90a4405ef98 | 68 | hdma.Init.Priority = DMA_PRIORITY_MEDIUM; |
peu605 | 5:836673938ba7 | 69 | hdma.Init.FIFOMode = DMA_FIFOMODE_ENABLE; |
peu605 | 0:f90a4405ef98 | 70 | hdma.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL; |
peu605 | 0:f90a4405ef98 | 71 | hdma.Init.MemBurst = DMA_MBURST_SINGLE; |
peu605 | 0:f90a4405ef98 | 72 | hdma.Init.PeriphBurst = DMA_PBURST_SINGLE; |
peu605 | 0:f90a4405ef98 | 73 | |
peu605 | 0:f90a4405ef98 | 74 | if(_spi.spi == SPI_1){ |
peu605 | 0:f90a4405ef98 | 75 | hdma.Instance = DMA2_Stream3; // DMA2_Stream2 |
peu605 | 0:f90a4405ef98 | 76 | hdma.Init.Channel = DMA_CHANNEL_3; // DMA_CHANNEL_2 |
peu605 | 0:f90a4405ef98 | 77 | __DMA2_CLK_ENABLE(); |
peu605 | 0:f90a4405ef98 | 78 | } else if(_spi.spi == SPI_2){ |
peu605 | 0:f90a4405ef98 | 79 | hdma.Instance = DMA1_Stream4; |
peu605 | 0:f90a4405ef98 | 80 | hdma.Init.Channel = DMA_CHANNEL_0; |
peu605 | 0:f90a4405ef98 | 81 | __DMA1_CLK_ENABLE(); |
peu605 | 0:f90a4405ef98 | 82 | } else if(_spi.spi == SPI_3){ |
peu605 | 0:f90a4405ef98 | 83 | hdma.Instance = DMA1_Stream5; // DMA1_Stream7 |
peu605 | 0:f90a4405ef98 | 84 | hdma.Init.Channel = DMA_CHANNEL_0; // DMA_CHANNEL0 |
peu605 | 0:f90a4405ef98 | 85 | __DMA1_CLK_ENABLE(); |
peu605 | 0:f90a4405ef98 | 86 | } else if(_spi.spi == SPI_4){ |
peu605 | 0:f90a4405ef98 | 87 | hdma.Instance = DMA2_Stream1; // DMA2_Stream4 |
peu605 | 0:f90a4405ef98 | 88 | hdma.Init.Channel = DMA_CHANNEL_4; // DMA_CHANNEL_5 |
peu605 | 0:f90a4405ef98 | 89 | __DMA2_CLK_ENABLE(); |
peu605 | 0:f90a4405ef98 | 90 | } else if(_spi.spi == SPI_5){ |
peu605 | 0:f90a4405ef98 | 91 | hdma.Instance = DMA2_Stream4; // DMA2_Stream5, DMA2_Stream6 |
peu605 | 0:f90a4405ef98 | 92 | hdma.Init.Channel = DMA_CHANNEL_2; // DMA_CHANNEL5, DMA_CHANNEL7 |
peu605 | 0:f90a4405ef98 | 93 | __DMA2_CLK_ENABLE(); |
peu605 | 0:f90a4405ef98 | 94 | } |
peu605 | 6:83f3605478ab | 95 | |
peu605 | 0:f90a4405ef98 | 96 | HAL_DMA_Init(&hdma); |
peu605 | 0:f90a4405ef98 | 97 | |
peu605 | 0:f90a4405ef98 | 98 | // set SPI DR ss Peripheral address |
peu605 | 0:f90a4405ef98 | 99 | hdma.Instance->PAR = (uint32_t) &spi_ptr->DR; |
peu605 | 2:6c1fadae252f | 100 | |
peu605 | 2:6c1fadae252f | 101 | // set bit band addresses |
peu605 | 2:6c1fadae252f | 102 | bb_spi_txdmaen = BITBAND_PERIPH(&spi_ptr->CR2, MASK_TO_BITNUM(SPI_CR2_TXDMAEN)); |
peu605 | 2:6c1fadae252f | 103 | bb_dma_sxcr_en = BITBAND_PERIPH(&hdma.Instance->CR, MASK_TO_BITNUM(DMA_SxCR_EN)); |
peu605 | 6:83f3605478ab | 104 | |
peu605 | 6:83f3605478ab | 105 | #elif defined(__NUCLEO_DMA__) & defined(TARGET_NUCLEO_F302R8) |
peu605 | 6:83f3605478ab | 106 | // init DMA |
peu605 | 6:83f3605478ab | 107 | hdma.Init.Direction = DMA_MEMORY_TO_PERIPH; |
peu605 | 6:83f3605478ab | 108 | hdma.Init.PeriphInc = DMA_PINC_DISABLE; |
peu605 | 6:83f3605478ab | 109 | hdma.Init.MemInc = DMA_MINC_DISABLE; |
peu605 | 6:83f3605478ab | 110 | hdma.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; |
peu605 | 6:83f3605478ab | 111 | hdma.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; |
peu605 | 6:83f3605478ab | 112 | hdma.Init.Mode = DMA_NORMAL; |
peu605 | 6:83f3605478ab | 113 | hdma.Init.Priority = DMA_PRIORITY_MEDIUM; |
peu605 | 6:83f3605478ab | 114 | |
peu605 | 6:83f3605478ab | 115 | if(_spi.spi == SPI_2){ |
peu605 | 6:83f3605478ab | 116 | hdma.Instance = DMA1_Channel5; |
peu605 | 6:83f3605478ab | 117 | __DMA1_CLK_ENABLE(); |
peu605 | 6:83f3605478ab | 118 | } else if(_spi.spi == SPI_3){ |
peu605 | 6:83f3605478ab | 119 | hdma.Instance = DMA1_Channel3; |
peu605 | 6:83f3605478ab | 120 | __DMA1_CLK_ENABLE(); |
peu605 | 6:83f3605478ab | 121 | } |
peu605 | 6:83f3605478ab | 122 | |
peu605 | 6:83f3605478ab | 123 | HAL_DMA_Init(&hdma); |
peu605 | 6:83f3605478ab | 124 | |
peu605 | 6:83f3605478ab | 125 | // set SPI DR ss Peripheral address |
peu605 | 6:83f3605478ab | 126 | hdma.Instance->CPAR = (uint32_t) &spi_ptr->DR; |
peu605 | 6:83f3605478ab | 127 | |
peu605 | 6:83f3605478ab | 128 | // set bit band addresses |
peu605 | 6:83f3605478ab | 129 | bb_spi_txdmaen = BITBAND_PERIPH(&spi_ptr->CR2, MASK_TO_BITNUM(SPI_CR2_TXDMAEN)); |
peu605 | 6:83f3605478ab | 130 | bb_dma_sxcr_en = BITBAND_PERIPH(&hdma.Instance->CCR, MASK_TO_BITNUM(DMA_CCR_EN)); |
peu605 | 0:f90a4405ef98 | 131 | #endif |
peu605 | 2:6c1fadae252f | 132 | } |
peu605 | 6:83f3605478ab | 133 | |
peu605 | 2:6c1fadae252f | 134 | inline void TFT_ILI9163C::selectSlave() { |
peu605 | 2:6c1fadae252f | 135 | // _cs = 0; // Use DigitalOut |
peu605 | 2:6c1fadae252f | 136 | // *bb_cs_port = 0; // Use bit band |
peu605 | 2:6c1fadae252f | 137 | cs_port_reg->BSRRH = cs_reg_mask; // Use BSRR register |
peu605 | 2:6c1fadae252f | 138 | } |
peu605 | 6:83f3605478ab | 139 | |
peu605 | 2:6c1fadae252f | 140 | inline void TFT_ILI9163C::deselectSlave() { |
peu605 | 2:6c1fadae252f | 141 | // _cs = 1; |
peu605 | 2:6c1fadae252f | 142 | // *bb_cs_port = 1; |
peu605 | 2:6c1fadae252f | 143 | cs_port_reg->BSRRL = cs_reg_mask; |
peu605 | 2:6c1fadae252f | 144 | } |
peu605 | 6:83f3605478ab | 145 | |
peu605 | 2:6c1fadae252f | 146 | inline void TFT_ILI9163C::setCommandMode() { |
peu605 | 2:6c1fadae252f | 147 | // _dc = 0; |
peu605 | 2:6c1fadae252f | 148 | // *bb_dc_port = 0; |
peu605 | 2:6c1fadae252f | 149 | dc_port_reg->BSRRH = dc_reg_mask; |
peu605 | 2:6c1fadae252f | 150 | } |
peu605 | 6:83f3605478ab | 151 | |
peu605 | 2:6c1fadae252f | 152 | inline void TFT_ILI9163C::setDataMode() { |
peu605 | 2:6c1fadae252f | 153 | // _dc = 1; |
peu605 | 2:6c1fadae252f | 154 | // *bb_dc_port = 1; |
peu605 | 2:6c1fadae252f | 155 | dc_port_reg->BSRRL = dc_reg_mask; |
peu605 | 2:6c1fadae252f | 156 | } |
peu605 | 6:83f3605478ab | 157 | |
peu605 | 2:6c1fadae252f | 158 | inline void TFT_ILI9163C::waitSpiFree() { |
peu605 | 2:6c1fadae252f | 159 | |
peu605 | 2:6c1fadae252f | 160 | // SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 161 | // while ((spi_ptr->SR & SPI_SR_TXE) == 0); |
peu605 | 2:6c1fadae252f | 162 | // while ((spi_ptr->SR & SPI_SR_BSY) != 0); |
peu605 | 2:6c1fadae252f | 163 | |
peu605 | 2:6c1fadae252f | 164 | while (*bb_spi_txe == 0); |
peu605 | 2:6c1fadae252f | 165 | while (*bb_spi_bsy != 0); |
peu605 | 2:6c1fadae252f | 166 | } |
peu605 | 2:6c1fadae252f | 167 | |
peu605 | 2:6c1fadae252f | 168 | inline void TFT_ILI9163C::waitBufferFree() { |
peu605 | 2:6c1fadae252f | 169 | |
peu605 | 2:6c1fadae252f | 170 | // SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 171 | // while ((spi_ptr->SR & SPI_SR_TXE) == 0); |
peu605 | 2:6c1fadae252f | 172 | |
peu605 | 2:6c1fadae252f | 173 | while (*bb_spi_txe == 0); |
peu605 | 2:6c1fadae252f | 174 | } |
peu605 | 2:6c1fadae252f | 175 | |
peu605 | 6:83f3605478ab | 176 | #if defined(TARGET_NUCLEO_F411RE) |
peu605 | 2:6c1fadae252f | 177 | inline void TFT_ILI9163C::set8bitMode() { |
peu605 | 2:6c1fadae252f | 178 | |
peu605 | 2:6c1fadae252f | 179 | // SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 180 | // spi_ptr->CR1 &= ~(SPI_CR1_SPE | SPI_CR1_DFF); |
peu605 | 2:6c1fadae252f | 181 | // spi_ptr->CR1 |= SPI_CR1_SPE; |
peu605 | 2:6c1fadae252f | 182 | |
peu605 | 2:6c1fadae252f | 183 | *bb_spi_spe = 0; |
peu605 | 2:6c1fadae252f | 184 | *bb_spi_dff = 0; |
peu605 | 2:6c1fadae252f | 185 | *bb_spi_spe = 1; |
peu605 | 2:6c1fadae252f | 186 | } |
peu605 | 2:6c1fadae252f | 187 | |
peu605 | 2:6c1fadae252f | 188 | inline void TFT_ILI9163C::set16bitMode() { |
peu605 | 2:6c1fadae252f | 189 | |
peu605 | 2:6c1fadae252f | 190 | // SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 191 | // spi_ptr->CR1 &= ~SPI_CR1_SPE; |
peu605 | 2:6c1fadae252f | 192 | // spi_ptr->CR1 |= (SPI_CR1_SPE | SPI_CR1_DFF); |
peu605 | 2:6c1fadae252f | 193 | |
peu605 | 2:6c1fadae252f | 194 | *bb_spi_spe = 0; |
peu605 | 2:6c1fadae252f | 195 | *bb_spi_dff = 1; |
peu605 | 2:6c1fadae252f | 196 | *bb_spi_spe = 1; |
peu605 | 2:6c1fadae252f | 197 | } |
peu605 | 2:6c1fadae252f | 198 | |
peu605 | 2:6c1fadae252f | 199 | void TFT_ILI9163C::writecommand(uint8_t c){ |
peu605 | 2:6c1fadae252f | 200 | |
peu605 | 2:6c1fadae252f | 201 | set8bitMode(); |
peu605 | 2:6c1fadae252f | 202 | setCommandMode(); |
peu605 | 2:6c1fadae252f | 203 | selectSlave(); |
peu605 | 2:6c1fadae252f | 204 | |
peu605 | 2:6c1fadae252f | 205 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 206 | spi_ptr->DR = c; |
peu605 | 2:6c1fadae252f | 207 | |
peu605 | 2:6c1fadae252f | 208 | waitSpiFree(); |
peu605 | 2:6c1fadae252f | 209 | deselectSlave(); |
peu605 | 2:6c1fadae252f | 210 | } |
peu605 | 2:6c1fadae252f | 211 | |
peu605 | 2:6c1fadae252f | 212 | void TFT_ILI9163C::writedata(uint8_t c){ |
peu605 | 2:6c1fadae252f | 213 | |
peu605 | 2:6c1fadae252f | 214 | set8bitMode(); |
peu605 | 2:6c1fadae252f | 215 | setDataMode(); |
peu605 | 2:6c1fadae252f | 216 | selectSlave(); |
peu605 | 2:6c1fadae252f | 217 | |
peu605 | 2:6c1fadae252f | 218 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 219 | spi_ptr->DR = c; |
peu605 | 2:6c1fadae252f | 220 | |
peu605 | 2:6c1fadae252f | 221 | waitSpiFree(); |
peu605 | 2:6c1fadae252f | 222 | deselectSlave(); |
peu605 | 2:6c1fadae252f | 223 | } |
peu605 | 6:83f3605478ab | 224 | #endif |
peu605 | 6:83f3605478ab | 225 | |
peu605 | 6:83f3605478ab | 226 | #if defined(TARGET_NUCLEO_F302R8) |
peu605 | 6:83f3605478ab | 227 | inline void TFT_ILI9163C::set8bitMode() { |
peu605 | 6:83f3605478ab | 228 | |
peu605 | 6:83f3605478ab | 229 | *bb_spi_spe = 0; |
peu605 | 6:83f3605478ab | 230 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 6:83f3605478ab | 231 | |
peu605 | 6:83f3605478ab | 232 | uint16_t tmp = spi_ptr->CR2; |
peu605 | 6:83f3605478ab | 233 | tmp &= ~SPI_CR2_DS; |
peu605 | 6:83f3605478ab | 234 | tmp |= SPI_DATASIZE_8BIT; |
peu605 | 6:83f3605478ab | 235 | spi_ptr->CR2 = tmp; |
peu605 | 6:83f3605478ab | 236 | |
peu605 | 6:83f3605478ab | 237 | *bb_spi_spe = 1; |
peu605 | 6:83f3605478ab | 238 | } |
peu605 | 6:83f3605478ab | 239 | |
peu605 | 6:83f3605478ab | 240 | inline void TFT_ILI9163C::set16bitMode() { |
peu605 | 6:83f3605478ab | 241 | |
peu605 | 6:83f3605478ab | 242 | *bb_spi_spe = 0; |
peu605 | 6:83f3605478ab | 243 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 6:83f3605478ab | 244 | |
peu605 | 6:83f3605478ab | 245 | uint16_t tmp = spi_ptr->CR2; |
peu605 | 6:83f3605478ab | 246 | tmp &= ~SPI_CR2_DS; |
peu605 | 6:83f3605478ab | 247 | tmp |= SPI_DATASIZE_16BIT; |
peu605 | 6:83f3605478ab | 248 | spi_ptr->CR2 = tmp; |
peu605 | 6:83f3605478ab | 249 | |
peu605 | 6:83f3605478ab | 250 | *bb_spi_spe = 1; |
peu605 | 6:83f3605478ab | 251 | } |
peu605 | 6:83f3605478ab | 252 | |
peu605 | 6:83f3605478ab | 253 | void TFT_ILI9163C::writecommand(uint8_t c){ |
peu605 | 6:83f3605478ab | 254 | |
peu605 | 6:83f3605478ab | 255 | set8bitMode(); |
peu605 | 6:83f3605478ab | 256 | setCommandMode(); |
peu605 | 6:83f3605478ab | 257 | selectSlave(); |
peu605 | 6:83f3605478ab | 258 | |
peu605 | 6:83f3605478ab | 259 | // Strange behavior :-( |
peu605 | 6:83f3605478ab | 260 | // Data packing RM0365 P.816 |
peu605 | 6:83f3605478ab | 261 | // When the data frame size fits into one byte (less than or equal to 8 bits), data packing is |
peu605 | 6:83f3605478ab | 262 | // used automatically when any read or write 16-bit access is performed on the SPIx_DR register. |
peu605 | 6:83f3605478ab | 263 | |
peu605 | 6:83f3605478ab | 264 | // Force 8-bit access to the data register |
peu605 | 6:83f3605478ab | 265 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 6:83f3605478ab | 266 | uint8_t *p_spi_dr = (uint8_t*) &spi_ptr->DR; |
peu605 | 6:83f3605478ab | 267 | *p_spi_dr = (uint8_t) c; |
peu605 | 6:83f3605478ab | 268 | |
peu605 | 6:83f3605478ab | 269 | waitSpiFree(); |
peu605 | 6:83f3605478ab | 270 | deselectSlave(); |
peu605 | 6:83f3605478ab | 271 | } |
peu605 | 6:83f3605478ab | 272 | |
peu605 | 6:83f3605478ab | 273 | |
peu605 | 6:83f3605478ab | 274 | void TFT_ILI9163C::writedata(uint8_t c){ |
peu605 | 6:83f3605478ab | 275 | |
peu605 | 6:83f3605478ab | 276 | set8bitMode(); |
peu605 | 6:83f3605478ab | 277 | setDataMode(); |
peu605 | 6:83f3605478ab | 278 | selectSlave(); |
peu605 | 6:83f3605478ab | 279 | |
peu605 | 6:83f3605478ab | 280 | // Force 8-bit access to the data register |
peu605 | 6:83f3605478ab | 281 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 6:83f3605478ab | 282 | uint8_t *p_spi_dr = (uint8_t*) &spi_ptr->DR; |
peu605 | 6:83f3605478ab | 283 | *p_spi_dr = (uint8_t) c; |
peu605 | 6:83f3605478ab | 284 | |
peu605 | 6:83f3605478ab | 285 | waitSpiFree(); |
peu605 | 6:83f3605478ab | 286 | deselectSlave(); |
peu605 | 6:83f3605478ab | 287 | } |
peu605 | 6:83f3605478ab | 288 | #endif |
peu605 | 2:6c1fadae252f | 289 | |
peu605 | 2:6c1fadae252f | 290 | |
peu605 | 2:6c1fadae252f | 291 | void TFT_ILI9163C::writedata16(uint16_t d){ |
peu605 | 2:6c1fadae252f | 292 | |
peu605 | 2:6c1fadae252f | 293 | set16bitMode(); |
peu605 | 2:6c1fadae252f | 294 | setDataMode(); |
peu605 | 2:6c1fadae252f | 295 | selectSlave(); |
peu605 | 2:6c1fadae252f | 296 | |
peu605 | 2:6c1fadae252f | 297 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 298 | spi_ptr->DR = d; |
peu605 | 2:6c1fadae252f | 299 | |
peu605 | 2:6c1fadae252f | 300 | waitSpiFree(); |
peu605 | 2:6c1fadae252f | 301 | deselectSlave(); |
peu605 | 2:6c1fadae252f | 302 | } |
peu605 | 2:6c1fadae252f | 303 | |
peu605 | 2:6c1fadae252f | 304 | |
peu605 | 2:6c1fadae252f | 305 | void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){ |
peu605 | 2:6c1fadae252f | 306 | |
peu605 | 2:6c1fadae252f | 307 | set16bitMode(); |
peu605 | 2:6c1fadae252f | 308 | setDataMode(); |
peu605 | 2:6c1fadae252f | 309 | selectSlave(); |
peu605 | 2:6c1fadae252f | 310 | |
peu605 | 2:6c1fadae252f | 311 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 312 | spi_ptr->DR = d1; |
peu605 | 2:6c1fadae252f | 313 | waitBufferFree(); |
peu605 | 2:6c1fadae252f | 314 | spi_ptr->DR = d2; |
peu605 | 2:6c1fadae252f | 315 | |
peu605 | 2:6c1fadae252f | 316 | waitSpiFree(); |
peu605 | 2:6c1fadae252f | 317 | deselectSlave(); |
peu605 | 2:6c1fadae252f | 318 | } |
peu605 | 2:6c1fadae252f | 319 | |
peu605 | 6:83f3605478ab | 320 | #if defined(__NUCLEO_DMA__) & defined(TARGET_NUCLEO_F411RE) |
peu605 | 2:6c1fadae252f | 321 | // use DMA, but polling... :-( |
peu605 | 2:6c1fadae252f | 322 | void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) { |
peu605 | 2:6c1fadae252f | 323 | |
peu605 | 2:6c1fadae252f | 324 | len = len < 0 ? -len : len; |
peu605 | 2:6c1fadae252f | 325 | |
peu605 | 2:6c1fadae252f | 326 | if (len > 0) { |
peu605 | 2:6c1fadae252f | 327 | set16bitMode(); |
peu605 | 2:6c1fadae252f | 328 | setDataMode(); |
peu605 | 2:6c1fadae252f | 329 | selectSlave(); |
peu605 | 2:6c1fadae252f | 330 | |
peu605 | 2:6c1fadae252f | 331 | // clear DMA flags |
peu605 | 2:6c1fadae252f | 332 | // __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma)); |
peu605 | 2:6c1fadae252f | 333 | __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma)); |
peu605 | 2:6c1fadae252f | 334 | |
peu605 | 2:6c1fadae252f | 335 | hdma.Instance->M0AR = (uint32_t) &d; |
peu605 | 2:6c1fadae252f | 336 | hdma.Instance->NDTR = len; |
peu605 | 2:6c1fadae252f | 337 | |
peu605 | 2:6c1fadae252f | 338 | // // enable DMA |
peu605 | 2:6c1fadae252f | 339 | // hdma.Instance->CR |= DMA_SxCR_EN; |
peu605 | 2:6c1fadae252f | 340 | // // enable DMA request from SPI |
peu605 | 2:6c1fadae252f | 341 | // SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 342 | // spi_ptr->CR2 |= SPI_CR2_TXDMAEN; |
peu605 | 2:6c1fadae252f | 343 | // // wait DMA complete |
peu605 | 2:6c1fadae252f | 344 | // while (hdma.Instance->NDTR); |
peu605 | 2:6c1fadae252f | 345 | // // disable SPI-DMA |
peu605 | 2:6c1fadae252f | 346 | // spi_ptr->CR2 &= ~SPI_CR2_TXDMAEN; |
peu605 | 2:6c1fadae252f | 347 | // // disable DMA |
peu605 | 2:6c1fadae252f | 348 | // hdma.Instance->CR &= ~DMA_SxCR_EN; |
peu605 | 2:6c1fadae252f | 349 | // while (hdma.Instance->CR & DMA_SxCR_EN); |
peu605 | 2:6c1fadae252f | 350 | |
peu605 | 2:6c1fadae252f | 351 | // enable DMA |
peu605 | 2:6c1fadae252f | 352 | *bb_dma_sxcr_en = 1; |
peu605 | 2:6c1fadae252f | 353 | // enable DMA request from SPI |
peu605 | 2:6c1fadae252f | 354 | *bb_spi_txdmaen = 1; |
peu605 | 2:6c1fadae252f | 355 | // wait DMA complete |
peu605 | 2:6c1fadae252f | 356 | while (hdma.Instance->NDTR); |
peu605 | 2:6c1fadae252f | 357 | // disable SPI-DMA |
peu605 | 2:6c1fadae252f | 358 | *bb_spi_txdmaen = 0; |
peu605 | 2:6c1fadae252f | 359 | // disable DMA |
peu605 | 2:6c1fadae252f | 360 | *bb_dma_sxcr_en = 0; |
peu605 | 2:6c1fadae252f | 361 | while (*bb_dma_sxcr_en); |
peu605 | 2:6c1fadae252f | 362 | |
peu605 | 2:6c1fadae252f | 363 | waitSpiFree(); |
peu605 | 2:6c1fadae252f | 364 | deselectSlave(); |
peu605 | 2:6c1fadae252f | 365 | } |
peu605 | 2:6c1fadae252f | 366 | } |
peu605 | 6:83f3605478ab | 367 | #elif defined(__NUCLEO_DMA__) & defined(TARGET_NUCLEO_F302R8) |
peu605 | 6:83f3605478ab | 368 | void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) { |
peu605 | 6:83f3605478ab | 369 | |
peu605 | 6:83f3605478ab | 370 | len = len < 0 ? -len : len; |
peu605 | 6:83f3605478ab | 371 | |
peu605 | 6:83f3605478ab | 372 | if (len > 0) { |
peu605 | 6:83f3605478ab | 373 | set16bitMode(); |
peu605 | 6:83f3605478ab | 374 | setDataMode(); |
peu605 | 6:83f3605478ab | 375 | selectSlave(); |
peu605 | 6:83f3605478ab | 376 | |
peu605 | 6:83f3605478ab | 377 | // clear DMA flags |
peu605 | 6:83f3605478ab | 378 | __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma)); |
peu605 | 6:83f3605478ab | 379 | |
peu605 | 6:83f3605478ab | 380 | hdma.Instance->CMAR = (uint32_t) &d; |
peu605 | 6:83f3605478ab | 381 | hdma.Instance->CNDTR = len; |
peu605 | 6:83f3605478ab | 382 | |
peu605 | 6:83f3605478ab | 383 | // enable DMA |
peu605 | 6:83f3605478ab | 384 | *bb_dma_sxcr_en = 1; |
peu605 | 6:83f3605478ab | 385 | // enable DMA request from SPI |
peu605 | 6:83f3605478ab | 386 | *bb_spi_txdmaen = 1; |
peu605 | 6:83f3605478ab | 387 | // wait DMA complete |
peu605 | 6:83f3605478ab | 388 | while (hdma.Instance->CNDTR); |
peu605 | 6:83f3605478ab | 389 | // disable SPI-DMA |
peu605 | 6:83f3605478ab | 390 | *bb_spi_txdmaen = 0; |
peu605 | 6:83f3605478ab | 391 | // disable DMA |
peu605 | 6:83f3605478ab | 392 | *bb_dma_sxcr_en = 0; |
peu605 | 6:83f3605478ab | 393 | while (*bb_dma_sxcr_en); |
peu605 | 6:83f3605478ab | 394 | |
peu605 | 6:83f3605478ab | 395 | waitSpiFree(); |
peu605 | 6:83f3605478ab | 396 | deselectSlave(); |
peu605 | 6:83f3605478ab | 397 | } |
peu605 | 6:83f3605478ab | 398 | } |
peu605 | 2:6c1fadae252f | 399 | #else |
peu605 | 2:6c1fadae252f | 400 | // use software loop, fast enough :-) |
peu605 | 2:6c1fadae252f | 401 | void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) { |
peu605 | 2:6c1fadae252f | 402 | |
peu605 | 2:6c1fadae252f | 403 | len = len < 0 ? -len : len; |
peu605 | 2:6c1fadae252f | 404 | |
peu605 | 2:6c1fadae252f | 405 | if (len > 0) { |
peu605 | 2:6c1fadae252f | 406 | set16bitMode(); |
peu605 | 2:6c1fadae252f | 407 | setDataMode(); |
peu605 | 2:6c1fadae252f | 408 | selectSlave(); |
peu605 | 2:6c1fadae252f | 409 | |
peu605 | 2:6c1fadae252f | 410 | SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; |
peu605 | 2:6c1fadae252f | 411 | while (len--) { |
peu605 | 2:6c1fadae252f | 412 | waitBufferFree(); |
peu605 | 2:6c1fadae252f | 413 | spi_ptr->DR = d; |
peu605 | 2:6c1fadae252f | 414 | } |
peu605 | 2:6c1fadae252f | 415 | |
peu605 | 2:6c1fadae252f | 416 | waitSpiFree(); |
peu605 | 2:6c1fadae252f | 417 | deselectSlave(); |
peu605 | 2:6c1fadae252f | 418 | } |
peu605 | 2:6c1fadae252f | 419 | } |
peu605 | 1:c271e7e2e330 | 420 | #endif |
peu605 | 2:6c1fadae252f | 421 | |
peu605 | 6:83f3605478ab | 422 | |
peu605 | 6:83f3605478ab | 423 | // mbed generic |
peu605 | 2:6c1fadae252f | 424 | #else |
peu605 | 2:6c1fadae252f | 425 | void TFT_ILI9163C::init(PinName cs, PinName dc){ |
peu605 | 2:6c1fadae252f | 426 | // nothing here |
peu605 | 2:6c1fadae252f | 427 | } |
peu605 | 2:6c1fadae252f | 428 | |
peu605 | 2:6c1fadae252f | 429 | void TFT_ILI9163C::writecommand(uint8_t c){ |
peu605 | 2:6c1fadae252f | 430 | |
peu605 | 2:6c1fadae252f | 431 | _dc = 0; |
peu605 | 2:6c1fadae252f | 432 | _cs = 0; |
peu605 | 2:6c1fadae252f | 433 | |
peu605 | 2:6c1fadae252f | 434 | SPI::write(c); |
peu605 | 2:6c1fadae252f | 435 | |
peu605 | 2:6c1fadae252f | 436 | _cs = 1; |
peu605 | 2:6c1fadae252f | 437 | } |
peu605 | 2:6c1fadae252f | 438 | |
peu605 | 2:6c1fadae252f | 439 | |
peu605 | 2:6c1fadae252f | 440 | void TFT_ILI9163C::writedata(uint8_t c){ |
peu605 | 2:6c1fadae252f | 441 | |
peu605 | 2:6c1fadae252f | 442 | _dc = 1; |
peu605 | 2:6c1fadae252f | 443 | _cs = 0; |
peu605 | 2:6c1fadae252f | 444 | |
peu605 | 2:6c1fadae252f | 445 | SPI::write(c); |
peu605 | 2:6c1fadae252f | 446 | |
peu605 | 2:6c1fadae252f | 447 | _cs = 1; |
peu605 | 2:6c1fadae252f | 448 | } |
peu605 | 2:6c1fadae252f | 449 | |
peu605 | 2:6c1fadae252f | 450 | |
peu605 | 2:6c1fadae252f | 451 | void TFT_ILI9163C::writedata16(uint16_t d){ |
peu605 | 2:6c1fadae252f | 452 | |
peu605 | 2:6c1fadae252f | 453 | _dc = 1; |
peu605 | 2:6c1fadae252f | 454 | _cs = 0; |
peu605 | 2:6c1fadae252f | 455 | |
peu605 | 2:6c1fadae252f | 456 | SPI::write(d >> 8); |
peu605 | 2:6c1fadae252f | 457 | SPI::write(d & 0xff); |
peu605 | 2:6c1fadae252f | 458 | |
peu605 | 2:6c1fadae252f | 459 | _cs = 1; |
peu605 | 2:6c1fadae252f | 460 | } |
peu605 | 2:6c1fadae252f | 461 | |
peu605 | 2:6c1fadae252f | 462 | |
peu605 | 2:6c1fadae252f | 463 | void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){ |
peu605 | 2:6c1fadae252f | 464 | |
peu605 | 2:6c1fadae252f | 465 | _dc = 1; |
peu605 | 2:6c1fadae252f | 466 | _cs = 0; |
peu605 | 2:6c1fadae252f | 467 | |
peu605 | 2:6c1fadae252f | 468 | SPI::write(d1 >> 8); |
peu605 | 2:6c1fadae252f | 469 | SPI::write(d1 & 0xff); |
peu605 | 2:6c1fadae252f | 470 | SPI::write(d2 >> 8); |
peu605 | 2:6c1fadae252f | 471 | SPI::write(d2 & 0xff); |
peu605 | 2:6c1fadae252f | 472 | |
peu605 | 2:6c1fadae252f | 473 | _cs = 1; |
peu605 | 2:6c1fadae252f | 474 | } |
peu605 | 2:6c1fadae252f | 475 | |
peu605 | 2:6c1fadae252f | 476 | |
peu605 | 2:6c1fadae252f | 477 | void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) { |
peu605 | 2:6c1fadae252f | 478 | |
peu605 | 2:6c1fadae252f | 479 | len = len < 0 ? -len : len; |
peu605 | 2:6c1fadae252f | 480 | |
peu605 | 2:6c1fadae252f | 481 | if (len > 0) { |
peu605 | 2:6c1fadae252f | 482 | |
peu605 | 2:6c1fadae252f | 483 | _dc = 1; |
peu605 | 2:6c1fadae252f | 484 | _cs = 0; |
peu605 | 2:6c1fadae252f | 485 | |
peu605 | 2:6c1fadae252f | 486 | while (len--) { |
peu605 | 2:6c1fadae252f | 487 | SPI::write(d >> 8); |
peu605 | 2:6c1fadae252f | 488 | SPI::write(d & 0xff); |
peu605 | 2:6c1fadae252f | 489 | } |
peu605 | 2:6c1fadae252f | 490 | |
peu605 | 2:6c1fadae252f | 491 | _cs = 1; |
peu605 | 2:6c1fadae252f | 492 | } |
peu605 | 2:6c1fadae252f | 493 | } |
peu605 | 2:6c1fadae252f | 494 | #endif |
peu605 | 2:6c1fadae252f | 495 | |
peu605 | 2:6c1fadae252f | 496 | |
peu605 | 2:6c1fadae252f | 497 | void TFT_ILI9163C::setBitrate(uint32_t n){ |
peu605 | 2:6c1fadae252f | 498 | SPI::frequency(n); |
peu605 | 2:6c1fadae252f | 499 | } |
peu605 | 2:6c1fadae252f | 500 | |
peu605 | 2:6c1fadae252f | 501 | |
peu605 | 2:6c1fadae252f | 502 | void TFT_ILI9163C::begin(void) { |
peu605 | 2:6c1fadae252f | 503 | |
peu605 | 2:6c1fadae252f | 504 | SPI::format(8,0); // 8 bit spi mode 0 |
peu605 | 2:6c1fadae252f | 505 | SPI::frequency(5000000L); // 5MHz |
peu605 | 0:f90a4405ef98 | 506 | |
peu605 | 0:f90a4405ef98 | 507 | if (_resetPinName != NC) { |
peu605 | 0:f90a4405ef98 | 508 | DigitalOut _reset(_resetPinName); |
peu605 | 0:f90a4405ef98 | 509 | _reset = 1; |
peu605 | 0:f90a4405ef98 | 510 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 511 | _reset = 0; |
peu605 | 0:f90a4405ef98 | 512 | wait_ms(2); |
peu605 | 0:f90a4405ef98 | 513 | _reset = 1; |
peu605 | 0:f90a4405ef98 | 514 | wait_ms(120); |
peu605 | 0:f90a4405ef98 | 515 | } |
peu605 | 0:f90a4405ef98 | 516 | |
peu605 | 0:f90a4405ef98 | 517 | /* |
peu605 | 0:f90a4405ef98 | 518 | 7) MY: 1(bottom to top), 0(top to bottom) Row Address Order |
peu605 | 0:f90a4405ef98 | 519 | 6) MX: 1(R to L), 0(L to R) Column Address Order |
peu605 | 0:f90a4405ef98 | 520 | 5) MV: 1(Exchanged), 0(normal) Row/Column exchange |
peu605 | 0:f90a4405ef98 | 521 | 4) ML: 1(bottom to top), 0(top to bottom) Vertical Refresh Order |
peu605 | 0:f90a4405ef98 | 522 | 3) RGB: 1(BGR), 0(RGB) Color Space |
peu605 | 0:f90a4405ef98 | 523 | 2) MH: 1(R to L), 0(L to R) Horizontal Refresh Order |
peu605 | 0:f90a4405ef98 | 524 | 1) |
peu605 | 0:f90a4405ef98 | 525 | 0) |
peu605 | 0:f90a4405ef98 | 526 | |
peu605 | 0:f90a4405ef98 | 527 | MY, MX, MV, ML,RGB, MH, D1, D0 |
peu605 | 0:f90a4405ef98 | 528 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 //normal |
peu605 | 0:f90a4405ef98 | 529 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 //Y-Mirror |
peu605 | 0:f90a4405ef98 | 530 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 //X-Mirror |
peu605 | 0:f90a4405ef98 | 531 | 1 | 1 | 0 | 0 | 1 | 0 | 0 | 0 //X-Y-Mirror |
peu605 | 0:f90a4405ef98 | 532 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 //X-Y Exchange |
peu605 | 0:f90a4405ef98 | 533 | 1 | 0 | 1 | 0 | 1 | 0 | 0 | 0 //X-Y Exchange, Y-Mirror |
peu605 | 0:f90a4405ef98 | 534 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 //XY exchange |
peu605 | 0:f90a4405ef98 | 535 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | 0 |
peu605 | 0:f90a4405ef98 | 536 | */ |
peu605 | 0:f90a4405ef98 | 537 | _Mactrl_Data = 0; // 0b00000000; |
peu605 | 0:f90a4405ef98 | 538 | _colorspaceData = __COLORSPC;//start with default data; |
peu605 | 6:83f3605478ab | 539 | |
peu605 | 0:f90a4405ef98 | 540 | chipInit(); |
peu605 | 0:f90a4405ef98 | 541 | } |
peu605 | 0:f90a4405ef98 | 542 | |
peu605 | 0:f90a4405ef98 | 543 | |
peu605 | 0:f90a4405ef98 | 544 | void TFT_ILI9163C::chipInit() { |
peu605 | 0:f90a4405ef98 | 545 | writecommand(CMD_SWRESET);//software reset |
peu605 | 0:f90a4405ef98 | 546 | wait_ms(120); |
peu605 | 0:f90a4405ef98 | 547 | writecommand(CMD_SLPOUT);//exit sleep |
peu605 | 0:f90a4405ef98 | 548 | wait_ms(5); |
peu605 | 0:f90a4405ef98 | 549 | writecommand(CMD_PIXFMT);//Set Color Format 16bit |
peu605 | 0:f90a4405ef98 | 550 | writedata(0x05); |
peu605 | 0:f90a4405ef98 | 551 | wait_ms(5); |
peu605 | 0:f90a4405ef98 | 552 | writecommand(CMD_GAMMASET);//default gamma curve 3 |
peu605 | 0:f90a4405ef98 | 553 | writedata(0x04);//0x04 |
peu605 | 0:f90a4405ef98 | 554 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 555 | writecommand(CMD_GAMRSEL);//Enable Gamma adj |
peu605 | 0:f90a4405ef98 | 556 | writedata(0x01); |
peu605 | 0:f90a4405ef98 | 557 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 558 | writecommand(CMD_NORML); |
peu605 | 0:f90a4405ef98 | 559 | |
peu605 | 0:f90a4405ef98 | 560 | writecommand(CMD_DFUNCTR); |
peu605 | 0:f90a4405ef98 | 561 | writedata(0xff); // writedata(0b11111111);// |
peu605 | 0:f90a4405ef98 | 562 | writedata(0x06); // writedata(0b00000110);// |
peu605 | 0:f90a4405ef98 | 563 | |
peu605 | 0:f90a4405ef98 | 564 | writecommand(CMD_PGAMMAC);//Positive Gamma Correction Setting |
peu605 | 0:f90a4405ef98 | 565 | #if defined(__GAMMASET1) |
peu605 | 0:f90a4405ef98 | 566 | writedata(0x36);//p1 |
peu605 | 0:f90a4405ef98 | 567 | writedata(0x29);//p2 |
peu605 | 0:f90a4405ef98 | 568 | writedata(0x12);//p3 |
peu605 | 0:f90a4405ef98 | 569 | writedata(0x22);//p4 |
peu605 | 0:f90a4405ef98 | 570 | writedata(0x1C);//p5 |
peu605 | 0:f90a4405ef98 | 571 | writedata(0x15);//p6 |
peu605 | 0:f90a4405ef98 | 572 | writedata(0x42);//p7 |
peu605 | 0:f90a4405ef98 | 573 | writedata(0xB7);//p8 |
peu605 | 0:f90a4405ef98 | 574 | writedata(0x2F);//p9 |
peu605 | 0:f90a4405ef98 | 575 | writedata(0x13);//p10 |
peu605 | 0:f90a4405ef98 | 576 | writedata(0x12);//p11 |
peu605 | 0:f90a4405ef98 | 577 | writedata(0x0A);//p12 |
peu605 | 0:f90a4405ef98 | 578 | writedata(0x11);//p13 |
peu605 | 0:f90a4405ef98 | 579 | writedata(0x0B);//p14 |
peu605 | 0:f90a4405ef98 | 580 | writedata(0x06);//p15 |
peu605 | 0:f90a4405ef98 | 581 | #else |
peu605 | 0:f90a4405ef98 | 582 | writedata(0x3F);//p1 |
peu605 | 0:f90a4405ef98 | 583 | writedata(0x25);//p2 |
peu605 | 0:f90a4405ef98 | 584 | writedata(0x1C);//p3 |
peu605 | 0:f90a4405ef98 | 585 | writedata(0x1E);//p4 |
peu605 | 0:f90a4405ef98 | 586 | writedata(0x20);//p5 |
peu605 | 0:f90a4405ef98 | 587 | writedata(0x12);//p6 |
peu605 | 0:f90a4405ef98 | 588 | writedata(0x2A);//p7 |
peu605 | 0:f90a4405ef98 | 589 | writedata(0x90);//p8 |
peu605 | 0:f90a4405ef98 | 590 | writedata(0x24);//p9 |
peu605 | 0:f90a4405ef98 | 591 | writedata(0x11);//p10 |
peu605 | 0:f90a4405ef98 | 592 | writedata(0x00);//p11 |
peu605 | 0:f90a4405ef98 | 593 | writedata(0x00);//p12 |
peu605 | 0:f90a4405ef98 | 594 | writedata(0x00);//p13 |
peu605 | 0:f90a4405ef98 | 595 | writedata(0x00);//p14 |
peu605 | 0:f90a4405ef98 | 596 | writedata(0x00);//p15 |
peu605 | 0:f90a4405ef98 | 597 | #endif |
peu605 | 0:f90a4405ef98 | 598 | |
peu605 | 0:f90a4405ef98 | 599 | writecommand(CMD_NGAMMAC);//Negative Gamma Correction Setting |
peu605 | 0:f90a4405ef98 | 600 | #if defined(__GAMMASET1) |
peu605 | 0:f90a4405ef98 | 601 | writedata(0x09);//p1 |
peu605 | 0:f90a4405ef98 | 602 | writedata(0x16);//p2 |
peu605 | 0:f90a4405ef98 | 603 | writedata(0x2D);//p3 |
peu605 | 0:f90a4405ef98 | 604 | writedata(0x0D);//p4 |
peu605 | 0:f90a4405ef98 | 605 | writedata(0x13);//p5 |
peu605 | 0:f90a4405ef98 | 606 | writedata(0x15);//p6 |
peu605 | 0:f90a4405ef98 | 607 | writedata(0x40);//p7 |
peu605 | 0:f90a4405ef98 | 608 | writedata(0x48);//p8 |
peu605 | 0:f90a4405ef98 | 609 | writedata(0x53);//p9 |
peu605 | 0:f90a4405ef98 | 610 | writedata(0x0C);//p10 |
peu605 | 0:f90a4405ef98 | 611 | writedata(0x1D);//p11 |
peu605 | 0:f90a4405ef98 | 612 | writedata(0x25);//p12 |
peu605 | 0:f90a4405ef98 | 613 | writedata(0x2E);//p13 |
peu605 | 0:f90a4405ef98 | 614 | writedata(0x34);//p14 |
peu605 | 0:f90a4405ef98 | 615 | writedata(0x39);//p15 |
peu605 | 0:f90a4405ef98 | 616 | #else |
peu605 | 0:f90a4405ef98 | 617 | writedata(0x20);//p1 |
peu605 | 0:f90a4405ef98 | 618 | writedata(0x20);//p2 |
peu605 | 0:f90a4405ef98 | 619 | writedata(0x20);//p3 |
peu605 | 0:f90a4405ef98 | 620 | writedata(0x20);//p4 |
peu605 | 0:f90a4405ef98 | 621 | writedata(0x05);//p5 |
peu605 | 0:f90a4405ef98 | 622 | writedata(0x15);//p6 |
peu605 | 0:f90a4405ef98 | 623 | writedata(0x00);//p7 |
peu605 | 0:f90a4405ef98 | 624 | writedata(0xA7);//p8 |
peu605 | 0:f90a4405ef98 | 625 | writedata(0x3D);//p9 |
peu605 | 0:f90a4405ef98 | 626 | writedata(0x18);//p10 |
peu605 | 0:f90a4405ef98 | 627 | writedata(0x25);//p11 |
peu605 | 0:f90a4405ef98 | 628 | writedata(0x2A);//p12 |
peu605 | 0:f90a4405ef98 | 629 | writedata(0x2B);//p13 |
peu605 | 0:f90a4405ef98 | 630 | writedata(0x2B);//p14 |
peu605 | 0:f90a4405ef98 | 631 | writedata(0x3A);//p15 |
peu605 | 0:f90a4405ef98 | 632 | #endif |
peu605 | 0:f90a4405ef98 | 633 | |
peu605 | 0:f90a4405ef98 | 634 | writecommand(CMD_FRMCTR1);//Frame Rate Control (In normal mode/Full colors) |
peu605 | 0:f90a4405ef98 | 635 | writedata(0x08);//0x0C//0x08 |
peu605 | 0:f90a4405ef98 | 636 | writedata(0x02);//0x14//0x08 |
peu605 | 0:f90a4405ef98 | 637 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 638 | writecommand(CMD_DINVCTR);//display inversion |
peu605 | 0:f90a4405ef98 | 639 | writedata(0x07); |
peu605 | 0:f90a4405ef98 | 640 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 641 | writecommand(CMD_PWCTR1);//Set VRH1[4:0] & VC[2:0] for VCI1 & GVDD |
peu605 | 0:f90a4405ef98 | 642 | writedata(0x0A);//4.30 - 0x0A |
peu605 | 0:f90a4405ef98 | 643 | writedata(0x02);//0x05 |
peu605 | 0:f90a4405ef98 | 644 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 645 | writecommand(CMD_PWCTR2);//Set BT[2:0] for AVDD & VCL & VGH & VGL |
peu605 | 0:f90a4405ef98 | 646 | writedata(0x02); |
peu605 | 0:f90a4405ef98 | 647 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 648 | writecommand(CMD_VCOMCTR1);//Set VMH[6:0] & VML[6:0] for VOMH & VCOML |
peu605 | 0:f90a4405ef98 | 649 | writedata(0x50);//0x50 |
peu605 | 0:f90a4405ef98 | 650 | writedata(99);//0x5b |
peu605 | 0:f90a4405ef98 | 651 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 652 | writecommand(CMD_VCOMOFFS); |
peu605 | 0:f90a4405ef98 | 653 | writedata(0);//0x40 |
peu605 | 0:f90a4405ef98 | 654 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 655 | |
peu605 | 0:f90a4405ef98 | 656 | colorSpace(_colorspaceData); |
peu605 | 0:f90a4405ef98 | 657 | setRotation(0); |
peu605 | 0:f90a4405ef98 | 658 | wait_ms(1); |
peu605 | 0:f90a4405ef98 | 659 | |
peu605 | 0:f90a4405ef98 | 660 | fillScreen(BLACK); |
peu605 | 0:f90a4405ef98 | 661 | writecommand(CMD_DISPON);//display ON |
peu605 | 0:f90a4405ef98 | 662 | } |
peu605 | 0:f90a4405ef98 | 663 | |
peu605 | 0:f90a4405ef98 | 664 | /* |
peu605 | 0:f90a4405ef98 | 665 | Colorspace selection: |
peu605 | 0:f90a4405ef98 | 666 | 0: RGB |
peu605 | 0:f90a4405ef98 | 667 | 1: GBR |
peu605 | 0:f90a4405ef98 | 668 | */ |
peu605 | 0:f90a4405ef98 | 669 | void TFT_ILI9163C::colorSpace(uint8_t cspace) { |
peu605 | 0:f90a4405ef98 | 670 | if (cspace < 1){ |
peu605 | 0:f90a4405ef98 | 671 | _Mactrl_Data &= ~(1 << 3); // bitClear(_Mactrl_Data,3); |
peu605 | 0:f90a4405ef98 | 672 | } else { |
peu605 | 0:f90a4405ef98 | 673 | _Mactrl_Data |= 1 << 3; // bitSet(_Mactrl_Data,3); |
peu605 | 0:f90a4405ef98 | 674 | } |
peu605 | 0:f90a4405ef98 | 675 | } |
peu605 | 0:f90a4405ef98 | 676 | |
peu605 | 0:f90a4405ef98 | 677 | |
peu605 | 0:f90a4405ef98 | 678 | void TFT_ILI9163C::clearScreen(uint16_t color) { |
peu605 | 0:f90a4405ef98 | 679 | homeAddress(); |
peu605 | 0:f90a4405ef98 | 680 | writedata16burst(color, _GRAMSIZE); |
peu605 | 0:f90a4405ef98 | 681 | } |
peu605 | 0:f90a4405ef98 | 682 | |
peu605 | 0:f90a4405ef98 | 683 | void TFT_ILI9163C::homeAddress() { |
peu605 | 0:f90a4405ef98 | 684 | setAddrWindow(0x00,0x00,_GRAMWIDTH-1,_GRAMHEIGH-1); |
peu605 | 0:f90a4405ef98 | 685 | } |
peu605 | 0:f90a4405ef98 | 686 | |
peu605 | 0:f90a4405ef98 | 687 | |
peu605 | 0:f90a4405ef98 | 688 | void TFT_ILI9163C::setCursor(int16_t x, int16_t y) { |
peu605 | 0:f90a4405ef98 | 689 | if (boundaryCheck(x,y)) return; |
peu605 | 0:f90a4405ef98 | 690 | setAddrWindow(0x00,0x00,x,y); |
peu605 | 0:f90a4405ef98 | 691 | cursor_x = x; |
peu605 | 0:f90a4405ef98 | 692 | cursor_y = y; |
peu605 | 0:f90a4405ef98 | 693 | } |
peu605 | 0:f90a4405ef98 | 694 | |
peu605 | 0:f90a4405ef98 | 695 | |
peu605 | 0:f90a4405ef98 | 696 | void TFT_ILI9163C::pushColor(uint16_t color) { |
peu605 | 0:f90a4405ef98 | 697 | writedata16(color); |
peu605 | 0:f90a4405ef98 | 698 | } |
peu605 | 0:f90a4405ef98 | 699 | |
peu605 | 0:f90a4405ef98 | 700 | |
peu605 | 0:f90a4405ef98 | 701 | void TFT_ILI9163C::drawPixel(int16_t x, int16_t y, uint16_t color) { |
peu605 | 0:f90a4405ef98 | 702 | if (boundaryCheck(x,y)) return; |
peu605 | 0:f90a4405ef98 | 703 | if ((x < 0) || (y < 0)) return; |
peu605 | 0:f90a4405ef98 | 704 | setAddrWindow(x,y,x+1,y+1); |
peu605 | 0:f90a4405ef98 | 705 | writedata16(color); |
peu605 | 0:f90a4405ef98 | 706 | } |
peu605 | 0:f90a4405ef98 | 707 | |
peu605 | 0:f90a4405ef98 | 708 | |
peu605 | 0:f90a4405ef98 | 709 | void TFT_ILI9163C::drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color) { |
peu605 | 0:f90a4405ef98 | 710 | // Rudimentary clipping |
peu605 | 0:f90a4405ef98 | 711 | if (boundaryCheck(x,y)) return; |
peu605 | 0:f90a4405ef98 | 712 | if (((y + h) - 1) >= _height) h = _height-y; |
peu605 | 0:f90a4405ef98 | 713 | |
peu605 | 0:f90a4405ef98 | 714 | setAddrWindow(x,y,x,(y+h)-1); |
peu605 | 0:f90a4405ef98 | 715 | writedata16burst(color, h); |
peu605 | 0:f90a4405ef98 | 716 | } |
peu605 | 0:f90a4405ef98 | 717 | |
peu605 | 0:f90a4405ef98 | 718 | inline bool TFT_ILI9163C::boundaryCheck(int16_t x,int16_t y){ |
peu605 | 0:f90a4405ef98 | 719 | if ((x >= _width) || (y >= _height)) return true; |
peu605 | 0:f90a4405ef98 | 720 | return false; |
peu605 | 0:f90a4405ef98 | 721 | } |
peu605 | 0:f90a4405ef98 | 722 | |
peu605 | 0:f90a4405ef98 | 723 | void TFT_ILI9163C::drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color) { |
peu605 | 0:f90a4405ef98 | 724 | // Rudimentary clipping |
peu605 | 0:f90a4405ef98 | 725 | if (boundaryCheck(x,y)) return; |
peu605 | 0:f90a4405ef98 | 726 | if (((x+w) - 1) >= _width) w = _width-x; |
peu605 | 0:f90a4405ef98 | 727 | |
peu605 | 0:f90a4405ef98 | 728 | setAddrWindow(x,y,(x+w)-1,y); |
peu605 | 0:f90a4405ef98 | 729 | writedata16burst(color, w); |
peu605 | 0:f90a4405ef98 | 730 | } |
peu605 | 0:f90a4405ef98 | 731 | |
peu605 | 0:f90a4405ef98 | 732 | void TFT_ILI9163C::fillScreen(uint16_t color) { |
peu605 | 0:f90a4405ef98 | 733 | clearScreen(color); |
peu605 | 0:f90a4405ef98 | 734 | } |
peu605 | 0:f90a4405ef98 | 735 | |
peu605 | 0:f90a4405ef98 | 736 | // fill a rectangle |
peu605 | 0:f90a4405ef98 | 737 | void TFT_ILI9163C::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { |
peu605 | 0:f90a4405ef98 | 738 | |
peu605 | 0:f90a4405ef98 | 739 | if (boundaryCheck(x,y)) return; |
peu605 | 0:f90a4405ef98 | 740 | if (((x + w) - 1) >= _width) w = _width - x; |
peu605 | 0:f90a4405ef98 | 741 | if (((y + h) - 1) >= _height) h = _height - y; |
peu605 | 0:f90a4405ef98 | 742 | |
peu605 | 0:f90a4405ef98 | 743 | setAddrWindow(x,y,(x+w)-1,(y+h)-1); |
peu605 | 0:f90a4405ef98 | 744 | writedata16burst(color, w * h); |
peu605 | 0:f90a4405ef98 | 745 | } |
peu605 | 0:f90a4405ef98 | 746 | |
peu605 | 0:f90a4405ef98 | 747 | |
peu605 | 0:f90a4405ef98 | 748 | // Pass 8-bit (each) R,G,B, get back 16-bit packed color |
peu605 | 0:f90a4405ef98 | 749 | |
peu605 | 0:f90a4405ef98 | 750 | uint16_t TFT_ILI9163C::Color565(uint8_t r, uint8_t g, uint8_t b) { |
peu605 | 0:f90a4405ef98 | 751 | return ((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3); |
peu605 | 0:f90a4405ef98 | 752 | } |
peu605 | 0:f90a4405ef98 | 753 | |
peu605 | 0:f90a4405ef98 | 754 | |
peu605 | 0:f90a4405ef98 | 755 | void TFT_ILI9163C::setAddrWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { |
peu605 | 0:f90a4405ef98 | 756 | |
peu605 | 0:f90a4405ef98 | 757 | writecommand(CMD_CLMADRS); // Column |
peu605 | 0:f90a4405ef98 | 758 | |
peu605 | 0:f90a4405ef98 | 759 | if (rotation == 1) { |
peu605 | 0:f90a4405ef98 | 760 | writedata32(x0 + __OFFSET, x1 + __OFFSET); |
peu605 | 0:f90a4405ef98 | 761 | } else { |
peu605 | 0:f90a4405ef98 | 762 | writedata32(x0, x1); |
peu605 | 0:f90a4405ef98 | 763 | } |
peu605 | 0:f90a4405ef98 | 764 | |
peu605 | 0:f90a4405ef98 | 765 | writecommand(CMD_PGEADRS); // Page |
peu605 | 0:f90a4405ef98 | 766 | if (rotation == 0){ |
peu605 | 0:f90a4405ef98 | 767 | writedata32(y0 + __OFFSET, y1 + __OFFSET); |
peu605 | 0:f90a4405ef98 | 768 | } else { |
peu605 | 0:f90a4405ef98 | 769 | writedata32(y0, y1); |
peu605 | 0:f90a4405ef98 | 770 | } |
peu605 | 0:f90a4405ef98 | 771 | |
peu605 | 0:f90a4405ef98 | 772 | writecommand(CMD_RAMWR); //Into RAM |
peu605 | 0:f90a4405ef98 | 773 | } |
peu605 | 0:f90a4405ef98 | 774 | |
peu605 | 0:f90a4405ef98 | 775 | |
peu605 | 0:f90a4405ef98 | 776 | void TFT_ILI9163C::setRotation(uint8_t m) { |
peu605 | 0:f90a4405ef98 | 777 | rotation = m &3; // can't be higher than 3 |
peu605 | 0:f90a4405ef98 | 778 | switch (rotation) { |
peu605 | 0:f90a4405ef98 | 779 | case 0: |
peu605 | 0:f90a4405ef98 | 780 | _Mactrl_Data = 0x08; // 0b00001000; |
peu605 | 0:f90a4405ef98 | 781 | _width = _TFTWIDTH; |
peu605 | 0:f90a4405ef98 | 782 | _height = _TFTHEIGHT;//-__OFFSET; |
peu605 | 0:f90a4405ef98 | 783 | break; |
peu605 | 0:f90a4405ef98 | 784 | case 1: |
peu605 | 0:f90a4405ef98 | 785 | _Mactrl_Data = 0x68; // 0b01101000; |
peu605 | 0:f90a4405ef98 | 786 | _width = _TFTHEIGHT;//-__OFFSET; |
peu605 | 0:f90a4405ef98 | 787 | _height = _TFTWIDTH; |
peu605 | 0:f90a4405ef98 | 788 | break; |
peu605 | 0:f90a4405ef98 | 789 | case 2: |
peu605 | 0:f90a4405ef98 | 790 | _Mactrl_Data = 0xC8; // 0b11001000; |
peu605 | 0:f90a4405ef98 | 791 | _width = _TFTWIDTH; |
peu605 | 0:f90a4405ef98 | 792 | _height = _TFTHEIGHT;//-__OFFSET; |
peu605 | 0:f90a4405ef98 | 793 | break; |
peu605 | 0:f90a4405ef98 | 794 | case 3: |
peu605 | 0:f90a4405ef98 | 795 | _Mactrl_Data = 0xA8; // 0b10101000; |
peu605 | 0:f90a4405ef98 | 796 | _width = _TFTWIDTH; |
peu605 | 0:f90a4405ef98 | 797 | _height = _TFTHEIGHT;//-__OFFSET; |
peu605 | 0:f90a4405ef98 | 798 | break; |
peu605 | 0:f90a4405ef98 | 799 | } |
peu605 | 0:f90a4405ef98 | 800 | colorSpace(_colorspaceData); |
peu605 | 0:f90a4405ef98 | 801 | writecommand(CMD_MADCTL); |
peu605 | 0:f90a4405ef98 | 802 | writedata(_Mactrl_Data); |
peu605 | 0:f90a4405ef98 | 803 | } |
peu605 | 0:f90a4405ef98 | 804 | |
peu605 | 0:f90a4405ef98 | 805 | |
peu605 | 0:f90a4405ef98 | 806 | void TFT_ILI9163C::invertDisplay(bool i) { |
peu605 | 0:f90a4405ef98 | 807 | writecommand(i ? CMD_DINVON : CMD_DINVOF); |
peu605 | 0:f90a4405ef98 | 808 | } |