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)
#excludes
SRC := $(filter-out ${MCU_EXCLUDES}, $(SRC))
SRC := $(filter-out $(MCU_EXCLUDES), $(SRC))
ifneq ($(filter SDCARD,$(FEATURES)),)
SRC += \

View File

@ -27,20 +27,20 @@
/*
* DMA descriptors.
*/
static dmaChannelDescriptor_t dmaDescriptors[] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel1, 0, DMA1_Channel1_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel2, 4, DMA1_Channel2_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel3, 8, DMA1_Channel3_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel4, 12, DMA1_Channel4_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel5, 16, DMA1_Channel5_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel6, 20, DMA1_Channel6_IRQn, RCC_AHBPeriph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Channel7, 24, DMA1_Channel7_IRQn, RCC_AHBPeriph_DMA1),
static dmaChannelDescriptor_t dmaDescriptors[DMA_LAST_HANDLER] = {
DEFINE_DMA_CHANNEL(DMA1, 1, 0),
DEFINE_DMA_CHANNEL(DMA1, 2, 4),
DEFINE_DMA_CHANNEL(DMA1, 3, 8),
DEFINE_DMA_CHANNEL(DMA1, 4, 12),
DEFINE_DMA_CHANNEL(DMA1, 5, 16),
DEFINE_DMA_CHANNEL(DMA1, 6, 20),
DEFINE_DMA_CHANNEL(DMA1, 7, 24),
#if defined(STM32F3) || defined(STM32F10X_CL)
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel1, 0, DMA2_Channel1_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel2, 4, DMA2_Channel2_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel3, 8, DMA2_Channel3_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel4, 12, DMA2_Channel4_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Channel5, 16, DMA2_Channel5_IRQn, RCC_AHBPeriph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, 1, 0),
DEFINE_DMA_CHANNEL(DMA2, 2, 4),
DEFINE_DMA_CHANNEL(DMA2, 3, 8),
DEFINE_DMA_CHANNEL(DMA2, 4, 12),
DEFINE_DMA_CHANNEL(DMA2, 5, 16),
#endif
};
@ -63,23 +63,47 @@ DEFINE_DMA_IRQ_HANDLER(2, 4, DMA2_CH4_HANDLER)
DEFINE_DMA_IRQ_HANDLER(2, 5, DMA2_CH5_HANDLER)
#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)
{
RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE);
dmaDescriptors[identifier].owner = owner;
dmaDescriptors[identifier].resourceIndex = resourceIndex;
const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
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)
{
NVIC_InitTypeDef NVIC_InitStructure;
const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
/* TODO: remove this - enforce the init */
RCC_AHBPeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE);
dmaDescriptors[identifier].irqHandlerCallback = callback;
dmaDescriptors[identifier].userParam = userParam;
RCC_AHBPeriphClockCmd(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[identifier].irqN;
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;
@ -88,20 +112,30 @@ void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callbac
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier)
{
return dmaDescriptors[identifier].owner;
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
}
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)
{
for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) {
for (int i = 0; i < DMA_LAST_HANDLER; i++) {
if (dmaDescriptors[i].ref == channel) {
return i;
return i + 1;
}
}
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;
#if defined(STM32F4) || defined(STM32F7)
DMA_Stream_TypeDef* ref;
uint8_t stream;
#else
DMA_Channel_TypeDef* ref;
#endif
dmaCallbackHandlerFuncPtr irqHandlerCallback;
uint8_t flagsShift;
IRQn_Type irqN;
uint32_t rcc;
uint32_t userParam;
resourceOwner_e owner;
uint8_t resourceIndex;
uint32_t completeFlag;
} dmaChannelDescriptor_t;
#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_CLEANCACHE(addr, size) (SCB_CleanDCache_by_Addr((uint32_t*)((uint32_t)addr & ~0x1f), ((uint32_t)(addr + size + 0x1f) & ~0x1f) - ((uint32_t)addr & ~0x1f)))
#endif
#define DMA_IDENTIFIER_TO_INDEX(x) ((x) - 1)
#if defined(STM32F4) || defined(STM32F7)
uint32_t dmaFlag_IT_TCIF(const DMA_Stream_TypeDef *stream);
typedef enum {
DMA1_ST0_HANDLER = 0,
DMA_NONE = 0,
DMA1_ST0_HANDLER = 1,
DMA1_ST1_HANDLER,
DMA1_ST2_HANDLER,
DMA1_ST3_HANDLER,
@ -64,15 +67,27 @@ typedef enum {
DMA2_ST5_HANDLER,
DMA2_ST6_HANDLER,
DMA2_ST7_HANDLER,
DMA_MAX_DESCRIPTORS
DMA_LAST_HANDLER = DMA2_ST7_HANDLER
} dmaIdentifier_e;
#define DMA_MOD_VALUE 8
#define DMA_MOD_OFFSET 0
#define DMA_DEVICE_NO(x) ((((x)-1) / 8) + 1)
#define DMA_DEVICE_INDEX(x) ((((x)-1) % 8))
#define DMA_OUTPUT_INDEX 0
#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) {\
if (dmaDescriptors[i].irqHandlerCallback)\
dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\
@ -89,12 +104,15 @@ typedef enum {
#define DMA_IT_FEIF ((uint32_t)0x00000001)
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
typedef enum {
DMA1_CH1_HANDLER = 0,
DMA_NONE = 0,
DMA1_CH1_HANDLER = 1,
DMA1_CH2_HANDLER,
DMA1_CH3_HANDLER,
DMA1_CH4_HANDLER,
@ -107,16 +125,29 @@ typedef enum {
DMA2_CH3_HANDLER,
DMA2_CH4_HANDLER,
DMA2_CH5_HANDLER,
DMA_LAST_HANDLER = DMA2_CH5_HANDLER
#else
DMA_LAST_HANDLER = DMA1_CH7_HANDLER
#endif
DMA_MAX_DESCRIPTORS
} dmaIdentifier_e;
#define DMA_MOD_VALUE 7
#define DMA_MOD_OFFSET 1
#define DMA_DEVICE_NO(x) ((((x)-1) / 7) + 1)
#define DMA_DEVICE_INDEX(x) ((((x)-1) % 7) + 1)
#define DMA_OUTPUT_INDEX 0
#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) {\
if (dmaDescriptors[i].irqHandlerCallback)\
dmaDescriptors[i].irqHandlerCallback(&dmaDescriptors[i]);\
@ -130,6 +161,7 @@ typedef enum {
#define DMA_IT_TEIF ((uint32_t)0x00000008)
dmaIdentifier_e dmaGetIdentifier(const DMA_Channel_TypeDef* channel);
DMA_Channel_TypeDef* dmaGetRefByIdentifier(const dmaIdentifier_e identifier);
#endif
@ -138,3 +170,4 @@ void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callbac
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier);
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier);
dmaChannelDescriptor_t* dmaGetDescriptorByIdentifier(const dmaIdentifier_e identifier);

View File

@ -28,24 +28,24 @@
/*
* DMA descriptors.
*/
static dmaChannelDescriptor_t dmaDescriptors[DMA_MAX_DESCRIPTORS] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream0, 0, DMA1_Stream0_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream1, 6, DMA1_Stream1_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream2, 16, DMA1_Stream2_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream3, 22, DMA1_Stream3_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream4, 32, DMA1_Stream4_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream5, 38, DMA1_Stream5_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream6, 48, DMA1_Stream6_IRQn, RCC_AHB1Periph_DMA1),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream7, 54, DMA1_Stream7_IRQn, RCC_AHB1Periph_DMA1),
static dmaChannelDescriptor_t dmaDescriptors[DMA_LAST_HANDLER] = {
DEFINE_DMA_CHANNEL(DMA1, 0, 0),
DEFINE_DMA_CHANNEL(DMA1, 1, 6),
DEFINE_DMA_CHANNEL(DMA1, 2, 16),
DEFINE_DMA_CHANNEL(DMA1, 3, 22),
DEFINE_DMA_CHANNEL(DMA1, 4, 32),
DEFINE_DMA_CHANNEL(DMA1, 5, 38),
DEFINE_DMA_CHANNEL(DMA1, 6, 48),
DEFINE_DMA_CHANNEL(DMA1, 7, 54),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream0, 0, DMA2_Stream0_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream1, 6, DMA2_Stream1_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream2, 16, DMA2_Stream2_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream3, 22, DMA2_Stream3_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream4, 32, DMA2_Stream4_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream5, 38, DMA2_Stream5_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream6, 48, DMA2_Stream6_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream7, 54, DMA2_Stream7_IRQn, RCC_AHB1Periph_DMA2),
DEFINE_DMA_CHANNEL(DMA2, 0, 0),
DEFINE_DMA_CHANNEL(DMA2, 1, 6),
DEFINE_DMA_CHANNEL(DMA2, 2, 16),
DEFINE_DMA_CHANNEL(DMA2, 3, 22),
DEFINE_DMA_CHANNEL(DMA2, 4, 32),
DEFINE_DMA_CHANNEL(DMA2, 5, 38),
DEFINE_DMA_CHANNEL(DMA2, 6, 48),
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, 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)
{
RCC_AHB1PeriphClockCmd(dmaDescriptors[identifier].rcc, ENABLE);
dmaDescriptors[identifier].owner = owner;
dmaDescriptors[identifier].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);
const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
RCC_AHB1PeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE);
dmaDescriptors[index].owner = owner;
dmaDescriptors[index].resourceIndex = resourceIndex;
}
#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;
}
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)
{
return dmaDescriptors[identifier].owner;
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
}
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)
{
for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) {
for (int i = 0; i < DMA_LAST_HANDLER; i++) {
if (dmaDescriptors[i].ref == stream) {
return i;
return i + 1;
}
}
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) {
return &dmaDescriptors[i];
}
}
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.
*/
static dmaChannelDescriptor_t dmaDescriptors[DMA_MAX_DESCRIPTORS] = {
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream0, 0, DMA1_Stream0_IRQn, RCC_AHB1ENR_DMA1EN),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream1, 6, DMA1_Stream1_IRQn, RCC_AHB1ENR_DMA1EN),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream2, 16, DMA1_Stream2_IRQn, RCC_AHB1ENR_DMA1EN),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream3, 22, DMA1_Stream3_IRQn, RCC_AHB1ENR_DMA1EN),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream4, 32, DMA1_Stream4_IRQn, RCC_AHB1ENR_DMA1EN),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream5, 38, DMA1_Stream5_IRQn, RCC_AHB1ENR_DMA1EN),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream6, 48, DMA1_Stream6_IRQn, RCC_AHB1ENR_DMA1EN),
DEFINE_DMA_CHANNEL(DMA1, DMA1_Stream7, 54, DMA1_Stream7_IRQn, RCC_AHB1ENR_DMA1EN),
static dmaChannelDescriptor_t dmaDescriptors[DMA_LAST_HANDLER] = {
DEFINE_DMA_CHANNEL(DMA1, 0, 0),
DEFINE_DMA_CHANNEL(DMA1, 1, 6),
DEFINE_DMA_CHANNEL(DMA1, 2, 16),
DEFINE_DMA_CHANNEL(DMA1, 3, 22),
DEFINE_DMA_CHANNEL(DMA1, 4, 32),
DEFINE_DMA_CHANNEL(DMA1, 5, 38),
DEFINE_DMA_CHANNEL(DMA1, 6, 48),
DEFINE_DMA_CHANNEL(DMA1, 7, 54),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream0, 0, DMA2_Stream0_IRQn, RCC_AHB1ENR_DMA2EN),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream1, 6, DMA2_Stream1_IRQn, RCC_AHB1ENR_DMA2EN),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream2, 16, DMA2_Stream2_IRQn, RCC_AHB1ENR_DMA2EN),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream3, 22, DMA2_Stream3_IRQn, RCC_AHB1ENR_DMA2EN),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream4, 32, DMA2_Stream4_IRQn, RCC_AHB1ENR_DMA2EN),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream5, 38, DMA2_Stream5_IRQn, RCC_AHB1ENR_DMA2EN),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream6, 48, DMA2_Stream6_IRQn, RCC_AHB1ENR_DMA2EN),
DEFINE_DMA_CHANNEL(DMA2, DMA2_Stream7, 54, DMA2_Stream7_IRQn, RCC_AHB1ENR_DMA2EN),
DEFINE_DMA_CHANNEL(DMA2, 0, 0),
DEFINE_DMA_CHANNEL(DMA2, 1, 6),
DEFINE_DMA_CHANNEL(DMA2, 2, 16),
DEFINE_DMA_CHANNEL(DMA2, 3, 22),
DEFINE_DMA_CHANNEL(DMA2, 4, 32),
DEFINE_DMA_CHANNEL(DMA2, 5, 38),
DEFINE_DMA_CHANNEL(DMA2, 6, 48),
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, 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 {
__IO uint32_t tmpreg;
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)
{
enableDmaClock(dmaDescriptors[identifier].rcc);
dmaDescriptors[identifier].owner = owner;
dmaDescriptors[identifier].resourceIndex = resourceIndex;
const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
enableDmaClock(index);
dmaDescriptors[index].owner = owner;
dmaDescriptors[index].resourceIndex = resourceIndex;
}
void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
{
enableDmaClock(dmaDescriptors[identifier].rcc);
dmaDescriptors[identifier].irqHandlerCallback = callback;
dmaDescriptors[identifier].userParam = userParam;
const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
HAL_NVIC_SetPriority(dmaDescriptors[identifier].irqN, NVIC_PRIORITY_BASE(priority), NVIC_PRIORITY_SUB(priority));
HAL_NVIC_EnableIRQ(dmaDescriptors[identifier].irqN);
enableDmaClock(index);
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)
{
return dmaDescriptors[identifier].owner;
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
}
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)
{
for (int i = 0; i < DMA_MAX_DESCRIPTORS; i++) {
for (int i = 0; i < DMA_LAST_HANDLER; i++) {
if (dmaDescriptors[i].ref == stream) {
return i;
return i + 1;
}
}
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,8 +36,8 @@
#define SDCARD_PROFILING
#endif
#define SET_CS_HIGH IOHi(sdCardCsPin)
#define SET_CS_LOW IOLo(sdCardCsPin)
#define SET_CS_HIGH IOHi(sdcard.chipSelectPin)
#define SET_CS_LOW IOLo(sdcard.chipSelectPin)
#define SDCARD_INIT_NUM_DUMMY_BYTES 10
#define SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY 8
@ -100,41 +100,34 @@ typedef struct sdcard_t {
#ifdef SDCARD_PROFILING
sdcard_profilerCallback_c profiler;
#endif
SPI_TypeDef *instance;
bool enabled;
bool detectionInverted;
bool useDMAForTx;
IO_t cardDetectPin;
IO_t chipSelectPin;
dmaChannelDescriptor_t * dma;
uint8_t dmaChannel;
} sdcard_t;
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);
#ifdef SDCARD_DETECT_PIN
static IO_t sdCardDetectPin = IO_NONE;
#endif
static IO_t sdCardCsPin = IO_NONE;
void sdcardInsertionDetectDeinit(void)
{
#ifdef SDCARD_DETECT_PIN
sdCardDetectPin = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN));
IOInit(sdCardDetectPin, OWNER_FREE, 0);
IOConfigGPIO(sdCardDetectPin, IOCFG_IN_FLOATING);
#endif
if (sdcard.cardDetectPin) {
IOInit(sdcard.cardDetectPin, OWNER_FREE, 0);
IOConfigGPIO(sdcard.cardDetectPin, IOCFG_IN_FLOATING);
}
}
void sdcardInsertionDetectInit(void)
{
#ifdef SDCARD_DETECT_PIN
sdCardDetectPin = IOGetByTag(IO_TAG(SDCARD_DETECT_PIN));
IOInit(sdCardDetectPin, OWNER_SDCARD_DETECT, 0);
IOConfigGPIO(sdCardDetectPin, IOCFG_IPU);
#endif
if (sdcard.cardDetectPin) {
IOInit(sdcard.cardDetectPin, OWNER_SDCARD_DETECT, 0);
IOConfigGPIO(sdcard.cardDetectPin, IOCFG_IPU);
}
}
/**
@ -143,17 +136,12 @@ void sdcardInsertionDetectInit(void)
bool sdcard_isInserted(void)
{
bool result = true;
#ifdef SDCARD_DETECT_PIN
result = IORead(sdCardDetectPin) != 0;
#ifdef SDCARD_DETECT_INVERTED
if (sdcard.cardDetectPin) {
result = IORead(sdcard.cardDetectPin) != 0;
if (sdcard.detectionInverted) {
result = !result;
#endif
#endif
}
}
return result;
}
@ -174,9 +162,9 @@ static void sdcard_select(void)
static void sdcard_deselect(void)
{
// 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;
@ -196,7 +184,7 @@ static void sdcard_reset(void)
}
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++;
@ -216,7 +204,7 @@ static void sdcard_reset(void)
static bool sdcard_waitForIdle(int maxBytesToWait)
{
while (maxBytesToWait > 0) {
uint8_t b = spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF);
uint8_t b = spiTransferByte(sdcard.instance, 0xFF);
if (b == 0xFF) {
return true;
}
@ -234,7 +222,7 @@ static bool sdcard_waitForIdle(int maxBytesToWait)
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
uint8_t response = spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF);
uint8_t response = spiTransferByte(sdcard.instance, 0xFF);
if (response != 0xFF) {
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)
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
@ -305,7 +293,7 @@ static bool sdcard_validateInterfaceCondition(void)
// V1 cards don't support this command
sdcard.version = 1;
} 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
@ -329,7 +317,7 @@ static bool sdcard_readOCRRegister(uint32_t *result)
uint8_t response[4];
spiTransfer(SDCARD_SPI_INSTANCE, NULL, response, sizeof(response));
spiTransfer(sdcard.instance, NULL, response, sizeof(response));
if (status == 0) {
sdcard_deselect();
@ -367,11 +355,11 @@ static sdcardReceiveBlockStatus_e sdcard_receiveDataBlock(uint8_t *buffer, int c
return SDCARD_RECEIVE_ERROR;
}
spiTransfer(SDCARD_SPI_INSTANCE, NULL, buffer, count);
spiTransfer(sdcard.instance, NULL, buffer, count);
// Discard trailing CRC, we don't care
spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF);
spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF);
spiTransferByte(sdcard.instance, 0xFF);
spiTransferByte(sdcard.instance, 0xFF);
return SDCARD_RECEIVE_SUCCESS;
}
@ -379,10 +367,10 @@ static sdcardReceiveBlockStatus_e sdcard_receiveDataBlock(uint8_t *buffer, int c
static bool sdcard_sendDataBlockFinish(void)
{
// Send a dummy CRC
spiTransferByte(SDCARD_SPI_INSTANCE, 0x00);
spiTransferByte(SDCARD_SPI_INSTANCE, 0x00);
spiTransferByte(sdcard.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)
@ -405,25 +393,21 @@ static bool sdcard_sendDataBlockFinish(void)
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:
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 defined(SDCARD_DMA_TX) && defined(USE_HAL_DRIVER)
#ifdef SDCARD_DMA_CLK
// LL_AHB1_GRP1_EnableClock(SDCARD_DMA_CLK); // XXX Should not be necessary; dmaInit handles it.
#endif
if (sdcard.useDMAForTx) {
#if defined(USE_HAL_DRIVER)
LL_DMA_InitTypeDef init;
LL_DMA_StructInit(&init);
init.Channel = SDCARD_DMA_CHANNEL;
init.Channel = dmaGetChannel(sdcard.dmaChannel);
init.Mode = LL_DMA_MODE_NORMAL;
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.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
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;
LL_DMA_DeInit(SDCARD_DMA_TX, SDCARD_DMA_STREAM_TX);
LL_DMA_Init(SDCARD_DMA_TX, SDCARD_DMA_STREAM_TX, &init);
LL_DMA_DeInit(sdcard.dma->dma, sdcard.dma->stream);
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_StructInit(&init);
#ifdef SDCARD_DMA_CHANNEL
init.DMA_Channel = SDCARD_DMA_CHANNEL;
#ifdef STM32F4
init.DMA_Channel = dmaGetChannel(sdcard.dmaChannel);
init.DMA_Memory0BaseAddr = (uint32_t) buffer;
init.DMA_DIR = DMA_DIR_MemoryToPeripheral;
#else
@ -459,7 +439,7 @@ static void sdcard_sendDataBlockBegin(const uint8_t *buffer, bool multiBlockWrit
init.DMA_MemoryBaseAddr = (uint32_t) buffer;
init.DMA_DIR = DMA_DIR_PeripheralDST;
#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_PeripheralInc = DMA_PeripheralInc_Disable;
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_Mode = DMA_Mode_Normal;
DMA_DeInit(SDCARD_DMA_CHANNEL_TX);
DMA_Init(SDCARD_DMA_CHANNEL_TX, &init);
DMA_DeInit(sdcard.dma->ref);
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
} else {
// 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.
*/
void sdcard_init(bool useDMA)
void sdcard_init(const sdcardConfig_t *config)
{
#if defined(SDCARD_DMA_TX)
useDMAForTx = useDMA;
if (useDMAForTx) {
dmaInit(dmaGetIdentifier(SDCARD_DMA_STREAM_TX_FULL), OWNER_SDCARD, 0);
sdcard.enabled = config->enabled;
if (!sdcard.enabled) {
sdcard.state = SDCARD_STATE_NOT_PRESENT;
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
sdCardCsPin = IOGetByTag(IO_TAG(SDCARD_SPI_CS_PIN));
IOInit(sdCardCsPin, OWNER_SDCARD_CS, 0);
IOConfigGPIO(sdCardCsPin, SPI_IO_CS_CFG);
#endif // SDCARD_SPI_CS_PIN
sdcard.instance = spiInstanceByDevice(config->device);
sdcard.useDMAForTx = config->useDma;
if (sdcard.useDMAForTx) {
#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
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
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
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:
int time = 100000;
while (spiIsBusBusy(SDCARD_SPI_INSTANCE)) {
while (spiIsBusBusy(sdcard.instance)) {
if (time-- == 0) {
sdcard.state = SDCARD_STATE_NOT_PRESENT;
sdcard.failureCount++;
@ -652,9 +644,9 @@ static sdcardOperationStatus_e sdcard_endWriteBlocks(void)
sdcard.multiWriteBlocksRemain = 0;
// 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
if (sdcard_waitForNonIdleByte(1) == 0xFF) {
@ -675,6 +667,11 @@ static sdcardOperationStatus_e sdcard_endWriteBlocks(void)
*/
bool sdcard_poll(void)
{
if (!sdcard.enabled) {
sdcard.state = SDCARD_STATE_NOT_PRESENT;
return false;
}
uint8_t initStatus;
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)
spiSetDivisor(SDCARD_SPI_INSTANCE, SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER);
spiSetDivisor(sdcard.instance, SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER);
sdcard.multiWriteBlocksRemain = 0;
@ -765,50 +762,50 @@ bool sdcard_poll(void)
// Have we finished sending the write yet?
sendComplete = false;
#ifdef SDCARD_DMA_TX
#if defined(USE_HAL_DRIVER)
// 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)
while (LL_SPI_IsActiveFlag_RXNE(SDCARD_SPI_INSTANCE)) {
SDCARD_SPI_INSTANCE->DR;
while (LL_SPI_IsActiveFlag_RXNE(sdcard.instance)) {
sdcard.instance->DR;
}
// 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;
}
#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
if (useDMAForTx && DMA_GetFlagStatus(SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG) == SET) {
DMA_ClearFlag(SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG);
#ifdef STM32F4
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
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)
while (SPI_I2S_GetFlagStatus(SDCARD_SPI_INSTANCE, SPI_I2S_FLAG_RXNE) == SET) {
SDCARD_SPI_INSTANCE->DR;
while (SPI_I2S_GetFlagStatus(sdcard.instance, SPI_I2S_FLAG_RXNE) == SET) {
sdcard.instance->DR;
}
// 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;
}
#endif
if (!useDMAForTx) {
if (!sdcard.useDMAForTx) {
// 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++;

View File

@ -20,6 +20,8 @@
#include <stdint.h>
#include <stdbool.h>
#include "pg/sdcard.h"
typedef struct sdcardMetadata_s {
uint32_t numBlocks; /* Card capacity in 512-byte blocks*/
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);
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);

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.
*/
void sdcard_init(bool useDMA)
void sdcard_init(const sdcardConfig_t *config)
{
UNUSED(useDMA);
UNUSED(config);
if (SD_Detect() == SD_PRESENT) {
if (SD_Init() != SD_OK) {
sdcard.state = SDCARD_STATE_NOT_PRESENT;

View File

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

View File

@ -1224,7 +1224,7 @@ static void cliRxRange(char *cmdline)
ptr = cmdline;
i = atoi(ptr);
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);
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)
{
int len = strlen(cmdline);
@ -3336,27 +3357,6 @@ static void cliResource(char *cmdline)
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
cliPrintLine("\r\nUse: 'resource' to see how to change resources.");
#endif
@ -3396,10 +3396,9 @@ static void cliResource(char *cmdline)
ioTag_t *tag = getIoTag(resourceTable[resourceIndex], index);
uint8_t pin = 0;
if (strlen(pch) > 0) {
if (strcasecmp(pch, "NONE") == 0) {
*tag = IO_TAG_NONE;
if (strToPin(pch, tag)) {
if (*tag == IO_TAG_NONE) {
#ifdef MINIMAL_CLI
cliPrintLine("Freed");
#else
@ -3407,24 +3406,14 @@ static void cliResource(char *cmdline)
#endif
return;
} else {
uint8_t port = (*pch) - 'A';
if (port >= 8) {
port = (*pch) - 'a';
}
if (port < 8) {
pch++;
pin = atoi(pch);
if (pin < 16) {
ioRec_t *rec = IO_Rec(IOGetByTag(DEFIO_TAG_MAKE(port, pin)));
ioRec_t *rec = IO_Rec(IOGetByTag(*tag));
if (rec) {
resourceCheck(resourceIndex, index, DEFIO_TAG_MAKE(port, pin));
resourceCheck(resourceIndex, index, *tag);
#ifdef MINIMAL_CLI
cliPrintLinef(" %c%02d set", port + 'A', pin);
cliPrintLinef(" %c%02d set", IO_GPIOPortIdx(rec) + 'A', IO_GPIOPinIdx(rec));
#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
*tag = DEFIO_TAG_MAKE(port, pin);
} else {
cliShowParseError();
}
@ -3432,10 +3421,39 @@ static void cliResource(char *cmdline)
}
}
}
}
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 */
static void backupConfigs(void)
@ -3660,8 +3678,7 @@ const clicmd_t cmdTable[] = {
CLI_COMMAND_DEF("color", "configure colors", NULL, cliColor),
#endif
CLI_COMMAND_DEF("defaults", "reset to defaults and reboot", "[nosave]", cliDefaults),
CLI_COMMAND_DEF("diff", "list configuration changes from default",
"[master|profile|rates|all] {defaults}", cliDiff),
CLI_COMMAND_DEF("diff", "list configuration changes from default", "[master|profile|rates|all] {showdefaults}", cliDiff),
#ifdef USE_DSHOT
CLI_COMMAND_DEF("dshotprog", "program DShot ESC(s)", "<index> <command>+", cliDshotProg),
#endif
@ -3708,8 +3725,9 @@ const clicmd_t cmdTable[] = {
#endif
CLI_COMMAND_DEF("profile", "change profile", "[<index>]", cliProfile),
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("dma", "list dma utilisation", NULL, cliDma),
#endif
CLI_COMMAND_DEF("rxfail", "show/set rx failsafe settings", NULL, cliRxFailsafe),
CLI_COMMAND_DEF("rxrange", "configure rx channel ranges", NULL, cliRxRange),

View File

@ -26,10 +26,47 @@
#include "pg/pg_ids.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,
.useDma = false
);
void pgResetFn_sdcardConfig(sdcardConfig_t *config)
{
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

View File

@ -18,9 +18,19 @@
#pragma once
#include "pg/pg.h"
#include "drivers/io.h"
typedef struct sdcardConfig_s {
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;
PG_DECLARE(sdcardConfig_t, sdcardConfig);

View File

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

View File

@ -89,12 +89,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream4
#define SDCARD_DMA_TX DMA1
#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
#define SDCARD_DMA_CHANNEL 0
// Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -139,12 +139,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2
#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 SDCARD_DMA_CHANNEL 4
#define USE_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_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define SDCARD_DMA_CHANNEL 0
#define USE_VCP
#define VBUS_SENSING_ENABLED

View File

@ -116,7 +116,6 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 2
#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_CURRENT_METER_SOURCE CURRENT_METER_ADC

View File

@ -83,9 +83,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define SDCARD_DMA_CHANNEL 0
// Performance logging for SD card operations:
// #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.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
//#define USE_FLASHFS
//#define USE_FLASH_M25P16

View File

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

View File

@ -79,12 +79,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream4
#define SDCARD_DMA_TX DMA1
#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 SDCARD_DMA_CHANNEL 0
#define USE_VCP
#define USE_UART1

View File

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

View File

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

View File

@ -65,9 +65,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define SDCARD_DMA_CHANNEL 0
#define USE_VCP
#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.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -103,14 +103,10 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
//#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
//#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5
//#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
//#define SDCARD_DMA_CHANNEL DMA_Channel_0
//#define SDCARD_DMA_CHANNEL 0
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define SDCARD_DMA_CHANNEL 0
#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_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2
#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 SDCARD_DMA_CHANNEL 4
#define USE_FLASHFS
#define USE_FLASH_M25P16

View File

@ -137,12 +137,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream5
#define SDCARD_DMA_TX DMA2
#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 SDCARD_DMA_CHANNEL 3
#define USE_I2C
#define USE_I2C_DEVICE_1

View File

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

View File

@ -68,9 +68,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF5
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define SDCARD_DMA_CHANNEL 0
#define USE_OSD
#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.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
#endif
#define MPU6000_CS_PIN SPI1_NSS_PIN

View File

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

View File

@ -95,12 +95,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream7
#define SDCARD_DMA_TX DMA1
#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
#define SDCARD_DMA_CHANNEL 0
// *************** OSD *****************************
#define USE_SPI_DEVICE_2

View File

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

View File

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

View File

@ -63,12 +63,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
//#define SDCARD_DMA_STREAM_TX_FULL DMA1_Stream5
//#define SDCARD_DMA_TX DMA1
//#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 SDCARD_DMA_CHANNEL 0
#define USE_I2C
#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.
//#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
//#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

@ -122,12 +122,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2
#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 SDCARD_DMA_CHANNEL 4
#define USE_I2C
#define USE_I2C_DEVICE_1

View File

@ -124,12 +124,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2
#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 SDCARD_DMA_CHANNEL 4
#define USE_I2C
#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
#ifndef USE_DSHOT
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
#endif
// Performance logging for SD card operations:

View File

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

View File

@ -155,12 +155,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 8 // 27MHz
#define SDCARD_DMA_STREAM_TX_FULL DMA2_Stream1
#define SDCARD_DMA_TX DMA2
#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 SDCARD_DMA_CHANNEL 4
#define USE_I2C
#define USE_I2C_DEVICE_2

View File

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

View File

@ -73,7 +73,6 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 2
#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 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.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations:
// #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.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
#define MPU6500_CS_PIN PB9
#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.
#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations:
// #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.
#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_SPI_INSTANCE SPI1

View File

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

View File

@ -168,9 +168,7 @@
#define SDCARD_SPI_FULL_SPEED_CLOCK_DIVIDER 4 // 21MHz
#define SDCARD_DMA_CHANNEL_TX DMA1_Stream4
#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA_FLAG_TCIF4
#define SDCARD_DMA_CLK RCC_AHB1Periph_DMA1
#define SDCARD_DMA_CHANNEL DMA_Channel_0
#define SDCARD_DMA_CHANNEL 0
#define MPU6500_CS_PIN SPI1_NSS_PIN
#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.
//#define SDCARD_DMA_CHANNEL_TX DMA1_Channel5
//#define SDCARD_DMA_CHANNEL_TX_COMPLETE_FLAG DMA1_FLAG_TC5
// Performance logging for SD card operations:
// #define AFATFS_USE_INTROSPECTIVE_LOGGING

View File

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

View File

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

View File

@ -128,15 +128,10 @@
#if (FLASH_SIZE > 128)
#define USE_CMS
#define USE_TELEMETRY_CRSF
#define USE_TELEMETRY_IBUS
#define USE_TELEMETRY_JETIEXBUS
#define USE_TELEMETRY_MAVLINK
#define USE_TELEMETRY_SRXL
#define USE_MSP_DISPLAYPORT
#define USE_RCDEVICE
#define USE_RX_MSP
#define USE_SERIALRX_JETIEXBUS
#define USE_SENSOR_NAMES
#define USE_SERIALRX_FPORT // FrSky FPort
#define USE_VIRTUAL_CURRENT_METER
#define USE_VTX_COMMON
@ -162,6 +157,11 @@
#endif
#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_DASHBOARD
#define USE_GPS