Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <string.h>
- #include <freertos/FreeRTOS.h>
- #include <freertos/task.h>
- #include <driver/gpio.h>
- #include <driver/spi_master.h>
- uint8_t transfer_buffer[320*20*2];
- static spi_device_handle_t device_handle=nullptr;
- static void m5stack_lcd_spi_pre_transfer_fire(spi_transaction_t *t)
- {
- constexpr static const int pin_dc=27;
- int dc=(int)t->user;
- gpio_set_level((gpio_num_t)pin_dc, dc!=0);
- }
- static void m5stack_lcd_send_command_fire_internal(uint8_t cmd, const uint8_t* params, size_t params_size) {
- /* Send a command to the LCD. Uses spi_device_polling_transmit, which waits
- * until the transfer is complete.
- *
- * Since command transactions are usually small, they are handled in polling
- * mode for higher speed. The overhead of interrupt transactions is more than
- * just waiting for the transaction to complete.
- */
- spi_transaction_t t;
- memset(&t, 0, sizeof(t)); //Zero out the transaction
- t.length=8; //Command is 8 bits
- t.tx_buffer=&cmd; //The data is the cmd itself
- t.user=(void*)0; //D/C needs to be set to 0
- ESP_ERROR_CHECK(spi_device_polling_transmit(device_handle, &t)); //Transmit!
- if (params_size==0) return; //no need to send anything
- memset(&t, 0, sizeof(t)); //Zero out the transaction
- t.length=params_size*8; //Len is in bytes, transaction length is in bits.
- t.tx_buffer=params; //Data
- t.user=(void*)1; //D/C needs to be set to 1
- ESP_ERROR_CHECK(spi_device_polling_transmit(device_handle, &t)); //Transmit!
- }
- void m5stack_lcd_flush_fire(int x1, int y1, int x2, int y2, const void* bitmap) {
- static int state = -1;
- if(state==-1) {
- state=0;
- } else {
- spi_transaction_t *rtrans;
- //Wait for all 6 transactions to be done and get back the results.
- for (int x=0; x<6; x++) {
- ESP_ERROR_CHECK(spi_device_get_trans_result(device_handle, &rtrans, portMAX_DELAY));
- //We could inspect rtrans now if we received any info back. The LCD is treated as write-only, though.
- }
- }
- int x;
- //Transaction descriptors. Declared static so they're not allocated on the stack; we need this memory even when this
- //function is finished because the SPI driver needs access to it even while we're already calculating the next line.
- static spi_transaction_t trans[6];
- //In theory, it's better to initialize trans and data only once and hang on to the initialized
- //variables. We allocate them on the stack, so we need to re-init them each call.
- for (x=0; x<6; x++) {
- memset(&trans[x], 0, sizeof(spi_transaction_t));
- if ((x&1)==0) {
- //Even transfers are commands
- trans[x].length=8;
- trans[x].user=(void*)0;
- } else {
- //Odd transfers are data
- trans[x].length=8*4;
- trans[x].user=(void*)1;
- }
- trans[x].flags=SPI_TRANS_USE_TXDATA;
- }
- trans[0].tx_data[0]=0x2A; //Column Address Set
- trans[1].tx_data[0]=x1>>8; //Start Col High
- trans[1].tx_data[1]=x1&0xFF; //Start Col Low
- trans[1].tx_data[2]=(x2)>>8; //End Col High
- trans[1].tx_data[3]=(x2)&0xff; //End Col Low
- trans[2].tx_data[0]=0x2B; //Page address set
- trans[3].tx_data[0]=y1>>8; //Start page high
- trans[3].tx_data[1]=y1&0xff; //start page low
- trans[3].tx_data[2]=(y2)>>8; //end page high
- trans[3].tx_data[3]=(y2)&0xff; //end page low
- trans[4].tx_data[0]=0x2C; //memory write
- trans[5].tx_buffer=bitmap; //finally send the line data
- trans[5].length=(x2-x1+1)*(y2-y1+1)*2*8;
- trans[5].user=(void*)2;
- trans[5].flags=0; //undo SPI_TRANS_USE_TXDATA flag
- //Queue all transactions.
- for (x=0; x<6; x++) {
- ESP_ERROR_CHECK(spi_device_queue_trans(device_handle, &trans[x], portMAX_DELAY));
- }
- }
- extern "C" void app_main() {
- constexpr static const int pin_clk = 18;
- constexpr static const int pin_mosi = 23;
- constexpr static const int pin_miso = 19;
- constexpr static const int pin_bl = 32;
- constexpr static const int pin_rst = 33;
- constexpr static const int pin_cs = 14;
- constexpr static const int pin_dc = 27;
- gpio_config_t io_conf = {};
- io_conf.pin_bit_mask = ((1ULL<<pin_cs) | (1ULL<<pin_dc) | (1ULL<<pin_rst) | (1ULL<<pin_bl));
- io_conf.mode = GPIO_MODE_OUTPUT;
- io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
- gpio_config(&io_conf);
- spi_bus_config_t spi_bus_cfg;
- memset(&spi_bus_cfg,0,sizeof(spi_bus_cfg));
- spi_bus_cfg.mosi_io_num = pin_mosi;
- spi_bus_cfg.miso_io_num = pin_miso;
- spi_bus_cfg.sclk_io_num = pin_clk;
- spi_bus_cfg.quadhd_io_num = -1;
- spi_bus_cfg.quadwp_io_num = -1;
- spi_bus_cfg.max_transfer_sz = 32*1024+8;
- ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST,&spi_bus_cfg,SPI_DMA_CH_AUTO));
- spi_device_interface_config_t devcfg;
- memset(&devcfg,0,sizeof(devcfg));
- devcfg.clock_speed_hz=10*1000*1000;
- devcfg.mode=0; //SPI mode 0
- devcfg.spics_io_num=pin_cs; //CS pin
- devcfg.queue_size=7; //We want to be able to queue 7 transactions at a time
- devcfg.pre_cb=m5stack_lcd_spi_pre_transfer_fire; //Specify pre-transfer callback to handle D/C line
- devcfg.post_cb=nullptr;
- //Attach the LCD to the SPI bus
- ESP_ERROR_CHECK(spi_bus_add_device(SPI3_HOST, &devcfg, &device_handle));
- //Reset the display
- gpio_set_level((gpio_num_t)pin_rst, 0);
- vTaskDelay(100 / portTICK_PERIOD_MS);
- gpio_set_level((gpio_num_t)pin_rst, 1);
- vTaskDelay(100 / portTICK_PERIOD_MS);
- // send ILI9342c init codes (works under Arduino - same code)
- static const uint8_t params1[] = {0xFF,0x93,0x42};
- m5stack_lcd_send_command_fire_internal(0xC8,params1,sizeof(params1));
- static const uint8_t params2[] = {0x12,0x12};
- m5stack_lcd_send_command_fire_internal(0xC0,params2,sizeof(params2));
- static const uint8_t params3[] = {0x03};
- m5stack_lcd_send_command_fire_internal(0xC1,params3,sizeof(params3));
- static const uint8_t params4[] = {0x0E};
- m5stack_lcd_send_command_fire_internal(0xB0,params4,sizeof(params4));
- static const uint8_t params5[] = {0x00,0x01,0x01};
- m5stack_lcd_send_command_fire_internal(0xF6,params5,sizeof(params5));
- static const uint8_t params6[] = {/*0x80|0x20|*/0x08};
- m5stack_lcd_send_command_fire_internal(0x36,params6,sizeof(params6));
- uint8_t tmp = 0x55;
- m5stack_lcd_send_command_fire_internal(0x3A,&tmp ,1);
- static const uint8_t params7[] = { 0x08,0x82,0x27 };
- m5stack_lcd_send_command_fire_internal(0xB6,params7,sizeof(params7));
- static const uint8_t params8[] = { 0x00,0x0C,0x11,0x04,0x11,0x08,0x37,0x89,0x4C,0x06,0x0C,0x0A,0x2E,0x34,0x0F };
- m5stack_lcd_send_command_fire_internal(0xE0,params8,sizeof(params8));
- static const uint8_t params9[] = { 0x00,0x0B,0x11,0x05,0x13,0x09,0x33,0x67,0x48,0x07,0x0E,0x0B,0x2E,0x33,0x0F };
- m5stack_lcd_send_command_fire_internal(0xE1,params9,sizeof(params9));
- m5stack_lcd_send_command_fire_internal(0x21,nullptr ,0);
- vTaskDelay(pdMS_TO_TICKS(120));
- m5stack_lcd_send_command_fire_internal(0x11,nullptr,0);
- gpio_set_direction((gpio_num_t)pin_bl, GPIO_MODE_OUTPUT);
- gpio_set_level((gpio_num_t)pin_bl, 1);
- uint16_t* p = (uint16_t*)transfer_buffer;
- // yellow
- uint16_t col = uint16_t(uint32_t(31<<11)|uint32_t(63<<5)|uint32_t(0<<0));
- uint8_t hi = col>>8;
- uint8_t lo = col&0xFF;
- col = (lo<<8)|hi;
- for(int i = 0;i<sizeof(transfer_buffer)/sizeof(uint16_t);++i) {
- *p++=col;
- }
- for(int y=0;y<240;y+=20) {
- m5stack_lcd_flush_fire(0,y,319,y+20-1,transfer_buffer);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement