Hi @Carlos_Diaz
It would be amazing if you could help me out of this.
try giving this a go
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_freertos_hooks.h"
#include "freertos/semphr.h"
#include "esp_system.h"
#include "driver/gpio.h"
#include <sys/unistd.h>
#include <sys/stat.h>
#include <sys/dirent.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_vfs_fat.h"
#include "freertos/task.h"
#include "driver/sdmmc_host.h"
#include "driver/sdspi_host.h"
#include "sdmmc_cmd.h"
/* Littlevgl specific */
#include "lvgl/lvgl.h"
#include "lvgl_driver.h"
#include "lv_examples/lv_apps/demo/demo.h"
static const char *TAG = "SD-CARD";
#define SD_CARD_MOSI 23
#define SD_CARD_MISO 19
#define SD_CARD_CLK 18
#define SD_CARD_CS 4
#define DMA_CHANNEL 2
#define MAX_BUFSIZE (16 * 1024)
/*********************
* DEFINES
*********************/
/**********************
* STATIC PROTOTYPES
**********************/
static void IRAM_ATTR lv_tick_task(void *arg);
void guiTask();
void test_sd_card(void);
/**********************
* APPLICATION MAIN
**********************/
void app_main()
{
xTaskCreatePinnedToCore(guiTask, "gui", 4096 * 2, NULL, 0, NULL, 1);
//give a delay to ensure little vgl is working
printf("screen still working...\n");
printf("writing to card in...\n");
for (size_t i = 10; i > 0; i--)
{
printf("..%d\n",i);
vTaskDelay(pdMS_TO_TICKS(1000));
}
printf("writing to card\n");
test_sd_card();
printf("SD card routine complete\n");
printf("Screen is now frozen\n");
}
void test_sd_card(void)
{
sdspi_slot_config_t slot_config = SDSPI_SLOT_CONFIG_DEFAULT();
slot_config.gpio_miso = SD_CARD_MISO;
slot_config.gpio_mosi = SD_CARD_MOSI;
slot_config.gpio_sck = SD_CARD_CLK;
slot_config.gpio_cs = SD_CARD_CS;
slot_config.dma_channel = DMA_CHANNEL;
sdmmc_host_t host = SDSPI_HOST_DEFAULT();
esp_vfs_fat_sdmmc_mount_config_t mount_config = {
.format_if_mount_failed = false,
.max_files = 5,
.allocation_unit_size = MAX_BUFSIZE};
// Use settings defined above to initialize SD card and mount FAT filesystem.
// Note: esp_vfs_fat_sdmmc_mount is an all-in-one convenience function.
// Please check its source code and implement error recovery when developing
// production applications.
sdmmc_card_t *card;
esp_err_t ret = esp_vfs_fat_sdmmc_mount("/sdcard", &host, &slot_config, &mount_config, &card);
if (ret != ESP_OK)
{
if (ret == ESP_FAIL)
{
ESP_LOGE(TAG, "Failed to mount filesystem. "
"If you want the card to be formatted, set format_if_mount_failed = true.");
}
else
{
ESP_LOGE(TAG, "Failed to initialize the card (%s). "
"Make sure SD card lines have pull-up resistors in place.",
esp_err_to_name(ret));
}
return;
}
// Card has been initialized, print its properties
sdmmc_card_print_info(stdout, card);
// Use POSIX and C standard library functions to work with files.
// First create a file.
ESP_LOGI(TAG, "Opening file");
FILE *f = fopen("/sdcard/hello.txt", "w");
if (f == NULL)
{
ESP_LOGE(TAG, "Failed to open file for writing");
return;
}
fprintf(f, "Hello %s!\n", card->cid.name);
fclose(f);
ESP_LOGI(TAG, "File written");
// Check if destination file exists before renaming
struct stat st;
if (stat("/sdcard/foo.txt", &st) == 0)
{
// Delete it if it exists
unlink("/sdcard/foo.txt");
}
// Rename original file
ESP_LOGI(TAG, "Renaming file");
if (rename("/sdcard/hello.txt", "/sdcard/foo.txt") != 0)
{
ESP_LOGE(TAG, "Rename failed");
return;
}
// Open renamed file for reading
ESP_LOGI(TAG, "Reading file");
f = fopen("/sdcard/foo.txt", "r");
if (f == NULL)
{
ESP_LOGE(TAG, "Failed to open file for reading");
return;
}
char line[64];
fgets(line, sizeof(line), f);
fclose(f);
// strip newline
char *pos = strchr(line, '\n');
if (pos)
{
*pos = '\0';
}
ESP_LOGI(TAG, "Read from file: '%s'", line);
// All done, unmount partition and disable SDMMC or SPI peripheral
esp_vfs_fat_sdmmc_unmount();
ESP_LOGI(TAG, "Card unmounted");
}
static void IRAM_ATTR lv_tick_task(void *arg)
{
(void)arg;
lv_tick_inc(portTICK_RATE_MS);
}
void some_random_task()
{
printf("vgl task still ticks but screen freezes \n");
}
SemaphoreHandle_t xGuiSemaphore;
void guiTask()
{
xGuiSemaphore = xSemaphoreCreateMutex();
lv_init();
lvgl_driver_init();
static lv_color_t buf1[DISP_BUF_SIZE];
static lv_color_t buf2[DISP_BUF_SIZE];
static lv_disp_buf_t disp_buf;
lv_disp_buf_init(&disp_buf, buf1, buf2, DISP_BUF_SIZE);
lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.flush_cb = disp_driver_flush;
disp_drv.buffer = &disp_buf;
lv_disp_drv_register(&disp_drv);
#if CONFIG_LVGL_TOUCH_CONTROLLER != TOUCH_CONTROLLER_NONE
lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.read_cb = touch_driver_read;
indev_drv.type = LV_INDEV_TYPE_POINTER;
lv_indev_drv_register(&indev_drv);
#endif
const esp_timer_create_args_t periodic_timer_args = {
.callback = &lv_tick_task,
/* name is optional, but may help identify the timer when debugging */
.name = "periodic_gui"};
esp_timer_handle_t periodic_timer;
ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
//On ESP32 it's better to create a periodic task instead of esp_register_freertos_tick_hook
ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 10 * 1000)); //10ms (expressed as microseconds)
demo_create();
lv_task_create(some_random_task, 2000, LV_TASK_PRIO_LOWEST, NULL);
while (1)
{
vTaskDelay(1);
//Try to lock the semaphore, if success, call lvgl stuff
if (xSemaphoreTake(xGuiSemaphore, (TickType_t)10) == pdTRUE)
{
lv_task_handler();
xSemaphoreGive(xGuiSemaphore);
}
}
//A task should NEVER return
vTaskDelete(NULL);
}