Merge pull request #5045 from blckmn/sdcard_config

Configurable SDCARD and DMA cleanup
This commit is contained in:
Michael Keller 2018-01-29 14:11:55 +13:00 committed by GitHub
commit e5e6fcb60a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
54 changed files with 504 additions and 436 deletions

View File

@ -365,7 +365,7 @@ endif
SRC += $(COMMON_SRC) SRC += $(COMMON_SRC)
#excludes #excludes
SRC := $(filter-out ${MCU_EXCLUDES}, $(SRC)) SRC := $(filter-out $(MCU_EXCLUDES), $(SRC))
ifneq ($(filter SDCARD,$(FEATURES)),) ifneq ($(filter SDCARD,$(FEATURES)),)
SRC += \ SRC += \

View File

@ -27,20 +27,20 @@
/* /*
* DMA descriptors. * DMA descriptors.
*/ */
static dmaChannelDescriptor_t dmaDescriptors[] = { static dmaChannelDescriptor_t dmaDescriptors[DMA_LAST_HANDLER] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel1, 0, DMA1_Channel1_IRQn, RCC_AHBPeriph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 1, 0),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel2, 4, DMA1_Channel2_IRQn, RCC_AHBPeriph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 2, 4),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel3, 8, DMA1_Channel3_IRQn, RCC_AHBPeriph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 3, 8),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel4, 12, DMA1_Channel4_IRQn, RCC_AHBPeriph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 4, 12),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel5, 16, DMA1_Channel5_IRQn, RCC_AHBPeriph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 5, 16),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel6, 20, DMA1_Channel6_IRQn, RCC_AHBPeriph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 6, 20),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel7, 24, DMA1_Channel7_IRQn, RCC_AHBPeriph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 7, 24),
#if defined(STM32F3) || defined(STM32F10X_CL) #if defined(STM32F3) || defined(STM32F10X_CL)
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel1, 0, DMA2_Channel1_IRQn, RCC_AHBPeriph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 1, 0),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel2, 4, DMA2_Channel2_IRQn, RCC_AHBPeriph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 2, 4),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel3, 8, DMA2_Channel3_IRQn, RCC_AHBPeriph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 3, 8),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel4, 12, DMA2_Channel4_IRQn, RCC_AHBPeriph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 4, 12),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel5, 16, DMA2_Channel5_IRQn, RCC_AHBPeriph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 5, 16),
#endif #endif
}; };
@ -63,23 +63,47 @@ DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_CH4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_CH5_HANDLER) DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_CH5_HANDLER)
#endif #endif
#define RETURN_TCIF_FLAG(s, d, n) if (s == DMA ## d ## _Channel ## n) return DMA ## d ## _FLAG_TC ## n
uint32_t dmaFlag_IT_TCIF(const DMA_Channel_TypeDef *channel)
{
RETURN_TCIF_FLAG(channel, 1, 1);
RETURN_TCIF_FLAG(channel, 1, 2);
RETURN_TCIF_FLAG(channel, 1, 3);
RETURN_TCIF_FLAG(channel, 1, 4);
RETURN_TCIF_FLAG(channel, 1, 5);
RETURN_TCIF_FLAG(channel, 1, 6);
RETURN_TCIF_FLAG(channel, 1, 7);
RETURN_TCIF_FLAG(channel, 2, 1);
RETURN_TCIF_FLAG(channel, 2, 2);
RETURN_TCIF_FLAG(channel, 2, 3);
RETURN_TCIF_FLAG(channel, 2, 4);
RETURN_TCIF_FLAG(channel, 2, 5);
return 0;
}
#define DMA_RCC(x) ((x) == DMA1 ? RCC_AHBPeriph_DMA1 : RCC_AHBPeriph_DMA2)
void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resourceIndex) void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resourceIndex)
{ {
RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE); const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
dmaDescriptors[identifier].owner = owner;
dmaDescriptors[identifier].resourceIndex = resourceIndex; RCC_AHBPeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE);
dmaDescriptors[index].owner = owner;
dmaDescriptors[index].resourceIndex = resourceIndex;
} }
void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam) void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
{ {
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
/* TODO: remove this - enforce the init */ /* TODO: remove this - enforce the init */
RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE); RCC_AHBPeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE);
dmaDescriptors[identifier].irqHandlerCallback = callback; dmaDescriptors[index].irqHandlerCallback = callback;
dmaDescriptors[identifier].userParam = userParam; dmaDescriptors[index].userParam = userParam;
dmaDescriptors[index].completeFlag = dmaFlag_IT_TCIF(dmaDescriptors[index].ref);
NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[identifier].irqN; NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[index].irqN;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority); NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
@ -88,20 +112,30 @@ void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callbac
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[identifier].owner; return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
} }
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[identifier].resourceIndex; return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex;
} }
dmaIdentifier_e dmaGetIdentifier(const DMA_Channel_TypeDef* channel) dmaIdentifier_e dmaGetIdentifier(const DMA_Channel_TypeDef* channel)
{ {
for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) { for (int i = 0; i < DMA_LAST_HANDLER; i++) {
if (dmaDescriptors[i].ref == channel) { if (dmaDescriptors[i].ref == channel) {
return i; return i + 1;
} }
} }
return 0; return 0;
} }
DMA_Channel_TypeDef* dmaGetRefByIdentifier(const dmaIdentifier_e identifier)
{
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].ref;
}
dmaChannelDescriptor_t* dmaGetDescriptorByIdentifier(const dmaIdentifier_e identifier)
{
return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)];
}

View File

@ -26,29 +26,32 @@ typedef struct dmaChannelDescriptor_s {
DMA_TypeDef* dma; DMA_TypeDef* dma;
#if defined(STM32F4) || defined(STM32F7) #if defined(STM32F4) || defined(STM32F7)
DMA_Stream_TypeDef* ref; DMA_Stream_TypeDef* ref;
uint8_t stream;
#else #else
DMA_Channel_TypeDef* ref; DMA_Channel_TypeDef* ref;
#endif #endif
dmaCallbackHandlerFuncPtr irqHandlerCallback; dmaCallbackHandlerFuncPtr irqHandlerCallback;
uint8_t flagsShift; uint8_t flagsShift;
IRQn_Type irqN; IRQn_Type irqN;
uint32_t rcc;
uint32_t userParam; uint32_t userParam;
resourceOwner_e owner; resourceOwner_e owner;
uint8_t resourceIndex; uint8_t resourceIndex;
uint32_t completeFlag;
} dmaChannelDescriptor_t; } dmaChannelDescriptor_t;
#if defined(STM32F7) #if defined(STM32F7)
//#define HAL_CLEANINVALIDATECACHE(addr, size) (SCB_CleanInvalidateDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)(addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f))) //#define HAL_CLEANINVALIDATECACHE(addr, size) (SCB_CleanInvalidateDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)(addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
//#define HAL_CLEANCACHE(addr, size) (SCB_CleanDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)(addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f))) //#define HAL_CLEANCACHE(addr, size) (SCB_CleanDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)(addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
#endif #endif
#define DMA_IDENTIFIER_TO_INDEX(x) ((x) - 1)
#if defined(STM32F4) || defined(STM32F7) #if defined(STM32F4) || defined(STM32F7)
uint32_t dmaFlag_IT_TCIF(const DMA_Stream_TypeDef *stream);
typedef enum { typedef enum {
DMA1_ST0_HANDLER = 0, DMA_NONE = 0,
DMA1_ST0_HANDLER = 1,
DMA1_ST1_HANDLER, DMA1_ST1_HANDLER,
DMA1_ST2_HANDLER, DMA1_ST2_HANDLER,
DMA1_ST3_HANDLER, DMA1_ST3_HANDLER,
@ -64,15 +67,27 @@ typedef enum {
DMA2_ST5_HANDLER, DMA2_ST5_HANDLER,
DMA2_ST6_HANDLER, DMA2_ST6_HANDLER,
DMA2_ST7_HANDLER, DMA2_ST7_HANDLER,
DMA_MAX_DESCRIPTORS DMA_LAST_HANDLER = DMA2_ST7_HANDLER
} dmaIdentifier_e; } dmaIdentifier_e;
#define DMA_MOD_VALUE 8 #define DMA_DEVICE_NO(x) ((((x)-1) / 8) + 1)
#define DMA_MOD_OFFSET 0 #define DMA_DEVICE_INDEX(x) ((((x)-1) % 8))
#define DMA_OUTPUT_INDEX 0 #define DMA_OUTPUT_INDEX 0
#define DMA_OUTPUT_STRING "DMA%d Stream %d:" #define DMA_OUTPUT_STRING "DMA%d Stream %d:"
#define DMA_INPUT_STRING "DMA%d_ST%d"
#define DEFINE_DMA_CHANNEL(d, s, f) { \
.dma = d, \
.ref = d ## _Stream ## s, \
.stream = s, \
.irqHandlerCallback = NULL, \
.flagsShift = f, \
.irqN = d ## _Stream ## s ## _IRQn, \
.userParam = 0, \
.owner = 0, \
.resourceIndex = 0 \
}
#define DEFINE_DMA_CHANNEL(d, s, f, i, r) {.dma = d, .ref = s, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0, .owner = 0, .resourceIndex = 0 }
#define DEFINE_DMA_IRQ_HANDLER(d, s, i) void DMA ## d ## _Stream ## s ## _IRQHandler(void) {\ #define DEFINE_DMA_IRQ_HANDLER(d, s, i) void DMA ## d ## _Stream ## s ## _IRQHandler(void) {\
if (dmaDescriptors[i].irqHandlerCallback)\ if (dmaDescriptors[i].irqHandlerCallback)\
dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\ dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\
@ -89,12 +104,15 @@ typedef enum {
#define DMA_IT_FEIF ((uint32_t)0x00000001) #define DMA_IT_FEIF ((uint32_t)0x00000001)
dmaIdentifier_e dmaGetIdentifier(const DMA_Stream_TypeDef* stream); dmaIdentifier_e dmaGetIdentifier(const DMA_Stream_TypeDef* stream);
dmaChannelDescriptor_t* getDmaDescriptor(const DMA_Stream_TypeDef* stream); dmaChannelDescriptor_t* dmaGetDmaDescriptor(const DMA_Stream_TypeDef* stream);
DMA_Stream_TypeDef* dmaGetRefByIdentifier(const dmaIdentifier_e identifier);
uint32_t dmaGetChannel(const uint8_t channel);
#else #else
typedef enum { typedef enum {
DMA1_CH1_HANDLER = 0, DMA_NONE = 0,
DMA1_CH1_HANDLER = 1,
DMA1_CH2_HANDLER, DMA1_CH2_HANDLER,
DMA1_CH3_HANDLER, DMA1_CH3_HANDLER,
DMA1_CH4_HANDLER, DMA1_CH4_HANDLER,
@ -107,16 +125,29 @@ typedef enum {
DMA2_CH3_HANDLER, DMA2_CH3_HANDLER,
DMA2_CH4_HANDLER, DMA2_CH4_HANDLER,
DMA2_CH5_HANDLER, DMA2_CH5_HANDLER,
DMA_LAST_HANDLER = DMA2_CH5_HANDLER
#else
DMA_LAST_HANDLER = DMA1_CH7_HANDLER
#endif #endif
DMA_MAX_DESCRIPTORS
} dmaIdentifier_e; } dmaIdentifier_e;
#define DMA_MOD_VALUE 7 #define DMA_DEVICE_NO(x) ((((x)-1) / 7) + 1)
#define DMA_MOD_OFFSET 1 #define DMA_DEVICE_INDEX(x) ((((x)-1) % 7) + 1)
#define DMA_OUTPUT_INDEX 0 #define DMA_OUTPUT_INDEX 0
#define DMA_OUTPUT_STRING "DMA%d Channel %d:" #define DMA_OUTPUT_STRING "DMA%d Channel %d:"
#define DMA_INPUT_STRING "DMA%d_CH%d"
#define DEFINE_DMA_CHANNEL(d, c, f) { \
.dma = d, \
.ref = d ## _Channel ## c, \
.irqHandlerCallback = NULL, \
.flagsShift = f, \
.irqN = d ## _Channel ## c ## _IRQn, \
.userParam = 0, \
.owner = 0, \
.resourceIndex = 0 \
}
#define DEFINE_DMA_CHANNEL(d, c, f, i, r) {.dma = d, .ref = c, .irqHandlerCallback = NULL, .flagsShift = f, .irqN = i, .rcc = r, .userParam = 0, .owner = 0, .resourceIndex = 0 }
#define DEFINE_DMA_IRQ_HANDLER(d, c, i) void DMA ## d ## _Channel ## c ## _IRQHandler(void) {\ #define DEFINE_DMA_IRQ_HANDLER(d, c, i) void DMA ## d ## _Channel ## c ## _IRQHandler(void) {\
if (dmaDescriptors[i].irqHandlerCallback)\ if (dmaDescriptors[i].irqHandlerCallback)\
dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\ dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\
@ -130,6 +161,7 @@ typedef enum {
#define DMA_IT_TEIF ((uint32_t)0x00000008) #define DMA_IT_TEIF ((uint32_t)0x00000008)
dmaIdentifier_e dmaGetIdentifier(const DMA_Channel_TypeDef* channel); dmaIdentifier_e dmaGetIdentifier(const DMA_Channel_TypeDef* channel);
DMA_Channel_TypeDef* dmaGetRefByIdentifier(const dmaIdentifier_e identifier);
#endif #endif
@ -138,3 +170,4 @@ void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callbac
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier); resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier);
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier); uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier);
dmaChannelDescriptor_t* dmaGetDescriptorByIdentifier(const dmaIdentifier_e identifier);

View File

@ -28,24 +28,24 @@
/* /*
* DMA descriptors. * DMA descriptors.
*/ */
static dmaChannelDescriptor_t dmaDescriptors[DMA_MAX_DESCRIPTORS] = { static dmaChannelDescriptor_t dmaDescriptors[DMA_LAST_HANDLER] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream0, 0, DMA1_Stream0_IRQn, RCC_AHB1Periph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 0, 0),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream1, 6, DMA1_Stream1_IRQn, RCC_AHB1Periph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 1, 6),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream2, 16, DMA1_Stream2_IRQn, RCC_AHB1Periph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 2, 16),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream3, 22, DMA1_Stream3_IRQn, RCC_AHB1Periph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 3, 22),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream4, 32, DMA1_Stream4_IRQn, RCC_AHB1Periph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 4, 32),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream5, 38, DMA1_Stream5_IRQn, RCC_AHB1Periph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 5, 38),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream6, 48, DMA1_Stream6_IRQn, RCC_AHB1Periph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 6, 48),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream7, 54, DMA1_Stream7_IRQn, RCC_AHB1Periph_DMA1), DEFINE_DMA_CHANNEL(DMA1, 7, 54),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream0, 0, DMA2_Stream0_IRQn, RCC_AHB1Periph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 0, 0),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream1, 6, DMA2_Stream1_IRQn, RCC_AHB1Periph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 1, 6),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream2, 16, DMA2_Stream2_IRQn, RCC_AHB1Periph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 2, 16),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream3, 22, DMA2_Stream3_IRQn, RCC_AHB1Periph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 3, 22),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream4, 32, DMA2_Stream4_IRQn, RCC_AHB1Periph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 4, 32),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream5, 38, DMA2_Stream5_IRQn, RCC_AHB1Periph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 5, 38),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream6, 48, DMA2_Stream6_IRQn, RCC_AHB1Periph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 6, 48),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream7, 54, DMA2_Stream7_IRQn, RCC_AHB1Periph_DMA2), DEFINE_DMA_CHANNEL(DMA2, 7, 54),
}; };
/* /*
@ -68,26 +68,13 @@ DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_ST5_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 6, DMA2_ST6_HANDLER) DEFINE_DMA_IRQ_HANDLER(2, 6, DMA2_ST6_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 7, DMA2_ST7_HANDLER) DEFINE_DMA_IRQ_HANDLER(2, 7, DMA2_ST7_HANDLER)
#define DMA_RCC(x) ((x) == DMA1 ? RCC_AHB1Periph_DMA1 : RCC_AHB1Periph_DMA2)
void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resourceIndex) void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resourceIndex)
{ {
RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE); const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
dmaDescriptors[identifier].owner = owner; RCC_AHB1PeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE);
dmaDescriptors[identifier].resourceIndex = resourceIndex; dmaDescriptors[index].owner = owner;
} dmaDescriptors[index].resourceIndex = resourceIndex;
void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
{
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE);
dmaDescriptors[identifier].irqHandlerCallback = callback;
dmaDescriptors[identifier].userParam = userParam;
NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[identifier].irqN;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
} }
#define RETURN_TCIF_FLAG(s, n) if (s == DMA1_Stream ## n || s == DMA2_Stream ## n) return DMA_IT_TCIF ## n #define RETURN_TCIF_FLAG(s, n) if (s == DMA1_Stream ## n || s == DMA2_Stream ## n) return DMA_IT_TCIF ## n
@ -105,32 +92,65 @@ uint32_t dmaFlag_IT_TCIF(const DMA_Stream_TypeDef *stream)
return 0; return 0;
} }
void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
{
NVIC_InitTypeDef NVIC_InitStructure;
const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
RCC_AHB1PeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE);
dmaDescriptors[index].irqHandlerCallback = callback;
dmaDescriptors[index].userParam = userParam;
dmaDescriptors[index].completeFlag = dmaFlag_IT_TCIF(dmaDescriptors[index].ref);
NVIC_InitStructure.NVIC_IRQChannel = dmaDescriptors[index].irqN;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = NVIC_PRIORITY_BASE(priority);
NVIC_InitStructure.NVIC_IRQChannelSubPriority = NVIC_PRIORITY_SUB(priority);
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[identifier].owner; return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
} }
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[identifier].resourceIndex; return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex;
} }
dmaIdentifier_e dmaGetIdentifier(const DMA_Stream_TypeDef* stream) dmaIdentifier_e dmaGetIdentifier(const DMA_Stream_TypeDef* stream)
{ {
for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) { for (int i = 0; i < DMA_LAST_HANDLER; i++) {
if (dmaDescriptors[i].ref == stream) { if (dmaDescriptors[i].ref == stream) {
return i; return i + 1;
} }
} }
return 0; return 0;
} }
dmaChannelDescriptor_t* getDmaDescriptor(const DMA_Stream_TypeDef* stream) dmaChannelDescriptor_t* dmaGetDescriptor(const DMA_Stream_TypeDef* stream)
{ {
for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) { for (int i = 0; i < DMA_LAST_HANDLER; i++) {
if (dmaDescriptors[i].ref == stream) { if (dmaDescriptors[i].ref == stream) {
return &dmaDescriptors[i]; return &dmaDescriptors[i];
} }
} }
return NULL; return NULL;
} }
DMA_Stream_TypeDef* dmaGetRefByIdentifier(const dmaIdentifier_e identifier)
{
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].ref;
}
dmaChannelDescriptor_t* dmaGetDescriptorByIdentifier(const dmaIdentifier_e identifier)
{
return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)];
}
uint32_t dmaGetChannel(const uint8_t channel)
{
return ((uint32_t)channel*2)<<24;
}

View File

@ -28,24 +28,24 @@
/* /*
* DMA descriptors. * DMA descriptors.
*/ */
static dmaChannelDescriptor_t dmaDescriptors[DMA_MAX_DESCRIPTORS] = { static dmaChannelDescriptor_t dmaDescriptors[DMA_LAST_HANDLER] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream0, 0, DMA1_Stream0_IRQn, RCC_AHB1ENR_DMA1EN), DEFINE_DMA_CHANNEL(DMA1, 0, 0),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream1, 6, DMA1_Stream1_IRQn, RCC_AHB1ENR_DMA1EN), DEFINE_DMA_CHANNEL(DMA1, 1, 6),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream2, 16, DMA1_Stream2_IRQn, RCC_AHB1ENR_DMA1EN), DEFINE_DMA_CHANNEL(DMA1, 2, 16),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream3, 22, DMA1_Stream3_IRQn, RCC_AHB1ENR_DMA1EN), DEFINE_DMA_CHANNEL(DMA1, 3, 22),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream4, 32, DMA1_Stream4_IRQn, RCC_AHB1ENR_DMA1EN), DEFINE_DMA_CHANNEL(DMA1, 4, 32),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream5, 38, DMA1_Stream5_IRQn, RCC_AHB1ENR_DMA1EN), DEFINE_DMA_CHANNEL(DMA1, 5, 38),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream6, 48, DMA1_Stream6_IRQn, RCC_AHB1ENR_DMA1EN), DEFINE_DMA_CHANNEL(DMA1, 6, 48),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream7, 54, DMA1_Stream7_IRQn, RCC_AHB1ENR_DMA1EN), DEFINE_DMA_CHANNEL(DMA1, 7, 54),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream0, 0, DMA2_Stream0_IRQn, RCC_AHB1ENR_DMA2EN), DEFINE_DMA_CHANNEL(DMA2, 0, 0),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream1, 6, DMA2_Stream1_IRQn, RCC_AHB1ENR_DMA2EN), DEFINE_DMA_CHANNEL(DMA2, 1, 6),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream2, 16, DMA2_Stream2_IRQn, RCC_AHB1ENR_DMA2EN), DEFINE_DMA_CHANNEL(DMA2, 2, 16),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream3, 22, DMA2_Stream3_IRQn, RCC_AHB1ENR_DMA2EN), DEFINE_DMA_CHANNEL(DMA2, 3, 22),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream4, 32, DMA2_Stream4_IRQn, RCC_AHB1ENR_DMA2EN), DEFINE_DMA_CHANNEL(DMA2, 4, 32),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream5, 38, DMA2_Stream5_IRQn, RCC_AHB1ENR_DMA2EN), DEFINE_DMA_CHANNEL(DMA2, 5, 38),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream6, 48, DMA2_Stream6_IRQn, RCC_AHB1ENR_DMA2EN), DEFINE_DMA_CHANNEL(DMA2, 6, 48),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream7, 54, DMA2_Stream7_IRQn, RCC_AHB1ENR_DMA2EN), DEFINE_DMA_CHANNEL(DMA2, 7, 54),
}; };
@ -69,8 +69,9 @@ DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_ST5_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 6, DMA2_ST6_HANDLER) DEFINE_DMA_IRQ_HANDLER(2, 6, DMA2_ST6_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 7, DMA2_ST7_HANDLER) DEFINE_DMA_IRQ_HANDLER(2, 7, DMA2_ST7_HANDLER)
static void enableDmaClock(uint32_t rcc) static void enableDmaClock(int index)
{ {
const uint32_t rcc = dmaDescriptors[index].dma == DMA1 ? RCC_AHB1ENR_DMA1EN : RCC_AHB1ENR_DMA2EN;
do { do {
__IO uint32_t tmpreg; __IO uint32_t tmpreg;
SET_BIT(RCC->AHB1ENR, rcc); SET_BIT(RCC->AHB1ENR, rcc);
@ -82,37 +83,56 @@ static void enableDmaClock(uint32_t rcc)
void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resourceIndex) void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resourceIndex)
{ {
enableDmaClock(dmaDescriptors[identifier].rcc); const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
dmaDescriptors[identifier].owner = owner;
dmaDescriptors[identifier].resourceIndex = resourceIndex; enableDmaClock(index);
dmaDescriptors[index].owner = owner;
dmaDescriptors[index].resourceIndex = resourceIndex;
} }
void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam) void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
{ {
enableDmaClock(dmaDescriptors[identifier].rcc); const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
dmaDescriptors[identifier].irqHandlerCallback = callback;
dmaDescriptors[identifier].userParam = userParam;
HAL_NVIC_SetPriority(dmaDescriptors[identifier].irqN, NVIC_PRIORITY_BASE(priority), NVIC_PRIORITY_SUB(priority)); enableDmaClock(index);
HAL_NVIC_EnableIRQ(dmaDescriptors[identifier].irqN); dmaDescriptors[index].irqHandlerCallback = callback;
dmaDescriptors[index].userParam = userParam;
HAL_NVIC_SetPriority(dmaDescriptors[index].irqN, NVIC_PRIORITY_BASE(priority), NVIC_PRIORITY_SUB(priority));
HAL_NVIC_EnableIRQ(dmaDescriptors[index].irqN);
} }
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[identifier].owner; return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
} }
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[identifier].resourceIndex; return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex;
} }
dmaIdentifier_e dmaGetIdentifier(const DMA_Stream_TypeDef* stream) dmaIdentifier_e dmaGetIdentifier(const DMA_Stream_TypeDef* stream)
{ {
for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) { for (int i = 0; i < DMA_LAST_HANDLER; i++) {
if (dmaDescriptors[i].ref == stream) { if (dmaDescriptors[i].ref == stream) {
return i; return i + 1;
} }
} }
return 0; return 0;
} }
DMA_Stream_TypeDef* dmaGetRefByIdentifier(const dmaIdentifier_e identifier)
{
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].ref;
}
dmaChannelDescriptor_t* dmaGetDescriptorByIdentifier(const dmaIdentifier_e identifier)
{
return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)];
}
uint32_t dmaGetChannel(const uint8_t channel)
{
return ((uint32_t)channel*2)<<24;
}

View File

@ -36,21 +36,21 @@
#define SDCARD_PROFILING #define SDCARD_PROFILING
#endif #endif
#define SET_CS_HIGH IOHi(sdCardCsPin) #define SET_CS_HIGH IOHi(sdcard.chipSelectPin)
#define SET_CS_LOW IOLo(sdCardCsPin) #define SET_CS_LOW IOLo(sdcard.chipSelectPin)
#define SDCARD_INIT_NUM_DUMMY_BYTES 10 #define SDCARD_INIT_NUM_DUMMY_BYTES 10
#define SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY 8 #define SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY 8
// Chosen so that CMD8 will have the same CRC as CMD0: // Chosen so that CMD8 will have the same CRC as CMD0:
#define SDCARD_IF_COND_CHECK_PATTERN 0xAB #define SDCARD_IF_COND_CHECK_PATTERN 0xAB
#define SDCARD_TIMEOUT_INIT_MILLIS 200 #define SDCARD_TIMEOUT_INIT_MILLIS 200
#define SDCARD_MAX_CONSECUTIVE_FAILURES 8 #define SDCARD_MAX_CONSECUTIVE_FAILURES 8
/* Break up 512-byte SD card sectors into chunks of this size when writing without DMA to reduce the peak overhead /* Break up 512-byte SD card sectors into chunks of this size when writing without DMA to reduce the peak overhead
* per call to sdcard_poll(). * per call to sdcard_poll().
*/ */
#define SDCARD_NON_DMA_CHUNK_SIZE 256 #define SDCARD_NON_DMA_CHUNK_SIZE 256
typedef enum { typedef enum {
// In these states we run at the initialization 400kHz clockspeed: // In these states we run at the initialization 400kHz clockspeed:
@ -100,41 +100,34 @@ typedef struct sdcard_t {
#ifdef SDCARD_PROFILING #ifdef SDCARD_PROFILING
sdcard_profilerCallback_c profiler; sdcard_profilerCallback_c profiler;
#endif #endif
SPI_TypeDef *instance;
bool enabled;
bool detectionInverted;
bool useDMAForTx;
IO_t cardDetectPin;
IO_t chipSelectPin;
dmaChannelDescriptor_t * dma;
uint8_t dmaChannel;
} sdcard_t; } sdcard_t;
static sdcard_t sdcard; static sdcard_t sdcard;
#if defined(SDCARD_DMA_CHANNEL_TX) || defined(SDCARD_DMA_TX)
static bool useDMAForTx;
#else
// DMA channel not available so we can hard-code this to allow the non-DMA paths to be stripped by optimization
static const bool useDMAForTx = false;
#endif
STATIC_ASSERT(sizeof(sdcardCSD_t) == 16, sdcard_csd_bitfields_didnt_pack_properly); STATIC_ASSERT(sizeof(sdcardCSD_t) == 16, sdcard_csd_bitfields_didnt_pack_properly);
#ifdef SDCARD_DETECT_PIN
static IO_t sdCardDetectPin = IO_NONE;
#endif
static IO_t sdCardCsPin = IO_NONE;
void sdcardInsertionDetectDeinit(void) void sdcardInsertionDetectDeinit(void)
{ {
#ifdef SDCARD_DETECT_PIN if (sdcard.cardDetectPin) {
sdCardDetectPin = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN)); IOInit(sdcard.cardDetectPin, OWNER_FREE, 0);
IOInit(sdCardDetectPin, OWNER_FREE, 0); IOConfigGPIO(sdcard.cardDetectPin, IOCFG_IN_FLOATING);
IOConfigGPIO(sdCardDetectPin, IOCFG_IN_FLOATING); }
#endif
} }
void sdcardInsertionDetectInit(void) void sdcardInsertionDetectInit(void)
{ {
#ifdef SDCARD_DETECT_PIN if (sdcard.cardDetectPin) {
sdCardDetectPin = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN)); IOInit(sdcard.cardDetectPin, OWNER_SDCARD_DETECT, 0);
IOInit(sdCardDetectPin, OWNER_SDCARD_DETECT, 0); IOConfigGPIO(sdcard.cardDetectPin, IOCFG_IPU);
IOConfigGPIO(sdCardDetectPin, IOCFG_IPU); }
#endif
} }
/** /**
@ -143,17 +136,12 @@ void sdcardInsertionDetectInit(void)
bool sdcard_isInserted(void) bool sdcard_isInserted(void)
{ {
bool result = true; bool result = true;
if (sdcard.cardDetectPin) {
#ifdef SDCARD_DETECT_PIN result = IORead(sdcard.cardDetectPin) != 0;
if (sdcard.detectionInverted) {
result = IORead(sdCardDetectPin) != 0; result = !result;
}
#ifdef SDCARD_DETECT_INVERTED }
result = !result;
#endif
#endif
return result; return result;
} }
@ -174,9 +162,9 @@ static void sdcard_select(void)
static void sdcard_deselect(void) static void sdcard_deselect(void)
{ {
// As per the SD-card spec, give the card 8 dummy clocks so it can finish its operation // As per the SD-card spec, give the card 8 dummy clocks so it can finish its operation
//spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF); //spiTransferByte(sdcard.instance, 0xFF);
while (spiIsBusBusy(SDCARD_SPI_INSTANCE)) { while (spiIsBusBusy(sdcard.instance)) {
} }
SET_CS_HIGH; SET_CS_HIGH;
@ -196,7 +184,7 @@ static void sdcard_reset(void)
} }
if (sdcard.state >= SDCARD_STATE_READY) { if (sdcard.state >= SDCARD_STATE_READY) {
spiSetDivisor(SDCARD_SPI_INSTANCE, SDCARD_SPI_INITIALIZATION_CLOCK_DIVIDER); spiSetDivisor(sdcard.instance, SDCARD_SPI_INITIALIZATION_CLOCK_DIVIDER);
} }
sdcard.failureCount++; sdcard.failureCount++;
@ -216,7 +204,7 @@ static void sdcard_reset(void)
static bool sdcard_waitForIdle(int maxBytesToWait) static bool sdcard_waitForIdle(int maxBytesToWait)
{ {
while (maxBytesToWait > 0) { while (maxBytesToWait > 0) {
uint8_t b = spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF); uint8_t b = spiTransferByte(sdcard.instance, 0xFF);
if (b == 0xFF) { if (b == 0xFF) {
return true; return true;
} }
@ -234,7 +222,7 @@ static bool sdcard_waitForIdle(int maxBytesToWait)
static uint8_t sdcard_waitForNonIdleByte(int maxDelay) static uint8_t sdcard_waitForNonIdleByte(int maxDelay)
{ {
for (int i = 0; i < maxDelay + 1; i++) { // + 1 so we can wait for maxDelay '0xFF' bytes before reading a response byte afterwards for (int i = 0; i < maxDelay + 1; i++) { // + 1 so we can wait for maxDelay '0xFF' bytes before reading a response byte afterwards
uint8_t response = spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF); uint8_t response = spiTransferByte(sdcard.instance, 0xFF);
if (response != 0xFF) { if (response != 0xFF) {
return response; return response;
@ -269,7 +257,7 @@ static uint8_t sdcard_sendCommand(uint8_t commandCode, uint32_t commandArgument)
if (!sdcard_waitForIdle(SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY) && commandCode != SDCARD_COMMAND_GO_IDLE_STATE) if (!sdcard_waitForIdle(SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY) && commandCode != SDCARD_COMMAND_GO_IDLE_STATE)
return 0xFF; return 0xFF;
spiTransfer(SDCARD_SPI_INSTANCE, command, NULL, sizeof(command)); spiTransfer(sdcard.instance, command, NULL, sizeof(command));
/* /*
* The card can take up to SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY bytes to send the response, in the meantime * The card can take up to SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY bytes to send the response, in the meantime
@ -305,7 +293,7 @@ static bool sdcard_validateInterfaceCondition(void)
// V1 cards don't support this command // V1 cards don't support this command
sdcard.version = 1; sdcard.version = 1;
} else if (status == SDCARD_R1_STATUS_BIT_IDLE) { } else if (status == SDCARD_R1_STATUS_BIT_IDLE) {
spiTransfer(SDCARD_SPI_INSTANCE, NULL, ifCondReply, sizeof(ifCondReply)); spiTransfer(sdcard.instance, NULL, ifCondReply, sizeof(ifCondReply));
/* /*
* We don't bother to validate the SDCard's operating voltage range since the spec requires it to accept our * We don't bother to validate the SDCard's operating voltage range since the spec requires it to accept our
@ -329,7 +317,7 @@ static bool sdcard_readOCRRegister(uint32_t *result)
uint8_t response[4]; uint8_t response[4];
spiTransfer(SDCARD_SPI_INSTANCE, NULL, response, sizeof(response)); spiTransfer(sdcard.instance, NULL, response, sizeof(response));
if (status == 0) { if (status == 0) {
sdcard_deselect(); sdcard_deselect();
@ -367,11 +355,11 @@ static sdcardReceiveBlockStatus_e sdcard_receiveDataBlock(uint8_t *buffer, int c
return SDCARD_RECEIVE_ERROR; return SDCARD_RECEIVE_ERROR;
} }
spiTransfer(SDCARD_SPI_INSTANCE, NULL, buffer, count); spiTransfer(sdcard.instance, NULL, buffer, count);
// Discard trailing CRC, we don't care // Discard trailing CRC, we don't care
spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF); spiTransferByte(sdcard.instance, 0xFF);
spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF); spiTransferByte(sdcard.instance, 0xFF);
return SDCARD_RECEIVE_SUCCESS; return SDCARD_RECEIVE_SUCCESS;
} }
@ -379,10 +367,10 @@ static sdcardReceiveBlockStatus_e sdcard_receiveDataBlock(uint8_t *buffer, int c
static bool sdcard_sendDataBlockFinish(void) static bool sdcard_sendDataBlockFinish(void)
{ {
// Send a dummy CRC // Send a dummy CRC
spiTransferByte(SDCARD_SPI_INSTANCE, 0x00); spiTransferByte(sdcard.instance, 0x00);
spiTransferByte(SDCARD_SPI_INSTANCE, 0x00); spiTransferByte(sdcard.instance, 0x00);
uint8_t dataResponseToken = spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF); uint8_t dataResponseToken = spiTransferByte(sdcard.instance, 0xFF);
/* /*
* Check if the card accepted the write (no CRC error / no address error) * Check if the card accepted the write (no CRC error / no address error)
@ -405,25 +393,21 @@ static bool sdcard_sendDataBlockFinish(void)
static void sdcard_sendDataBlockBegin(const uint8_t *buffer, bool multiBlockWrite) static void sdcard_sendDataBlockBegin(const uint8_t *buffer, bool multiBlockWrite)
{ {
// Card wants 8 dummy clock cycles between the write command's response and a data block beginning: // Card wants 8 dummy clock cycles between the write command's response and a data block beginning:
spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF); spiTransferByte(sdcard.instance, 0xFF);
spiTransferByte(SDCARD_SPI_INSTANCE, multiBlockWrite ? SDCARD_MULTIPLE_BLOCK_WRITE_START_TOKEN : SDCARD_SINGLE_BLOCK_WRITE_START_TOKEN); spiTransferByte(sdcard.instance, multiBlockWrite ? SDCARD_MULTIPLE_BLOCK_WRITE_START_TOKEN : SDCARD_SINGLE_BLOCK_WRITE_START_TOKEN);
if (useDMAForTx) { if (sdcard.useDMAForTx) {
#if defined(SDCARD_DMA_TX) && defined(USE_HAL_DRIVER) #if defined(USE_HAL_DRIVER)
#ifdef SDCARD_DMA_CLK
// LL_AHB1_GRP1_EnableClock(SDCARD_DMA_CLK); // XXX Should not be necessary; dmaInit handles it.
#endif
LL_DMA_InitTypeDef init; LL_DMA_InitTypeDef init;
LL_DMA_StructInit(&init); LL_DMA_StructInit(&init);
init.Channel = SDCARD_DMA_CHANNEL; init.Channel = dmaGetChannel(sdcard.dmaChannel);
init.Mode = LL_DMA_MODE_NORMAL; init.Mode = LL_DMA_MODE_NORMAL;
init.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; init.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
init.PeriphOrM2MSrcAddress = (uint32_t)&SDCARD_SPI_INSTANCE->DR; init.PeriphOrM2MSrcAddress = (uint32_t)&sdcard.instance->DR;
init.Priority = LL_DMA_PRIORITY_LOW; init.Priority = LL_DMA_PRIORITY_LOW;
init.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; init.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
init.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE; init.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
@ -434,24 +418,20 @@ static void sdcard_sendDataBlockBegin(const uint8_t *buffer, bool multiBlockWrit
init.NbData = SDCARD_BLOCK_SIZE; init.NbData = SDCARD_BLOCK_SIZE;
LL_DMA_DeInit(SDCARD_DMA_TX, SDCARD_DMA_STREAM_TX); LL_DMA_DeInit(sdcard.dma->dma, sdcard.dma->stream);
LL_DMA_Init(SDCARD_DMA_TX, SDCARD_DMA_STREAM_TX, &init); LL_DMA_Init(sdcard.dma->dma, sdcard.dma->stream, &init);
LL_DMA_EnableStream(SDCARD_DMA_TX, SDCARD_DMA_STREAM_TX); LL_DMA_EnableStream(sdcard.dma->dma, sdcard.dma->stream);
LL_SPI_EnableDMAReq_TX(SDCARD_SPI_INSTANCE); LL_SPI_EnableDMAReq_TX(sdcard.instance);
#elif defined(SDCARD_DMA_CHANNEL_TX) #else
// Queue the transmission of the sector payload
#ifdef SDCARD_DMA_CLK
// RCC_AHB1PeriphClockCmd(SDCARD_DMA_CLK, ENABLE); // XXX Shouldn't be needed ...
#endif
DMA_InitTypeDef init; DMA_InitTypeDef init;
DMA_StructInit(&init); DMA_StructInit(&init);
#ifdef SDCARD_DMA_CHANNEL #ifdef STM32F4
init.DMA_Channel = SDCARD_DMA_CHANNEL; init.DMA_Channel = dmaGetChannel(sdcard.dmaChannel);
init.DMA_Memory0BaseAddr = (uint32_t) buffer; init.DMA_Memory0BaseAddr = (uint32_t) buffer;
init.DMA_DIR = DMA_DIR_MemoryToPeripheral; init.DMA_DIR = DMA_DIR_MemoryToPeripheral;
#else #else
@ -459,7 +439,7 @@ static void sdcard_sendDataBlockBegin(const uint8_t *buffer, bool multiBlockWrit
init.DMA_MemoryBaseAddr = (uint32_t) buffer; init.DMA_MemoryBaseAddr = (uint32_t) buffer;
init.DMA_DIR = DMA_DIR_PeripheralDST; init.DMA_DIR = DMA_DIR_PeripheralDST;
#endif #endif
init.DMA_PeripheralBaseAddr = (uint32_t) &SDCARD_SPI_INSTANCE->DR; init.DMA_PeripheralBaseAddr = (uint32_t) &sdcard.instance->DR;
init.DMA_Priority = DMA_Priority_Low; init.DMA_Priority = DMA_Priority_Low;
init.DMA_PeripheralInc = DMA_PeripheralInc_Disable; init.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; init.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
@ -470,16 +450,16 @@ static void sdcard_sendDataBlockBegin(const uint8_t *buffer, bool multiBlockWrit
init.DMA_BufferSize = SDCARD_BLOCK_SIZE; init.DMA_BufferSize = SDCARD_BLOCK_SIZE;
init.DMA_Mode = DMA_Mode_Normal; init.DMA_Mode = DMA_Mode_Normal;
DMA_DeInit(SDCARD_DMA_CHANNEL_TX); DMA_DeInit(sdcard.dma->ref);
DMA_Init(SDCARD_DMA_CHANNEL_TX, &init); DMA_Init(sdcard.dma->ref, &init);
DMA_Cmd(SDCARD_DMA_CHANNEL_TX, ENABLE); DMA_Cmd(sdcard.dma->ref, ENABLE);
SPI_I2S_DMACmd(SDCARD_SPI_INSTANCE, SPI_I2S_DMAReq_Tx, ENABLE); SPI_I2S_DMACmd(sdcard.instance, SPI_I2S_DMAReq_Tx, ENABLE);
#endif #endif
} else { } else {
// Send the first chunk now // Send the first chunk now
spiTransfer(SDCARD_SPI_INSTANCE, buffer, NULL, SDCARD_NON_DMA_CHUNK_SIZE); spiTransfer(sdcard.instance, buffer, NULL, SDCARD_NON_DMA_CHUNK_SIZE);
} }
} }
@ -569,31 +549,43 @@ static bool sdcard_checkInitDone(void)
/** /**
* Begin the initialization process for the SD card. This must be called first before any other sdcard_ routine. * Begin the initialization process for the SD card. This must be called first before any other sdcard_ routine.
*/ */
void sdcard_init(bool useDMA) void sdcard_init(const sdcardConfig_t *config)
{ {
#if defined(SDCARD_DMA_TX) sdcard.enabled = config->enabled;
useDMAForTx = useDMA; if (!sdcard.enabled) {
if (useDMAForTx) { sdcard.state = SDCARD_STATE_NOT_PRESENT;
dmaInit(dmaGetIdentifier(SDCARD_DMA_STREAM_TX_FULL), OWNER_SDCARD, 0); return;
} }
#elif defined(SDCARD_DMA_CHANNEL_TX)
useDMAForTx = useDMA;
if (useDMAForTx) {
dmaInit(dmaGetIdentifier(SDCARD_DMA_CHANNEL_TX), OWNER_SDCARD, 0);
}
#else
// DMA is not available
(void) useDMA;
#endif
#ifdef SDCARD_SPI_CS_PIN sdcard.instance = spiInstanceByDevice(config->device);
sdCardCsPin = IOGetByTag(IO_TAG(SDCARD_SPI_CS_PIN));
IOInit(sdCardCsPin, OWNER_SDCARD_CS, 0); sdcard.useDMAForTx = config->useDma;
IOConfigGPIO(sdCardCsPin, SPI_IO_CS_CFG); if (sdcard.useDMAForTx) {
#endif // SDCARD_SPI_CS_PIN #if defined(STM32F4) || defined(STM32F7)
sdcard.dmaChannel = config->dmaChannel;
#endif
sdcard.dma = dmaGetDescriptorByIdentifier(config->dmaIdentifier);
dmaInit(config->dmaIdentifier, OWNER_SDCARD, 0);
}
if (config->chipSelectTag) {
sdcard.chipSelectPin = IOGetByTag(config->chipSelectTag);
IOInit(sdcard.chipSelectPin, OWNER_SDCARD_CS, 0);
IOConfigGPIO(sdcard.chipSelectPin, SPI_IO_CS_CFG);
} else {
sdcard.chipSelectPin = IO_NONE;
}
if (config->cardDetectTag) {
sdcard.cardDetectPin = IOGetByTag(config->cardDetectTag);
sdcard.detectionInverted = config->cardDetectInverted;
} else {
sdcard.cardDetectPin = IO_NONE;
sdcard.detectionInverted = false;
}
// Max frequency is initially 400kHz // Max frequency is initially 400kHz
spiSetDivisor(SDCARD_SPI_INSTANCE, SDCARD_SPI_INITIALIZATION_CLOCK_DIVIDER); spiSetDivisor(sdcard.instance, SDCARD_SPI_INITIALIZATION_CLOCK_DIVIDER);
// SDCard wants 1ms minimum delay after power is applied to it // SDCard wants 1ms minimum delay after power is applied to it
delay(1000); delay(1000);
@ -601,11 +593,11 @@ void sdcard_init(bool useDMA)
// Transmit at least 74 dummy clock cycles with CS high so the SD card can start up // Transmit at least 74 dummy clock cycles with CS high so the SD card can start up
SET_CS_HIGH; SET_CS_HIGH;
spiTransfer(SDCARD_SPI_INSTANCE, NULL, NULL, SDCARD_INIT_NUM_DUMMY_BYTES); spiTransfer(sdcard.instance, NULL, NULL, SDCARD_INIT_NUM_DUMMY_BYTES);
// Wait for that transmission to finish before we enable the SDCard, so it receives the required number of cycles: // Wait for that transmission to finish before we enable the SDCard, so it receives the required number of cycles:
int time = 100000; int time = 100000;
while (spiIsBusBusy(SDCARD_SPI_INSTANCE)) { while (spiIsBusBusy(sdcard.instance)) {
if (time-- == 0) { if (time-- == 0) {
sdcard.state = SDCARD_STATE_NOT_PRESENT; sdcard.state = SDCARD_STATE_NOT_PRESENT;
sdcard.failureCount++; sdcard.failureCount++;
@ -652,9 +644,9 @@ static sdcardOperationStatus_e sdcard_endWriteBlocks(void)
sdcard.multiWriteBlocksRemain = 0; sdcard.multiWriteBlocksRemain = 0;
// 8 dummy clocks to guarantee N_WR clocks between the last card response and this token // 8 dummy clocks to guarantee N_WR clocks between the last card response and this token
spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF); spiTransferByte(sdcard.instance, 0xFF);
spiTransferByte(SDCARD_SPI_INSTANCE, SDCARD_MULTIPLE_BLOCK_WRITE_STOP_TOKEN); spiTransferByte(sdcard.instance, SDCARD_MULTIPLE_BLOCK_WRITE_STOP_TOKEN);
// Card may choose to raise a busy (non-0xFF) signal after at most N_BR (1 byte) delay // Card may choose to raise a busy (non-0xFF) signal after at most N_BR (1 byte) delay
if (sdcard_waitForNonIdleByte(1) == 0xFF) { if (sdcard_waitForNonIdleByte(1) == 0xFF) {
@ -675,6 +667,11 @@ static sdcardOperationStatus_e sdcard_endWriteBlocks(void)
*/ */
bool sdcard_poll(void) bool sdcard_poll(void)
{ {
if (!sdcard.enabled) {
sdcard.state = SDCARD_STATE_NOT_PRESENT;
return false;
}
uint8_t initStatus; uint8_t initStatus;
bool sendComplete; bool sendComplete;
@ -753,7 +750,7 @@ bool sdcard_poll(void)
} }
// Now we're done with init and we can switch to the full speed clock (<25MHz) // Now we're done with init and we can switch to the full speed clock (<25MHz)
spiSetDivisor(SDCARD_SPI_INSTANCE, SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER); spiSetDivisor(sdcard.instance, SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER);
sdcard.multiWriteBlocksRemain = 0; sdcard.multiWriteBlocksRemain = 0;
@ -765,50 +762,50 @@ bool sdcard_poll(void)
// Have we finished sending the write yet? // Have we finished sending the write yet?
sendComplete = false; sendComplete = false;
#ifdef SDCARD_DMA_TX #if defined(USE_HAL_DRIVER)
// TODO : need to verify this // TODO : need to verify this
if (useDMAForTx && LL_DMA_IsEnabledStream(SDCARD_DMA_TX, SDCARD_DMA_STREAM_TX)) { if (sdcard.useDMAForTx && LL_DMA_IsEnabledStream(sdcard.dma->dma, sdcard.dma->stream)) {
// Drain anything left in the Rx FIFO (we didn't read it during the write) // Drain anything left in the Rx FIFO (we didn't read it during the write)
while (LL_SPI_IsActiveFlag_RXNE(SDCARD_SPI_INSTANCE)) { while (LL_SPI_IsActiveFlag_RXNE(sdcard.instance)) {
SDCARD_SPI_INSTANCE->DR; sdcard.instance->DR;
} }
// Wait for the final bit to be transmitted // Wait for the final bit to be transmitted
while (spiIsBusBusy(SDCARD_SPI_INSTANCE)) { while (spiIsBusBusy(sdcard.instance)) {
} }
LL_SPI_DisableDMAReq_TX(SDCARD_SPI_INSTANCE); LL_SPI_DisableDMAReq_TX(sdcard.instance);
sendComplete = true; sendComplete = true;
} }
#elif defined(SDCARD_DMA_CHANNEL_TX)
#ifdef SDCARD_DMA_CHANNEL
if (useDMAForTx && DMA_GetFlagStatus(SDCARD_DMA_CHANNEL_TX, SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG) == SET) {
DMA_ClearFlag(SDCARD_DMA_CHANNEL_TX, SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG);
#else #else
if (useDMAForTx && DMA_GetFlagStatus(SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG) == SET) { #ifdef STM32F4
DMA_ClearFlag(SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG); if (sdcard.useDMAForTx && DMA_GetFlagStatus(sdcard.dma->ref, sdcard.dma->completeFlag) == SET) {
DMA_ClearFlag(sdcard.dma->ref, sdcard.dma->completeFlag);
#else
if (sdcard.useDMAForTx && DMA_GetFlagStatus(sdcard.dma->completeFlag) == SET) {
DMA_ClearFlag(sdcard.dma->completeFlag);
#endif #endif
DMA_Cmd(SDCARD_DMA_CHANNEL_TX, DISABLE); DMA_Cmd(sdcard.dma->ref, DISABLE);
// Drain anything left in the Rx FIFO (we didn't read it during the write) // Drain anything left in the Rx FIFO (we didn't read it during the write)
while (SPI_I2S_GetFlagStatus(SDCARD_SPI_INSTANCE, SPI_I2S_FLAG_RXNE) == SET) { while (SPI_I2S_GetFlagStatus(sdcard.instance, SPI_I2S_FLAG_RXNE) == SET) {
SDCARD_SPI_INSTANCE->DR; sdcard.instance->DR;
} }
// Wait for the final bit to be transmitted // Wait for the final bit to be transmitted
while (spiIsBusBusy(SDCARD_SPI_INSTANCE)) { while (spiIsBusBusy(sdcard.instance)) {
} }
SPI_I2S_DMACmd(SDCARD_SPI_INSTANCE, SPI_I2S_DMAReq_Tx, DISABLE); SPI_I2S_DMACmd(sdcard.instance, SPI_I2S_DMAReq_Tx, DISABLE);
sendComplete = true; sendComplete = true;
} }
#endif #endif
if (!useDMAForTx) { if (!sdcard.useDMAForTx) {
// Send another chunk // Send another chunk
spiTransfer(SDCARD_SPI_INSTANCE, sdcard.pendingOperation.buffer + SDCARD_NON_DMA_CHUNK_SIZE * sdcard.pendingOperation.chunkIndex, NULL, SDCARD_NON_DMA_CHUNK_SIZE); spiTransfer(sdcard.instance, sdcard.pendingOperation.buffer + SDCARD_NON_DMA_CHUNK_SIZE * sdcard.pendingOperation.chunkIndex, NULL, SDCARD_NON_DMA_CHUNK_SIZE);
sdcard.pendingOperation.chunkIndex++; sdcard.pendingOperation.chunkIndex++;

View File

@ -20,6 +20,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "pg/sdcard.h"
typedef struct sdcardMetadata_s { typedef struct sdcardMetadata_s {
uint32_t numBlocks; /* Card capacity in 512-byte blocks*/ uint32_t numBlocks; /* Card capacity in 512-byte blocks*/
uint16_t oemID; uint16_t oemID;
@ -52,7 +54,7 @@ typedef void(*sdcard_operationCompleteCallback_c)(sdcardBlockOperation_e operati
typedef void(*sdcard_profilerCallback_c)(sdcardBlockOperation_e operation, uint32_t blockIndex, uint32_t duration); typedef void(*sdcard_profilerCallback_c)(sdcardBlockOperation_e operation, uint32_t blockIndex, uint32_t duration);
void sdcard_init(bool useDMA); void sdcard_init(const sdcardConfig_t *config);
bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData); bool sdcard_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData);

View File

@ -235,9 +235,9 @@ static bool sdcard_checkInitDone(void)
/** /**
* Begin the initialization process for the SD card. This must be called first before any other sdcard_ routine. * Begin the initialization process for the SD card. This must be called first before any other sdcard_ routine.
*/ */
void sdcard_init(bool useDMA) void sdcard_init(const sdcardConfig_t *config)
{ {
UNUSED(useDMA); UNUSED(config);
if (SD_Detect() == SD_PRESENT) { if (SD_Detect() == SD_PRESENT) {
if (SD_Init() != SD_OK) { if (SD_Init() != SD_OK) {
sdcard.state = SDCARD_STATE_NOT_PRESENT; sdcard.state = SDCARD_STATE_NOT_PRESENT;

View File

@ -217,8 +217,8 @@ void spiPreInit(void)
#ifdef USE_MAX7456 #ifdef USE_MAX7456
spiPreInitCsOutPU(IO_TAG(MAX7456_SPI_CS_PIN)); // XXX 3.2 workaround for Kakute F4. See comment for spiPreInitCSOutPU. spiPreInitCsOutPU(IO_TAG(MAX7456_SPI_CS_PIN)); // XXX 3.2 workaround for Kakute F4. See comment for spiPreInitCSOutPU.
#endif #endif
#ifdef USE_SDCARD #ifdef USE_SDCARD
spiPreInitCs(IO_TAG(SDCARD_SPI_CS_PIN)); spiPreInitCs(sdcardConfig()->chipSelectTag);
#endif #endif
#ifdef USE_BARO_SPI_BMP280 #ifdef USE_BARO_SPI_BMP280
spiPreInitCs(IO_TAG(BMP280_CS_PIN)); spiPreInitCs(IO_TAG(BMP280_CS_PIN));
@ -665,7 +665,7 @@ void init(void)
#ifdef USE_SDCARD #ifdef USE_SDCARD
if (blackboxConfig()->device == BLACKBOX_DEVICE_SDCARD) { if (blackboxConfig()->device == BLACKBOX_DEVICE_SDCARD) {
sdcardInsertionDetectInit(); sdcardInsertionDetectInit();
sdcard_init(sdcardConfig()->useDma); sdcard_init(sdcardConfig());
afatfs_init(); afatfs_init();
} }
#endif #endif

View File

@ -1224,7 +1224,7 @@ static void cliRxRange(char *cmdline)
ptr = cmdline; ptr = cmdline;
i = atoi(ptr); i = atoi(ptr);
if (i >= 0 && i < NON_AUX_CHANNEL_COUNT) { if (i >= 0 && i < NON_AUX_CHANNEL_COUNT) {
int rangeMin = 0, rangeMax = 0; int rangeMin = PWM_PULSE_MIN, rangeMax = PWM_PULSE_MAX;
ptr = nextArg(ptr); ptr = nextArg(ptr);
if (ptr) { if (ptr) {
@ -3310,6 +3310,27 @@ static void resourceCheck(uint8_t resourceIndex, uint8_t index, ioTag_t newTag)
} }
} }
static bool strToPin(char *pch, ioTag_t *tag)
{
if (strcasecmp(pch, "NONE") == 0) {
*tag = IO_TAG_NONE;
return true;
} else {
unsigned pin = 0;
unsigned port = (*pch >= 'a') ? *pch - 'a' : *pch - 'A';
if (port < 8) {
pch++;
pin = atoi(pch);
if (pin < 16) {
*tag = DEFIO_TAG_MAKE(port, pin);
return true;
}
}
}
return false;
}
static void cliResource(char *cmdline) static void cliResource(char *cmdline)
{ {
int len = strlen(cmdline); int len = strlen(cmdline);
@ -3336,27 +3357,6 @@ static void cliResource(char *cmdline)
cliPrintLinefeed(); cliPrintLinefeed();
} }
cliPrintLinefeed();
#ifdef MINIMAL_CLI
cliPrintLine("DMA:");
#else
cliPrintLine("Currently active DMA:");
cliRepeat('-', 20);
#endif
for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) {
const char* owner;
owner = ownerNames[dmaGetOwner(i)];
cliPrintf(DMA_OUTPUT_STRING, i / DMA_MOD_VALUE + 1, (i % DMA_MOD_VALUE) + DMA_MOD_OFFSET);
uint8_t resourceIndex = dmaGetResourceIndex(i);
if (resourceIndex > 0) {
cliPrintLinef(" %s %d", owner, resourceIndex);
} else {
cliPrintLinef(" %s", owner);
}
}
#ifndef MINIMAL_CLI #ifndef MINIMAL_CLI
cliPrintLine("\r\nUse: 'resource' to see how to change resources."); cliPrintLine("\r\nUse: 'resource' to see how to change resources.");
#endif #endif
@ -3396,46 +3396,64 @@ static void cliResource(char *cmdline)
ioTag_t *tag = getIoTag(resourceTable[resourceIndex], index); ioTag_t *tag = getIoTag(resourceTable[resourceIndex], index);
uint8_t pin = 0;
if (strlen(pch) > 0) { if (strlen(pch) > 0) {
if (strcasecmp(pch, "NONE") == 0) { if (strToPin(pch, tag)) {
*tag = IO_TAG_NONE; if (*tag == IO_TAG_NONE) {
#ifdef MINIMAL_CLI #ifdef MINIMAL_CLI
cliPrintLine("Freed"); cliPrintLine("Freed");
#else #else
cliPrintLine("Resource is freed"); cliPrintLine("Resource is freed");
#endif #endif
return; return;
} else { } else {
uint8_t port = (*pch) - 'A'; ioRec_t *rec = IO_Rec(IOGetByTag(*tag));
if (port >= 8) { if (rec) {
port = (*pch) - 'a'; resourceCheck(resourceIndex, index, *tag);
}
if (port < 8) {
pch++;
pin = atoi(pch);
if (pin < 16) {
ioRec_t *rec = IO_Rec(IOGetByTag(DEFIO_TAG_MAKE(port, pin)));
if (rec) {
resourceCheck(resourceIndex, index, DEFIO_TAG_MAKE(port, pin));
#ifdef MINIMAL_CLI #ifdef MINIMAL_CLI
cliPrintLinef(" %c%02d set", port + 'A', pin); cliPrintLinef(" %c%02d set", IO_GPIOPortIdx(rec) + 'A', IO_GPIOPinIdx(rec));
#else #else
cliPrintLinef("\r\nResource is set to %c%02d", port + 'A', pin); cliPrintLinef("\r\nResource is set to %c%02d", IO_GPIOPortIdx(rec) + 'A', IO_GPIOPinIdx(rec));
#endif #endif
*tag = DEFIO_TAG_MAKE(port, pin); } else {
} else { cliShowParseError();
cliShowParseError();
}
return;
} }
return;
} }
} }
} }
cliShowParseError(); cliShowParseError();
} }
static void printDma(void)
{
cliPrintLinefeed();
#ifdef MINIMAL_CLI
cliPrintLine("DMA:");
#else
cliPrintLine("Currently active DMA:");
cliRepeat('-', 20);
#endif
for (int i = 1; i <= DMA_LAST_HANDLER; i++) {
const char* owner;
owner = ownerNames[dmaGetOwner(i)];
cliPrintf(DMA_OUTPUT_STRING, DMA_DEVICE_NO(i), DMA_DEVICE_INDEX(i));
uint8_t resourceIndex = dmaGetResourceIndex(i);
if (resourceIndex > 0) {
cliPrintLinef(" %s %d", owner, resourceIndex);
} else {
cliPrintLinef(" %s", owner);
}
}
}
static void cliDma(char* cmdLine)
{
UNUSED(cmdLine);
printDma();
}
#endif /* USE_RESOURCE_MGMT */ #endif /* USE_RESOURCE_MGMT */
static void backupConfigs(void) static void backupConfigs(void)
@ -3660,8 +3678,7 @@ const clicmd_t cmdTable[] = {
CLI_COMMAND_DEF("color", "configure colors", NULL, cliColor), CLI_COMMAND_DEF("color", "configure colors", NULL, cliColor),
#endif #endif
CLI_COMMAND_DEF("defaults", "reset to defaults and reboot", "[nosave]", cliDefaults), CLI_COMMAND_DEF("defaults", "reset to defaults and reboot", "[nosave]", cliDefaults),
CLI_COMMAND_DEF("diff", "list configuration changes from default", CLI_COMMAND_DEF("diff", "list configuration changes from default", "[master|profile|rates|all] {showdefaults}", cliDiff),
"[master|profile|rates|all] {defaults}", cliDiff),
#ifdef USE_DSHOT #ifdef USE_DSHOT
CLI_COMMAND_DEF("dshotprog", "program DShot ESC(s)", "<index> <command>+", cliDshotProg), CLI_COMMAND_DEF("dshotprog", "program DShot ESC(s)", "<index> <command>+", cliDshotProg),
#endif #endif
@ -3708,8 +3725,9 @@ const clicmd_t cmdTable[] = {
#endif #endif
CLI_COMMAND_DEF("profile", "change profile", "[<index>]", cliProfile), CLI_COMMAND_DEF("profile", "change profile", "[<index>]", cliProfile),
CLI_COMMAND_DEF("rateprofile", "change rate profile", "[<index>]", cliRateProfile), CLI_COMMAND_DEF("rateprofile", "change rate profile", "[<index>]", cliRateProfile),
#if defined(USE_RESOURCE_MGMT) #ifdef USE_RESOURCE_MGMT
CLI_COMMAND_DEF("resource", "show/set resources", NULL, cliResource), CLI_COMMAND_DEF("resource", "show/set resources", NULL, cliResource),
CLI_COMMAND_DEF("dma", "list dma utilisation", NULL, cliDma),
#endif #endif
CLI_COMMAND_DEF("rxfail", "show/set rx failsafe settings", NULL, cliRxFailsafe), CLI_COMMAND_DEF("rxfail", "show/set rx failsafe settings", NULL, cliRxFailsafe),
CLI_COMMAND_DEF("rxrange", "configure rx channel ranges", NULL, cliRxRange), CLI_COMMAND_DEF("rxrange", "configure rx channel ranges", NULL, cliRxRange),

View File

@ -26,10 +26,47 @@
#include "pg/pg_ids.h" #include "pg/pg_ids.h"
#include "sdcard.h" #include "sdcard.h"
#include "drivers/bus_spi.h"
#include "drivers/io.h"
#include "drivers/dma.h"
PG_REGISTER_WITH_RESET_TEMPLATE(sdcardConfig_t, sdcardConfig, PG_SDCARD_CONFIG, 0); PG_REGISTER_WITH_RESET_FN(sdcardConfig_t, sdcardConfig, PG_SDCARD_CONFIG, 0);
PG_RESET_TEMPLATE(sdcardConfig_t, sdcardConfig, void pgResetFn_sdcardConfig(sdcardConfig_t *config)
.useDma = false {
); config->useDma = false;
#ifdef SDCARD_SPI_INSTANCE
config->enabled = 1;
config->device = spiDeviceByInstance(SDCARD_SPI_INSTANCE);
#else
config->enabled = 0;
config->device = 0;
#endif
#ifdef SDCARD_DETECT_PIN
config->cardDetectTag = IO_TAG(SDCARD_DETECT_PIN);
#else
config->cardDetectTag = IO_TAG_NONE;
#endif
#ifdef SDCARD_DETECT_PIN
config->chipSelectTag = IO_TAG(SDCARD_SPI_CS_PIN);
#else
config->chipSelectTag = IO_TAG_NONE;
#endif
#ifdef SDCARD_DETECT_INVERTED
config->cardDetectInverted = 1;
#else
config->cardDetectInverted = 0;
#endif
#if defined(SDCARD_DMA_STREAM_TX_FULL)
config->dmaIdentifier = (uint8_t)dmaGetIdentifier(SDCARD_DMA_STREAM_TX_FULL);
#elif defined(SDCARD_DMA_CHANNEL_TX)
config->dmaIdentifier = (uint8_t)dmaGetIdentifier(SDCARD_DMA_CHANNEL_TX);
#endif
#if (defined(STM32F4) || defined(STM32F7)) && defined(SDCARD_DMA_CHANNEL)
config->dmaChannel = SDCARD_DMA_CHANNEL;
#endif
}
#endif #endif

View File

@ -18,9 +18,19 @@
#pragma once #pragma once
#include "pg/pg.h" #include "pg/pg.h"
#include "drivers/io.h"
typedef struct sdcardConfig_s { typedef struct sdcardConfig_s {
uint8_t useDma; uint8_t useDma;
uint8_t enabled;
uint8_t device;
ioTag_t cardDetectTag;
ioTag_t chipSelectTag;
uint8_t cardDetectInverted;
uint8_t dmaIdentifier;
#if defined(STM32F4) || defined(STM32F7)
uint8_t dmaChannel;
#endif
} sdcardConfig_t; } sdcardConfig_t;
PG_DECLARE(sdcardConfig_t, sdcardConfig); PG_DECLARE(sdcardConfig_t, sdcardConfig);

View File

@ -75,9 +75,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
// Performance logging for SD card operations: // Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING // #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -89,12 +89,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream4 #define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream4
#define SDCARD_DMA_TX DMA1 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_STREAM_TX 4
#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA1
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_0
// Performance logging for SD card operations: // Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING // #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -139,12 +139,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1 #define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2 #define SDCARD_DMA_CHANNEL 4
#define SDCARD_DMA_STREAM_TX 1
#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA2
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1_5
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_4
#define USE_I2C #define USE_I2C
#define USE_I2C_DEVICE_2 // External I2C #define USE_I2C_DEVICE_2 // External I2C

View File

@ -70,9 +70,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define USE_VCP #define USE_VCP
#define VBUS_SENSING_ENABLED #define VBUS_SENSING_ENABLED

View File

@ -116,7 +116,6 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 2 #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 2
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
#define DEFAULT_VOLTAGE_METER_SOURCE VOLTAGE_METER_ADC #define DEFAULT_VOLTAGE_METER_SOURCE VOLTAGE_METER_ADC
#define DEFAULT_CURRENT_METER_SOURCE CURRENT_METER_ADC #define DEFAULT_CURRENT_METER_SOURCE CURRENT_METER_ADC

View File

@ -83,9 +83,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
// Performance logging for SD card operations: // Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING // #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -54,7 +54,6 @@
// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx. // Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
//#define USE_FLASHFS //#define USE_FLASHFS
//#define USE_FLASH_M25P16 //#define USE_FLASH_M25P16

View File

@ -78,9 +78,7 @@
// Divide to under 25MHz for normal operation: // Divide to under 25MHz for normal operation:
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define USE_FLASHFS #define USE_FLASHFS
#define USE_FLASH_M25P16 #define USE_FLASH_M25P16

View File

@ -79,12 +79,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream4 #define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream4
#define SDCARD_DMA_TX DMA1 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_STREAM_TX 4
#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA1
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1_4
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_0
#define USE_VCP #define USE_VCP
#define USE_UART1 #define USE_UART1

View File

@ -65,9 +65,7 @@
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream3 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream3
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF3 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define USE_VCP #define USE_VCP

View File

@ -111,9 +111,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
// *************** RTC6705 ************************* // *************** RTC6705 *************************
#define USE_VTX_RTC6705 #define USE_VTX_RTC6705

View File

@ -65,9 +65,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define USE_VCP #define USE_VCP
#define VBUS_SENSING_PIN PC5 #define VBUS_SENSING_PIN PC5

View File

@ -113,7 +113,6 @@
// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx. // Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations: // Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING // #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -103,14 +103,10 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
//#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5 //#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
//#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5 //#define SDCARD_DMA_CHANNEL 0
//#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
//#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT #define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT

View File

@ -84,12 +84,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 13.5MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 13.5MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1 #define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2 #define SDCARD_DMA_CHANNEL 4
#define SDCARD_DMA_STREAM_TX 1
#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA2
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1_5
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_4
#define USE_FLASHFS #define USE_FLASHFS
#define USE_FLASH_M25P16 #define USE_FLASH_M25P16

View File

@ -137,12 +137,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream5 #define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream5
#define SDCARD_DMA_TX DMA2 #define SDCARD_DMA_CHANNEL 3
#define SDCARD_DMA_STREAM_TX 1
#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA2
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1_5
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_3
#define USE_I2C #define USE_I2C
#define USE_I2C_DEVICE_1 #define USE_I2C_DEVICE_1

View File

@ -93,14 +93,10 @@
//#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5 //#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
//#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5 //#define SDCARD_DMA_CHANNEL 0
//#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
//#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#else #else
#define USE_FLASHFS #define USE_FLASHFS

View File

@ -68,9 +68,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define USE_OSD #define USE_OSD
#ifdef USE_MSP_DISPLAYPORT #ifdef USE_MSP_DISPLAYPORT

View File

@ -82,7 +82,6 @@
// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx. // Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
#endif #endif
#define MPU6000_CS_PIN SPI1_NSS_PIN #define MPU6000_CS_PIN SPI1_NSS_PIN

View File

@ -110,9 +110,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream7 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream7
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF7 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
// *************** OSD ***************************** // *************** OSD *****************************
#define USE_SPI_DEVICE_2 #define USE_SPI_DEVICE_2

View File

@ -95,12 +95,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream7 #define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream7
#define SDCARD_DMA_TX DMA1 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_STREAM_TX 7
#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA1
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF7
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_0
// *************** OSD ***************************** // *************** OSD *****************************
#define USE_SPI_DEVICE_2 #define USE_SPI_DEVICE_2

View File

@ -81,7 +81,6 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 2 #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 2
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
#define USE_ADC #define USE_ADC
#define ADC_INSTANCE ADC1 #define ADC_INSTANCE ADC1

View File

@ -120,9 +120,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
// Pins are available unless USART3 is connected, not connected // Pins are available unless USART3 is connected, not connected
//#define USE_I2C //#define USE_I2C

View File

@ -63,12 +63,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
//#define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream5 //#define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream5
//#define SDCARD_DMA_TX DMA1 //#define SDCARD_DMA_CHANNEL 0
//#define SDCARD_DMA_STREAM_TX 5
//#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA1
//#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1_0
//#define SDCARD_DMA_CHANNEL DMA_CHANNEL_0
#define USE_I2C #define USE_I2C
#define USE_I2C_DEVICE_1 #define USE_I2C_DEVICE_1

View File

@ -81,7 +81,6 @@
// //
//// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx. //// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
//#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 //#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
//#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations: // Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING // #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -122,12 +122,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1 #define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2 #define SDCARD_DMA_CHANNEL 4
#define SDCARD_DMA_STREAM_TX 1
#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA2
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1_5
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_4
#define USE_I2C #define USE_I2C
#define USE_I2C_DEVICE_1 #define USE_I2C_DEVICE_1

View File

@ -124,12 +124,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1 #define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2 #define SDCARD_DMA_CHANNEL 4
#define SDCARD_DMA_STREAM_TX 1
#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA2
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1_5
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_4
#define USE_I2C #define USE_I2C
#define USE_I2C_DEVICE_1 #define USE_I2C_DEVICE_1

View File

@ -143,7 +143,6 @@
// DSHOT output 4 uses DMA1_Channel5, so don't use it for the SDCARD until we find an alternative // DSHOT output 4 uses DMA1_Channel5, so don't use it for the SDCARD until we find an alternative
#ifndef USE_DSHOT #ifndef USE_DSHOT
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
#endif #endif
// Performance logging for SD card operations: // Performance logging for SD card operations:

View File

@ -149,9 +149,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#elif defined(LUXF4OSD) #elif defined(LUXF4OSD)
#define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT #define ENABLE_BLACKBOX_LOGGING_ON_SPIFLASH_BY_DEFAULT
#define M25P16_CS_PIN PB12 #define M25P16_CS_PIN PB12

View File

@ -155,12 +155,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1 #define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2 #define SDCARD_DMA_CHANNEL 4
#define SDCARD_DMA_STREAM_TX 1
#define SDCARD_DMA_CLK LL_AHB1_GRP1_PERIPH_DMA2
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF1_5
#define SDCARD_DMA_CHANNEL DMA_CHANNEL_4
#define USE_I2C #define USE_I2C
#define USE_I2C_DEVICE_2 #define USE_I2C_DEVICE_2

View File

@ -171,9 +171,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#else #else

View File

@ -73,7 +73,6 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 2 #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 2
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel3 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel3
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC3
#define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT #define ENABLE_BLACKBOX_LOGGING_ON_SDCARD_BY_DEFAULT
#define USE_VCP #define USE_VCP

View File

@ -128,7 +128,6 @@
// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx. // Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations: // Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING // #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -145,7 +145,6 @@
// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx. // Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
#define MPU6500_CS_PIN PB9 #define MPU6500_CS_PIN PB9
#define MPU6500_SPI_INSTANCE SPI1 #define MPU6500_SPI_INSTANCE SPI1

View File

@ -167,7 +167,6 @@
// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx. // Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations: // Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING // #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -131,7 +131,6 @@
// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx. // Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 #define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
#define MPU6500_CS_PIN SPI1_NSS_PIN #define MPU6500_CS_PIN SPI1_NSS_PIN
#define MPU6500_SPI_INSTANCE SPI1 #define MPU6500_SPI_INSTANCE SPI1

View File

@ -136,9 +136,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define MPU6500_CS_PIN SPI1_NSS_PIN #define MPU6500_CS_PIN SPI1_NSS_PIN

View File

@ -168,9 +168,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define MPU6500_CS_PIN SPI1_NSS_PIN #define MPU6500_CS_PIN SPI1_NSS_PIN
#define MPU6500_SPI_INSTANCE SPI1 #define MPU6500_SPI_INSTANCE SPI1

View File

@ -144,7 +144,6 @@
// //
//// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx. //// Note, this is the same DMA channel as UART1_RX. Luckily we don't use DMA for USART Rx.
//#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5 //#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
//#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations: // Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING // #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -76,9 +76,7 @@
/* /*
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
*/ */

View File

@ -108,9 +108,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz #define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5 #define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5 #define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
// SPI Ports // SPI Ports
#define USE_SPI #define USE_SPI

View File

@ -128,15 +128,10 @@
#if (FLASH_SIZE > 128) #if (FLASH_SIZE > 128)
#define USE_CMS #define USE_CMS
#define USE_TELEMETRY_CRSF #define USE_TELEMETRY_CRSF
#define USE_TELEMETRY_IBUS
#define USE_TELEMETRY_JETIEXBUS
#define USE_TELEMETRY_MAVLINK
#define USE_TELEMETRY_SRXL #define USE_TELEMETRY_SRXL
#define USE_MSP_DISPLAYPORT #define USE_MSP_DISPLAYPORT
#define USE_RCDEVICE #define USE_RCDEVICE
#define USE_RX_MSP #define USE_RX_MSP
#define USE_SERIALRX_JETIEXBUS
#define USE_SENSOR_NAMES
#define USE_SERIALRX_FPORT // FrSky FPort #define USE_SERIALRX_FPORT // FrSky FPort
#define USE_VIRTUAL_CURRENT_METER #define USE_VIRTUAL_CURRENT_METER
#define USE_VTX_COMMON #define USE_VTX_COMMON
@ -162,6 +157,11 @@
#endif #endif
#if (FLASH_SIZE > 256) #if (FLASH_SIZE > 256)
#define USE_SENSOR_NAMES
#define USE_TELEMETRY_IBUS
#define USE_TELEMETRY_MAVLINK
#define USE_SERIALRX_JETIEXBUS
#define USE_TELEMETRY_JETIEXBUS
#define USE_ALT_HOLD #define USE_ALT_HOLD
#define USE_DASHBOARD #define USE_DASHBOARD
#define USE_GPS #define USE_GPS