spi_mem_worker.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. #include "spi_mem_worker_i.h"
  2. typedef enum {
  3. SPIMemEventStopThread = (1 << 0),
  4. SPIMemEventChipDetect = (1 << 1),
  5. SPIMemEventRead = (1 << 2),
  6. SPIMemEventVerify = (1 << 3),
  7. SPIMemEventErase = (1 << 4),
  8. SPIMemEventWrite = (1 << 5),
  9. SPIMemEventAll =
  10. (SPIMemEventStopThread | SPIMemEventChipDetect | SPIMemEventRead | SPIMemEventVerify |
  11. SPIMemEventErase | SPIMemEventWrite)
  12. } SPIMemEventEventType;
  13. static int32_t spi_mem_worker_thread(void* thread_context);
  14. SPIMemWorker* spi_mem_worker_alloc() {
  15. SPIMemWorker* worker = malloc(sizeof(SPIMemWorker));
  16. worker->callback = NULL;
  17. worker->thread = furi_thread_alloc();
  18. worker->mode_index = SPIMemWorkerModeIdle;
  19. furi_thread_set_name(worker->thread, "SPIMemWorker");
  20. furi_thread_set_callback(worker->thread, spi_mem_worker_thread);
  21. furi_thread_set_context(worker->thread, worker);
  22. furi_thread_set_stack_size(worker->thread, 10240);
  23. return worker;
  24. }
  25. void spi_mem_worker_free(SPIMemWorker* worker) {
  26. furi_thread_free(worker->thread);
  27. free(worker);
  28. }
  29. bool spi_mem_worker_check_for_stop(SPIMemWorker* worker) {
  30. UNUSED(worker);
  31. uint32_t flags = furi_thread_flags_get();
  32. return (flags & SPIMemEventStopThread);
  33. }
  34. static int32_t spi_mem_worker_thread(void* thread_context) {
  35. SPIMemWorker* worker = thread_context;
  36. while(true) {
  37. uint32_t flags = furi_thread_flags_wait(SPIMemEventAll, FuriFlagWaitAny, FuriWaitForever);
  38. if(flags != (unsigned)FuriFlagErrorTimeout) {
  39. if(flags & SPIMemEventStopThread) break;
  40. if(flags & SPIMemEventChipDetect) worker->mode_index = SPIMemWorkerModeChipDetect;
  41. if(flags & SPIMemEventRead) worker->mode_index = SPIMemWorkerModeRead;
  42. if(flags & SPIMemEventVerify) worker->mode_index = SPIMemWorkerModeVerify;
  43. if(flags & SPIMemEventErase) worker->mode_index = SPIMemWorkerModeErase;
  44. if(flags & SPIMemEventWrite) worker->mode_index = SPIMemWorkerModeWrite;
  45. if(spi_mem_worker_modes[worker->mode_index].process) {
  46. spi_mem_worker_modes[worker->mode_index].process(worker);
  47. }
  48. worker->mode_index = SPIMemWorkerModeIdle;
  49. }
  50. }
  51. return 0;
  52. }
  53. void spi_mem_worker_start_thread(SPIMemWorker* worker) {
  54. furi_thread_start(worker->thread);
  55. }
  56. void spi_mem_worker_stop_thread(SPIMemWorker* worker) {
  57. furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventStopThread);
  58. furi_thread_join(worker->thread);
  59. }
  60. void spi_mem_worker_chip_detect_start(
  61. SPIMemChip* chip_info,
  62. found_chips_t* found_chips,
  63. SPIMemWorker* worker,
  64. SPIMemWorkerCallback callback,
  65. void* context) {
  66. furi_check(worker->mode_index == SPIMemWorkerModeIdle);
  67. worker->callback = callback;
  68. worker->cb_ctx = context;
  69. worker->chip_info = chip_info;
  70. worker->found_chips = found_chips;
  71. furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventChipDetect);
  72. }
  73. void spi_mem_worker_read_start(
  74. SPIMemChip* chip_info,
  75. SPIMemWorker* worker,
  76. SPIMemWorkerCallback callback,
  77. void* context) {
  78. furi_check(worker->mode_index == SPIMemWorkerModeIdle);
  79. worker->callback = callback;
  80. worker->cb_ctx = context;
  81. worker->chip_info = chip_info;
  82. furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventRead);
  83. }
  84. void spi_mem_worker_verify_start(
  85. SPIMemChip* chip_info,
  86. SPIMemWorker* worker,
  87. SPIMemWorkerCallback callback,
  88. void* context) {
  89. furi_check(worker->mode_index == SPIMemWorkerModeIdle);
  90. worker->callback = callback;
  91. worker->cb_ctx = context;
  92. worker->chip_info = chip_info;
  93. furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventVerify);
  94. }
  95. void spi_mem_worker_erase_start(
  96. SPIMemChip* chip_info,
  97. SPIMemWorker* worker,
  98. SPIMemWorkerCallback callback,
  99. void* context) {
  100. furi_check(worker->mode_index == SPIMemWorkerModeIdle);
  101. worker->callback = callback;
  102. worker->cb_ctx = context;
  103. worker->chip_info = chip_info;
  104. furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventErase);
  105. }
  106. void spi_mem_worker_write_start(
  107. SPIMemChip* chip_info,
  108. SPIMemWorker* worker,
  109. SPIMemWorkerCallback callback,
  110. void* context) {
  111. furi_check(worker->mode_index == SPIMemWorkerModeIdle);
  112. worker->callback = callback;
  113. worker->cb_ctx = context;
  114. worker->chip_info = chip_info;
  115. furi_thread_flags_set(furi_thread_get_id(worker->thread), SPIMemEventWrite);
  116. }