MichaelM wrote:
The description provides some good ideas that may be useful when modifying my SPI Master peripheral in the future.
Feel free to use it, I don't mind to get refered for, even considering that it's not special in any way, just the usual maping of the a protocoll into simple hardware. I'm from a time when design was about functionality, not 'the way it's told'
) Being an oldtimer, I'm still thinking in TTL structures, not realy in terms of programmed logic. That's also the reason why $00 is transfered during read operations, as clearing the transmit register can be obtained by selecting the right 74xxx, while puting toward all ones would require another circuit. You may want to change this to $FF, as it reduces power consumption during reads.
MichaelM wrote:
You need free address space for implementing the memory-mapped interface ideas described. For the M16C5x project the
SPI Master interface had to map into a limited number of addresses since it was being added to a PIC soft-core. For the M65C02/M65C02A projects, the
SPI Master has a bit more freedom with the address space available. I may consider modifying my M65C02/M65C02A SPI Master core in the manner described..
From an outside view only 3 adresses are needed, as A/B can share adresses with C/D. A/B is write only, while C/D is read only. Even more, they only differ in CS handling, so they can be formulated as one unit. Only E offers additional functionality as it clears (well FFs) the transmit register and starts a transmit cycle as if that value had been writen to like using address A.
The assignment of different registers to one address and seperation via R/W (or WR and RD) is just another exampel of the same philosophy of using _all_ interface lines to transfer meaningful data
In my implementation another register pair is used mostly for the usual aspects (POL,CLK, Device select, etc.) two status bits might be interesting for you:
- SUA - SetUp Active - The interface has been configured
- TFA - TransFer Active - A Transfer is active (CS pulled)
While TFA basicly just echos the CS state, SUA gets set whenever there is a writing access to (one of) the controll register(s). It only gets reset when CS is released.
These bits come in handy as locking semaphores for concurent access in either a multi tasking enviroment, or just plain foregound and interrupt routines using the same SPI controller. Since they are derivated from and within the used hardware, they provide a fastdevice allocation method with (next to) zero software overhead. Of course it's not perfect or for complicated situations but when your OS is that complex, you'd need additional software layers anyway.
Whenever SUA (or TFA) is set, some process the SPI interface is occupied by some other process. In case of a foreground process this means is needs to sleep a bit (or use whatever machanism are provided) and aquire the device later. Similar during an interrupt (*1). This is all due the fact that SPI transfers can be slowed down, but usually not interrupted. So the SPI controller resource is not shareble during a transfer (*2). As with every semaphor seting, the check/set process needs to be safe within a CLI/SEI region. But thanks to our flags, only during a maximum of 10-14 cycles. (*3)
So even with the control register all I need is 5 controll lines (A1, A0, R/W, Phi, SEL)
MichaelM wrote:
The design philosophy described that the peripheral can relieve the processor of some of the "drudge" work necessary to execute a data exchange is well worth considering, particularly when the potential improvement in throughput is as described above.
Performance it is
Anyway, thanks or your interest. It would be nice to see any implementation of yours. And BTW, I liked the way you structured and documented your M16C5x project and files.
H.
--
*1 - Well, with modifying SUA/TFA into some kind of state numbering scheme like Reserved/Setup/Transfer Started/Last Transfer/Released an interrupt could see not only if a the device is in use, but also if the release is immanent (Last Transfer). Considering that going into an interrupt on a 6502 needs at least 7 cycles, plus 3 to check the state bia BIT, it would be only useful with extreme slow devices with less than CPU CLK/16 timing. Even assuming that transfers in a controll environment are usually rather short, thus waiting might be useful, it doesn't releif the need for something to postpone the interrupt in case it's not the last byte. Further more, as slower the devices get, as less acceptable are wait loops for release during an interrupt. So, still not sure if a more complivate status messaging is helpful at all.
*2 - Well, there are devices, most notably memories offering a way to suspend activity via a hold input, just support for this would need quite some hardware (i.e. a last byte buffer for each level on hold) - at least for a general purpose solution - and even more complex software.
*3 - When using a 65C02 it opens an option to add a mechanism using TSB on SUA (in a paralell, writabel address) as a 'device reserved' mechanism to remove the need of CLI/SEI. But that opens another list of constrains for the design.