Do STM32 DMA and CPU interrupts interfere ? - Page 1
Forum section: electronics / general

author: SpacedCowboy
author_rank: Frequent Contributor
timestamp: June 14, 2023, 07:06:53 pm
content: I'm noodling on having an STM32 (specifically a STM32H750 because it's a fast chip with 5v tolerance on most pins) interface to a 6502 bus with timings as below.I have 177ns from the falling edge of the 6502 bus-clock Phi2 to me reading the address, and then a further 48ns to having to assert /MPD (and /EXTSEL, though that's not shown in the diagram) if I want to handle the memory access instead of letting the 6502 system handle it. There's then a relative eternity to actually do the lookup-memory and handle read/write on the bus until the next clock cycle when I have to relinquish the bus again, some short time after the clock falls.I'd prefer to do this using event-driven processing, so I'm not busy-waiting the STM processor, I have other things it can do... I was thinking there were three main events to handle hereRead of the address. This can be a timer interrupt, triggered by clock-fall, building the latency of the interrupt into the timer delay appropriately, so it the event happens more or less on the dot of 177ns (or 85 clocks at 480 MHz)If it's a write-op (from the perspective of the 6502), I need to schedule another timer to trigger at 422ns (or 203 clocks @ 480MHz), read the 6502 D bus and populate STM memory at the already-stored addressIf it's a read-op (again from the perspective of the 6502), I can do all the work and push to the 6502-data lines as soon as I read the address. This means I end up driving the database early by the diagram's requirements, but I doubt that will be a problemThe problem comes with the last of these - since I had to enable the STM to drive the 6502 D[0..7] lines, I have to make those outputs into inputs pretty soon after the clock cycle ends. I can think of a few options:I could busy-wait (yuck),I could try using a timer again. I don'tthinkthere would be a conflict between the timer-event to clear the directionality (triggering some short time after Phi2 falls) and the timer being set up by Phi2 falling to read the address for the next clock in 177nsI could trigger a DMA interrupt based on a timer to write the correct value into the direction register to make them inputs again shortly after Phi2 fallsGiven this is very timing-based, I guess I'm not sure if the action to install the read-the-address timer interrupt at the start of the Phi2 clock cycle would be affected by an interrupt going off during that process if I'm using the second approach (ie using the CPU) or whether I'd be more insulated from that if I install a DMA event to trigger at the same time as I'm installing that read-the-address timer interrupt ?Or maybe there's an easier way to do it that I'm missingAny help gratefully appreciated... My pseudo-code outline currently looks like:Code:- enable interrupt on CLK fall- enable DMA to write to set direction regs of D at clk+30, make them all inputs- @IRQ,- set timer interrupt to trigger @177ns- set DMA interrupt from timer- unset 'isOurs' // flag to say we're responsible for this memory location- @177ns,- read A- if extmem[A>>8] == 1 // working with 256-byte page quanta- set MPD/EXTSEL- set isOurs- read 6502-rw from bus- if (read)- read mem- if isOurs- push to D- set D to output- enable interrupt on CLK fall- else- set timer irq to trigger @422ns- @IRQ, read D- write D to mem- enable interrupt on CLK fall

author: wek
author_rank: Frequent Contributor
timestamp: June 14, 2023, 08:25:19 pm
content: You can hold the data bus until the mcu outputs data in the next cycle (assuming it's a write cycle - if not, you don't need to release data bus anyway). So, if you succeed in timing all other things, you can simply release it just before or after reading the address.However, did you benchmark any of these? If not, you may be surprised...http://www.efton.sk/STM32/gotcha/g108.htmlTry perhaps just the first step, read the address and perhaps just echo it to some spare pins, to see what's your timing budget.JW

author: SpacedCowboy
author_rank: Frequent Contributor
timestamp: June 14, 2023, 10:00:03 pm
content: Huh, I wasn't aware of the timing issue, no.I was trying to come up with a way of doing this without using an FPGA, and the RP2040 is distressingly pin-shy, but perhaps I ought to go look over that plan again ...Thanks

author: wek
author_rank: Frequent Contributor
timestamp: June 14, 2023, 10:09:20 pm
content: I didn't say it can't be done, just that you have to be careful.JW

author: SpacedCowboy
author_rank: Frequent Contributor
timestamp: June 15, 2023, 02:44:18 am
content: Reading around, itlooks likea GPIO can be toggled in a tight loop at ~20MHz if you doCode:register volatile uint32_t* bsrr = (uint32_t*) (GPIOB_BASE + 24);register const uint32_t set = (uint32_t) GPIO_PIN_11;register const uint32_t reset = (uint32_t) GPIO_PIN_11 << 16U;while (1){*bsrr = set;*bsrr = reset;}That's a half-period (I only need to assert, for the fast case) of ~25ns, which is close to my ~40ns budget given that I have to do some interrupt bookkeeping and a lookup (even if in DTCM). There's also the issue of jitter coming through the various busses - I don't care if it jitters earlier, but I care if it jitters laterI ... think I've been spoilt with fast-response ports. I'm glad I asked here, though...