This was fueled by a user’s request to generate a 12MHz square wave output…
At 12MHz, the only most one reliable option would be a PIO program. I’ve dug into the PIO assembly and byte code in the past … so it got me thinking.
Could the buspirate allow dynamically adjusting and loading a (restricted) PIO program to control the plank outputs?
Overly-long details
The PIO byte code is surprisingly easy to parse. However, it would need to be restricted to a subset of instructions (at least initially), or else it’d easily mess up operation of the device.
Initial version restrictions
-
Restrict GPIO access in the incoming program to between 0…7
-
Restrict features (at least initially) to exclude…
- IRQs
- side-set other than pins 0…7
- write to a pin other than 0…7
- read to a pin other than 0…7
- etc.
-
Generally Permitted Interaction:
- Delay / side-set - all variations OK (Must map within GPIO 0…7)
JMP- address must be within program boundsWAITsourceof0b00– Allowed (abs. GPIO)sourceof0b01– Allowed (rel. GPIO)sourceof0b10– REJECTED (PIO IRQ, clears IRQ)sourceof0b11– Allowed (JMP PIN)
IN- All variations permitted except reserved sources0b100,0b101OUTdestinationof0b000(PINS) - ? see 11.5.6destinationof0b001(X) - Alloweddestinationof0b010(Y) - Alloweddestinationof0b011(NULL) - Alloweddestinationof0b100(PINDIRS) - ? see 11.5.6destinationof0b101(PC) - REJECTEDdestinationof0b110(ISR) - Alloweddestinationof0b111(EXEC) - REJECTED
PUSH- All variations permitted (verify all fixed bits)PULL- All variations permitted (verify all fixed bits)MOV to RX- All variations permitted (verify all fixed bits)MOV from RX- All variations permitted (verify all fixed bits)MOV Dest/Src
*destinationof0b000(PINS) - ? see 11.5.6
*destinationof0b001(X) - Allowed
*destinationof0b010(Y) - Allowed
*destinationof0b011(PINDIRS) - REJECTED
*destinationof0b100(EXEC) - Allowed
*destinationof0b101(PC) - REJECTED
*destinationof0b110(ISR) - Allowed
*destinationof0b111(OSR) - Allowed
*operation- All non-reserved variations OK
*sourceof0b000(PINS) - Allowed?
*sourceof0b001(X) - Allowed
*sourceof0b010(Y) - Allowed
*sourceof0b011(NULL) - Allowed
*sourceof0b100(reserved) - REJECTED
*sourceof0b101(Status) - Allowed
*sourceof0b110(ISR) - Allowed
*sourceof0b111(OSR) - AllowedIRQ- REJECTEDSET- Destination, Datadestinationof0b000(PINS) - ? see 11.5.6destinationof0b001(X) - Alloweddestinationof0b010(Y) - Alloweddestinationof0b011(reserved) - REJECTEDdestinationof0b100(PINDIRS) - ? see 11.5.6destinationof0b101(reserved) - REJECTEDdestinationof0b110(reserved) - REJECTEDdestinationof0b111(reserved) - REJECTED
WARNING! This presumes the eight plank outputs are contiguously numbered GPIO.
OUT/SET/SIDE-SET restrictions
To allow OUT, SET, and SIDE-SET, the following restrictions will ensure the PIO only affects the eight plank output pins:
OUT–PINCTRL_OUT_COUNTwill default to8(range 8…1), andPINCTRL_OUT_BASEwill default to the GPIO for plank pin0. (range +0…7). IfPINCTRL_OUT_BASEis increased,PINCTRL_OUT_COUNTwill be decreased accordingly.SET–PINCTRL_SET_COUNTwill default to8(range 8…1) andPINCTRL_SET_BASEwill default to the GPIO for plank pin0(range +0…7). IfPINCTRL_SET_BASEis increased,PINCTRL_SET_COUNTwill be decreased accordingly.SIDE-SET–PINCTRL_SIDESET_COUNTwill default to0(range 0…5 / 0…4 if optional) andPINCTRL_SIDESET_BASEwill default to the GPIO for plank pin0(range +0…7).PINCTRL_SIDESET_COUNT+PINCTRL_SIDESET_BASEshall be enforced to fit within the GPIO used by the plank outputs.
Those hidden details would be sufficient to support a large subset of the PIO commands, certainly sufficient for simple programs such as a 12MHz clock output on some (or all) of the plank outputs…
Not in my short-term queue, but putting the details out early, as enabling a “safer” PIO for classroom experimentation might be of interest to some folks…?