123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- #include <string.h> // for memcpy
- #include "main.h"
- #include "cmsis_os.h"
- #include "ide.h"
- #include "ide_async.h"
- #define CACHE_NUM_SECTORS 32
- #define CACHE_SIZE (512 * CACHE_NUM_SECTORS)
- enum {
- STATE_NOT_INITIALIZED,
- STATE_READY,
- STATE_READING,
- STATE_WRITING
- } state = STATE_NOT_INITIALIZED;
- static uint32_t capacity_in_sectors;
- static uint32_t requested_lba = 0;
- //static uint32_t max_sectors;
- static uint8_t cache[CACHE_SIZE];
- static uint32_t cache_len = 0;
- static osMutexId_t requestParamLock;
- static osSemaphoreId_t requestSem;
- static inline uint32_t min(uint32_t a, uint32_t b) {return a < b ? a : b;}
- uint32_t ide_async_get_num_sectors() {
- while (state == STATE_NOT_INITIALIZED) {
- osThreadYield();
- }
- return capacity_in_sectors;
- }
- int32_t ide_async_read(uint32_t lba, uint32_t offset, uint8_t* buf, uint32_t buf_size) {
- if ((state == STATE_READING || (state == STATE_READY && cache_len > 0)) && lba >= requested_lba) {
- uint32_t delta_lba = lba - requested_lba;
- if (delta_lba < CACHE_NUM_SECTORS) {
- uint32_t delta_bytes = delta_lba * 512;
- if ((delta_bytes + offset) < cache_len) {
- uint32_t len = min(cache_len - delta_bytes - offset, buf_size);
- memcpy(buf, cache + delta_bytes + offset, len);
- return len;
- }
- osThreadYield();
- return 0;
- }
- }
- osMutexAcquire(requestParamLock, osWaitForever);
- requested_lba = lba;
- //max_sectors = buf_size / 512;
- cache_len = 0;
- state = STATE_READING;
- osMutexRelease(requestParamLock);
- while(osOK != osSemaphoreRelease(requestSem));
- return 0;
- }
- int32_t ide_async_write(uint32_t lba, uint32_t offset, uint8_t* buf, uint32_t buf_size) {
- if (offset != 0) return 0;
- if (state == STATE_READY) {
- osMutexAcquire(requestParamLock, osWaitForever);
- memcpy(cache, buf, buf_size);
- requested_lba = lba;
- cache_len = buf_size;
- state = STATE_WRITING;
- osMutexRelease(requestParamLock);
- while(osOK != osSemaphoreRelease(requestSem));
- return buf_size;
- }
- osThreadYield();
- return 0;
- }
- void ide_async_init() {
- requestParamLock = osMutexNew(NULL);
- requestSem = osSemaphoreNew(1, 0, NULL);
- ide_init();
- capacity_in_sectors = ide_get_num_sectors();
- state = STATE_READY;
- }
- void ide_async_main_loop_step() {
- osSemaphoreAcquire(requestSem, osWaitForever);
- osMutexAcquire(requestParamLock, osWaitForever);
- if (state == STATE_READING) {
- uint16_t num_sectors = min(CACHE_NUM_SECTORS, capacity_in_sectors - requested_lba);
- //uint16_t num_sectors = min(CACHE_NUM_SECTORS, max_sectors);
- ide_begin_read_sectors(requested_lba, num_sectors);
- for (int i = 0; i < num_sectors; i++) {
- ide_read_next_sector(cache + cache_len);
- cache_len += 512;
- osThreadYield();
- }
- state = STATE_READY;
- } else if (state == STATE_WRITING) {
- uint16_t num_sectors = cache_len / 512;
- ide_begin_write_sectors(requested_lba, num_sectors);
- for (int i = 0; i < num_sectors; i++) {
- ide_write_next_sector(cache + (i * 512));
- }
- state = STATE_READY;
- }
- osMutexRelease(requestParamLock);
- }
|