Skip to content

Commit d964c15

Browse files
committed
Support starting interrupt DMAs.
1 parent fd86ba4 commit d964c15

File tree

4 files changed

+190
-31
lines changed

4 files changed

+190
-31
lines changed

cores/arduino/stm32/dma.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,149 @@ static dma_index_t get_dma_index(
287287
}
288288
}
289289

290+
/**
291+
* @brief This function will get the interrupt number for a DMA
292+
* @param dma_handle : dma channel or strea
293+
* @retval None
294+
*/
295+
IRQn_Type get_dma_interrupt(
296+
#if defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32F7xx)
297+
DMA_Stream_TypeDef
298+
#else
299+
DMA_Channel_TypeDef
300+
#endif
301+
*instance)
302+
{
303+
switch ((uint32_t)instance) {
304+
#ifdef DMA1_Channel1
305+
case (uint32_t)DMA1_Channel1:
306+
return DMA1_Channel1_IRQn;
307+
#endif
308+
#ifdef DMA1_Channel2
309+
case (uint32_t)DMA1_Channel2:
310+
return DMA1_Channel2_IRQn;
311+
#endif
312+
#ifdef DMA1_Channel3
313+
case (uint32_t)DMA1_Channel3:
314+
return DMA1_Channel3_IRQn;
315+
#endif
316+
#ifdef DMA1_Channel4
317+
case (uint32_t)DMA1_Channel4:
318+
return DMA1_Channel4_IRQn;
319+
#endif
320+
#ifdef DMA1_Channel5
321+
case (uint32_t)DMA1_Channel5:
322+
return DMA1_Channel5_IRQn;
323+
#endif
324+
#ifdef DMA1_Channel6
325+
case (uint32_t)DMA1_Channel6:
326+
return DMA1_Channel6_IRQn;
327+
#endif
328+
#ifdef DMA1_Channel7
329+
case (uint32_t)DMA1_Channel7:
330+
return DMA1_Channel7_IRQn;
331+
#endif
332+
#ifdef DMA2_Channel1
333+
case (uint32_t)DMA2_Channel1:
334+
return DMA2_Channel1_IRQn;
335+
#endif
336+
#ifdef DMA2_Channel2
337+
case (uint32_t)DMA2_Channel2:
338+
return DMA2_Channel2_IRQn;
339+
#endif
340+
#ifdef DMA2_Channel3
341+
case (uint32_t)DMA2_Channel3:
342+
return DMA2_Channel3_IRQn;
343+
#endif
344+
#ifdef DMA2_Channel4
345+
case (uint32_t)DMA2_Channel4:
346+
return DMA2_Channel4_IRQn;
347+
#endif
348+
#ifdef DMA2_Channel5
349+
case (uint32_t)DMA2_Channel5:
350+
return DMA2_Channel5_IRQn;
351+
#endif
352+
#ifdef DMA2_Channel6
353+
case (uint32_t)DMA2_Channel6:
354+
return DMA2_Channel6_IRQn;
355+
#endif
356+
#ifdef DMA2_Channel7
357+
case (uint32_t)DMA2_Channel7:
358+
return DMA2_Channel7_IRQn;
359+
#endif
360+
#ifdef DMA2_Channel8
361+
case (uint32_t)DMA2_Channel8:
362+
return DMA2_Channel8_IRQn;
363+
#endif
364+
#ifdef DMA1_Stream0
365+
case (uint32_t)DMA1_Stream0:
366+
return DMA1_Stream0_IRQn;
367+
#endif
368+
#ifdef DMA1_Stream1
369+
case (uint32_t)DMA1_Stream1:
370+
return DMA1_Stream1_IRQn;
371+
#endif
372+
#ifdef DMA1_Stream2
373+
case (uint32_t)DMA1_Stream2:
374+
return DMA1_Stream2_IRQn;
375+
#endif
376+
#ifdef DMA1_Stream3
377+
case (uint32_t)DMA1_Stream3:
378+
return DMA1_Stream3_IRQn;
379+
#endif
380+
#ifdef DMA1_Stream4
381+
case (uint32_t)DMA1_Stream4:
382+
return DMA1_Stream4_IRQn;
383+
#endif
384+
#ifdef DMA1_Stream5
385+
case (uint32_t)DMA1_Stream5:
386+
return DMA1_Stream5_IRQn;
387+
#endif
388+
#ifdef DMA1_Stream6
389+
case (uint32_t)DMA1_Stream6:
390+
return DMA1_Stream6_IRQn;
391+
#endif
392+
#ifdef DMA1_Stream7
393+
case (uint32_t)DMA1_Stream7:
394+
return DMA1_Stream7_IRQn;
395+
#endif
396+
#ifdef DMA2_Stream0
397+
case (uint32_t)DMA2_Stream0:
398+
return DMA2_Stream0_IRQn;
399+
#endif
400+
#ifdef DMA2_Stream1
401+
case (uint32_t)DMA2_Stream1:
402+
return DMA2_Stream1_IRQn;
403+
#endif
404+
#ifdef DMA2_Stream2
405+
case (uint32_t)DMA2_Stream2:
406+
return DMA2_Stream2_IRQn;
407+
#endif
408+
#ifdef DMA2_Stream3
409+
case (uint32_t)DMA2_Stream3:
410+
return DMA2_Stream3_IRQn;
411+
#endif
412+
#ifdef DMA2_Stream4
413+
case (uint32_t)DMA2_Stream4:
414+
return DMA2_Stream4_IRQn;
415+
#endif
416+
#ifdef DMA2_Stream5
417+
case (uint32_t)DMA2_Stream5:
418+
return DMA2_Stream5_IRQn;
419+
#endif
420+
#ifdef DMA2_Stream6
421+
case (uint32_t)DMA2_Stream6:
422+
return DMA2_Stream6_IRQn;
423+
#endif
424+
#ifdef DMA2_Stream7
425+
case (uint32_t)DMA2_Stream7:
426+
return DMA2_Stream7_IRQn;
427+
#endif
428+
default:
429+
return NC;
430+
}
431+
}
432+
290433
/**
291434
* @brief This function will store the DMA handle in the appropriate slot
292435
* @param dma_handle : dma handle

cores/arduino/stm32/dma.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,19 @@ extern "C" {
4646

4747
#include <stm32_def.h>
4848

49+
/**
50+
* @brief This function will get the interrupt number for a DMA
51+
* @param dma_handle : dma channel or strea
52+
* @retval None
53+
*/
54+
IRQn_Type get_dma_interrupt(
55+
#if defined(STM32F2xx) || defined(STM32F4xx) || defined(STM32F7xx)
56+
DMA_Stream_TypeDef
57+
#else
58+
DMA_Channel_TypeDef
59+
#endif
60+
*instance);
61+
4962
/**
5063
* @brief This function will store the DMA handle in the appropriate slot
5164
* @param dma_handle : dma handle

libraries/DMA/src/DMATransfer.cpp

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
* @param settings : dma transfer settings
88
* @retval None
99
*/
10-
void DMATransferClass::prepare(dmatransfer_t *settings)
10+
void DMATransferClass::prepare(DMA_HandleTypeDef *settings)
1111
{
1212
if (!_prepared) {
1313
// TODO - figure out which DMA to enable the clock for.
1414
__HAL_RCC_DMA1_CLK_ENABLE();
1515

16-
memcpy(&_transfer_settings, settings, sizeof(dmatransfer_t));
17-
16+
memcpy(&_dma, settings, sizeof(DMA_HandleTypeDef));
17+
/*
1818
_transfer_settings.dma_settings.Init.Direction = _transfer_settings.transfer_direction;
1919
_transfer_settings.dma_settings.Init.PeriphInc = DMA_PINC_DISABLE;
2020
_transfer_settings.dma_settings.Init.MemInc = DMA_MINC_DISABLE;
@@ -24,12 +24,17 @@ void DMATransferClass::prepare(dmatransfer_t *settings)
2424
_transfer_settings.dma_settings.Init.Priority = DMA_PRIORITY_VERY_HIGH;
2525
_transfer_settings.dma_settings.Instance = _transfer_settings.channel_stream;
2626
// TODO - intialize the callbacks.
27+
*/
2728

2829
// Perform HAL Initialization first.
29-
HAL_DMA_Init(&_transfer_settings.dma_settings);
30+
HAL_DMA_Init(&_dma);
31+
_dma.XferCpltCallback = settings->XferCpltCallback;
32+
_dma.XferHalfCpltCallback = settings->XferHalfCpltCallback;
33+
_dma.XferErrorCallback = settings->XferErrorCallback;
34+
_dma.XferAbortCallback = settings->XferAbortCallback;
3035

3136
// Call dma prepare
32-
prepare_dma(&_transfer_settings.dma_settings);
37+
prepare_dma(&_dma);
3338

3439
_prepared = true;
3540
}
@@ -39,23 +44,31 @@ void DMATransferClass::prepare(dmatransfer_t *settings)
3944
* @brief Begin the DMA transfer
4045
* @retval None
4146
*/
42-
void DMATransferClass::begin(int bytes_to_transfer)
47+
void DMATransferClass::begin(uint32_t source, uint32_t destination, int bytes_to_transfer, bool use_interrupt)
4348
{
4449
if (!_prepared) {
4550
// call dma prepare
46-
prepare_dma(&_transfer_settings.dma_settings);
51+
prepare_dma(&_dma);
4752
}
4853

4954
// Reset flags so it starts over
50-
__HAL_DMA_CLEAR_FLAG(&_transfer_settings.dma_settings, DMA_FLAG_TC2 | DMA_FLAG_HT2 | DMA_FLAG_TE2);
55+
__HAL_DMA_CLEAR_FLAG(&_dma, DMA_FLAG_TC2 | DMA_FLAG_HT2 | DMA_FLAG_TE2);
5156

5257
// Set size to transfer
53-
_transfer_settings.dma_settings.Instance->CNDTR = bytes_to_transfer;
58+
_dma.Instance->CNDTR = bytes_to_transfer;
5459

5560
// and enable it
56-
__HAL_DMA_ENABLE(&_transfer_settings.dma_settings);
61+
__HAL_DMA_ENABLE(&_dma);
5762

58-
HAL_DMA_Start(&_transfer_settings.dma_settings, _transfer_settings.source, _transfer_settings.destination, bytes_to_transfer);
63+
if (use_interrupt) {
64+
IRQn_Type interrupt_number = get_dma_interrupt(_dma.Instance);
65+
HAL_NVIC_SetPriority(interrupt_number, 0, 0);
66+
HAL_NVIC_EnableIRQ(interrupt_number);
67+
HAL_DMA_Start_IT(&_dma, source, destination, bytes_to_transfer);
68+
}
69+
else {
70+
HAL_DMA_Start(&_dma, source, destination, bytes_to_transfer);
71+
}
5972
}
6073

6174
/**
@@ -65,10 +78,10 @@ void DMATransferClass::begin(int bytes_to_transfer)
6578
void DMATransferClass::end()
6679
{
6780

68-
__HAL_DMA_DISABLE(&_transfer_settings.dma_settings);
81+
__HAL_DMA_DISABLE(&_dma);
6982

7083
if (_prepared) {
71-
end_dma(&_transfer_settings.dma_settings);
84+
end_dma(&_dma);
7285
_prepared = false;
7386
}
7487
}

libraries/DMA/src/DMATransfer.h

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,20 @@ typedef DMA_Stream_TypeDef DMA_CS_Selection;
1111
typedef DMA_Channel_TypeDef DMA_CS_Selection;
1212
#endif
1313

14-
15-
struct dmatransfer_s {
16-
/* Keep this the first member so casting back and forth is easy
17-
*/
18-
DMA_HandleTypeDef dma_settings;
19-
DMA_CS_Selection *channel_stream;
20-
uint32_t transfer_direction;
21-
boolean circular;
22-
uint32_t source;
23-
uint32_t destination;
24-
void (*transferComplete)(DMA_HandleTypeDef *);
25-
void (*transferHalfComplete)(DMA_HandleTypeDef *);
26-
void (*transferError)(DMA_HandleTypeDef *);
27-
};
28-
2914
typedef class DMATransferClass {
3015

3116
public:
32-
void prepare(dmatransfer_t *settings);
33-
void begin(int bytes_to_transfer);
17+
/*
18+
DMATransferClass(uint32_t transfer_direction, boolean circular, uint32_t source, uint32_t destination){
19+
this->dma.Init.
20+
}*/
21+
22+
void prepare(DMA_HandleTypeDef *settings);
23+
void begin(uint32_t source, uint32_t destination, int bytes_to_transfer, bool use_interrupt = false);
3424
void end();
3525
private:
3626
bool _prepared;
37-
dmatransfer_t _transfer_settings;
27+
DMA_HandleTypeDef _dma;
3828
} DMATransfer;
3929

4030

0 commit comments

Comments
 (0)