Checkpoint on the Shield Adapter and SPI Software
I’m going to stabilize the Shield Adapter hardware and related SPI software for now. The Schematic version 6 uses an 8 pin AVR to generate a 1 Mhz clock that is triggered automatically when the 1802 writes to the 4021 Master Out Shift Register(MOSR) with OUT 6. The AVR generates 8 pulses on SCK and the inverse /SCK. SCK notifies the slave to read the output of MOSR on MOSI and it latches the signal from the slave on MISO into the 74595 Master Input Shift Register(MISR). /SCK is used to advance the bits in MOSR and to clock the shifted bits in MISR from the shift register of the 74595 to the storage register where it can be read by the 1802 with INP 6.
At 1 mhz you need to leave one instruction time between accesses to the SPI registers. I know how to fix this but it’s not a big problem so I’m leaving it for now. The 1802 code shown includes 4 SPI routines:
- spixfer loads 1 byte out to MOSR and reads one from MISR. This is the standard SPI sequence
- spiSend loads 1 byte to MOSR but does not bother with the readback
- spiSendN transfers N bytes to MOSR as quickly as it can
- spiReceiveN sends garbage out to MOSR and reads MISR into a supplied buffer
There doesn’t seem to be a need for an individual spiReceive or an spixferN.
//hspi2.c - routines for hardware spi on olduino with shield adapter outboard clock //spixfer sends and receives, spisend output only //spisendN spireceiveN, multibyte send and receive //dec 18 cleanup spixfer: //send and receive one byte over SPI //this code depends on the argument being in Reg 12 and returned value in reg 15 glo 12 //get the char to be sent dec 2 //make a work area str 2 //save the character out 6 //this loads the shift register and starts the outboard clock dec 2 sex 2 //delay to allow outbound shift to complete inp 6 //read the shift register plo 15 //leave it in 15 inc 2 //restore the stack cretn spiSend://this is for output only //this code depends on the argument being in Reg 12 glo 12 //get the char to send dec 2 //make a work area str 2 //place the outbound char out 6 //this loads the MOSR and starts the outboard clock cretn //there needs to be a 1 instruction gap before the next spi accesee - return is 12 or so spiSendN: //send n bytes over spi -buffer address in R12 and a non-zero count in R13 sex 12 //point X to the buffer $$spiSendLoop: //we will do this N times out 6 //this sends out a byte dec 13 //decrement the byte count glo 13 //check bottom byte of counter bnz $$spiSendLoop //back for more if needed - 4 inst. per byte ghi 13 //check high byte of counter if necessary bnz $$spiSendLoop sex 2 //reset X register cretn //return to caller spiReceiveN: //Receive n bytes over spi sex 12 //point X to the buffer dec 12 //back off so the first OUT will leave us in the 1st position $$spiRxvLoop: //we will do this N times out 6 //this sends out garbage and clocks in the 1st character dec 13 //decrement the byte count(and allow shift to complete) inp 6 //this reads the nth byte into the nth buffer location glo 13 //check bottom byte of counter bnz $$spiRxvLoop //back for more if needed - 6 inst. per byte ghi 13 //check high byte of counter if necessary bnz $$spiRxvLoop sex 2 //reset X register cretn
I’m going to leave the hardware and software alone for now. If I do another run I would do the following in priority sequence:
- Gate the signal that loads MOSR with TPB and /MRD. Even with a 1mhz clock there would be no delay needed between accesses
- Use the cpu clock and a counter to replace the AVR
- replace the 4021 with a 74165 to allow the clock speed to go above 2.5 mhz.