Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Support starting interrupt DMAs.
  • Loading branch information
xC0000005 committed Mar 26, 2020
commit 12825f8b490d18e91f10976159951c20c542f325
143 changes: 143 additions & 0 deletions cores/arduino/stm32/dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,149 @@ static dma_index_t get_dma_index(
}
}

/**
* @brief This function will get the interrupt number for a DMA
* @param dma_handle : dma channel or strea
* @retval None
*/
IRQn_Type get_dma_interrupt(
#if defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32F7xx)
DMA_Stream_TypeDef
#else
DMA_Channel_TypeDef
#endif
*instance)
{
switch ((uint32_t)instance) {
#ifdef DMA1_Channel1
case (uint32_t)DMA1_Channel1:
return DMA1_Channel1_IRQn;
#endif
#ifdef DMA1_Channel2
case (uint32_t)DMA1_Channel2:
return DMA1_Channel2_IRQn;
#endif
#ifdef DMA1_Channel3
case (uint32_t)DMA1_Channel3:
return DMA1_Channel3_IRQn;
#endif
#ifdef DMA1_Channel4
case (uint32_t)DMA1_Channel4:
return DMA1_Channel4_IRQn;
#endif
#ifdef DMA1_Channel5
case (uint32_t)DMA1_Channel5:
return DMA1_Channel5_IRQn;
#endif
#ifdef DMA1_Channel6
case (uint32_t)DMA1_Channel6:
return DMA1_Channel6_IRQn;
#endif
#ifdef DMA1_Channel7
case (uint32_t)DMA1_Channel7:
return DMA1_Channel7_IRQn;
#endif
#ifdef DMA2_Channel1
case (uint32_t)DMA2_Channel1:
return DMA2_Channel1_IRQn;
#endif
#ifdef DMA2_Channel2
case (uint32_t)DMA2_Channel2:
return DMA2_Channel2_IRQn;
#endif
#ifdef DMA2_Channel3
case (uint32_t)DMA2_Channel3:
return DMA2_Channel3_IRQn;
#endif
#ifdef DMA2_Channel4
case (uint32_t)DMA2_Channel4:
return DMA2_Channel4_IRQn;
#endif
#ifdef DMA2_Channel5
case (uint32_t)DMA2_Channel5:
return DMA2_Channel5_IRQn;
#endif
#ifdef DMA2_Channel6
case (uint32_t)DMA2_Channel6:
return DMA2_Channel6_IRQn;
#endif
#ifdef DMA2_Channel7
case (uint32_t)DMA2_Channel7:
return DMA2_Channel7_IRQn;
#endif
#ifdef DMA2_Channel8
case (uint32_t)DMA2_Channel8:
return DMA2_Channel8_IRQn;
#endif
#ifdef DMA1_Stream0
case (uint32_t)DMA1_Stream0:
return DMA1_Stream0_IRQn;
#endif
#ifdef DMA1_Stream1
case (uint32_t)DMA1_Stream1:
return DMA1_Stream1_IRQn;
#endif
#ifdef DMA1_Stream2
case (uint32_t)DMA1_Stream2:
return DMA1_Stream2_IRQn;
#endif
#ifdef DMA1_Stream3
case (uint32_t)DMA1_Stream3:
return DMA1_Stream3_IRQn;
#endif
#ifdef DMA1_Stream4
case (uint32_t)DMA1_Stream4:
return DMA1_Stream4_IRQn;
#endif
#ifdef DMA1_Stream5
case (uint32_t)DMA1_Stream5:
return DMA1_Stream5_IRQn;
#endif
#ifdef DMA1_Stream6
case (uint32_t)DMA1_Stream6:
return DMA1_Stream6_IRQn;
#endif
#ifdef DMA1_Stream7
case (uint32_t)DMA1_Stream7:
return DMA1_Stream7_IRQn;
#endif
#ifdef DMA2_Stream0
case (uint32_t)DMA2_Stream0:
return DMA2_Stream0_IRQn;
#endif
#ifdef DMA2_Stream1
case (uint32_t)DMA2_Stream1:
return DMA2_Stream1_IRQn;
#endif
#ifdef DMA2_Stream2
case (uint32_t)DMA2_Stream2:
return DMA2_Stream2_IRQn;
#endif
#ifdef DMA2_Stream3
case (uint32_t)DMA2_Stream3:
return DMA2_Stream3_IRQn;
#endif
#ifdef DMA2_Stream4
case (uint32_t)DMA2_Stream4:
return DMA2_Stream4_IRQn;
#endif
#ifdef DMA2_Stream5
case (uint32_t)DMA2_Stream5:
return DMA2_Stream5_IRQn;
#endif
#ifdef DMA2_Stream6
case (uint32_t)DMA2_Stream6:
return DMA2_Stream6_IRQn;
#endif
#ifdef DMA2_Stream7
case (uint32_t)DMA2_Stream7:
return DMA2_Stream7_IRQn;
#endif
default:
return NC;
}
}

/**
* @brief This function will store the DMA handle in the appropriate slot
* @param dma_handle : dma handle
Expand Down
13 changes: 13 additions & 0 deletions cores/arduino/stm32/dma.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ extern "C" {

#include <stm32_def.h>

/**
* @brief This function will get the interrupt number for a DMA
* @param dma_handle : dma channel or strea
* @retval None
*/
IRQn_Type get_dma_interrupt(
#if defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32F7xx)
DMA_Stream_TypeDef
#else
DMA_Channel_TypeDef
#endif
*instance);

/**
* @brief This function will store the DMA handle in the appropriate slot
* @param dma_handle : dma handle
Expand Down
39 changes: 26 additions & 13 deletions libraries/DMA/src/DMATransfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
* @param settings : dma transfer settings
* @retval None
*/
void DMATransferClass::prepare(dmatransfer_t *settings)
void DMATransferClass::prepare(DMA_HandleTypeDef *settings)
{
if (!_prepared) {
// TODO - figure out which DMA to enable the clock for.
__HAL_RCC_DMA1_CLK_ENABLE();

memcpy(&_transfer_settings, settings, sizeof(dmatransfer_t));

memcpy(&_dma, settings, sizeof(DMA_HandleTypeDef));
/*
_transfer_settings.dma_settings.Init.Direction = _transfer_settings.transfer_direction;
_transfer_settings.dma_settings.Init.PeriphInc = DMA_PINC_DISABLE;
_transfer_settings.dma_settings.Init.MemInc = DMA_MINC_DISABLE;
Expand All @@ -24,12 +24,17 @@ void DMATransferClass::prepare(dmatransfer_t *settings)
_transfer_settings.dma_settings.Init.Priority = DMA_PRIORITY_VERY_HIGH;
_transfer_settings.dma_settings.Instance = _transfer_settings.channel_stream;
// TODO - intialize the callbacks.
*/

// Perform HAL Initialization first.
HAL_DMA_Init(&_transfer_settings.dma_settings);
HAL_DMA_Init(&_dma);
_dma.XferCpltCallback = settings->XferCpltCallback;
_dma.XferHalfCpltCallback = settings->XferHalfCpltCallback;
_dma.XferErrorCallback = settings->XferErrorCallback;
_dma.XferAbortCallback = settings->XferAbortCallback;

// Call dma prepare
prepare_dma(&_transfer_settings.dma_settings);
prepare_dma(&_dma);

_prepared = true;
}
Expand All @@ -39,23 +44,31 @@ void DMATransferClass::prepare(dmatransfer_t *settings)
* @brief Begin the DMA transfer
* @retval None
*/
void DMATransferClass::begin(int bytes_to_transfer)
void DMATransferClass::begin(uint32_t source, uint32_t destination, int bytes_to_transfer, bool use_interrupt)
{
if (!_prepared) {
// call dma prepare
prepare_dma(&_transfer_settings.dma_settings);
prepare_dma(&_dma);
}

// Reset flags so it starts over
__HAL_DMA_CLEAR_FLAG(&_transfer_settings.dma_settings, DMA_FLAG_TC2 | DMA_FLAG_HT2 | DMA_FLAG_TE2);
__HAL_DMA_CLEAR_FLAG(&_dma, DMA_FLAG_TC2 | DMA_FLAG_HT2 | DMA_FLAG_TE2);

// Set size to transfer
_transfer_settings.dma_settings.Instance->CNDTR = bytes_to_transfer;
_dma.Instance->CNDTR = bytes_to_transfer;

// and enable it
__HAL_DMA_ENABLE(&_transfer_settings.dma_settings);
__HAL_DMA_ENABLE(&_dma);

HAL_DMA_Start(&_transfer_settings.dma_settings, _transfer_settings.source, _transfer_settings.destination, bytes_to_transfer);
if (use_interrupt) {
IRQn_Type interrupt_number = get_dma_interrupt(_dma.Instance);
HAL_NVIC_SetPriority(interrupt_number, 0, 0);
HAL_NVIC_EnableIRQ(interrupt_number);
HAL_DMA_Start_IT(&_dma, source, destination, bytes_to_transfer);
}
else {
HAL_DMA_Start(&_dma, source, destination, bytes_to_transfer);
}
}

/**
Expand All @@ -65,10 +78,10 @@ void DMATransferClass::begin(int bytes_to_transfer)
void DMATransferClass::end()
{

__HAL_DMA_DISABLE(&_transfer_settings.dma_settings);
__HAL_DMA_DISABLE(&_dma);

if (_prepared) {
end_dma(&_transfer_settings.dma_settings);
end_dma(&_dma);
_prepared = false;
}
}
26 changes: 8 additions & 18 deletions libraries/DMA/src/DMATransfer.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,20 @@ typedef DMA_Stream_TypeDef DMA_CS_Selection;
typedef DMA_Channel_TypeDef DMA_CS_Selection;
#endif


struct dmatransfer_s {
/* Keep this the first member so casting back and forth is easy
*/
DMA_HandleTypeDef dma_settings;
DMA_CS_Selection *channel_stream;
uint32_t transfer_direction;
boolean circular;
uint32_t source;
uint32_t destination;
void (*transferComplete)(DMA_HandleTypeDef *);
void (*transferHalfComplete)(DMA_HandleTypeDef *);
void (*transferError)(DMA_HandleTypeDef *);
};

typedef class DMATransferClass {

public:
void prepare(dmatransfer_t *settings);
void begin(int bytes_to_transfer);
/*
DMATransferClass(uint32_t transfer_direction, boolean circular, uint32_t source, uint32_t destination){
this->dma.Init.
}*/

void prepare(DMA_HandleTypeDef *settings);
void begin(uint32_t source, uint32_t destination, int bytes_to_transfer, bool use_interrupt = false);
void end();
private:
bool _prepared;
dmatransfer_t _transfer_settings;
DMA_HandleTypeDef _dma;
} DMATransfer;


Expand Down