VamPI - Vampire SPI to Raspberry PI interface: Target: Raspberry Pi 0 W Raspberry Pi 3 is not a good option for this because the power requirements are too high. The Pi 0 W can provide all core functionalities in <3 watts. Core functionalities (planned to be implemented): DC Pri Functionality Description W 1 Wifi packet Pre-decoded Wifi Packet (SANA II compatible frame) w 1 Wifi control Wifi interface control channel U 1 USB interface Raw USB packets ready for Trident/Poseidon u 1 USB control USB interface control channel D 1 Disk interface Exposes remaining SD card space as an RDB disk d 1 Disk control Disk control channel and configurator C 2 Battclock battclock.resource compatible interface for NVRam/Time c 2 Battclock control Reserved for battclock control channel @ 2 Remote reset Remote power or reset F 3 Floppy emulation Raspberry Pi Floppy emulator for Amiga f 3 Floppy control Control channel for floppy emulation P 4 Pi Shell Access to a Pi TTY p 4 Pi Console Access to Pi console device Potential functionalities (not planned to be implemented but could be): A X AHI data Reserved: AHI unit to BCM283x sound a X AHI control Reserved: AHI control channel N X bsdsocket packet Reserved: Pi provided socket stack n X bsdsocket control Reserved: socket stack control channel S X Screen data Reserved: P96 compatible interface to Pi framebuffer s X Screen control Reserved: Framebuffer control channel G X GPIO data Reserved: PI GPIO access g X GPIO control Reserved: PI GPIO control Device channels typically use a capital letter for a data interface and a small letter for its corresponding control interface. Channel specs and reservations: $00-0F (Control characters) Reserved $10-1F (Control characters) Data channels for prototype / user channels $20 Firmware interface (a control channel) $21-2F Reserved $30-3F (Numerics) Control channels for prototype / user channels $40-5F (ASCII capitals) Data channels $60-7F (ASCII smalls) Control channels $80-FF Bit 7 set to indicate entire channel is either offline (on either Amiga or Pi side) or that the channel is not implemented or not active. If you get a packet back that is "acknowledged" but bit 7 in the DC, the rest of the header will be filled with error information, usually in the function number, and the payload may contain an error message. How it is expected to work: Amiga side: There will be a primary driver (probably vampi.device) that will receive all SPI data on SPI CS2. It will be responsible for checking the packet integrity and dispatching packets to and from the Pi. It will also send data on the control channels as function calls to the appropriate device driver (example wifi.vampi.device), and sending the raw data as needed to those drivers. With the primary device handling the packets, it is expected that adding drivers for additional functions will be easy to do as needed. Pi side: A kernel module will be responsible for dispatching data to and from the Amiga. This interface will be a character device (/dev/amiga/) that userspace modules will be able to open. Control channels and data channels live side by side here, anotherwords data arriving for the USB interface will arrive in /dev/amiga/U and can be controlled over /dev/amiga/u. The pi side userspace handlers send their raw packet to their device, but their device channel in their packet will be made to match the device channel they have opened. Additionally, the userspace handlers only receive data on their channel, eliminating their need to check that in the handler. Devices are created in /dev/amiga/ as their Amiga side drivers initialize, or when the pi side driver goes to access it. Both sides: Both sides are expected to check the integrity of their packets and respond accordingly at the base driver level. Once dispatched to a handler, error channels should be used to return an error state to the other side. Expected setup procedure (pi side): "Firmware" as in a buildroot with the Vampi kernel and support software will come as an image that can be written to any sized SD card you want. Any space not used by the flashed firmware will be auto-partitioned and exposed as a disk to the Amiga. On the Amiga, the installation of an LHA containing vampi.device and implemented device driver modules will need to be extracted to DEVS: . Expected directory structure is: DEVS: vampi.device VamPI (Dir) deviceclass.vampi.device ... Interface: Due to massive limitations to the SPI interface on Raspberry Pi, i've decided to write my own SPI slave module on the GPIO bus with blackjack and hookers. It will be implemented as a kernel module for maximum performance and will map an SPI slave to the following pins: Pi GPIO 5 Pin 29: SPIs MISO Pi GPIO 6 Pin 31: SPIs MOSI Pi GPIO 12 Pin 32: SPIs CS Pi GPIO 13 Pin 33: SPIs CLK Pi GPIO 26 Pin 37: SPIs IRQ Please note that when transfers are taking place, multitasking on the Raspberry Pi will be halted, as reading a packet at ~47mhz requires realtime latency on the Pi. The floppy emulator interface sits on the Pi SPI0 bus. The Vampire should be wired to SPIs as above and if a floppy emulator circuit is present it should be wired to SPI0. Expected wiring should be as follows: Pi Amiga VCC 5v 2 <-> 5v Power supply contact GND 6 <-> GND Power supply contact Pi Vampire CS SPIs 32 <-> 4 EXP nCS2 MOSI SPIs 31 <-> 8 EXP MISO MISO SPIs 29 <-> 1 EXP MOSI SCLK SPIs 33 <-> 6 EXP CLK IRQ SPIs 37 <-> 6 EXP IRQ For the optional floppy emulator at http://amigadrive.blogspot.com/ wire it just as listed at the site. The interface for Vampi is designed to not interfere with this interface. Raw signaling (General rules for contacting the pi on the SPIs interface): 1) To send packets from the Amiga to the Pi, a) Assert nCS2 (Signaling data available) b) Wait for MISO to go high (Signaling ready to receive) c) Send a single packet over MOSI d) Lower the nCS2 line (Signaling data finished) e) Wait for MISO to go low (Signaling data received) You may immediately repeat this procedure if more data needs to be sent. 2) To send packets from the Pi to the Amiga: a) Assert IRQ (Signaling data available) b) Wait for MOSI to go high (Signaling ready to receive) c) Send a single packet over MISO d) Lower the IRQ line (Signaling data finished) e) Wait for MOSI to go low (Signaling data received) 3) As can be inferred from the above, a receiver should a) Check if its assertion line (nCS2/IRQ) is high b) Raise its output line to signal it is ready to receive data, MISO for Pi->Amiga, MOSI for Amiga->Pi. c) Receive input on its input line, until the (nCS2/IRQ) line is lowered. d) Once all data is buffered, lower its output line indicating data has been received, Note "Received" just mean in a buffer for processing. Verifying packet integrity and dispatching the packet comes later, and AFTER the SPI bus is freed. 4) All lines should remain low at any other times. 5) If a packet is indicated to be a burst packet, the receiver should prepare to receive the next packet ASAP, foregoing giving time to other processes if it is reasonable to do so at that time. Packet structure: 64 bit header with up to 4k of data per packet. Packets are big endian, it is the Pi's responsibility to do any endian changes required to send or receive the packet. 0000000000111111111122222222223333333333444444444455555555556666 0123456789012345678901234567890123456789012345678901234567890123 ---------------------------------------------------------------- | DC || Func || DID ||FLAGS ||SQ| PL Size || 16bit CRC | ... payload ---------------------------------------------------------------- DC: Device code as given above Every function provided by the pi is given a code, usually an ASCII character, but can be any byte value except 00 and FF (reserved), which tells the SPI driver what device type the packet is addressing. Func: Function number Every device class has different function numbers, see docs for that device class. On a data channel, the "function" can be used by the driver as desired. DID: Device id (for multiple device addressing) If you have multiple devices to address, this allows you to select up to 240 different devices in a device class (such as USB disks, sound channels, etc). Do not use device addresses $F0-$FF, they are reserved. in particular $FF is reserved for "all devices". Flags: See below Sq: Sequence number Incremented for each packet modulo 16. Each time a packet is received, the header should be sent back with bits 30-31 set accordingly as an acknowledgement. If your driver is more than 16 packets behind in acknowledgments, send 11 in bits 30-31 too tell the remote host to wait. PLsize: Payload size This is in bytes, up to 4k packets supported, send exactly this number of bytes after the header. CRC: Packet CRC check Calculated as expected for a CRC check. Flags (8 flags reserved): 24-25: 00 Lone packet 01 Start burst 10 Continued burst 11 End burst 26: Header parity (Even expected) 27: 0 On packet error: Packet header parity was bad 1 On packet error: Packet payload CRC was bad 28: 1 Payload continues into next packet, for transfers greater than 4k 29: 1 This is a retransmitted packet 30-31: 00 Ready to receive 01 Packet acknowledged 10 Packet error 11 Not ready to receive The PI SPIs can have high latency if you try to use interrupts per packet, as it will allow OS processes to run even if more data is immediately available to be sent. Bits 24-25 implement a burst mode for communication between the two devices. 00 Lone packet Accept this packet without entering a burst mode. (continue to service interrupts) 01 Start burst This is the first packet in a burst. Accept this packet and prepare to receive the next without waiting for an interrupt. 10 Continued burst This is the next packet in a burst, Accept this packet and prepare to receive the next without waiting for an interrupt. 11 End burst This is the last packet in a burst. Accept this packet then return to servicing interrupts. Note that ending a burst does not necessarily end a transfer. Burst mode can be started and ended arbitrarily. Packet confirmation and integrity testing is "TCP-like" and implemented in the last 2 flags: 00 Ready to receive Usually used after sending a 11 Not ready to receive, tells the sender you are ready to continue receiving packets. 01 Packet acknowleged This is sent when you have received a packet and the CRC is correct. Send the header back as is with these bits set as indicated. 10 Packet bad CRC / Packet header parity bad Sent when the CRC (of payload) or header parity is bad. Bits 28 and 30-31 will indicate what conditions exist. If header parity is bad then the header cannot be trusted and the sender should resend any packets it has not received an ACK for. Else it should resend the packet matching the sequence number. 11 Not ready to receive Should be sent if: 1) The receiver is going to need to stop processing packets for a bit (a realtime process on Pi or the Amiga is going Forbid() or otherwise entering a non-multitasking state) 2) The receiver has received 16 packets and has not acknowledged them yet 3) The receiver has been in burst mode for an excessive amount of time and needs to give the OS time 4) Any other time the receiver must stop receiving packets. The receiver should avoid doing this whenever possible as it halts the operation of all drivers. Payload structure: For "data channels", the payload is usually raw data that can be used directly by a driver, such as USB channel data, ethernet packets, PCM data, etc. The "function number" on data channels can also be used as the driver sees fit. For control channels, this structure should be used: <32 bit key> <4 bit datatype> <12 bit length> <#Length bytes> ... repeated as needed until all control data is sent. If the control data exceeds 4k, you can split it on 4k boundaries and send it in burst mode. The control sequence should terminate with 48 bits of zeroes (6 bytes). An example might look like this: "SSID" $1 $005 "Amiga" $000000000000 Which should translate on each side to a key of "SSID" containing a 5 character string with the value "Amiga". The key should always have 4 bytes of data in it padded with nulls if necessary. Datatypes should be as follows: $0 End of data $1 String $2 Integer $3 Float $4-$E Reserved $F Pointer There will be routines on both the Amiga and Pi sides that will turn these packets into structures of data that your driver can use directly.