Other Parts Discussed in Thread: HALCOGEN
Hey everyone,
I'm in the middle of developing a board support package for SPI communication. To make a long story short, I'm using the master and slave's respective R5F PMUs to monitor timeouts/ abort transfers. I was originally intent on just using the built in C2EDELAY interrupt to flush/ clear out the SPI Tx registers and buffers. However this feature only exists in the master. Plus HALCOgen doesn't seem willing to let me specify a delay less than 1ms (my SPI baud is 1MHz).
My current line of thinking is to toggle SPIEN (SPIGCR1). For thoroughness I've put the peripheral control registers in an MPU region with device type and non-shared settings. From stepping through the code I noticed I ended up needing a "DMB" instruction anyway. So maybe this alludes to my MPU settings being incorrect (see screenshot below; regions 0-12 are not enabled).
Below is the current crux of my code. What I'm about to describe is occurring on the slave side. I haven't looked at the master side yet. I ended up framing the code in a 'while' block, because I wasn't clear from the User Manual whether toggling SPIEN flushes out the TXBUF. I figured this was the most thorough way to do it. By line 6 of this code SPIFLG is cleared. The code flow even breaks out of this loop. One instruction later though I see TXINTFLG re-asserted. So my question is: how do I reset the Tx hardware manually? I feel like I'm close.
My suspicions so far are:
1) Need to insert a delay because SPI peripheral (not the bus) runs at a slower rate. Maybe that means I'm missing TXBUF being copied into the shift register after the toggle.
2) Maybe something's going on with cache, but I thought device type memory would force write throughs all the way to the real memory location.
1: while (spi->FLG != 0x0UL) 2: { 3: spi->GCR1 = spi->GCR1 & 0xFEFFFFFFU; 4: asm("DMB"); 5: spi->GCR1 = spi->GCR1 | 0x01000000U; 6: }