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
Diff: TFT_ILI9163C.cpp
- Revision:
- 2:6c1fadae252f
- Parent:
- 1:c271e7e2e330
- Child:
- 3:254e799c24ca
--- a/TFT_ILI9163C.cpp Thu Jan 22 12:16:31 2015 +0000 +++ b/TFT_ILI9163C.cpp Mon Jan 26 10:39:12 2015 +0000 @@ -15,216 +15,47 @@ : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT) , SPI(mosi,miso,sclk,NC), _cs(cs), _dc(dc) { _resetPinName = reset; + init(cs, dc); } TFT_ILI9163C::TFT_ILI9163C(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName dc) : Adafruit_GFX(_TFTWIDTH,_TFTHEIGHT) , SPI(mosi,miso,sclk,NC), _cs(cs), _dc(dc) { - _resetPinName = NC; + TFT_ILI9163C(mosi, miso, sclk, cs, dc, NC); } - //Serial pc(SERIAL_TX, SERIAL_RX); // F411RE specific -#if defined(__F411RE__) -inline void TFT_ILI9163C::waitSpiFree() { - - while ((spi_ptr->SR & SPI_SR_TXE) == 0); - while ((spi_ptr->SR & SPI_SR_BSY) != 0); -} - - -inline void TFT_ILI9163C::writecommand(uint8_t c){ - - spi_ptr->CR1 &= ~SPI_CR1_DFF; - - _dc = 0; - _cs = 0; - - spi_ptr->DR = c; - - waitSpiFree(); - _cs = 1; -} - - -inline void TFT_ILI9163C::writedata(uint8_t c){ - - spi_ptr->CR1 &= ~SPI_CR1_DFF; - - _dc = 1; - _cs = 0; - - spi_ptr->DR = c; - - waitSpiFree(); - _cs = 1; -} - - -inline void TFT_ILI9163C::writedata16(uint16_t d){ +#if defined(TARGET_NUCLEO_F411RE) +void TFT_ILI9163C::init(PinName cs, PinName dc){ - spi_ptr->CR1 |= SPI_CR1_DFF; - - _dc = 1; - _cs = 0; - - spi_ptr->DR = d; - - waitSpiFree(); - _cs = 1; -} - - -inline void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){ - - spi_ptr->CR1 |= SPI_CR1_DFF; - - _dc = 1; - _cs = 0; - - spi_ptr->DR = d1; - while ((spi_ptr->SR & SPI_SR_TXE) == 0); - spi_ptr->DR = d2; - - waitSpiFree(); - _cs = 1; -} - - -inline void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) { - - if (len < 0) { - len = -len; - } - - spi_ptr->CR1 |= SPI_CR1_DFF; - - _dc = 1; - _cs = 0; + SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; + + uint32_t cs_port_index = (uint32_t) cs >> 4; + uint32_t dc_port_index = (uint32_t) dc >> 4; + + //set cs/dc port addresses and masks + cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10)); + cs_reg_mask = 1 << ((uint32_t) cs & 0xf); + dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10)); + dc_reg_mask = 1 << ((uint32_t) dc & 0xf); + + // set bit band addresses +// GPIO_TypeDef *cs_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (cs_port_index << 10)); +// GPIO_TypeDef *dc_port_reg = (GPIO_TypeDef *) (GPIOA_BASE + (dc_port_index << 10)); +// uint8_t cs_port_bit = (uint32_t) cs & 0xf; +// uint8_t dc_port_bit = (uint32_t) dc & 0xf; +// bb_cs_port = BITBAND_PERIPH(&cs_port_reg->ODR, cs_port_bit); +// bb_dc_port = BITBAND_PERIPH(&dc_port_reg->ODR, dc_port_bit); + + bb_spi_txe = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_TXE)); + bb_spi_bsy = BITBAND_PERIPH(&spi_ptr->SR, MASK_TO_BITNUM(SPI_SR_BSY)); + bb_spi_spe = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_SPE)); + bb_spi_dff = BITBAND_PERIPH(&spi_ptr->CR1, MASK_TO_BITNUM(SPI_CR1_DFF)); #if defined(__F411RE_DMA__) - // use DMA, but polling... :-( - - // clear DMA flags -// __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma)); - __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma)); - - hdma.Instance->M0AR = (uint32_t) &d; - hdma.Instance->NDTR = len; - // enable DMA - hdma.Instance->CR |= DMA_SxCR_EN; - - // enable DMA request from SPI - spi_ptr->CR2 |= SPI_CR2_TXDMAEN; - // wait DMA complete - while (hdma.Instance->NDTR); - // disable SPI-DMA - spi_ptr->CR2 &= ~SPI_CR2_TXDMAEN; - - // disable DMA - hdma.Instance->CR &= ~DMA_SxCR_EN; - while (hdma.Instance->CR & DMA_SxCR_EN); - -#else - // use software loop, fast enough :-) - while (len--) { - while ((spi_ptr->SR & SPI_SR_TXE) == 0); - spi_ptr->DR = d; - } -#endif - - waitSpiFree(); - _cs = 1; -} - -// mbed general -#else -inline void TFT_ILI9163C::waitSpiFree() { -} - -inline void TFT_ILI9163C::writecommand(uint8_t c){ - - _dc = 0; - _cs = 0; - - SPI::write(c); - - _cs = 1; -} - - -inline void TFT_ILI9163C::writedata(uint8_t c){ - - _dc = 1; - _cs = 0; - - SPI::write(c); - - _cs = 1; -} - - -inline void TFT_ILI9163C::writedata16(uint16_t d){ - - _dc = 1; - _cs = 0; - - SPI::write(d >> 8); - SPI::write(d & 0xff); - - _cs = 1; -} - - -inline void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){ - - _dc = 1; - _cs = 0; - - SPI::write(d1 >> 8); - SPI::write(d1 & 0xff); - SPI::write(d2 >> 8); - SPI::write(d2 & 0xff); - - _cs = 1; -} - - -inline void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) { - - if (len < 0) { - len = -len; - } - - _dc = 1; - _cs = 0; - - while (len--) { - SPI::write(d >> 8); - SPI::write(d & 0xff); - } - - _cs = 1; -} -#endif - - -void TFT_ILI9163C::setBitrate(uint32_t n){ - SPI::frequency(n); -} - - -void TFT_ILI9163C::begin(void) { - - SPI::format(8,0); // 8 bit spi mode 0 - SPI::frequency(5000000L); // 5MHz - -#if defined(__F411RE__) - spi_ptr = (SPI_TypeDef*) _spi.spi; - -#if defined(__F411RE_DMA__) + // init DMA hdma.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma.Init.PeriphInc = DMA_PINC_DISABLE; hdma.Init.MemInc = DMA_MINC_DISABLE; @@ -263,8 +94,291 @@ // set SPI DR ss Peripheral address hdma.Instance->PAR = (uint32_t) &spi_ptr->DR; + + // set bit band addresses + bb_spi_txdmaen = BITBAND_PERIPH(&spi_ptr->CR2, MASK_TO_BITNUM(SPI_CR2_TXDMAEN)); + bb_dma_sxcr_en = BITBAND_PERIPH(&hdma.Instance->CR, MASK_TO_BITNUM(DMA_SxCR_EN)); #endif +} +inline void TFT_ILI9163C::selectSlave() { +// _cs = 0; // Use DigitalOut +// *bb_cs_port = 0; // Use bit band + cs_port_reg->BSRRH = cs_reg_mask; // Use BSRR register +} +inline void TFT_ILI9163C::deselectSlave() { +// _cs = 1; +// *bb_cs_port = 1; + cs_port_reg->BSRRL = cs_reg_mask; +} +inline void TFT_ILI9163C::setCommandMode() { +// _dc = 0; +// *bb_dc_port = 0; + dc_port_reg->BSRRH = dc_reg_mask; +} +inline void TFT_ILI9163C::setDataMode() { +// _dc = 1; +// *bb_dc_port = 1; + dc_port_reg->BSRRL = dc_reg_mask; +} +inline void TFT_ILI9163C::waitSpiFree() { + +// SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; +// while ((spi_ptr->SR & SPI_SR_TXE) == 0); +// while ((spi_ptr->SR & SPI_SR_BSY) != 0); + + while (*bb_spi_txe == 0); + while (*bb_spi_bsy != 0); +} + +inline void TFT_ILI9163C::waitBufferFree() { + +// SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; +// while ((spi_ptr->SR & SPI_SR_TXE) == 0); + + while (*bb_spi_txe == 0); +} + +inline void TFT_ILI9163C::set8bitMode() { + +// SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; +// spi_ptr->CR1 &= ~(SPI_CR1_SPE | SPI_CR1_DFF); +// spi_ptr->CR1 |= SPI_CR1_SPE; + + *bb_spi_spe = 0; + *bb_spi_dff = 0; + *bb_spi_spe = 1; +} + +inline void TFT_ILI9163C::set16bitMode() { + +// SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; +// spi_ptr->CR1 &= ~SPI_CR1_SPE; +// spi_ptr->CR1 |= (SPI_CR1_SPE | SPI_CR1_DFF); + + *bb_spi_spe = 0; + *bb_spi_dff = 1; + *bb_spi_spe = 1; +} + +void TFT_ILI9163C::writecommand(uint8_t c){ + + set8bitMode(); + setCommandMode(); + selectSlave(); + + SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; + spi_ptr->DR = c; + + waitSpiFree(); + deselectSlave(); +} + + +void TFT_ILI9163C::writedata(uint8_t c){ + + set8bitMode(); + setDataMode(); + selectSlave(); + + SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; + spi_ptr->DR = c; + + waitSpiFree(); + deselectSlave(); +} + + +void TFT_ILI9163C::writedata16(uint16_t d){ + + set16bitMode(); + setDataMode(); + selectSlave(); + + SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; + spi_ptr->DR = d; + + waitSpiFree(); + deselectSlave(); +} + + +void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){ + + set16bitMode(); + setDataMode(); + selectSlave(); + + SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; + spi_ptr->DR = d1; + waitBufferFree(); + spi_ptr->DR = d2; + + waitSpiFree(); + deselectSlave(); +} + +#if defined(__F411RE_DMA__) +// use DMA, but polling... :-( +void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) { + + len = len < 0 ? -len : len; + + if (len > 0) { + set16bitMode(); + setDataMode(); + selectSlave(); + + // clear DMA flags +// __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma)); + __HAL_DMA_CLEAR_FLAG(&hdma, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma)); + + hdma.Instance->M0AR = (uint32_t) &d; + hdma.Instance->NDTR = len; + +// // enable DMA +// hdma.Instance->CR |= DMA_SxCR_EN; +// +// // enable DMA request from SPI +// SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; +// spi_ptr->CR2 |= SPI_CR2_TXDMAEN; +// +// // wait DMA complete +// while (hdma.Instance->NDTR); +// +// // disable SPI-DMA +// spi_ptr->CR2 &= ~SPI_CR2_TXDMAEN; +// +// // disable DMA +// hdma.Instance->CR &= ~DMA_SxCR_EN; +// while (hdma.Instance->CR & DMA_SxCR_EN); + + // enable DMA + *bb_dma_sxcr_en = 1; + + // enable DMA request from SPI + *bb_spi_txdmaen = 1; + + // wait DMA complete + while (hdma.Instance->NDTR); + + // disable SPI-DMA + *bb_spi_txdmaen = 0; + + // disable DMA + *bb_dma_sxcr_en = 0; + while (*bb_dma_sxcr_en); + + waitSpiFree(); + deselectSlave(); + } +} + +#else +// use software loop, fast enough :-) +void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) { + + len = len < 0 ? -len : len; + + if (len > 0) { + set16bitMode(); + setDataMode(); + selectSlave(); + + SPI_TypeDef *spi_ptr = (SPI_TypeDef*) _spi.spi; + while (len--) { + waitBufferFree(); + spi_ptr->DR = d; + } + + waitSpiFree(); + deselectSlave(); + } +} #endif + +// mbed general +#else +void TFT_ILI9163C::init(PinName cs, PinName dc){ + // nothing here +} + +void TFT_ILI9163C::writecommand(uint8_t c){ + + _dc = 0; + _cs = 0; + + SPI::write(c); + + _cs = 1; +} + + +void TFT_ILI9163C::writedata(uint8_t c){ + + _dc = 1; + _cs = 0; + + SPI::write(c); + + _cs = 1; +} + + +void TFT_ILI9163C::writedata16(uint16_t d){ + + _dc = 1; + _cs = 0; + + SPI::write(d >> 8); + SPI::write(d & 0xff); + + _cs = 1; +} + + +void TFT_ILI9163C::writedata32(uint16_t d1, uint16_t d2){ + + _dc = 1; + _cs = 0; + + SPI::write(d1 >> 8); + SPI::write(d1 & 0xff); + SPI::write(d2 >> 8); + SPI::write(d2 & 0xff); + + _cs = 1; +} + + +void TFT_ILI9163C::writedata16burst(uint16_t d, int32_t len) { + + len = len < 0 ? -len : len; + + if (len > 0) { + + _dc = 1; + _cs = 0; + + while (len--) { + SPI::write(d >> 8); + SPI::write(d & 0xff); + } + + _cs = 1; + } +} +#endif + + +void TFT_ILI9163C::setBitrate(uint32_t n){ + SPI::frequency(n); +} + + +void TFT_ILI9163C::begin(void) { + + SPI::format(8,0); // 8 bit spi mode 0 + SPI::frequency(5000000L); // 5MHz if (_resetPinName != NC) { DigitalOut _reset(_resetPinName);