1 /* 2 * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include "freertos/FreeRTOS.h" 8 #include "soc/soc_caps.h" 9 #include "esp_lcd_common.h" 10 #if SOC_LCDCAM_SUPPORTED 11 #include "hal/lcd_ll.h" 12 #include "hal/lcd_hal.h" 13 14 typedef struct esp_lcd_platform_t { 15 portMUX_TYPE spinlock; // spinlock used to protect platform level resources 16 union { 17 void *panels[SOC_LCD_RGB_PANELS]; // array of RGB LCD panel instances 18 void *buses[SOC_LCD_I80_BUSES]; // array of i80 bus instances 19 }; // LCD peripheral can only work under either RGB mode or intel 8080 mode 20 } esp_lcd_platform_t; 21 22 esp_lcd_platform_t s_lcd_platform = { 23 .spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED, 24 .buses = {} // initially the bus slots and panel slots are empty 25 }; 26 lcd_com_register_device(lcd_com_device_type_t device_type,void * device_obj)27int lcd_com_register_device(lcd_com_device_type_t device_type, void *device_obj) 28 { 29 int member_id = -1; 30 switch (device_type) { 31 case LCD_COM_DEVICE_TYPE_I80: 32 // search for a bus slot then register to platform 33 for (int i = 0; (i < SOC_LCD_I80_BUSES) && (member_id == -1); i++) { 34 portENTER_CRITICAL(&s_lcd_platform.spinlock); 35 if (!s_lcd_platform.buses[i]) { 36 s_lcd_platform.buses[i] = device_obj; 37 member_id = i; 38 } 39 portEXIT_CRITICAL(&s_lcd_platform.spinlock); 40 } 41 break; 42 case LCD_COM_DEVICE_TYPE_RGB: 43 // search for a panel slot then register to platform 44 for (int i = 0; (i < SOC_LCD_RGB_PANELS) && (member_id == -1); i++) { 45 portENTER_CRITICAL(&s_lcd_platform.spinlock); 46 if (!s_lcd_platform.panels[i]) { 47 s_lcd_platform.panels[i] = device_obj; 48 member_id = i; 49 } 50 portEXIT_CRITICAL(&s_lcd_platform.spinlock); 51 } 52 break; 53 default: 54 break; 55 } 56 return member_id; 57 } 58 lcd_com_remove_device(lcd_com_device_type_t device_type,int member_id)59void lcd_com_remove_device(lcd_com_device_type_t device_type, int member_id) 60 { 61 switch (device_type) { 62 case LCD_COM_DEVICE_TYPE_I80: 63 portENTER_CRITICAL(&s_lcd_platform.spinlock); 64 if (s_lcd_platform.buses[member_id]) { 65 s_lcd_platform.buses[member_id] = NULL; 66 } 67 portEXIT_CRITICAL(&s_lcd_platform.spinlock); 68 break; 69 case LCD_COM_DEVICE_TYPE_RGB: 70 portENTER_CRITICAL(&s_lcd_platform.spinlock); 71 if (s_lcd_platform.panels[member_id]) { 72 s_lcd_platform.panels[member_id] = NULL; 73 } 74 portEXIT_CRITICAL(&s_lcd_platform.spinlock); 75 break; 76 default: 77 break; 78 } 79 } 80 #endif // SOC_LCDCAM_SUPPORTED 81 lcd_com_mount_dma_data(dma_descriptor_t * desc_head,const void * buffer,size_t len)82void lcd_com_mount_dma_data(dma_descriptor_t *desc_head, const void *buffer, size_t len) 83 { 84 size_t prepared_length = 0; 85 uint8_t *data = (uint8_t *)buffer; 86 dma_descriptor_t *desc = desc_head; 87 while (len > DMA_DESCRIPTOR_BUFFER_MAX_SIZE) { 88 desc->dw0.suc_eof = 0; // not the end of the transaction 89 desc->dw0.size = DMA_DESCRIPTOR_BUFFER_MAX_SIZE; 90 desc->dw0.length = DMA_DESCRIPTOR_BUFFER_MAX_SIZE; 91 desc->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; 92 desc->buffer = &data[prepared_length]; 93 desc = desc->next; // move to next descriptor 94 prepared_length += DMA_DESCRIPTOR_BUFFER_MAX_SIZE; 95 len -= DMA_DESCRIPTOR_BUFFER_MAX_SIZE; 96 } 97 if (len) { 98 desc->dw0.suc_eof = 1; // end of the transaction 99 desc->dw0.size = len; 100 desc->dw0.length = len; 101 desc->dw0.owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; 102 desc->buffer = &data[prepared_length]; 103 desc = desc->next; // move to next descriptor 104 prepared_length += len; 105 } 106 } 107