mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-26 05:54:46 -07:00
digital_signal: show unoptimized and optimized code for digital_signal_update_dma() next to each other
This commit is contained in:
@@ -342,36 +342,42 @@ void digital_sequence_add(DigitalSequence* sequence, uint8_t signal_index) {
|
|||||||
sequence->sequence[sequence->sequence_used++] = signal_index;
|
sequence->sequence[sequence->sequence_used++] = signal_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DIGITAL_SIGNAL_PORTABLE_CODE)
|
bool digital_signal_optimization = true;
|
||||||
|
|
||||||
static void digital_signal_update_dma(DigitalSignal* signal) {
|
static void digital_signal_update_dma_c(DigitalSignal* signal) {
|
||||||
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)signal->internals->gpio_buff);
|
/* if transfer was already active, wait till DMA is done and the last timer ticks are running */
|
||||||
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)signal->reload_reg_buff);
|
while(LL_DMA_GetDataLength(DMA1, LL_DMA_CHANNEL_2)) {
|
||||||
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 2);
|
|
||||||
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, signal->internals->reload_reg_entries);
|
|
||||||
|
|
||||||
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
|
|
||||||
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
|
||||||
|
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)signal->reload_reg_buff);
|
||||||
|
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, signal->internals->reload_reg_entries);
|
||||||
|
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
|
||||||
|
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
|
||||||
|
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)signal->internals->gpio_buff);
|
||||||
|
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, 2);
|
||||||
|
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
|
||||||
|
|
||||||
static void digital_signal_update_dma(DigitalSignal* signal) {
|
LL_DMA_ClearFlag_TC1(DMA1);
|
||||||
|
LL_DMA_ClearFlag_TC2(DMA1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void digital_signal_update_dma_asm(DigitalSignal* signal) {
|
||||||
volatile uint32_t dma1_data[] = {
|
volatile uint32_t dma1_data[] = {
|
||||||
/* R6 */ (uint32_t) & (DMA1_Channel1->CCR),
|
/* R6 */ (uint32_t) & (DMA1_Channel1->CCR), /* base address of DMA channel 1 */
|
||||||
/* R7 */ DMA1_Channel1->CCR & ~DMA_CCR_EN,
|
/* R7 */ DMA1_Channel1->CCR & ~DMA_CCR_EN, /* CCR value to write first */
|
||||||
/* R8 */ 2,
|
/* R8 */ 2, /* CNDTR to write */
|
||||||
/* R9 */ (uint32_t) & (signal->internals->gpio->port->BSRR),
|
/* R9 */ (uint32_t) & (signal->internals->gpio->port->BSRR), /* CPAR to write */
|
||||||
/* R10 */ (uint32_t)signal->internals->gpio_buff,
|
/* R10 */ (uint32_t)signal->internals->gpio_buff, /* CMAR to write */
|
||||||
/* R11 */ DMA1_Channel1->CCR | DMA_CCR_EN};
|
/* R11 */ DMA1_Channel1->CCR | DMA_CCR_EN}; /* and CCR again to write after finished */
|
||||||
|
|
||||||
volatile uint32_t dma2_data[] = {
|
volatile uint32_t dma2_data[] = {
|
||||||
/* R0 */ (uint32_t) & (DMA1_Channel2->CCR),
|
/* R0 */ (uint32_t) & (DMA1_Channel2->CCR), /* base address of DMA channel 2 */
|
||||||
/* R1 */ DMA1_Channel2->CCR & ~DMA_CCR_EN,
|
/* R1 */ DMA1_Channel2->CCR & ~DMA_CCR_EN, /* CCR value to write first */
|
||||||
/* R2 */ (uint32_t)signal->internals->reload_reg_entries,
|
/* R2 */ (uint32_t)signal->internals->reload_reg_entries, /* CNDTR to write */
|
||||||
/* R3 */ (uint32_t) & (TIM2->ARR),
|
/* R3 */ (uint32_t) & (TIM2->ARR), /* CPAR to write */
|
||||||
/* R4 */ (uint32_t)signal->reload_reg_buff,
|
/* R4 */ (uint32_t)signal->reload_reg_buff, /* CMAR to write */
|
||||||
/* R5 */ DMA1_Channel2->CCR | DMA_CCR_EN};
|
/* R5 */ DMA1_Channel2->CCR | DMA_CCR_EN}; /* and CCR again to write after finished */
|
||||||
|
|
||||||
/* hurry when setting up next transfer */
|
/* hurry when setting up next transfer */
|
||||||
asm volatile(
|
asm volatile(
|
||||||
@@ -389,10 +395,12 @@ static void digital_signal_update_dma(DigitalSignal* signal) {
|
|||||||
"CMP r12, #0\n\t"
|
"CMP r12, #0\n\t"
|
||||||
"BNE loop\n\t"
|
"BNE loop\n\t"
|
||||||
|
|
||||||
|
/* no transfers left, the DMA has finished. now quickly re-enable with new settings
|
||||||
|
the next 4 instructions are the critical part */
|
||||||
"STM r6, {r7-r10}\n\t" /* disable channel and set up new parameters */
|
"STM r6, {r7-r10}\n\t" /* disable channel and set up new parameters */
|
||||||
"STR r11, [r6, #0]\n\t" /* enable channel again */
|
"STR r11, [r6, #0]\n\t" /* enable channel again by writing CCR */
|
||||||
"STM r0, {r1-r4}\n\t" /* disable channel and set up new parameters */
|
"STM r0, {r1-r4}\n\t" /* disable channel and set up new parameters */
|
||||||
"STR r5, [r0, #0]\n\t" /* enable channel again */
|
"STR r5, [r0, #0]\n\t" /* enable channel again by writing CCR */
|
||||||
|
|
||||||
"POP {r0-r12}\n\t"
|
"POP {r0-r12}\n\t"
|
||||||
|
|
||||||
@@ -405,7 +413,13 @@ static void digital_signal_update_dma(DigitalSignal* signal) {
|
|||||||
LL_DMA_ClearFlag_TC2(DMA1);
|
LL_DMA_ClearFlag_TC2(DMA1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
void digital_signal_update_dma(DigitalSignal* signal) {
|
||||||
|
if(digital_signal_optimization) {
|
||||||
|
digital_signal_update_dma_asm(signal);
|
||||||
|
} else {
|
||||||
|
digital_signal_update_dma_c(signal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool digital_sequence_send_signal(DigitalSequence* sequence, DigitalSignal* signal) {
|
static bool digital_sequence_send_signal(DigitalSequence* sequence, DigitalSignal* signal) {
|
||||||
furi_assert(sequence);
|
furi_assert(sequence);
|
||||||
|
|||||||
Reference in New Issue
Block a user