Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * IL9341.c - interface routines for IL9341 LCD.
- * shamelessly ganked from Adafruit_IL9341 library
- * 03-11-16 E. Brombaugh
- */
- #include "il9341.h"
- #include "cyclesleep.h"
- /* ----------------------- I/O definitions ----------------------- */
- #define IL9341_CS_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
- #define IL9341_CS_GPIO_PORT GPIOB
- #define IL9341_CS_PIN GPIO_PIN_10
- #define IL9341_DC_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
- #define IL9341_DC_GPIO_PORT GPIOE
- #define IL9341_DC_PIN GPIO_PIN_13
- #define IL9341_RST_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
- #define IL9341_RST_GPIO_PORT GPIOB
- #define IL9341_RST_PIN GPIO_PIN_11
- /* diag is not hooked up on AD-AB-04 */
- #define IL9341_DIAG_GPIO_CLK_ENABLE()
- #define IL9341_DIAG_GPIO_PORT
- #define IL9341_DIAG_PIN
- #define IL9341_MOSI_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
- #define IL9341_MOSI_GPIO_PORT GPIOE
- #define IL9341_MOSI_PIN GPIO_PIN_14
- #define IL9341_MOSI_AF GPIO_AF5_SPI4
- #define IL9341_SCLK_GPIO_CLK_ENABLE() __HAL_RCC_GPIOE_CLK_ENABLE()
- #define IL9341_SCLK_GPIO_PORT GPIOE
- #define IL9341_SCLK_PIN GPIO_PIN_12
- #define IL9341_SCLK_AF GPIO_AF5_SPI4
- #define IL9341_SPI_CLK_ENABLE() __HAL_RCC_SPI4_CLK_ENABLE()
- #define IL9341_SPI_PORT SPI4
- #define IL9341_SPI_DMA_CLK_ENABLE() __HAL_RCC_DMA2_CLK_ENABLE();
- #define IL9341_SPI_DMA_STREAM DMA2_Stream1
- #define IL9341_SPI_DMA_CHANNEL DMA_CHANNEL_4
- #define IL9341_SPI_DMA_TX_IRQn DMA2_Stream1_IRQn
- #define IL9341_SPI_DMA_TX_IRQHandler DMA2_Stream1_IRQHandler
- #define IL9341_SPI_DMA_TCFLAG DMA_FLAG_TCIF1_5
- #define IL9341_CS_LOW() HAL_GPIO_WritePin(IL9341_CS_GPIO_PORT, IL9341_CS_PIN, GPIO_PIN_RESET)
- #define IL9341_CS_HIGH() HAL_GPIO_WritePin(IL9341_CS_GPIO_PORT, IL9341_CS_PIN, GPIO_PIN_SET)
- #define IL9341_DC_CMD() HAL_GPIO_WritePin(IL9341_DC_GPIO_PORT, IL9341_DC_PIN, GPIO_PIN_RESET)
- #define IL9341_DC_DATA() HAL_GPIO_WritePin(IL9341_DC_GPIO_PORT, IL9341_DC_PIN, GPIO_PIN_SET)
- #define IL9341_RST_LOW() HAL_GPIO_WritePin(IL9341_RST_GPIO_PORT, IL9341_RST_PIN, GPIO_PIN_RESET)
- #define IL9341_RST_HIGH() HAL_GPIO_WritePin(IL9341_RST_GPIO_PORT, IL9341_RST_PIN, GPIO_PIN_SET)
- #if 0
- #define IL9341_DIAG_LOW() HAL_GPIO_WritePin(IL9341_DIAG_GPIO_PORT, IL9341_DIAG_PIN, GPIO_PIN_RESET)
- #define IL9341_DIAG_HIGH() HAL_GPIO_WritePin(IL9341_DIAG_GPIO_PORT, IL9341_DIAG_PIN, GPIO_PIN_SET)
- #else
- #define IL9341_DIAG_LOW()
- #define IL9341_DIAG_HIGH()
- #endif
- // some flags for initR() :(
- #define INITR_GREENTAB 0x0
- #define INITR_REDTAB 0x1
- #define IL9341_TFTWIDTH 240
- #define IL9341_TFTHEIGHT 320
- #define IL9341_NOP 0x00
- #define IL9341_SWRESET 0x01
- #define IL9341_RDDID 0x04
- #define IL9341_RDDST 0x09
- #define IL9341_SLPIN 0x10
- #define IL9341_SLPOUT 0x11
- #define IL9341_PTLON 0x12
- #define IL9341_NORON 0x13
- #define IL9341_INVOFF 0x20
- #define IL9341_INVON 0x21
- #define IL9341_GAMMASET 0x26
- #define IL9341_DISPOFF 0x28
- #define IL9341_DISPON 0x29
- #define IL9341_CASET 0x2A
- #define IL9341_RASET 0x2B
- #define IL9341_RAMWR 0x2C
- #define IL9341_RAMRD 0x2E
- #define IL9341_PTLAR 0x30
- #define IL9341_PIXFMT 0x3A
- #define IL9341_MADCTL 0x36
- #define IL9341_FRMCTR1 0xB1
- #define IL9341_FRMCTR2 0xB2
- #define IL9341_FRMCTR3 0xB3
- #define IL9341_INVCTR 0xB4
- #define IL9341_DFUNCTR 0xB6
- #define IL9341_PWCTR1 0xC0
- #define IL9341_PWCTR2 0xC1
- #define IL9341_PWCTR3 0xC2
- #define IL9341_PWCTR4 0xC3
- #define IL9341_PWCTR5 0xC4
- #define IL9341_VMCTR1 0xC5
- #define IL9341_VMCTR2 0xC7
- #define IL9341_RDID1 0xDA
- #define IL9341_RDID2 0xDB
- #define IL9341_RDID3 0xDC
- #define IL9341_RDID4 0xDD
- #define IL9341_PWCTR6 0xFC
- #define IL9341_GMCTRP1 0xE0
- #define IL9341_GMCTRN1 0xE1
- /* uncomment this to use DMA */
- #define IL9341_USE_DMA
- /* ----------------------- private variables ----------------------- */
- /* 320x240 IL9341 specific sequence */
- const static uint16_t initlst[] = {
- 0xEF | IL9341_CMD, // Unknown magic!
- 0x03, 0x80, 0x02,
- 0xCF | IL9341_CMD, // Power control B
- 0x00, 0x83, 0x30,
- 0xED | IL9341_CMD, // Power on sequence control
- 0x64, 0x03, 0x12, 0x81,
- 0xE8 | IL9341_CMD, // Driver timing control A
- 0x85, 0x01, 0x79,
- 0xCB | IL9341_CMD, // Power control B
- 0x39, 0x2C, 0x00, 0x34, 0x02,
- 0xF7 | IL9341_CMD, // Pump ratio control
- 0x20,
- 0xEA | IL9341_CMD, // Driver timing control B
- 0x00, 0x00,
- IL9341_PWCTR1 | IL9341_CMD, // Power control 1
- 0x23,
- IL9341_PWCTR2 | IL9341_CMD, // Power control 2
- 0x10,
- IL9341_VMCTR1 | IL9341_CMD, // VCOM Control 1
- 0x35, 0x3E,
- IL9341_VMCTR2 | IL9341_CMD, // VCOM Control 2
- 0xBE,
- IL9341_MADCTL | IL9341_CMD, // Memory Access Control
- 0x48,
- IL9341_PIXFMT | IL9341_CMD, //
- 0x55,
- IL9341_FRMCTR1| IL9341_CMD, //
- 0x00, 0x18,
- IL9341_DFUNCTR| IL9341_CMD, //
- 0x08, 0x82, 0x27,
- 0xF2| IL9341_CMD, // 3Gamma Function Disable
- 0x00,
- IL9341_GAMMASET| IL9341_CMD, // Set Gamma
- 0x01,
- IL9341_GMCTRP1| IL9341_CMD, // Gamma
- 0x1F, 0x1A, 0x18, 0x0A,
- 0x0F, 0x06, 0x45, 0x87,
- 0x32, 0x0A, 0x07, 0x02,
- 0x07, 0x05, 0x00,
- IL9341_GMCTRN1 | IL9341_CMD, // Gamma
- 0x00, 0x25, 0x27, 0x05,
- 0x10, 0x09, 0x3A, 0x78,
- 0x4D, 0x05, 0x18, 0x0D,
- 0x38, 0x3A, 0x1F,
- IL9341_SLPOUT | IL9341_CMD, // Exit Sleep
- 50 | IL9341_DLY, // 50 ms delay
- IL9341_DISPON | IL9341_CMD, // display on
- 10 | IL9341_DLY, // 10 ms delay
- IL9341_END // END
- };
- /* SPI port handle */
- SPI_HandleTypeDef SpiHandle;
- /* SPI lock */
- uint8_t il9341_spi_lock;
- #ifdef IL9341_USE_DMA
- /* DMA channel handle */
- DMA_HandleTypeDef hdma_spi;
- /* uncomment this for non-blocking multi-byte writes */
- #define IL9341_NONBLOCKING
- #endif
- /* LCD state */
- uint16_t _width, _height, rotation;
- /* ----------------------- Private functions ----------------------- */
- /**
- * @brief Custom - Transmit an amount of data in blocking mode
- * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
- * the configuration information for SPI module.
- * @param pData: pointer to data buffer
- * @param Size: amount of data to be sent
- * @retval none
- */
- void IL9341_SPI_Blocking_PIO_WriteBytes(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
- {
- /* Set the transaction information */
- hspi->State = HAL_SPI_STATE_BUSY_TX;
- hspi->ErrorCode = HAL_SPI_ERROR_NONE;
- hspi->pTxBuffPtr = pData;
- hspi->TxXferSize = Size;
- hspi->TxXferCount = Size;
- hspi->pRxBuffPtr = (uint8_t *)NULL;
- hspi->RxXferSize = 0;
- hspi->RxXferCount = 0;
- /* send it in 16 and 8 modes for speed */
- while (hspi->TxXferCount > 0)
- {
- if(hspi->TxXferCount != 0x1)
- {
- /* Wait until TXE flag is set to send data */
- while(__HAL_SPI_GET_FLAG(hspi,SPI_FLAG_TXE) != SET);
- hspi->Instance->DR = *((uint16_t*)hspi->pTxBuffPtr);
- hspi->pTxBuffPtr += sizeof(uint16_t);
- hspi->TxXferCount -= 2;
- }
- else
- {
- /* Wait until TXE flag is set to send data */
- while(__HAL_SPI_GET_FLAG(hspi,SPI_FLAG_TXE) != SET);
- *((__IO uint8_t*)&hspi->Instance->DR) = (*hspi->pTxBuffPtr++);
- hspi->TxXferCount--;
- }
- }
- /* wait for tx fifo to drain */
- while((hspi->Instance->SR & SPI_FLAG_FTLVL) != SPI_FTLVL_EMPTY);
- /* wait for not busy */
- while(__HAL_SPI_GET_FLAG(hspi,SPI_FLAG_BSY) != RESET);
- /* drain rx fifo */
- while((hspi->Instance->SR & SPI_FLAG_FRLVL) != SPI_FRLVL_EMPTY)
- {
- __IO uint8_t tmpreg = *((__IO uint8_t*)&hspi->Instance->DR);
- UNUSED(tmpreg); /* To avoid GCC warning */
- }
- /* Clear OVERUN flag because received is not read */
- __HAL_SPI_CLEAR_OVRFLAG(hspi);
- hspi->State = HAL_SPI_STATE_READY;
- }
- #ifdef IL9341_USE_DMA
- /*
- * Setup DMA
- */
- void IL9341_SPI_InitDMA(void)
- {
- // turn on DMA clock
- IL9341_SPI_DMA_CLK_ENABLE();
- // Common
- hdma_spi.Instance = IL9341_SPI_DMA_STREAM;
- hdma_spi.Init.Channel = IL9341_SPI_DMA_CHANNEL;
- hdma_spi.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
- hdma_spi.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
- hdma_spi.Init.MemBurst = DMA_MBURST_SINGLE;
- hdma_spi.Init.PeriphBurst = DMA_PBURST_SINGLE;
- hdma_spi.Init.Direction = DMA_MEMORY_TO_PERIPH;
- hdma_spi.Init.PeriphInc = DMA_PINC_DISABLE;
- hdma_spi.Init.MemInc = DMA_MINC_ENABLE;
- hdma_spi.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
- hdma_spi.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
- hdma_spi.Init.Mode = DMA_NORMAL;
- hdma_spi.Init.Priority = DMA_PRIORITY_LOW;
- HAL_DMA_Init(&hdma_spi);
- /* Associate the initialized DMA handle to the the SPI handle */
- __HAL_LINKDMA(&SpiHandle, hdmatx, hdma_spi);
- #ifdef IL9341_NONBLOCKING
- /* Enable TC IRQ */
- __HAL_DMA_ENABLE_IT(&hdma_spi, DMA_IT_TC);
- /* NVIC configuration for DMA transfer complete interrupt */
- HAL_NVIC_SetPriority(IL9341_SPI_DMA_TX_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(IL9341_SPI_DMA_TX_IRQn);
- #endif
- }
- /*
- * Start DMA multi-write - used both in blocking and non-blocking
- */
- void IL9341_SPI_start_DMA_WriteBytes(uint8_t *buffer, int32_t count)
- {
- /* Setup buffer loc / len */
- hdma_spi.Instance->NDTR = (uint32_t)count;
- hdma_spi.Instance->M0AR = (uint32_t)buffer;
- hdma_spi.Instance->CR &= (uint32_t)(~DMA_SxCR_DBM);
- hdma_spi.Instance->PAR = (uint32_t)&SpiHandle.Instance->DR;
- /* Enable SPI_DMA_TX */
- __HAL_DMA_ENABLE(&hdma_spi);
- /* Enable SPI DMA TX request */
- SpiHandle.Instance->CR2 |= SPI_CR2_TXDMAEN;
- }
- /*
- * Finish DMA multi-write - used both in blocking and non-blocking
- */
- void IL9341_SPI_end_DMA_WriteBytes(void)
- {
- /* Wait until DMA count == 0 */
- while(hdma_spi.Instance->NDTR != 0);
- /* wait for tx fifo to drain */
- while((SpiHandle.Instance->SR & SPI_FLAG_FTLVL) != SPI_FTLVL_EMPTY);
- /* wait for not busy */
- while(__HAL_SPI_GET_FLAG(&SpiHandle,SPI_FLAG_BSY) != RESET);
- /* drain rx fifo */
- while((SpiHandle.Instance->SR & SPI_FLAG_FRLVL) != SPI_FRLVL_EMPTY)
- {
- __IO uint8_t tmpreg = *((__IO uint8_t*)&SpiHandle.Instance->DR);
- UNUSED(tmpreg); /* To avoid GCC warning */
- }
- /* Clear OVERUN flag because received is not read */
- __HAL_SPI_CLEAR_OVRFLAG(&SpiHandle);
- /* DISABLE SPI DMA TX request */
- SpiHandle.Instance->CR2 &= ~SPI_CR2_TXDMAEN;
- /* DISABLE SPI_DMA_TX */
- __HAL_DMA_DISABLE(&hdma_spi);
- /* Clear DMA TransferComplete Flag */
- __HAL_DMA_CLEAR_FLAG(&hdma_spi, IL9341_SPI_DMA_TCFLAG);
- }
- #ifdef IL9341_NONBLOCKING
- /*
- * Finish up non-blocking DMW multi-write in Interrupt Context
- */
- void IL9341_SPI_DMA_TX_IRQHandler(void)
- {
- /* check for IRQ */
- // if(__HAL_DMA_GET_FLAG(&hdma_spi, IL9341_SPI_DMA_TCFLAG) == SET)
- // {
- /* finish the write */
- IL9341_SPI_end_DMA_WriteBytes();
- /* de-assert CS */
- IL9341_CS_HIGH();
- /* clear buffer write flag */
- IL9341_DIAG_LOW();
- /* clear busy flag */
- il9341_spi_lock = 0;
- // }
- }
- #endif
- #endif
- /*
- * Initialize SPI interface to LCD
- */
- void IL9341_SPI_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- /* Enable CS pin Clock */
- IL9341_CS_GPIO_CLK_ENABLE();
- /* Enable CS pin for output */
- GPIO_InitStructure.Pin = IL9341_CS_PIN;
- GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
- GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
- GPIO_InitStructure.Pull = GPIO_NOPULL ;
- HAL_GPIO_Init(IL9341_CS_GPIO_PORT, &GPIO_InitStructure);
- /* Enable DC pin Clock */
- IL9341_DC_GPIO_CLK_ENABLE();
- /* Enable DC pin for output */
- GPIO_InitStructure.Pin = IL9341_DC_PIN;
- HAL_GPIO_Init(IL9341_DC_GPIO_PORT, &GPIO_InitStructure);
- /* Enable RST pin Clock */
- IL9341_RST_GPIO_CLK_ENABLE();
- /* Enable RST pin for output */
- GPIO_InitStructure.Pin = IL9341_RST_PIN;
- HAL_GPIO_Init(IL9341_RST_GPIO_PORT, &GPIO_InitStructure);
- /* Enable Diag pin Clock */
- //IL9341_DIAG_GPIO_CLK_ENABLE();
- /* Enable Diag pin for output */
- //GPIO_InitStructure.Pin = IL9341_DIAG_PIN;
- //HAL_GPIO_Init(IL9341_DIAG_GPIO_PORT, &GPIO_InitStructure);
- /* Enable MOSI pin Clock */
- IL9341_MOSI_GPIO_CLK_ENABLE();
- /* Enable MOSI pin for AF output */
- GPIO_InitStructure.Pin = IL9341_MOSI_PIN;
- GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStructure.Alternate = IL9341_MOSI_AF;
- HAL_GPIO_Init(IL9341_MOSI_GPIO_PORT, &GPIO_InitStructure);
- /* Enable SCLK pin Clock */
- IL9341_SCLK_GPIO_CLK_ENABLE();
- /* Enable SCLK pin for AF output */
- GPIO_InitStructure.Pin = IL9341_SCLK_PIN;
- GPIO_InitStructure.Alternate = IL9341_SCLK_AF;
- HAL_GPIO_Init(IL9341_SCLK_GPIO_PORT, &GPIO_InitStructure);
- /* Enable SPI Port Clock */
- IL9341_SPI_CLK_ENABLE();
- /* Set up SPI port */
- SpiHandle.Instance = IL9341_SPI_PORT;
- SpiHandle.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
- SpiHandle.Init.Direction = SPI_DIRECTION_2LINES;
- SpiHandle.Init.CLKPhase = SPI_PHASE_1EDGE;
- SpiHandle.Init.CLKPolarity = SPI_POLARITY_LOW;
- SpiHandle.Init.DataSize = SPI_DATASIZE_8BIT;
- SpiHandle.Init.FirstBit = SPI_FIRSTBIT_MSB;
- SpiHandle.Init.TIMode = SPI_TIMODE_DISABLE;
- SpiHandle.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
- SpiHandle.Init.CRCPolynomial = 7;
- SpiHandle.Init.NSS = SPI_NSS_SOFT;
- SpiHandle.Init.Mode = SPI_MODE_MASTER;
- HAL_SPI_Init(&SpiHandle);
- #ifdef IL9341_USE_DMA
- /* set up SPI DMA */
- IL9341_SPI_InitDMA();
- #endif
- /* Enable SPI */
- __HAL_SPI_ENABLE(&SpiHandle);
- }
- /* ----------------------- Public functions ----------------------- */
- /*
- * send single byte via SPI - cmd or data depends on bit 8
- */
- void IL9341_write(uint16_t dat)
- {
- /* wait for pending transactions to complete */
- while(il9341_spi_lock);
- /* take the lock */
- il9341_spi_lock = 1;
- /* command or data */
- if((dat&IL9341_CMD) == IL9341_CMD)
- IL9341_DC_CMD();
- else
- IL9341_DC_DATA();
- /* assert CS */
- IL9341_CS_LOW();
- /* Wait until the transmit buffer is empty */
- while(__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_TXE) == RESET);
- /* Send the byte */
- *(__IO uint8_t *) ((uint32_t)IL9341_SPI_PORT+0x0C) = dat&0xff;
- /* wait for receive buffer full */
- while(__HAL_SPI_GET_FLAG(&SpiHandle, SPI_FLAG_RXNE) == RESET);
- /* get the byte read from the SPI bus */
- uint8_t dummy = *(__IO uint8_t *) ((uint32_t)IL9341_SPI_PORT+0x0C);
- /* de-assert CS */
- IL9341_CS_HIGH();
- /* drop the lock */
- il9341_spi_lock = 0;
- }
- #ifndef IL9341_NONBLOCKING
- /*
- * send byte buffer to data - Blocking
- */
- void IL9341_write_buffer(uint8_t *buffer, int32_t count)
- {
- /* wait for pending transactions to complete */
- while(il9341_spi_lock);
- /* take the lock */
- il9341_spi_lock = 1;
- /* flag a buffer write */
- IL9341_DIAG_HIGH();
- /* always data */
- IL9341_DC_DATA();
- /* assert CS */
- IL9341_CS_LOW();
- #ifdef IL9341_USE_DMA
- /* with DMA */
- /* start a DMA transfer */
- IL9341_SPI_start_DMA_WriteBytes(buffer, count);
- /* wait for it to end */
- IL9341_SPI_end_DMA_WriteBytes();
- #else
- /* PIO */
- IL9341_SPI_Blocking_PIO_WriteBytes(&SpiHandle, buffer, count);
- #endif
- /* de-assert CS */
- IL9341_CS_HIGH();
- /* clear buffer write flag */
- IL9341_DIAG_LOW();
- /* drop the lock */
- il9341_spi_lock = 0;
- }
- #else
- #ifdef IL9341_USE_DMA
- /*
- * send byte buffer to data - Non-blocking
- */
- void IL9341_write_buffer(uint8_t *buffer, int32_t count)
- {
- /* wait for pending transactions to complete */
- while(il9341_spi_lock);
- /* take the lock */
- il9341_spi_lock = 1;
- /* flag a buffer write */
- IL9341_DIAG_HIGH();
- /* always data */
- IL9341_DC_DATA();
- /* assert CS */
- IL9341_CS_LOW();
- /* Start Non-blocking write with IRQ to end it */
- IL9341_SPI_start_DMA_WriteBytes(buffer, count);
- }
- #else
- #error "No non-blocking IO in PIO mode."
- #endif
- #endif
- // Initialization for IL9341R
- void IL9341_init(void)
- {
- /* disable lock */
- il9341_spi_lock = 0;
- // init the SPI port
- IL9341_SPI_Init();
- // default settings
- _width = IL9341_TFTWIDTH;
- _height = IL9341_TFTHEIGHT;
- rotation = 0;
- // Reset it
- IL9341_RST_LOW();
- HAL_Delay(10);
- IL9341_RST_HIGH();
- HAL_Delay(10);
- // Send init command list
- uint16_t *addr = (uint16_t *)initlst, ms;
- while(*addr != IL9341_END)
- {
- if((*addr & IL9341_DLY) != IL9341_DLY)
- IL9341_write(*addr++);
- else
- {
- ms = (*addr++)&0x1ff; // strip delay time (ms)
- HAL_Delay(ms);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement