storage.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "storage.h"
  2. #include "storage-i.h"
  3. #include "storage-message.h"
  4. #include "storage-processing.h"
  5. #include "storages/storage-int.h"
  6. #include "storages/storage-ext.h"
  7. #define STORAGE_TICK 1000
  8. #define ICON_SD_MOUNTED &I_SDcardMounted_11x8
  9. #define ICON_SD_ERROR &I_SDcardFail_11x8
  10. static void storage_app_sd_icon_draw_callback(Canvas* canvas, void* context) {
  11. furi_assert(canvas);
  12. furi_assert(context);
  13. Storage* app = context;
  14. // here we don't care about thread race when reading / writing status
  15. switch(app->storage[ST_EXT].status) {
  16. case StorageStatusNotReady:
  17. break;
  18. case StorageStatusOK:
  19. canvas_draw_icon(canvas, 0, 0, ICON_SD_MOUNTED);
  20. break;
  21. default:
  22. canvas_draw_icon(canvas, 0, 0, ICON_SD_ERROR);
  23. break;
  24. }
  25. }
  26. Storage* storage_app_alloc() {
  27. Storage* app = malloc(sizeof(Storage));
  28. app->message_queue = osMessageQueueNew(8, sizeof(StorageMessage), NULL);
  29. for(uint8_t i = 0; i < STORAGE_COUNT; i++) {
  30. storage_data_init(&app->storage[i]);
  31. }
  32. storage_int_init(&app->storage[ST_INT]);
  33. storage_ext_init(&app->storage[ST_EXT]);
  34. // sd icon gui
  35. app->sd_gui.enabled = false;
  36. app->sd_gui.view_port = view_port_alloc();
  37. view_port_set_width(app->sd_gui.view_port, icon_get_width(ICON_SD_MOUNTED));
  38. view_port_draw_callback_set(app->sd_gui.view_port, storage_app_sd_icon_draw_callback, app);
  39. view_port_enabled_set(app->sd_gui.view_port, false);
  40. Gui* gui = furi_record_open("gui");
  41. gui_add_view_port(gui, app->sd_gui.view_port, GuiLayerStatusBarLeft);
  42. furi_record_close("gui");
  43. return app;
  44. }
  45. void storage_tick(Storage* app) {
  46. for(uint8_t i = 0; i < STORAGE_COUNT; i++) {
  47. StorageApi api = app->storage[i].api;
  48. if(api.tick != NULL) {
  49. api.tick(&app->storage[i]);
  50. }
  51. }
  52. // storage not enabled but was enabled (sd card unmount)
  53. if(app->storage[ST_EXT].status == StorageStatusNotReady && app->sd_gui.enabled == true) {
  54. app->sd_gui.enabled = false;
  55. view_port_enabled_set(app->sd_gui.view_port, false);
  56. }
  57. // storage enabled (or in error state) but was not enabled (sd card mount)
  58. if((app->storage[ST_EXT].status == StorageStatusOK ||
  59. app->storage[ST_EXT].status == StorageStatusNotMounted ||
  60. app->storage[ST_EXT].status == StorageStatusNoFS ||
  61. app->storage[ST_EXT].status == StorageStatusNotAccessible ||
  62. app->storage[ST_EXT].status == StorageStatusErrorInternal) &&
  63. app->sd_gui.enabled == false) {
  64. app->sd_gui.enabled = true;
  65. view_port_enabled_set(app->sd_gui.view_port, true);
  66. }
  67. }
  68. int32_t storage_app(void* p) {
  69. Storage* app = storage_app_alloc();
  70. furi_record_create("storage", app);
  71. StorageMessage message;
  72. while(1) {
  73. if(osMessageQueueGet(app->message_queue, &message, NULL, STORAGE_TICK) == osOK) {
  74. storage_process_message(app, &message);
  75. } else {
  76. storage_tick(app);
  77. }
  78. }
  79. return 0;
  80. }