Can DMA_CNDTRx NDT be read zero when DMA is enabled in cyclic mode?
NDT, which is the counter, is automatically reloaded to initial settings when it reaches 0 but I cannot find in the reference manual any clear indication that it cannot be ever read 0.
I'm currently working on STM32L4A6 but the dma peripheral should be the same for most Fx.
I've worked with several dma but I have always ignored that fact.
Thanks
Related
I'm working with TIM2 on the STM32L068K which is a Cortex M0 processor. When I write to the timer enable bit, all the interrupt flags immediately get set. This in itself is a known issue and apparently endemic to the processor design based on the online commentary I've read.
I can clear out the interrupt flags by writing to the status register, but the problem is that the NVIC pending IRQ bit for this source (#15) is also set. This means that the second I execute cpsie i I get vectored to the ISR for source #15 (confirmed by seeing that this is the reported source in IPSR). I've tried multiple techniques for writing to NVIC_ICPR, but the bit remains set. As one example of many things I've tried, check out this site : https://www.sciencedirect.com/topics/engineering/pending-interrupt. I've also tried the CMSIS calls to no good effect. Do writes to this register only work in handler mode, not thread mode? And if so, how then can you stop a spurious interrupt from happening? Is it possible to manually enable handler mode without triggering an exception?
Note that this website does say "If the interrupt source generates an interrupt request continuously (level output), then the pending status could remain high even if you try to clear it at the NVIC." I wouldn't expect the TIM2 IRQ to fall into this category as it should only be triggering when the count reaches zero, which is not happening here, and the interrupt flags for it have already been cleared anyway.
Testing out an STM32 with an FDCAN module (updated from the older BxCAN peripheral). CAN Classic at 500kbps.
I am running into an issue that when using the default pair of pins (D0/D1 in my case) I get expected behavior, but when switching the pins to the secondary option (B8/B9) using GPIO remapping, I get strange output on the bus.
I tried baud settings and options like protocol exception. Nothing seems to explain where this scope output is coming from.
I'm using the HAL to get this working, so I'm certain I'm not missing any registers on remapping. I've DeInit and ReInit the FDCAN module, started/stopped, etc. There seems to be no documented "process" for remapping pins. The entire FDCAN section of the reference module doesn't have the letters GPIO.
Picture: Yellow is the CANTX 0-3V signal (low is dominant). Purple is the CAN+ signal that idles at 2.5V and pulls past ~3.5V on a dominant. There is nothing else on this line, so I'm not concerned about the sawtoothing. The large initial CAN "SOF" pulse is wrong for timing. The long recessives are nonsense. Then the small value 1 bits are of the correct 2uS pulses for 500kbps. Changing the data put into the FDCAN FIFO makes no difference, the output is always the same.
Solved.
After sending this message, the INIT bits were set in the FDCAN->CCCR register. There were values in the error counters. Indicates an internal error. I was using the HAL as a time saver, but it was over-writting my desired GPIO settings.
I would set the pins B8/B9 to AF mode for FDCAN. Then call FDCAN_DeInit/Init, which via an MSP_INIT callback also calls GPIO Init, but for the original D0/D1 pins. Meaning the B8/B9 I set, and the D0/D1 pins were enabled at the same time.
This is an obvious problem. The HAL is fine for prototyping, but careful because it will try and "help". Undefined behavior at best and I normally wouldn't even post such a dumb mistake.
However... Maybe someone else finds it interesting that whatever the FDCAN state machine is doing here, makes this unique output seen in the scope picture. I initially didn't double check my pin setup, because it looked right, I was getting output on the scope, just the wrong output. I spent much more time going over peripheral settings and data I was feeding to it.
I recently ended up in the Default_Handler in my stm32 project and couldn't figure out what was casing it:
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop <--- here!
By default, a lot of interrupts are mapped to the default handler and the only way I could figure out what the actual interrupt reason was, would be to write handlers for all the interrupts (60+) and pause the code in the debugger. Bah!
I didn't find a good answer googling, so I thought I document the solution for others (or most likely myself in 6 months...)
So, it turns out there are some registers in the NVIC (interrupt controller) that we could use:
The above is from the STM32CubeIDE debugger. NVIC_IABRX contains a bitmask of the currently active interrupts and I can see that NVIC_IABR1 has a non-zero bit (it's 0x1000).
Each IABR reg is 32 bits wide, so with some simple bit counting I conclude that the interrupt source is 32+12 = 44. Now I need to look at the datasheet for my mcu (an stm32wb55) so see what that corresponds to:
Aha, so it's the IPCC that's causing the interrupt! To double check, I added a handler for this specific interrupt
void IPCC_C1_RX_IRQHandler(void)
{
}
And it got called!
Note: I initially just had a look at interrupt vector in the startup_stm32xxx.s file and counted from the start of that but that didn't work out since the first few interrupts are not included in the NVIC_IABRX registers.
I am working on a custom battery powered board with a STM32F746 on which I would like to set the RDP option byte to level 1 from code. Basically, while booting the software checks if the option bytes are set correctly and if not it will reprogram the option bytes to the correct values. This means that any unit shipped to customers is ensured to have the read-out protection set and we don't have to worry about the assembly house forgetting to set it and thus exposing the firmware.
To do this, I follow the procedure in the reference manual:
unlock the option bytes by writing the correct keys to FLASH_OPTKEYR and clearing OPTLOCK
set the desired option values in FLASH_OPTCR
set OPTSTRT in FLASH_OPTCR
This works fine for all option bytes except RDP, which locks the MCU after setting OPTSTRT. As far as I can tell, this is intended behaviour, and requires a reset of the device through a power cycle after which the option byte is set correctly. But since our board is battery powered (soldered connection) this is a bit cumbersome and so my first question is if there exists another way of doing this.
A bit of googling revealed that some STMs can also activate the altered option bytes by transitioning from the STBY state, here is a specific example by ST: https://www.youtube.com/watch?v=f7vs0NwZPFo&ab_channel=STMicroelectronics.
So far I have no luck with this method: when returning from STBY the RDP is not set. The example deals with an STM32L4, does anyone know if this method is supported on the F7?
I have DMA2 stream 0 configured so that it transfers given number of samples from ADC3 (triggered by TIM2 rising edge) to memory, and after completing the transfer an interrupt happens in which I make calculations on the samples gathered.
Everything is working as intented, except that I would like to be able to repeat the whole process. Transfer should be started by user command (button press, or eventually by command send through USART), therefore I can't use DMA in circular mode for this task.
From what I've found, it is possible to re-run the transfer by modifying some registers and restarting the DMA and ADC, yet I was unable to complete the task. What is the correct set of instructions I have to run to achieve my goal?