ide_async.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #include <string.h> // for memcpy
  2. #include "main.h"
  3. #include "cmsis_os.h"
  4. #include "ide.h"
  5. #include "ide_async.h"
  6. #define CACHE_NUM_SECTORS 32
  7. #define CACHE_SIZE (512 * CACHE_NUM_SECTORS)
  8. enum {
  9. STATE_NOT_INITIALIZED,
  10. STATE_READY,
  11. STATE_READING,
  12. STATE_WRITING
  13. } state = STATE_NOT_INITIALIZED;
  14. static uint32_t capacity_in_sectors;
  15. static uint32_t requested_lba = 0;
  16. //static uint32_t max_sectors;
  17. static uint8_t cache[CACHE_SIZE];
  18. static uint32_t cache_len = 0;
  19. static osMutexId_t requestParamLock;
  20. static osSemaphoreId_t requestSem;
  21. static inline uint32_t min(uint32_t a, uint32_t b) {return a < b ? a : b;}
  22. uint32_t ide_async_get_num_sectors() {
  23. while (state == STATE_NOT_INITIALIZED) {
  24. osThreadYield();
  25. }
  26. return capacity_in_sectors;
  27. }
  28. int32_t ide_async_read(uint32_t lba, uint32_t offset, uint8_t* buf, uint32_t buf_size) {
  29. if ((state == STATE_READING || (state == STATE_READY && cache_len > 0)) && lba >= requested_lba) {
  30. uint32_t delta_lba = lba - requested_lba;
  31. if (delta_lba < CACHE_NUM_SECTORS) {
  32. uint32_t delta_bytes = delta_lba * 512;
  33. if ((delta_bytes + offset) < cache_len) {
  34. uint32_t len = min(cache_len - delta_bytes - offset, buf_size);
  35. memcpy(buf, cache + delta_bytes + offset, len);
  36. return len;
  37. }
  38. osThreadYield();
  39. return 0;
  40. }
  41. }
  42. osMutexAcquire(requestParamLock, osWaitForever);
  43. requested_lba = lba;
  44. //max_sectors = buf_size / 512;
  45. cache_len = 0;
  46. state = STATE_READING;
  47. osMutexRelease(requestParamLock);
  48. while(osOK != osSemaphoreRelease(requestSem));
  49. return 0;
  50. }
  51. int32_t ide_async_write(uint32_t lba, uint32_t offset, uint8_t* buf, uint32_t buf_size) {
  52. if (offset != 0) return 0;
  53. if (state == STATE_READY) {
  54. osMutexAcquire(requestParamLock, osWaitForever);
  55. memcpy(cache, buf, buf_size);
  56. requested_lba = lba;
  57. cache_len = buf_size;
  58. state = STATE_WRITING;
  59. osMutexRelease(requestParamLock);
  60. while(osOK != osSemaphoreRelease(requestSem));
  61. return buf_size;
  62. }
  63. osThreadYield();
  64. return 0;
  65. }
  66. void ide_async_init() {
  67. requestParamLock = osMutexNew(NULL);
  68. requestSem = osSemaphoreNew(1, 0, NULL);
  69. ide_init();
  70. capacity_in_sectors = ide_get_num_sectors();
  71. state = STATE_READY;
  72. }
  73. void ide_async_main_loop_step() {
  74. osSemaphoreAcquire(requestSem, osWaitForever);
  75. osMutexAcquire(requestParamLock, osWaitForever);
  76. if (state == STATE_READING) {
  77. uint16_t num_sectors = min(CACHE_NUM_SECTORS, capacity_in_sectors - requested_lba);
  78. //uint16_t num_sectors = min(CACHE_NUM_SECTORS, max_sectors);
  79. ide_begin_read_sectors(requested_lba, num_sectors);
  80. for (int i = 0; i < num_sectors; i++) {
  81. ide_read_next_sector(cache + cache_len);
  82. cache_len += 512;
  83. osThreadYield();
  84. }
  85. state = STATE_READY;
  86. } else if (state == STATE_WRITING) {
  87. uint16_t num_sectors = cache_len / 512;
  88. ide_begin_write_sectors(requested_lba, num_sectors);
  89. for (int i = 0; i < num_sectors; i++) {
  90. ide_write_next_sector(cache + (i * 512));
  91. }
  92. state = STATE_READY;
  93. }
  94. osMutexRelease(requestParamLock);
  95. }