Advertisement
honey_the_codewitch

esp-idf m5stack fire LCD problems

Mar 27th, 2023 (edited)
1,620
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.84 KB | None | 0 0
  1. #include <string.h>
  2. #include <freertos/FreeRTOS.h>
  3. #include <freertos/task.h>
  4. #include <driver/gpio.h>
  5. #include <driver/spi_master.h>
  6.  
  7. uint8_t transfer_buffer[320*20*2];
  8. static spi_device_handle_t device_handle=nullptr;
  9. static void m5stack_lcd_spi_pre_transfer_fire(spi_transaction_t *t)
  10. {
  11.     constexpr static const int pin_dc=27;
  12.     int dc=(int)t->user;
  13.     gpio_set_level((gpio_num_t)pin_dc, dc!=0);
  14. }
  15. static void m5stack_lcd_send_command_fire_internal(uint8_t cmd, const uint8_t* params, size_t params_size) {
  16. /* Send a command to the LCD. Uses spi_device_polling_transmit, which waits
  17.  * until the transfer is complete.
  18.  *
  19.  * Since command transactions are usually small, they are handled in polling
  20.  * mode for higher speed. The overhead of interrupt transactions is more than
  21.  * just waiting for the transaction to complete.
  22.  */
  23.     spi_transaction_t t;
  24.     memset(&t, 0, sizeof(t));       //Zero out the transaction
  25.     t.length=8;                     //Command is 8 bits
  26.     t.tx_buffer=&cmd;               //The data is the cmd itself
  27.     t.user=(void*)0;                //D/C needs to be set to 0
  28.     ESP_ERROR_CHECK(spi_device_polling_transmit(device_handle, &t));  //Transmit!
  29.     if (params_size==0) return;             //no need to send anything
  30.     memset(&t, 0, sizeof(t));       //Zero out the transaction
  31.     t.length=params_size*8;                 //Len is in bytes, transaction length is in bits.
  32.     t.tx_buffer=params;               //Data
  33.     t.user=(void*)1;                //D/C needs to be set to 1
  34.     ESP_ERROR_CHECK(spi_device_polling_transmit(device_handle, &t));  //Transmit!
  35.  
  36. }
  37. void m5stack_lcd_flush_fire(int x1, int y1, int x2, int y2, const void* bitmap) {
  38.     static int state = -1;
  39.     if(state==-1) {
  40.         state=0;
  41.     } else {
  42.         spi_transaction_t *rtrans;
  43.         //Wait for all 6 transactions to be done and get back the results.
  44.         for (int x=0; x<6; x++) {
  45.             ESP_ERROR_CHECK(spi_device_get_trans_result(device_handle, &rtrans, portMAX_DELAY));
  46.             //We could inspect rtrans now if we received any info back. The LCD is treated as write-only, though.
  47.         }
  48.     }
  49.     int x;
  50.     //Transaction descriptors. Declared static so they're not allocated on the stack; we need this memory even when this
  51.     //function is finished because the SPI driver needs access to it even while we're already calculating the next line.
  52.     static spi_transaction_t trans[6];
  53.  
  54.     //In theory, it's better to initialize trans and data only once and hang on to the initialized
  55.     //variables. We allocate them on the stack, so we need to re-init them each call.
  56.     for (x=0; x<6; x++) {
  57.         memset(&trans[x], 0, sizeof(spi_transaction_t));
  58.         if ((x&1)==0) {
  59.             //Even transfers are commands
  60.             trans[x].length=8;
  61.             trans[x].user=(void*)0;
  62.         } else {
  63.             //Odd transfers are data
  64.             trans[x].length=8*4;
  65.             trans[x].user=(void*)1;
  66.         }
  67.         trans[x].flags=SPI_TRANS_USE_TXDATA;
  68.     }
  69.     trans[0].tx_data[0]=0x2A;           //Column Address Set
  70.     trans[1].tx_data[0]=x1>>8;              //Start Col High
  71.     trans[1].tx_data[1]=x1&0xFF;              //Start Col Low
  72.     trans[1].tx_data[2]=(x2)>>8;       //End Col High
  73.     trans[1].tx_data[3]=(x2)&0xff;     //End Col Low
  74.     trans[2].tx_data[0]=0x2B;           //Page address set
  75.     trans[3].tx_data[0]=y1>>8;        //Start page high
  76.     trans[3].tx_data[1]=y1&0xff;      //start page low
  77.     trans[3].tx_data[2]=(y2)>>8;    //end page high
  78.     trans[3].tx_data[3]=(y2)&0xff;  //end page low
  79.     trans[4].tx_data[0]=0x2C;           //memory write
  80.     trans[5].tx_buffer=bitmap;        //finally send the line data
  81.     trans[5].length=(x2-x1+1)*(y2-y1+1)*2*8;
  82.     trans[5].user=(void*)2;
  83.     trans[5].flags=0; //undo SPI_TRANS_USE_TXDATA flag
  84.  
  85.     //Queue all transactions.
  86.     for (x=0; x<6; x++) {
  87.         ESP_ERROR_CHECK(spi_device_queue_trans(device_handle, &trans[x], portMAX_DELAY));
  88.     }
  89. }
  90.  
  91. extern "C" void app_main() {
  92.     constexpr static const int pin_clk = 18;
  93.     constexpr static const int pin_mosi = 23;
  94.     constexpr static const int pin_miso = 19;
  95.     constexpr static const int pin_bl = 32;
  96.     constexpr static const int pin_rst = 33;
  97.     constexpr static const int pin_cs = 14;
  98.     constexpr static const int pin_dc = 27;
  99.  
  100.     gpio_config_t io_conf = {};
  101.     io_conf.pin_bit_mask = ((1ULL<<pin_cs) | (1ULL<<pin_dc) | (1ULL<<pin_rst) | (1ULL<<pin_bl));
  102.     io_conf.mode = GPIO_MODE_OUTPUT;
  103.     io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
  104.     gpio_config(&io_conf);
  105.  
  106.     spi_bus_config_t spi_bus_cfg;
  107.     memset(&spi_bus_cfg,0,sizeof(spi_bus_cfg));
  108.     spi_bus_cfg.mosi_io_num = pin_mosi;
  109.     spi_bus_cfg.miso_io_num = pin_miso;
  110.     spi_bus_cfg.sclk_io_num = pin_clk;
  111.     spi_bus_cfg.quadhd_io_num = -1;
  112.     spi_bus_cfg.quadwp_io_num = -1;
  113.     spi_bus_cfg.max_transfer_sz = 32*1024+8;
  114.     ESP_ERROR_CHECK(spi_bus_initialize(SPI3_HOST,&spi_bus_cfg,SPI_DMA_CH_AUTO));
  115.  
  116.     spi_device_interface_config_t devcfg;
  117.     memset(&devcfg,0,sizeof(devcfg));
  118.     devcfg.clock_speed_hz=10*1000*1000;
  119.     devcfg.mode=0;                                //SPI mode 0
  120.     devcfg.spics_io_num=pin_cs;               //CS pin
  121.     devcfg.queue_size=7;                          //We want to be able to queue 7 transactions at a time
  122.     devcfg.pre_cb=m5stack_lcd_spi_pre_transfer_fire;  //Specify pre-transfer callback to handle D/C line
  123.     devcfg.post_cb=nullptr;
  124.  
  125.     //Attach the LCD to the SPI bus
  126.     ESP_ERROR_CHECK(spi_bus_add_device(SPI3_HOST, &devcfg, &device_handle));
  127.  
  128.      //Reset the display
  129.     gpio_set_level((gpio_num_t)pin_rst, 0);
  130.     vTaskDelay(100 / portTICK_PERIOD_MS);
  131.     gpio_set_level((gpio_num_t)pin_rst, 1);
  132.     vTaskDelay(100 / portTICK_PERIOD_MS);
  133.     // send ILI9342c init codes (works under Arduino - same code)
  134.     static const uint8_t params1[] = {0xFF,0x93,0x42};
  135.     m5stack_lcd_send_command_fire_internal(0xC8,params1,sizeof(params1));
  136.     static const uint8_t params2[] = {0x12,0x12};
  137.     m5stack_lcd_send_command_fire_internal(0xC0,params2,sizeof(params2));
  138.     static const uint8_t params3[] = {0x03};
  139.     m5stack_lcd_send_command_fire_internal(0xC1,params3,sizeof(params3));
  140.     static const uint8_t params4[] = {0x0E};
  141.     m5stack_lcd_send_command_fire_internal(0xB0,params4,sizeof(params4));
  142.     static const uint8_t params5[] = {0x00,0x01,0x01};
  143.     m5stack_lcd_send_command_fire_internal(0xF6,params5,sizeof(params5));
  144.     static const uint8_t params6[] = {/*0x80|0x20|*/0x08};
  145.     m5stack_lcd_send_command_fire_internal(0x36,params6,sizeof(params6));
  146.     uint8_t tmp = 0x55;
  147.     m5stack_lcd_send_command_fire_internal(0x3A,&tmp ,1);
  148.     static const uint8_t params7[] = { 0x08,0x82,0x27 };
  149.     m5stack_lcd_send_command_fire_internal(0xB6,params7,sizeof(params7));
  150.     static const uint8_t params8[] = { 0x00,0x0C,0x11,0x04,0x11,0x08,0x37,0x89,0x4C,0x06,0x0C,0x0A,0x2E,0x34,0x0F };
  151.     m5stack_lcd_send_command_fire_internal(0xE0,params8,sizeof(params8));
  152.     static const uint8_t params9[] = { 0x00,0x0B,0x11,0x05,0x13,0x09,0x33,0x67,0x48,0x07,0x0E,0x0B,0x2E,0x33,0x0F };
  153.     m5stack_lcd_send_command_fire_internal(0xE1,params9,sizeof(params9));
  154.     m5stack_lcd_send_command_fire_internal(0x21,nullptr ,0);
  155.     vTaskDelay(pdMS_TO_TICKS(120));
  156.     m5stack_lcd_send_command_fire_internal(0x11,nullptr,0);  
  157.  
  158.     gpio_set_direction((gpio_num_t)pin_bl, GPIO_MODE_OUTPUT);
  159.     gpio_set_level((gpio_num_t)pin_bl, 1);
  160.  
  161.     uint16_t* p = (uint16_t*)transfer_buffer;
  162.     // yellow
  163.     uint16_t col = uint16_t(uint32_t(31<<11)|uint32_t(63<<5)|uint32_t(0<<0));
  164.     uint8_t hi = col>>8;
  165.     uint8_t lo = col&0xFF;
  166.     col = (lo<<8)|hi;
  167.     for(int i = 0;i<sizeof(transfer_buffer)/sizeof(uint16_t);++i) {
  168.         *p++=col;
  169.     }
  170.     for(int y=0;y<240;y+=20) {
  171.         m5stack_lcd_flush_fire(0,y,319,y+20-1,transfer_buffer);
  172.        
  173.     }
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement