From 874156122d8a0a189f5597657d0ee7eec6560560 Mon Sep 17 00:00:00 2001 From: Damjan Adamic Date: Fri, 26 Sep 2014 11:31:16 +0200 Subject: [PATCH] Re #1610: * sport.log only active if SPORT_FILE_LOG=YES * audio concurrent access fixes * added IO mutex * added Event Trace Buffer * fixed SD card error Conflicts: radio/src/Makefile radio/src/targets/taranis/diskio.cpp --- radio/src/Makefile | 40 +- radio/src/audio_arm.cpp | 20 +- radio/src/audio_arm.h | 6 +- radio/src/bootloader/Makefile | 1 + radio/src/debug.cpp | 64 +- radio/src/debug.h | 84 +++ radio/src/gui/menus.h | 3 + radio/src/gui/view_statistics.cpp | 62 ++ radio/src/opentx.cpp | 4 + radio/src/targets/sky9x/diskio.cpp | 267 ++++---- radio/src/targets/taranis/diskio.cpp | 926 ++++++++++++++------------- radio/src/telemetry/frsky.cpp | 2 +- 12 files changed, 901 insertions(+), 578 deletions(-) diff --git a/radio/src/Makefile b/radio/src/Makefile index 566662fcc..73a88cd48 100644 --- a/radio/src/Makefile +++ b/radio/src/Makefile @@ -297,6 +297,16 @@ CHANNELS_MONITOR_INV_HIDE = NO # Values = NO, YES NANO = NO +# Enable trace of events into Trace Buffer for debugging purposes +# Activating any of these options also activates DEBUG and DEBUG_TRACE_BUFFER +# Values = NO, YES +# TRACE_SD_CARD SD card operations (read, write, etc) +# TRACE_FATFS FatFs file operations +# TRACE_AUDIO Audio processing (not yet implemented) +TRACE_SD_CARD = NO +TRACE_FATFS = NO +TRACE_AUDIO = NO + #------- END BUILD OPTIONS --------------------------- # Define programs and commands. @@ -311,6 +321,7 @@ CPPSRC = INCDIRS = . translations EXTRAINCDIRS = LUADEP = +DEBUG_TRACE_BUFFER = NO # MCU name ifneq ($(PCB), $(filter $(PCB), STD 9X 9XR STD128 9X128 9XR128 9X2561 9XR2561 GRUVIN9X MEGA2560 SKY9X 9XRPRO TARANIS)) @@ -645,13 +656,13 @@ ifeq ($(PCB), $(filter $(PCB), SKY9X 9XRPRO)) endif ifeq ($(BLUETOOTH), YES) - CPPDEFS += -DBLUETOOTH - CPPSRC += targets/sky9x/bluetooth.cpp + CPPDEFS += -DBLUETOOTH + CPPSRC += targets/sky9x/bluetooth.cpp endif ifeq ($(DEBUG), YES) CPPSRC += debug.cpp - SRC += targets/sky9x/syscalls.c + SRC += targets/sky9x/syscalls.c endif endif @@ -669,9 +680,26 @@ ifeq ($(PCB), TARANIS) CPPDEFS = -DREV4 endif ifeq ($(SPORT_FILE_LOG), YES) - DEBUG = YES CPPDEFS += -DSPORT_FILE_LOG - endif + endif + ifeq ($(TRACE_SD_CARD), YES) + DEBUG = YES + DEBUG_TRACE_BUFFER = YES + CPPDEFS += -DTRACE_SD_CARD + endif + ifeq ($(TRACE_FATFS), YES) + DEBUG = YES + DEBUG_TRACE_BUFFER = YES + CPPDEFS += -DTRACE_FATFS + endif + ifeq ($(TRACE_AUDIO), YES) + DEBUG = YES + DEBUG_TRACE_BUFFER = YES + CPPDEFS += -DTRACE_AUDIO + endif + ifeq ($(DEBUG_TRACE_BUFFER), YES) + CPPDEFS += -DDEBUG_TRACE_BUFFER + endif LDSCRIPT = targets/taranis/stm32_flash_bl.ld TRGT = arm-none-eabi- MCU = cortex-m3 @@ -990,7 +1018,7 @@ endif ifeq ($(EXT), $(filter $(EXT), FRSKY FRSKY_SPORT TELEMETREZ)) CPPDEFS += -DFRSKY ifeq ($(EXT), FRSKY_SPORT) - CPPSRC += telemetry/frsky.cpp telemetry/frsky_sport.cpp telemetry/frsky_d.cpp + CPPSRC += telemetry/frsky.cpp telemetry/frsky_sport.cpp telemetry/frsky_d.cpp CPPDEFS += -DFRSKY_SPORT else CPPSRC += telemetry/frsky.cpp telemetry/frsky_d.cpp diff --git a/radio/src/audio_arm.cpp b/radio/src/audio_arm.cpp index d1a8c0cf2..ad8d6618a 100644 --- a/radio/src/audio_arm.cpp +++ b/radio/src/audio_arm.cpp @@ -494,21 +494,6 @@ void audioTask(void* pdata) } #endif -void AudioQueue::pushBuffer(AudioBuffer *buffer) -{ - buffer->state = AUDIO_BUFFER_FILLED; - - __disable_irq(); - - bufferWIdx = nextBufferIdx(bufferWIdx); - - if (dacQueue(buffer)) { - buffer->state = AUDIO_BUFFER_PLAYING; - } - - __enable_irq(); -} - void mixSample(uint16_t * result, int sample, unsigned int fade) { *result = limit(0, *result + ((sample >> fade) >> 4), 4095); @@ -762,8 +747,11 @@ void AudioQueue::wakeup() // push the buffer if needed if (size > 0) { + __disable_irq(); + bufferWIdx = nextBufferIdx(bufferWIdx); buffer->size = size; - pushBuffer(buffer); + buffer->state = dacQueue(buffer) ? AUDIO_BUFFER_PLAYING : AUDIO_BUFFER_FILLED; + __enable_irq(); } } } diff --git a/radio/src/audio_arm.h b/radio/src/audio_arm.h index 5061c19a8..52a9cbb2b 100644 --- a/radio/src/audio_arm.h +++ b/radio/src/audio_arm.h @@ -199,6 +199,10 @@ class AudioQueue { AudioBuffer * buffer = &buffers[idx]; if (buffer->state == AUDIO_BUFFER_FILLED) { buffer->state = AUDIO_BUFFER_PLAYING; + if (idx != bufferRIdx) { + TRACEI_AUDIO_EVENT(1, audio_getNextFilledBuffer_skip, ((uint32_t)bufferRIdx << 8) + idx); + bufferRIdx = idx; + } return buffer; } idx = nextBufferIdx(idx); @@ -239,8 +243,6 @@ class AudioQueue { else return NULL; } - - void pushBuffer(AudioBuffer *buffer); }; extern AudioQueue audioQueue; diff --git a/radio/src/bootloader/Makefile b/radio/src/bootloader/Makefile index 9af032263..4d4081b50 100644 --- a/radio/src/bootloader/Makefile +++ b/radio/src/bootloader/Makefile @@ -116,6 +116,7 @@ else EXTRAINCDIRS += ../targets/taranis/STM32_USB-Host-Device_Lib_V2.1.0/Libraries/STM32_USB_Device_Library/Class/msc/inc EXTRAINCDIRS += ../targets/taranis EXTRAINCDIRS += ../fonts/std + EXTRAINCDIRS += ../ ifeq ($(PCBREV), REV3) CPPDEFS += -DREV3 diff --git a/radio/src/debug.cpp b/radio/src/debug.cpp index 83394f38e..a50338443 100644 --- a/radio/src/debug.cpp +++ b/radio/src/debug.cpp @@ -38,7 +38,7 @@ #include #include -#if !defined(SIMU) +#if !defined(SIMU) && defined(DEBUG) Fifo<512> debugRxFifo; @@ -215,3 +215,65 @@ void debugTask(void* pdata) } } #endif + + +#if defined(DEBUG_TRACE_BUFFER) + +static struct TraceElement traceBuffer[TRACE_BUFFER_LEN]; +static uint8_t traceBufferPos; +extern Fifo<512> uart3TxFifo; +gtime_t filltm(gtime_t *t, struct gtm *tp); + +void trace_event(enum TraceEvent event, uint32_t data) +{ + if (traceBufferPos >= TRACE_BUFFER_LEN) return; + __disable_irq(); + struct TraceElement * p = &traceBuffer[traceBufferPos++]; + __enable_irq(); + p->time = g_rtcTime; + p->time_ms = g_ms100; + p->event = event; + p->data = data; +} + +void trace_event_i(enum TraceEvent event, uint32_t data) +{ + if (traceBufferPos >= TRACE_BUFFER_LEN) return; + struct TraceElement * p = &traceBuffer[traceBufferPos++]; + p->time = g_rtcTime; + p->time_ms = g_ms100; + p->event = event; + p->data = data; +} + + +const struct TraceElement * getTraceElement(uint16_t idx) +{ + if (idx < TRACE_BUFFER_LEN) return &traceBuffer[idx]; + return 0; +} + +#include "stamp-opentx.h" + +void dumpTraceBuffer() +{ + TRACE("Dump of Trace Buffer ("VERS_STR " " DATE_STR " " TIME_STR "):"); + TRACE("# Time Event Data"); + for(int n = 0; n < TRACE_BUFFER_LEN; ++n) { + struct gtm tp; + filltm(&traceBuffer[n].time, &tp); + TRACE_INFO_WP("%02d ", n); + TRACE_INFO_WP("%4d-%02d-%02d,%02d:%02d:%02d.%02d0", tp.tm_year+1900, tp.tm_mon+1, tp.tm_mday, tp.tm_hour, tp.tm_min, tp.tm_sec, traceBuffer[n].time_ms); + TRACE(" %03d 0x%08x", traceBuffer[n].event, traceBuffer[n].data); + if (traceBuffer[n].time == 0 && traceBuffer[n].time_ms == 0) break; + if ((n % 5) == 0) { + while (!uart3TxFifo.empty()) { + CoTickDelay(1); + } + } + } + TRACE("End of Trace Buffer dump"); +} + +#endif + diff --git a/radio/src/debug.h b/radio/src/debug.h index 52cd66229..4fe093f62 100644 --- a/radio/src/debug.h +++ b/radio/src/debug.h @@ -38,6 +38,7 @@ #define debug_h #include +#include "rtc.h" #if defined(SIMU) @@ -108,5 +109,88 @@ void debugTask(void* pdata); #endif + +#if defined(DEBUG_TRACE_BUFFER) + +#define TRACE_BUFFER_LEN 50 + +enum TraceEvent { + trace_start = 1, + + sd_wait_ready = 10, + sd_rcvr_datablock, + sd_xmit_datablock_wait_ready, + sd_xmit_datablock_rcvr_spi, + sd_send_cmd_wait_ready, + sd_send_cmd_rcvr_spi, + + sd_SD_ReadSectors = 16, + sd_disk_read, + sd_SD_WriteSectors, + sd_disk_write, + + sd_disk_ioctl_CTRL_SYNC = 20, + sd_disk_ioctl_GET_SECTOR_COUNT, + sd_disk_ioctl_MMC_GET_CSD, + sd_disk_ioctl_MMC_GET_CID, + sd_disk_ioctl_MMC_GET_OCR, + sd_disk_ioctl_MMC_GET_SDSTAT_1, + sd_disk_ioctl_MMC_GET_SDSTAT_2, + sd_spi_reset, + + ff_f_write_validate = 30, + ff_f_write_flag, + ff_f_write_clst, + ff_f_write_sync_window, + ff_f_write_disk_write_dirty, + ff_f_write_clust2sect, + ff_f_write_disk_write, + ff_f_write_disk_read, + ff_f_write_move_window, + + audio_getNextFilledBuffer_skip = 50, +}; + +struct TraceElement { + gtime_t time; + uint8_t time_ms; + uint8_t event; + uint32_t data; +}; + +void trace_event(enum TraceEvent event, uint32_t data); +void trace_event_i(enum TraceEvent event, uint32_t data); +const struct TraceElement * getTraceElement(uint16_t idx); +void dumpTraceBuffer(); + +#define TRACE_EVENT(condition, event, data) if (condition) { trace_event(event, data); } +#define TRACEI_EVENT(condition, event, data) if (condition) { trace_event_i(event, data); } + +#else // #if defined(DEBUG_TRACE_BUFFER) + +#define TRACE_EVENT(condition, event, data) +#define TRACEI_EVENT(condition, event, data) + +#endif // #if defined(DEBUG_TRACE_BUFFER) + +#if defined(TRACE_SD_CARD) + #define TRACE_SD_CARD_EVENT(condition, event, data) TRACE_EVENT(condition, event, data) +#else + #define TRACE_SD_CARD_EVENT(condition, event, data) +#endif +#if defined(TRACE_FATFS) + #define TRACE_FATFS_EVENT(condition, event, data) TRACE_EVENT(condition, event, data) +#else + #define TRACE_FATFS_EVENT(condition, event, data) +#endif +#if defined(TRACE_AUDIO) + #define TRACE_AUDIO_EVENT(condition, event, data) TRACE_EVENT(condition, event, data) + #define TRACEI_AUDIO_EVENT(condition, event, data) TRACEI_EVENT(condition, event, data) +#else + #define TRACE_AUDIO_EVENT(condition, event, data) + #define TRACEI_AUDIO_EVENT(condition, event, data) #endif + +#endif // #ifndef debug_h + diff --git a/radio/src/gui/menus.h b/radio/src/gui/menus.h index 48056863c..980ba9181 100644 --- a/radio/src/gui/menus.h +++ b/radio/src/gui/menus.h @@ -141,6 +141,9 @@ void menuModelCustomFunctions(uint8_t event); void menuStatisticsView(uint8_t event); void menuStatisticsDebug(uint8_t event); void menuAboutView(uint8_t event); +#if defined(DEBUG_TRACE_BUFFER) +void menuTraceBuffer(uint8_t event); +#endif #if !defined(CPUM64) void displaySlider(coord_t x, coord_t y, uint8_t value, uint8_t max, uint8_t attr); diff --git a/radio/src/gui/view_statistics.cpp b/radio/src/gui/view_statistics.cpp index 67966664c..12497c9ac 100644 --- a/radio/src/gui/view_statistics.cpp +++ b/radio/src/gui/view_statistics.cpp @@ -141,6 +141,13 @@ void menuStatisticsDebug(uint8_t event) maxMixerDuration = 0; AUDIO_KEYPAD_UP(); break; + +#if defined(DEBUG_TRACE_BUFFER) + case EVT_KEY_FIRST(KEY_UP): + pushMenu(menuTraceBuffer); + return; +#endif + case EVT_KEY_FIRST(KEY_DOWN): chainMenu(menuStatisticsView); break; @@ -256,3 +263,58 @@ void menuStatisticsDebug(uint8_t event) lcd_puts(3*FW, 7*FH+1, STR_MENUTORESET); lcd_status_line(); } + + +#if defined(DEBUG_TRACE_BUFFER) +#include "stamp-opentx.h" + +void menuTraceBuffer(uint8_t event) +{ + switch(event) + { + case EVT_KEY_LONG(KEY_ENTER): + dumpTraceBuffer(); + killEvents(event); + break; + } + + SIMPLE_SUBMENU("Trace Buffer " VERS_STR, TRACE_BUFFER_LEN); + /* RTC time */ + struct gtm t; + gettime(&t); + putsTime(LCD_W+1, 0, t, TIMEBLINK); + + uint8_t y = 0; + uint8_t k = 0; + int8_t sub = m_posVert; + + lcd_putc(0, FH, '#'); + lcd_puts(4*FW, FH, "Time"); + lcd_puts(14*FW, FH, "Event"); + lcd_puts(20*FW, FH, "Data"); + + for (uint8_t i=0; itime % SECS_PER_DAY; + putsTimer(4*FW, y, tme, TIMEHOUR|LEFT, TIMEHOUR|LEFT); + //event + lcd_outdezNAtt(14*FW, y, te->event, LEADING0|LEFT, 3); + //data + lcd_putsn (20*FW, y, "0x", 2); + lcd_outhex4(22*FW-2, y, (uint16_t)(te->data >> 16)); + lcd_outhex4(25*FW, y, (uint16_t)(te->data & 0xFFFF)); + } + + } + + +} +#endif //#if defined(DEBUG_TRACE_BUFFER) diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 34aab0143..9ced22258 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -2055,6 +2055,10 @@ void opentxStart() { doSplash(); +#if defined(DEBUG_TRACE_BUFFER) + trace_event(trace_start, 0x12345678); +#endif + #if defined(PCBSKY9X) && defined(SDCARD) && !defined(SIMU) for (int i=0; i<500 && !Card_initialized; i++) { CoTickDelay(1); // 2ms diff --git a/radio/src/targets/sky9x/diskio.cpp b/radio/src/targets/sky9x/diskio.cpp index 8d9ff5cfc..388182ad0 100644 --- a/radio/src/targets/sky9x/diskio.cpp +++ b/radio/src/targets/sky9x/diskio.cpp @@ -94,6 +94,16 @@ uint32_t Cmd_A41_resp ; uint8_t cardType; uint32_t transSpeed; +#if !defined(BOOT) +static OS_MutexID ioMutex; +#define IO_MUTEX_ENTER() CoEnterMutexSection(ioMutex); +#define IO_MUTEX_LEAVE() CoLeaveMutexSection(ioMutex); +#else +#define IO_MUTEX_ENTER() +#define IO_MUTEX_LEAVE() +#endif //#if !defined(BOOT) + + /*-----------------------------------------------------------------------*/ /* Lock / unlock functions */ /*-----------------------------------------------------------------------*/ @@ -1272,33 +1282,38 @@ DRESULT disk_read ( BYTE count /* Sector count (1..255) */ ) { - uint32_t result ; + uint32_t result ; - if (drv || !count) return RES_PARERR; + if (drv || !count) return RES_PARERR; - if ( sd_card_ready() == 0 ) return RES_NOTRDY; + if ( sd_card_ready() == 0 ) return RES_NOTRDY; - do { - result = sd_read_block(sector, dma_sd_buffer) ; - if (result) { - memcpy(buff, dma_sd_buffer, 512); - sector += 1 ; - buff += 512 ; - count -= 1 ; - } - else { - count = 1 ; // Flag error - break ; - } - } while ( count ) ; + IO_MUTEX_ENTER(); - if (!count) - return RES_OK; + do { + result = sd_read_block(sector, dma_sd_buffer) ; + if (result) { + memcpy(buff, dma_sd_buffer, 512); + sector += 1 ; + buff += 512 ; + count -= 1 ; + } + else { + count = 1 ; // Flag error + break ; + } + } while ( count ) ; - if (++sdErrorCount > 3) - Card_state = SD_ST_ERR; + if (!count) { + IO_MUTEX_LEAVE(); + return RES_OK; + } - return RES_ERROR; + if (++sdErrorCount > 3) + Card_state = SD_ST_ERR; + + IO_MUTEX_LEAVE(); + return RES_ERROR; } @@ -1315,49 +1330,54 @@ DRESULT disk_write ( BYTE count /* Sector count (1..255) */ ) { - uint32_t result ; + uint32_t result ; - if (drv || !count) return RES_PARERR; + if (drv || !count) return RES_PARERR; - if ( sd_card_ready() == 0 ) return RES_NOTRDY; + if ( sd_card_ready() == 0 ) return RES_NOTRDY; - do { + IO_MUTEX_ENTER(); - while (1) { + do { - memcpy(dma_sd_buffer, buff, 512); + while (1) { - result = sd_write_block(sector, dma_sd_buffer) ; + memcpy(dma_sd_buffer, buff, 512); - sd_read_block(sector, dma_sd_buffer) ; + result = sd_write_block(sector, dma_sd_buffer) ; - if (!memcmp(dma_sd_buffer, buff, 512)) - break; - else { - TRACE_ERROR("Block %d ko SR=%.2X\r\n", sector, HSMCI->HSMCI_SR); - // DUMP(buff, 512); - // DUMP(copy, 512); - } - } + sd_read_block(sector, dma_sd_buffer) ; - if (result) { - sector += 1 ; - buff += 512 ; - count -= 1 ; - } - else { - count = 1 ; // Flag error - break ; - } - } while ( count ) ; + if (!memcmp(dma_sd_buffer, buff, 512)) + break; + else { + TRACE_ERROR("Block %d ko SR=%.2X\r\n", sector, HSMCI->HSMCI_SR); + // DUMP(buff, 512); + // DUMP(copy, 512); + } + } - if (!count) - return RES_OK; + if (result) { + sector += 1 ; + buff += 512 ; + count -= 1 ; + } + else { + count = 1 ; // Flag error + break ; + } + } while ( count ) ; - if (++sdErrorCount > 3) - Card_state = SD_ST_ERR; + if (!count) { + IO_MUTEX_LEAVE(); + return RES_OK; + } - return RES_ERROR; + if (++sdErrorCount > 3) + Card_state = SD_ST_ERR; + + IO_MUTEX_LEAVE(); + return RES_ERROR; } @@ -1372,89 +1392,92 @@ DRESULT disk_ioctl ( void *buff /* Buffer to send/receive control data */ ) { - DRESULT res; + DRESULT res; - if (drv) return RES_PARERR; + if (drv) return RES_PARERR; - res = RES_ERROR; + res = RES_ERROR; - if (ctrl == CTRL_POWER) { + IO_MUTEX_ENTER(); + + if (ctrl == CTRL_POWER) { #if 0 - switch (ptr[0]) { - case 0: /* Sub control code (POWER_OFF) */ - power_off(); /* Power off */ - res = RES_OK; - break; - case 1: /* Sub control code (POWER_GET) */ - ptr[1] = (BYTE)power_status(); - res = RES_OK; - break; - default : - res = RES_PARERR; - } + switch (ptr[0]) { + case 0: /* Sub control code (POWER_OFF) */ + power_off(); /* Power off */ + res = RES_OK; + break; + case 1: /* Sub control code (POWER_GET) */ + ptr[1] = (BYTE)power_status(); + res = RES_OK; + break; + default : + res = RES_PARERR; + } #endif - } - else { - switch (ctrl) { - case CTRL_SYNC : /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */ - res = RES_OK; - break; + } + else { + switch (ctrl) { + case CTRL_SYNC : /* Make sure that no pending write process. Do not remove this or written sector might not left updated. */ + res = RES_OK; + break; - case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ - *(DWORD*)buff = SD_GET_BLOCKNR(); - res = RES_OK; - break; + case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ + *(DWORD*)buff = SD_GET_BLOCKNR(); + res = RES_OK; + break; - case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ - *(WORD*)buff = 512; - res = RES_OK; - break; + case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ + *(WORD*)buff = 512; + res = RES_OK; + break; - case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ - *(WORD*)buff = 1; - res = RES_OK; - break; + case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ + *(WORD*)buff = 1; + res = RES_OK; + break; #if 0 - case MMC_GET_TYPE : /* Get card type flags (1 byte) */ - *ptr = CardType; - res = RES_OK; - break; + case MMC_GET_TYPE : /* Get card type flags (1 byte) */ + *ptr = CardType; + res = RES_OK; + break; - case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */ - if (send_cmd(CMD9, 0) == 0 /* READ_CSD */ - && rcvr_datablock(ptr, 16)) - res = RES_OK; - break; + case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */ + if (send_cmd(CMD9, 0) == 0 /* READ_CSD */ + && rcvr_datablock(ptr, 16)) + res = RES_OK; + break; - case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */ - if (send_cmd(CMD10, 0) == 0 /* READ_CID */ - && rcvr_datablock(ptr, 16)) - res = RES_OK; - break; + case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */ + if (send_cmd(CMD10, 0) == 0 /* READ_CID */ + && rcvr_datablock(ptr, 16)) + res = RES_OK; + break; - case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */ - if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */ - for (n = 4; n; n--) *ptr++ = rcvr_spi(); - res = RES_OK; - } - break; - - case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */ - if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ - rcvr_spi(); - if (rcvr_datablock(ptr, 64)) - res = RES_OK; - } - break; -#endif - default: - res = RES_PARERR; - break; - } - - // BSS deselect(); + case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */ + if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */ + for (n = 4; n; n--) *ptr++ = rcvr_spi(); + res = RES_OK; } + break; - return res; + case MMC_GET_SDSTAT : /* Receive SD statsu as a data block (64 bytes) */ + if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ + rcvr_spi(); + if (rcvr_datablock(ptr, 64)) + res = RES_OK; + } + break; +#endif + default: + res = RES_PARERR; + break; + } + // BSS deselect(); + } + + IO_MUTEX_LEAVE(); + + return res; } diff --git a/radio/src/targets/taranis/diskio.cpp b/radio/src/targets/taranis/diskio.cpp index b967537c3..ae9252ba1 100644 --- a/radio/src/targets/taranis/diskio.cpp +++ b/radio/src/targets/taranis/diskio.cpp @@ -40,6 +40,7 @@ #include "../../FatFs/ff.h" #include "../../CoOS/kernel/CoOS.h" #include "hal.h" +#include "debug.h" /* Definitions for MMC/SDC command */ #define CMD0 (0x40+0) /* GO_IDLE_STATE */ @@ -118,6 +119,16 @@ int ff_del_syncobj (_SYNC_t mutex) } #endif + +#if !defined(BOOT) +static OS_MutexID ioMutex; +#define IO_MUTEX_ENTER() CoEnterMutexSection(ioMutex); +#define IO_MUTEX_LEAVE() CoLeaveMutexSection(ioMutex); +#else +#define IO_MUTEX_ENTER() +#define IO_MUTEX_LEAVE() +#endif //#if !defined(BOOT) + static const DWORD socket_state_mask_cp = (1 << 0); static const DWORD socket_state_mask_wp = (1 << 1); @@ -133,56 +144,56 @@ enum speed_setting { INTERFACE_SLOW, INTERFACE_FAST }; static void interface_speed( enum speed_setting speed ) { - DWORD tmp; + DWORD tmp; - tmp = SPI_SD->CR1; - if ( speed == INTERFACE_SLOW ) { - /* Set slow clock (100k-400k) */ - tmp = ( tmp | SPI_BaudRatePrescaler_128 ); - } else { - /* Set fast clock (depends on the CSD) */ - tmp = ( tmp & ~SPI_BaudRatePrescaler_128 ) | SPI_BaudRatePrescaler_SPI_SD; - } - SPI_SD->CR1 = tmp; + tmp = SPI_SD->CR1; + if ( speed == INTERFACE_SLOW ) { + /* Set slow clock (100k-400k) */ + tmp = ( tmp | SPI_BaudRatePrescaler_128 ); + } else { + /* Set fast clock (depends on the CSD) */ + tmp = ( tmp & ~SPI_BaudRatePrescaler_128 ) | SPI_BaudRatePrescaler_SPI_SD; + } + SPI_SD->CR1 = tmp; } static void socket_wp_init(void) { - return; + return; } static inline DWORD socket_is_write_protected(void) { - return 0; /* fake not protected */ + return 0; /* fake not protected */ } static void socket_cp_init(void) { - GPIO_InitTypeDef GPIO_InitStructure; - - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_SD_PRESENT, ENABLE); - - GPIO_InitStructure.GPIO_Pin = SD_PRESENT_GPIO_Pin; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(SD_PRESENT_GPIO, &GPIO_InitStructure); + GPIO_InitTypeDef GPIO_InitStructure; + + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_SD_PRESENT, ENABLE); + + GPIO_InitStructure.GPIO_Pin = SD_PRESENT_GPIO_Pin; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_Init(SD_PRESENT_GPIO, &GPIO_InitStructure); } static inline DWORD socket_is_empty(void) { - return !SD_CARD_PRESENT(); /* fake inserted */ + return !SD_CARD_PRESENT(); /* fake inserted */ } static void card_power(BYTE on) { - on=on; + on=on; } static int chk_power(void) { - return 1; /* fake powered */ + return 1; /* fake powered */ } /*-----------------------------------------------------------------------*/ @@ -190,17 +201,17 @@ static int chk_power(void) /*-----------------------------------------------------------------------*/ static BYTE stm32_spi_rw( BYTE out ) { - /* Loop while DR register in not empty */ - /// not needed: while (SPI_I2S_GetFlagStatus(SPI_SD, SPI_I2S_FLAG_TXE) == RESET) { ; } + /* Loop while DR register in not empty */ + /// not needed: while (SPI_I2S_GetFlagStatus(SPI_SD, SPI_I2S_FLAG_TXE) == RESET) { ; } - /* Send byte through the SPI peripheral */ - SPI_I2S_SendData(SPI_SD, out); + /* Send byte through the SPI peripheral */ + SPI_I2S_SendData(SPI_SD, out); - /* Wait to receive a byte */ - while (SPI_I2S_GetFlagStatus(SPI_SD, SPI_I2S_FLAG_RXNE) == RESET) { ; } + /* Wait to receive a byte */ + while (SPI_I2S_GetFlagStatus(SPI_SD, SPI_I2S_FLAG_RXNE) == RESET) { ; } - /* Return the byte read from the SPI bus */ - return SPI_I2S_ReceiveData(SPI_SD); + /* Return the byte read from the SPI bus */ + return SPI_I2S_ReceiveData(SPI_SD); } @@ -218,7 +229,7 @@ static BYTE stm32_spi_rw( BYTE out ) static BYTE rcvr_spi (void) { - return stm32_spi_rw(0xff); + return stm32_spi_rw(0xff); } /* Alternative macro to receive data fast */ @@ -229,28 +240,25 @@ BYTE rcvr_spi (void) /*-----------------------------------------------------------------------*/ /* Wait for card ready */ /*-----------------------------------------------------------------------*/ - -static -BYTE wait_ready (void) +static BYTE wait_ready (void) { - BYTE res; + BYTE res; + Timer2 = 50; /* Wait for ready in timeout of 500ms */ + rcvr_spi(); + do { + res = rcvr_spi(); + } while ((res != 0xFF) && Timer2); - Timer2 = 50; /* Wait for ready in timeout of 500ms */ - rcvr_spi(); - do - res = rcvr_spi(); - while ((res != 0xFF) && Timer2); - - return res; + return res; } - static void spi_reset() { - for(int n=0; n < 520; ++n) { + for (int n=0; n<520; ++n) { stm32_spi_rw(0xFF); } + TRACE_SD_CARD_EVENT(1, sd_spi_reset, 0); } /*-----------------------------------------------------------------------*/ @@ -260,8 +268,8 @@ static void spi_reset() static void release_spi (void) { - DESELECT(); - rcvr_spi(); + DESELECT(); + rcvr_spi(); } #ifdef STM32_SD_USE_DMA @@ -270,95 +278,95 @@ void release_spi (void) /*-----------------------------------------------------------------------*/ static void stm32_dma_transfer( - BOOL receive, /* FALSE for buff->SPI, TRUE for SPI->buff */ - const BYTE *buff, /* receive TRUE : 512 byte data block to be transmitted - receive FALSE : Data buffer to store received data */ - UINT btr /* receive TRUE : Byte count (must be multiple of 2) - receive FALSE : Byte count (must be 512) */ + BOOL receive, /* FALSE for buff->SPI, TRUE for SPI->buff */ + const BYTE *buff, /* receive TRUE : 512 byte data block to be transmitted + receive FALSE : Data buffer to store received data */ + UINT btr /* receive TRUE : Byte count (must be multiple of 2) + receive FALSE : Byte count (must be 512) */ ) { - DMA_InitTypeDef DMA_InitStructure; - WORD rw_workbyte[] = { 0xffff }; + DMA_InitTypeDef DMA_InitStructure; + WORD rw_workbyte[] = { 0xffff }; - DMA_DeInit(DMA_Channel_SPI_SD_RX); - DMA_DeInit(DMA_Channel_SPI_SD_TX); - - /* shared DMA configuration values between SPI2 RX & TX*/ - DMA_InitStructure.DMA_Channel = DMA_Channel_SPI2_TX;//the same channel - DMA_InitStructure.DMA_PeripheralBaseAddr = (DWORD)(&(SPI_SD->DR)); - DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; - DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; - DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; - DMA_InitStructure.DMA_BufferSize = btr; - DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; - DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; - - DMA_InitStructure.DMA_FIFOMode =DMA_FIFOMode_Enable; - DMA_InitStructure.DMA_FIFOThreshold =DMA_FIFOThreshold_Full; - DMA_InitStructure.DMA_MemoryBurst =DMA_MemoryBurst_Single; - DMA_InitStructure.DMA_PeripheralBurst =DMA_PeripheralBurst_Single; + DMA_DeInit(DMA_Channel_SPI_SD_RX); + DMA_DeInit(DMA_Channel_SPI_SD_TX); + + /* shared DMA configuration values between SPI2 RX & TX*/ + DMA_InitStructure.DMA_Channel = DMA_Channel_SPI2_TX;//the same channel + DMA_InitStructure.DMA_PeripheralBaseAddr = (DWORD)(&(SPI_SD->DR)); + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_BufferSize = btr; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh; + + DMA_InitStructure.DMA_FIFOMode =DMA_FIFOMode_Enable; + DMA_InitStructure.DMA_FIFOThreshold =DMA_FIFOThreshold_Full; + DMA_InitStructure.DMA_MemoryBurst =DMA_MemoryBurst_Single; + DMA_InitStructure.DMA_PeripheralBurst =DMA_PeripheralBurst_Single; - //seperate RX & TX - if ( receive ) { //true =read + //seperate RX & TX + if ( receive ) { //true =read - /* DMA1 channel3 configuration SPI2 RX ---------------------------------------------*/ - DMA_InitStructure.DMA_Memory0BaseAddr = (DWORD)buff; - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_Init(DMA_Channel_SPI_SD_RX, &DMA_InitStructure); + /* DMA1 channel3 configuration SPI2 RX ---------------------------------------------*/ + DMA_InitStructure.DMA_Memory0BaseAddr = (DWORD)buff; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_Init(DMA_Channel_SPI_SD_RX, &DMA_InitStructure); - /* DMA1 channel4 configuration SPI2 TX ---------------------------------------------*/ - DMA_InitStructure.DMA_Memory0BaseAddr = (DWORD)rw_workbyte; - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; - DMA_Init(DMA_Channel_SPI_SD_TX, &DMA_InitStructure); + /* DMA1 channel4 configuration SPI2 TX ---------------------------------------------*/ + DMA_InitStructure.DMA_Memory0BaseAddr = (DWORD)rw_workbyte; + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; + DMA_Init(DMA_Channel_SPI_SD_TX, &DMA_InitStructure); - } else {//false = write + } else {//false = write #if _FS_READONLY == 0 //READ AND WRITE = write enabled. - /* DMA1 channel2 configuration SPI1 RX ---------------------------------------------*/ - /* DMA1 channel4 configuration SPI2 RX ---------------------------------------------*/ - DMA_InitStructure.DMA_Memory0BaseAddr = (DWORD)rw_workbyte; - DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; - DMA_Init(DMA_Channel_SPI_SD_RX, &DMA_InitStructure); + /* DMA1 channel2 configuration SPI1 RX ---------------------------------------------*/ + /* DMA1 channel4 configuration SPI2 RX ---------------------------------------------*/ + DMA_InitStructure.DMA_Memory0BaseAddr = (DWORD)rw_workbyte; + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; + DMA_Init(DMA_Channel_SPI_SD_RX, &DMA_InitStructure); - /* DMA1 channel3 configuration SPI1 TX ---------------------------------------------*/ - /* DMA1 channel5 configuration SPI2 TX ---------------------------------------------*/ - DMA_InitStructure.DMA_Memory0BaseAddr = (DWORD)buff; - DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; - DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; - DMA_Init(DMA_Channel_SPI_SD_TX, &DMA_InitStructure); + /* DMA1 channel3 configuration SPI1 TX ---------------------------------------------*/ + /* DMA1 channel5 configuration SPI2 TX ---------------------------------------------*/ + DMA_InitStructure.DMA_Memory0BaseAddr = (DWORD)buff; + DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_Init(DMA_Channel_SPI_SD_TX, &DMA_InitStructure); #endif - } + } - /* Enable DMA RX Channel */ - DMA_Cmd(DMA_Channel_SPI_SD_RX, ENABLE); - /* Enable DMA TX Channel */ - DMA_Cmd(DMA_Channel_SPI_SD_TX, ENABLE); + /* Enable DMA RX Channel */ + DMA_Cmd(DMA_Channel_SPI_SD_RX, ENABLE); + /* Enable DMA TX Channel */ + DMA_Cmd(DMA_Channel_SPI_SD_TX, ENABLE); - /* Enable SPI TX/RX request */ - SPI_I2S_DMACmd(SPI_SD, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, ENABLE); + /* Enable SPI TX/RX request */ + SPI_I2S_DMACmd(SPI_SD, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, ENABLE); - /* Wait until DMA1_Channel 3 Transfer Complete */ - - while (DMA_GetFlagStatus(DMA_Channel_SPI_SD_TX,DMA_FLAG_SPI_SD_TC_TX) == RESET) { ; } - - /* Wait until DMA1_Channel 2 Receive Complete */ - - while (DMA_GetFlagStatus(DMA_Channel_SPI_SD_RX,DMA_FLAG_SPI_SD_TC_RX) == RESET) { ; } + /* Wait until DMA1_Channel 3 Transfer Complete */ + + while (DMA_GetFlagStatus(DMA_Channel_SPI_SD_TX,DMA_FLAG_SPI_SD_TC_TX) == RESET) { ; } + + /* Wait until DMA1_Channel 2 Receive Complete */ + + while (DMA_GetFlagStatus(DMA_Channel_SPI_SD_RX,DMA_FLAG_SPI_SD_TC_RX) == RESET) { ; } - // same w/o function-call: - // while ( ( ( DMA1->ISR ) & DMA_FLAG_SPI_SD_TC_RX ) == RESET ) { ; } + // same w/o function-call: + // while ( ( ( DMA1->ISR ) & DMA_FLAG_SPI_SD_TC_RX ) == RESET ) { ; } - /* Disable DMA RX Channel */ - DMA_Cmd(DMA_Channel_SPI_SD_RX, DISABLE); - /* Disable DMA TX Channel */ - DMA_Cmd(DMA_Channel_SPI_SD_TX, DISABLE); + /* Disable DMA RX Channel */ + DMA_Cmd(DMA_Channel_SPI_SD_RX, DISABLE); + /* Disable DMA TX Channel */ + DMA_Cmd(DMA_Channel_SPI_SD_TX, DISABLE); - /* Disable SPI RX/TX request */ - SPI_I2S_DMACmd(SPI_SD, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, DISABLE); + /* Disable SPI RX/TX request */ + SPI_I2S_DMACmd(SPI_SD, SPI_I2S_DMAReq_Rx | SPI_I2S_DMAReq_Tx, DISABLE); } #endif /* STM32_SD_USE_DMA */ @@ -370,71 +378,71 @@ void stm32_dma_transfer( static void power_on (void) { - SPI_InitTypeDef SPI_InitStructure; - GPIO_InitTypeDef GPIO_InitStructure; - volatile BYTE dummyread; + SPI_InitTypeDef SPI_InitStructure; + GPIO_InitTypeDef GPIO_InitStructure; + volatile BYTE dummyread; - /* Enable GPIO clock for CS */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO_SD, ENABLE); - /* Enable SPI clock, SPI1: APB2, SPI2: APB1 */ - RCC_APBPeriphClockCmd_SPI_SD(RCC_APBPeriph_SPI_SD, ENABLE); + /* Enable GPIO clock for CS */ + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIO_SD, ENABLE); + /* Enable SPI clock, SPI1: APB2, SPI2: APB1 */ + RCC_APBPeriphClockCmd_SPI_SD(RCC_APBPeriph_SPI_SD, ENABLE); - card_power(1); + card_power(1); - socket_cp_init();//Empty return - socket_wp_init();//Empty return. + socket_cp_init();//Empty return + socket_wp_init();//Empty return. - for (uint32_t Timer = 25000; Timer>0;Timer--); /* Wait for 250ms */ + for (uint32_t Timer = 25000; Timer>0;Timer--); /* Wait for 250ms */ - /* Configure I/O for Flash Chip select */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SPI_SD_CS; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + /* Configure I/O for Flash Chip select */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SPI_SD_CS; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_Init(GPIO_SPI_SD, &GPIO_InitStructure); + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_Init(GPIO_SPI_SD, &GPIO_InitStructure); - /* De-select the Card: Chip Select high */ - DESELECT(); + /* De-select the Card: Chip Select high */ + DESELECT(); - /* Configure SPI pins: SCK MISO and MOSI with alternate function push-down */ - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SPI_SD_SCK | GPIO_Pin_SPI_SD_MOSI|GPIO_Pin_SPI_SD_MISO; - GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; + /* Configure SPI pins: SCK MISO and MOSI with alternate function push-down */ + GPIO_InitStructure.GPIO_Pin = GPIO_Pin_SPI_SD_SCK | GPIO_Pin_SPI_SD_MOSI|GPIO_Pin_SPI_SD_MISO; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_Init(GPIO_SPI_SD, &GPIO_InitStructure); + GPIO_Init(GPIO_SPI_SD, &GPIO_InitStructure); GPIO_PinAFConfig(GPIO_SPI_SD,GPIO_PinSource_SCK ,GPIO_AF_SD); GPIO_PinAFConfig(GPIO_SPI_SD,GPIO_PinSource_MISO,GPIO_AF_SD); GPIO_PinAFConfig(GPIO_SPI_SD,GPIO_PinSource_MOSI,GPIO_AF_SD); - /* SPI configuration */ - SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; - SPI_InitStructure.SPI_Mode = SPI_Mode_Master; - SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; - SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; - SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; - SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; - SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_SPI_SD; - SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; - SPI_InitStructure.SPI_CRCPolynomial = 7; + /* SPI configuration */ + SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; + SPI_InitStructure.SPI_Mode = SPI_Mode_Master; + SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; + SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low; + SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge; + SPI_InitStructure.SPI_NSS = SPI_NSS_Soft; + SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_SPI_SD; + SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; + SPI_InitStructure.SPI_CRCPolynomial = 7; - SPI_Init(SPI_SD, &SPI_InitStructure); - SPI_CalculateCRC(SPI_SD, DISABLE); - SPI_Cmd(SPI_SD, ENABLE); + SPI_Init(SPI_SD, &SPI_InitStructure); + SPI_CalculateCRC(SPI_SD, DISABLE); + SPI_Cmd(SPI_SD, ENABLE); - /* drain SPI */ - while (SPI_I2S_GetFlagStatus(SPI_SD, SPI_I2S_FLAG_TXE) == RESET) { ; } - dummyread = SPI_I2S_ReceiveData(SPI_SD); + /* drain SPI */ + while (SPI_I2S_GetFlagStatus(SPI_SD, SPI_I2S_FLAG_TXE) == RESET) { ; } + dummyread = SPI_I2S_ReceiveData(SPI_SD); #ifdef STM32_SD_USE_DMA - /* enable DMA clock */ - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA_SD, ENABLE); + /* enable DMA clock */ + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA_SD, ENABLE); #endif - (void) dummyread; // Discard value - prevents compiler warning + (void) dummyread; // Discard value - prevents compiler warning } static void power_off (void) @@ -474,33 +482,34 @@ BOOL rcvr_datablock ( UINT btr /* Byte count (must be multiple of 4) */ ) { - BYTE token; + BYTE token; - Timer1 = 10; - do { /* Wait for data packet in timeout of 100ms */ - token = rcvr_spi(); - } while ((token == 0xFF) && Timer1); - if(token != 0xFE) { - spi_reset(); - return FALSE; /* If not valid data token, return with error */ - } + Timer1 = 10; + do { /* Wait for data packet in timeout of 100ms */ + token = rcvr_spi(); + } while ((token == 0xFF) && Timer1); + if(token != 0xFE) { + TRACE_SD_CARD_EVENT(1, sd_rcvr_datablock, ((uint32_t)(Timer1) << 24) + ((uint32_t)(btr) << 8) + token); + spi_reset(); + return FALSE; /* If not valid data token, return with error */ + } #ifdef STM32_SD_USE_DMA - stm32_dma_transfer( TRUE, buff, btr ); + stm32_dma_transfer( TRUE, buff, btr ); #else - do { /* Receive the data block into buffer */ - rcvr_spi_m(buff++); - rcvr_spi_m(buff++); - rcvr_spi_m(buff++); - rcvr_spi_m(buff++); - } while (btr -= 4); + do { /* Receive the data block into buffer */ + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + rcvr_spi_m(buff++); + } while (btr -= 4); #endif /* STM32_SD_USE_DMA */ - rcvr_spi(); /* Discard CRC */ - rcvr_spi(); + rcvr_spi(); /* Discard CRC */ + rcvr_spi(); - return TRUE; /* Return with success */ + return TRUE; /* Return with success */ } @@ -517,53 +526,56 @@ BOOL xmit_datablock ( BYTE token /* Data/Stop token */ ) { - BYTE resp; + BYTE resp; #ifndef STM32_SD_USE_DMA - BYTE wc; + BYTE wc; #endif - if (wait_ready() != 0xFF) { - spi_reset(); - return FALSE; - } + if (wait_ready() != 0xFF) { + TRACE_SD_CARD_EVENT(1, sd_xmit_datablock_wait_ready, token); + spi_reset(); + return FALSE; + } - xmit_spi(token); /* transmit data token */ - if (token != 0xFD) { /* Is data token */ + xmit_spi(token); /* transmit data token */ + if (token != 0xFD) { /* Is data token */ #ifdef STM32_SD_USE_DMA - stm32_dma_transfer( FALSE, buff, 512 ); + stm32_dma_transfer( FALSE, buff, 512 ); #else - wc = 0; - do { /* transmit the 512 byte data block to MMC */ - xmit_spi(*buff++); - xmit_spi(*buff++); - } while (--wc); + wc = 0; + do { /* transmit the 512 byte data block to MMC */ + xmit_spi(*buff++); + xmit_spi(*buff++); + } while (--wc); #endif /* STM32_SD_USE_DMA */ - xmit_spi(0xFF); /* CRC (Dummy) */ - xmit_spi(0xFF); + xmit_spi(0xFF); /* CRC (Dummy) */ + xmit_spi(0xFF); - /* - Despite what the SD card standard says, the reality is that (at least for some SD cards) - the Data Response byte does not come immediately after the last byte of data. - - This delay only happens very rarely, but it does happen. Typical response delay is some 10ms - */ - Timer2 = DATA_RESPONSE_TIMEOUT; - do { - resp = rcvr_spi(); /* Receive data response */ - if ((resp & 0x1F) == 0x05) { /* If not accepted, return with error */ - return TRUE; - } - if (resp != 0xFF) { - spi_reset(); - return FALSE; - } - } while (Timer2); - - } + /* + Despite what the SD card standard says, the reality is that (at least for some SD cards) + the Data Response byte does not come immediately after the last byte of data. + This delay only happens very rarely, but it does happen. Typical response delay is some 10ms + */ + Timer2 = DATA_RESPONSE_TIMEOUT; + do { + resp = rcvr_spi(); /* Receive data response */ + if ((resp & 0x1F) == 0x05) { + TRACE_SD_CARD_EVENT((Timer2 != DATA_RESPONSE_TIMEOUT), sd_xmit_datablock_rcvr_spi, ((uint32_t)(Timer2) << 16) + ((uint32_t)(resp) << 8) + token); return TRUE; + } + if (resp != 0xFF) { + TRACE_SD_CARD_EVENT(1, sd_xmit_datablock_rcvr_spi, ((uint32_t)(Timer2) << 16) + ((uint32_t)(resp) << 8) + token); + spi_reset(); + return FALSE; + } + } while (Timer2); + TRACE_SD_CARD_EVENT(1, sd_xmit_datablock_rcvr_spi, ((uint32_t)(Timer2) << 16) + ((uint32_t)(resp) << 8) + token); + return FALSE; + } + return TRUE; } @@ -577,42 +589,45 @@ BYTE send_cmd ( DWORD arg /* Argument */ ) { - BYTE n, res; + BYTE n, res; - if (cmd & 0x80) { /* ACMD is the command sequence of CMD55-CMD */ - cmd &= 0x7F; - res = send_cmd(CMD55, 0); - if (res > 1) return res; - } + if (cmd & 0x80) { /* ACMD is the command sequence of CMD55-CMD */ + cmd &= 0x7F; + res = send_cmd(CMD55, 0); + if (res > 1) return res; + } - /* Select the card and wait for ready */ - SELECT(); - if (wait_ready() != 0xFF) { - spi_reset(); - return 0xFF; - } + /* Select the card and wait for ready */ + SELECT(); + if (wait_ready() != 0xFF) { + TRACE_SD_CARD_EVENT(1, sd_send_cmd_wait_ready, cmd); + spi_reset(); + return 0xFF; + } - /* Send command packet */ - xmit_spi(cmd); /* Start + Command index */ - xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */ - xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */ - xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */ - xmit_spi((BYTE)arg); /* Argument[7..0] */ - n = 0x01; /* Dummy CRC + Stop */ - if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ - if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ - xmit_spi(n); + /* Send command packet */ + xmit_spi(cmd); /* Start + Command index */ + xmit_spi((BYTE)(arg >> 24)); /* Argument[31..24] */ + xmit_spi((BYTE)(arg >> 16)); /* Argument[23..16] */ + xmit_spi((BYTE)(arg >> 8)); /* Argument[15..8] */ + xmit_spi((BYTE)arg); /* Argument[7..0] */ + n = 0x01; /* Dummy CRC + Stop */ + if (cmd == CMD0) n = 0x95; /* Valid CRC for CMD0(0) */ + if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */ + xmit_spi(n); - /* Receive command response */ - if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */ + /* Receive command response */ + if (cmd == CMD12) rcvr_spi(); /* Skip a stuff byte when stop reading */ - n = 10; /* Wait for a valid response in timeout of 10 attempts */ - do { - res = rcvr_spi(); - } while ((res & 0x80) && --n); + n = 10; /* Wait for a valid response in timeout of 10 attempts */ + do { + res = rcvr_spi(); + } while ((res & 0x80) && --n); - return res; /* Return with the response value */ + TRACE_SD_CARD_EVENT((res > 1), sd_send_cmd_rcvr_spi, ((uint32_t)(n) << 16) + ((uint32_t)(res) << 8) + cmd); + + return res; /* Return with the response value */ } @@ -632,49 +647,53 @@ DSTATUS disk_initialize ( BYTE drv /* Physical drive number (0) */ ) { - BYTE n, cmd, ty, ocr[4]; + BYTE n, cmd, ty, ocr[4]; - if (drv) return STA_NOINIT; /* Supports only single drive */ - if (Stat & STA_NODISK) return Stat; /* No card in the socket */ + if (drv) return STA_NOINIT; /* Supports only single drive */ + if (Stat & STA_NODISK) return Stat; /* No card in the socket */ - power_on(); /* Force socket power on and initialize interface */ - interface_speed(INTERFACE_SLOW); - for (n = 10; n; n--) rcvr_spi(); /* 80 dummy clocks */ + IO_MUTEX_ENTER(); + power_on(); /* Force socket power on and initialize interface */ + interface_speed(INTERFACE_SLOW); + for (n = 10; n; n--) rcvr_spi(); /* 80 dummy clocks */ + + ty = 0; + if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ + Timer1 = 100; /* Initialization timeout of 1000 milliseconds */ + if (send_cmd(CMD8, 0x1AA) == 1) { /* SDHC */ + for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); /* Get trailing return value of R7 response */ + if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at VDD range of 2.7-3.6V */ + while (Timer1 && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */ + if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ + for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); + ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; + } + } + } else { /* SDSC or MMC */ + if (send_cmd(ACMD41, 0) <= 1) { + ty = CT_SD1; cmd = ACMD41; /* SDSC */ + } else { + ty = CT_MMC; cmd = CMD1; /* MMC */ + } + while (Timer1 && send_cmd(cmd, 0)); /* Wait for leaving idle state */ + if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ ty = 0; - if (send_cmd(CMD0, 0) == 1) { /* Enter Idle state */ - Timer1 = 100; /* Initialization timeout of 1000 milliseconds */ - if (send_cmd(CMD8, 0x1AA) == 1) { /* SDHC */ - for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); /* Get trailing return value of R7 response */ - if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at VDD range of 2.7-3.6V */ - while (Timer1 && send_cmd(ACMD41, 1UL << 30)); /* Wait for leaving idle state (ACMD41 with HCS bit) */ - if (Timer1 && send_cmd(CMD58, 0) == 0) { /* Check CCS bit in the OCR */ - for (n = 0; n < 4; n++) ocr[n] = rcvr_spi(); - ty = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2; - } - } - } else { /* SDSC or MMC */ - if (send_cmd(ACMD41, 0) <= 1) { - ty = CT_SD1; cmd = ACMD41; /* SDSC */ - } else { - ty = CT_MMC; cmd = CMD1; /* MMC */ - } - while (Timer1 && send_cmd(cmd, 0)); /* Wait for leaving idle state */ - if (!Timer1 || send_cmd(CMD16, 512) != 0) /* Set R/W block length to 512 */ - ty = 0; - } - } - CardType = ty; - release_spi(); + } + } + CardType = ty; + release_spi(); - if (ty) { /* Initialization succeeded */ - Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ - interface_speed(INTERFACE_FAST); - } else { /* Initialization failed */ - power_off(); - } + if (ty) { /* Initialization succeeded */ + Stat &= ~STA_NOINIT; /* Clear STA_NOINIT */ + interface_speed(INTERFACE_FAST); + } else { /* Initialization failed */ + power_off(); + } - return Stat; + IO_MUTEX_LEAVE(); + + return Stat; } @@ -686,8 +705,8 @@ DSTATUS disk_status ( BYTE drv /* Physical drive number (0) */ ) { - if (drv) return STA_NOINIT; /* Supports only single drive */ - return Stat; + if (drv) return STA_NOINIT; /* Supports only single drive */ + return Stat; } @@ -695,11 +714,12 @@ DSTATUS disk_status ( /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ -// TODO quick & dirty int8_t SD_ReadSectors(uint8_t *buff, uint32_t sector, uint32_t count) { if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + IO_MUTEX_ENTER(); + if (count == 1) { /* Single block read */ if (send_cmd(CMD17, sector) == 0) { /* READ_SINGLE_BLOCK */ if (rcvr_datablock(buff, 512)) { @@ -724,8 +744,10 @@ int8_t SD_ReadSectors(uint8_t *buff, uint32_t sector, uint32_t count) spi_reset(); } } - release_spi(); + TRACE_SD_CARD_EVENT((count != 0), sd_SD_ReadSectors, (count << 24) + ((sector/((CardType & CT_BLOCK) ? 1 : 512)) & 0x00FFFFFF)); + + IO_MUTEX_LEAVE(); return count ? -1 : 0; } @@ -737,10 +759,11 @@ DRESULT disk_read ( BYTE count /* Sector count (1..255) */ ) { - if (drv || !count) return RES_PARERR; - if (Stat & STA_NOINIT) return RES_NOTRDY; - int8_t res = SD_ReadSectors(buff, sector, count); - return (res != 0) ? RES_ERROR : RES_OK; + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + int8_t res = SD_ReadSectors(buff, sector, count); + TRACE_SD_CARD_EVENT((res != 0), sd_disk_read, (count << 24) + (sector & 0x00FFFFFF)); + return (res != 0) ? RES_ERROR : RES_OK; } @@ -749,10 +772,12 @@ DRESULT disk_read ( /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ -// TODO quick & dirty int8_t SD_WriteSectors(const uint8_t *buff, uint32_t sector, uint32_t count) { if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */ + + IO_MUTEX_ENTER(); + if (count == 1) { /* Single block write */ if (send_cmd(CMD24, sector) == 0) { /* WRITE_BLOCK */ if (xmit_datablock(buff, 0xFE)) { @@ -763,7 +788,7 @@ int8_t SD_WriteSectors(const uint8_t *buff, uint32_t sector, uint32_t count) spi_reset(); } } - else { + else { /* Multiple block write */ if (CardType & CT_SDC) send_cmd(ACMD23, count); if (send_cmd(CMD25, sector) == 0) { /* WRITE_MULTIPLE_BLOCK */ do { @@ -777,8 +802,10 @@ int8_t SD_WriteSectors(const uint8_t *buff, uint32_t sector, uint32_t count) spi_reset(); } } - release_spi(); + TRACE_SD_CARD_EVENT((count != 0), sd_SD_WriteSectors, (count << 24) + ((sector/((CardType & CT_BLOCK) ? 1 : 512)) & 0x00FFFFFF)); + + IO_MUTEX_LEAVE(); return count ? -1 : 0; } @@ -792,11 +819,12 @@ DRESULT disk_write ( BYTE count /* Sector count (1..255) */ ) { - if (drv || !count) return RES_PARERR; - if (Stat & STA_NOINIT) return RES_NOTRDY; - if (Stat & STA_PROTECT) return RES_WRPRT; - int8_t res = SD_WriteSectors(buff, sector, count); - return (res != 0) ? RES_ERROR : RES_OK; + if (drv || !count) return RES_PARERR; + if (Stat & STA_NOINIT) return RES_NOTRDY; + if (Stat & STA_PROTECT) return RES_WRPRT; + int8_t res = SD_WriteSectors(buff, sector, count); + TRACE_SD_CARD_EVENT((res != 0), sd_disk_write, (count << 24) + (sector & 0x00FFFFFF)); + return (res != 0) ? RES_ERROR : RES_OK; } #endif /* _READONLY == 0 */ @@ -812,124 +840,156 @@ DRESULT disk_ioctl ( void *buff /* Buffer to send/receive control data */ ) { - DRESULT res; - BYTE n, csd[16], *ptr = (BYTE *)buff; - WORD csize; + DRESULT res; + BYTE n, csd[16], *ptr = (BYTE *)buff; + WORD csize; - if (drv) return RES_PARERR; + if (drv) return RES_PARERR; - res = RES_ERROR; + res = RES_ERROR; - if (ctrl == CTRL_POWER) { - switch (*ptr) { - case 0: /* Sub control code == 0 (POWER_OFF) */ - if (chk_power()) - power_off(); /* Power off */ - res = RES_OK; - break; - case 1: /* Sub control code == 1 (POWER_ON) */ - power_on(); /* Power on */ - res = RES_OK; - break; - case 2: /* Sub control code == 2 (POWER_GET) */ - *(ptr+1) = (BYTE)chk_power(); - res = RES_OK; - break; - default : - res = RES_PARERR; - } + IO_MUTEX_ENTER(); + + if (ctrl == CTRL_POWER) { + switch (*ptr) { + case 0: /* Sub control code == 0 (POWER_OFF) */ + if (chk_power()) + power_off(); /* Power off */ + res = RES_OK; + break; + case 1: /* Sub control code == 1 (POWER_ON) */ + power_on(); /* Power on */ + res = RES_OK; + break; + case 2: /* Sub control code == 2 (POWER_GET) */ + *(ptr+1) = (BYTE)chk_power(); + res = RES_OK; + break; + default : + res = RES_PARERR; + } + } + else { + if (Stat & STA_NOINIT) { + IO_MUTEX_LEAVE(); + return RES_NOTRDY; + } + + switch (ctrl) { + case CTRL_SYNC : /* Make sure that no pending write process */ + SELECT(); + if (wait_ready() == 0xFF) { + res = RES_OK; + } + else { + TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_CTRL_SYNC, 0); + } + break; + + case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ + if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { + if ((csd[0] >> 6) == 1) { /* SDC version 2.00 */ + csize = csd[9] + ((WORD)csd[8] << 8) + 1; + *(DWORD*)buff = (DWORD)csize << 10; + } else { /* SDC version 1.XX or MMC*/ + n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; + csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; + *(DWORD*)buff = (DWORD)csize << (n - 9); + } + res = RES_OK; + } + else { + TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_GET_SECTOR_COUNT, 0); + } + break; + + case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ + *(WORD*)buff = 512; + res = RES_OK; + break; + + case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ + if (CardType & CT_SD2) { /* SDC version 2.00 */ + if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */ + rcvr_spi(); + if (rcvr_datablock(csd, 16)) { /* Read partial block */ + for (n = 64 - 16; n; n--) rcvr_spi(); /* Purge trailing data */ + *(DWORD*)buff = 16UL << (csd[10] >> 4); + res = RES_OK; + } + } + } else { /* SDC version 1.XX or MMC */ + if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */ + if (CardType & CT_SD1) { /* SDC version 1.XX */ + *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); + } else { /* MMC */ + *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); + } + res = RES_OK; + } + } + break; + + case MMC_GET_TYPE : /* Get card type flags (1 byte) */ + *ptr = CardType; + res = RES_OK; + break; + + case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */ + if (send_cmd(CMD9, 0) == 0 /* READ_CSD */ + && rcvr_datablock(ptr, 16)) { + res = RES_OK; + } + else { + TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_CSD, 0); + } + break; + + case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */ + if (send_cmd(CMD10, 0) == 0 /* READ_CID */ + && rcvr_datablock(ptr, 16)) { + res = RES_OK; + } + else { + TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_CID, 0); + } + break; + + case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */ + if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */ + for (n = 4; n; n--) *ptr++ = rcvr_spi(); + res = RES_OK; + } + else { + TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_OCR, 0); + } + break; + + case MMC_GET_SDSTAT : /* Receive SD status as a data block (64 bytes) */ + if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ + rcvr_spi(); + if (rcvr_datablock(ptr, 64)) { + res = RES_OK; } else { - if (Stat & STA_NOINIT) return RES_NOTRDY; - - switch (ctrl) { - case CTRL_SYNC : /* Make sure that no pending write process */ - SELECT(); - if (wait_ready() == 0xFF) - res = RES_OK; - break; - - case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */ - if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { - if ((csd[0] >> 6) == 1) { /* SDC version 2.00 */ - csize = csd[9] + ((WORD)csd[8] << 8) + 1; - *(DWORD*)buff = (DWORD)csize << 10; - } else { /* SDC version 1.XX or MMC*/ - n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; - csize = (csd[8] >> 6) + ((WORD)csd[7] << 2) + ((WORD)(csd[6] & 3) << 10) + 1; - *(DWORD*)buff = (DWORD)csize << (n - 9); - } - res = RES_OK; - } - break; - - case GET_SECTOR_SIZE : /* Get R/W sector size (WORD) */ - *(WORD*)buff = 512; - res = RES_OK; - break; - - case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */ - if (CardType & CT_SD2) { /* SDC version 2.00 */ - if (send_cmd(ACMD13, 0) == 0) { /* Read SD status */ - rcvr_spi(); - if (rcvr_datablock(csd, 16)) { /* Read partial block */ - for (n = 64 - 16; n; n--) rcvr_spi(); /* Purge trailing data */ - *(DWORD*)buff = 16UL << (csd[10] >> 4); - res = RES_OK; - } - } - } else { /* SDC version 1.XX or MMC */ - if ((send_cmd(CMD9, 0) == 0) && rcvr_datablock(csd, 16)) { /* Read CSD */ - if (CardType & CT_SD1) { /* SDC version 1.XX */ - *(DWORD*)buff = (((csd[10] & 63) << 1) + ((WORD)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1); - } else { /* MMC */ - *(DWORD*)buff = ((WORD)((csd[10] & 124) >> 2) + 1) * (((csd[11] & 3) << 3) + ((csd[11] & 224) >> 5) + 1); - } - res = RES_OK; - } - } - break; - - case MMC_GET_TYPE : /* Get card type flags (1 byte) */ - *ptr = CardType; - res = RES_OK; - break; - - case MMC_GET_CSD : /* Receive CSD as a data block (16 bytes) */ - if (send_cmd(CMD9, 0) == 0 /* READ_CSD */ - && rcvr_datablock(ptr, 16)) - res = RES_OK; - break; - - case MMC_GET_CID : /* Receive CID as a data block (16 bytes) */ - if (send_cmd(CMD10, 0) == 0 /* READ_CID */ - && rcvr_datablock(ptr, 16)) - res = RES_OK; - break; - - case MMC_GET_OCR : /* Receive OCR as an R3 resp (4 bytes) */ - if (send_cmd(CMD58, 0) == 0) { /* READ_OCR */ - for (n = 4; n; n--) *ptr++ = rcvr_spi(); - res = RES_OK; - } - break; - - case MMC_GET_SDSTAT : /* Receive SD status as a data block (64 bytes) */ - if (send_cmd(ACMD13, 0) == 0) { /* SD_STATUS */ - rcvr_spi(); - if (rcvr_datablock(ptr, 64)) - res = RES_OK; - } - break; - - default: - res = RES_PARERR; - } - - release_spi(); + TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_SDSTAT_1, 0); } + } + else { + TRACE_SD_CARD_EVENT(1, sd_disk_ioctl_MMC_GET_SDSTAT_2, 0); + } + break; - return res; + default: + res = RES_PARERR; + } + + release_spi(); + } + + IO_MUTEX_LEAVE(); + + return res; } @@ -940,34 +1000,34 @@ DRESULT disk_ioctl ( void sdPoll10ms() { - static DWORD pv; - DWORD ns; - BYTE n, s; + static DWORD pv; + DWORD ns; + BYTE n, s; - n = Timer1; /* 100Hz decrement timers */ - if (n) Timer1 = --n; - n = Timer2; - if (n) Timer2 = --n; + n = Timer1; /* 100Hz decrement timers */ + if (n) Timer1 = --n; + n = Timer2; + if (n) Timer2 = --n; - ns = pv; - pv = socket_is_empty() | socket_is_write_protected(); /* Sample socket switch */ + ns = pv; + pv = socket_is_empty() | socket_is_write_protected(); /* Sample socket switch */ - if (ns == pv) { /* Have contacts stabled? */ - s = Stat; + if (ns == pv) { /* Have contacts stabled? */ + s = Stat; - if (pv & socket_state_mask_wp) /* WP is H (write protected) */ - s |= STA_PROTECT; - else /* WP is L (write enabled) */ - s &= ~STA_PROTECT; + if (pv & socket_state_mask_wp) /* WP is H (write protected) */ + s |= STA_PROTECT; + else /* WP is L (write enabled) */ + s &= ~STA_PROTECT; - if (pv & socket_state_mask_cp) /* INS = H (Socket empty) */ - s |= (STA_NODISK | STA_NOINIT); - else /* INS = L (Card inserted) */ - s &= ~STA_NODISK; + if (pv & socket_state_mask_cp) /* INS = H (Socket empty) */ + s |= (STA_NODISK | STA_NOINIT); + else /* INS = L (Card inserted) */ + s &= ~STA_NODISK; - Stat = s; - } + Stat = s; + } } // TODO everything here should not be in the driver layer ... @@ -988,6 +1048,12 @@ void sdInit(void) // TODO shouldn't be there! void sdInit(void) { + ioMutex = CoCreateMutex(); + if (ioMutex >= CFG_MAX_MUTEX ) { + //sd error + return; + } + if (f_mount(0, &g_FATFS_Obj) == FR_OK) { referenceSystemAudioFiles(); diff --git a/radio/src/telemetry/frsky.cpp b/radio/src/telemetry/frsky.cpp index 340548b45..2d8c198e4 100644 --- a/radio/src/telemetry/frsky.cpp +++ b/radio/src/telemetry/frsky.cpp @@ -286,7 +286,7 @@ void telemetryWakeup() #if defined(PCBTARANIS) uint8_t data; -#if defined(DEBUG) && !defined(SIMU) +#if defined(SPORT_FILE_LOG) && !defined(SIMU) static tmr10ms_t lastTime = 0; tmr10ms_t newTime = get_tmr10ms(); struct gtm utm;