-
-
Notifications
You must be signed in to change notification settings - Fork 24
spi_slave
Slave mode allows other SPI masters to acces the K210 slave buffer memory.
Slave buffer can be configured as memory area of 512B ~ 1MB, with optional read only area at the end of the buffer.
Master can read from or write to slave buffer (except to the read only area.
Maximal supported SPI clock (from master) is 24 MHz
If master device supports 3-line SPI mode, master and slave can be connected by only 3 lines:
MOSI
, SCK
and CS
.
If master device does not support 3-line mode, K210 slave must be configured for 4-line communication (MISO
used) and master and slave must be connected by 4-lines:
MOSI
, MISO
, SCK
and CS
.
Master <-> Slave communication is performed using the simple communication protocol:
- Master sends to the slave a command block requesting specific operation
- Master reads or sends data from/to slave depending on the requested operation
Before reading or writting any data, master must send to slave the 8-bytes command block describing the specific operation.
The structure of the command block is as follows:
Position | Length | Desctiption |
---|---|---|
0 | 1 | Command code |
1 | 3 | 24-bit slave buffer address |
4 | 3 | 24-bit data size or special meaning, depending on command |
7 | 1 | CSUM byte, generated as xor operation over 1st 7 bytes |
Here is a typical Python code used to generate the command block:
def setcmd(cmd, addr, size):
spi_cmd = bytearray(8)
spi_cmd[7] = 0
spi_cmd[0] = cmd;
spi_cmd[1] = addr & 0xff
spi_cmd[2] = (addr >> 8) & 0xff
spi_cmd[3] = (addr >> 16) & 0xff
spi_cmd[4] = size & 0xff
spi_cmd[5] = (size >> 8) & 0xff
spi_cmd[6] = (size >> 16) & 0xff
for i in range(7):
spi_cmd[7] ^= spi_cmd[i]
return spi_cmd
The following commands are accepted by K210 SPI slave:
Command code | Command | Description |
---|---|---|
1 | SLAVE_CMD_TEST |
Test command, slave responds by sending requeste number of bytes of requested value address field must be set to the requested byte balue (0~255) size field must be set to the requested number of bytes |
2 | SLAVE_CMD_INFO |
Request K210 SPI slave info Slave send the 18-byte info block containing the slave driver version, size of the slave buffer and size of the read only area See slave example for more information |
3 | SLAVE_CMD_STATUS |
Request the status of the previously executed command Slave responds by sending 26-bytes status block See slave example for more information |
4 | SLAVE_CMD_WRITE |
Master writes data block to slave buffer. address field must be set to the slave buffer address size field must be set to the data block size |
5 | SLAVE_CMD_WRITE_CSUM |
Master writes data block to slave buffer. address field must be set to the slave buffer address size field must be set to the data block size 2-bytes CRC16 csum must be appended to the data block by the master |
6 | SLAVE_CMD_READ |
Master reads data block from slave buffer. address field must be set to the slave buffer address size field must be set to the data block size |
7 | SLAVE_CMD_READ_CSUM |
Master reads data block from slave buffer. address field must be set to the slave buffer address size field must be set to the data block size 2-bytes CRC16 csum is appended to the data block by the slave |
Set slave buffer at address addr
to the content of the buffer object buffer
Writting to the read only area of the slave buffer is allowed.
Fill the whole slave buffer with the byte val
Get len
bytes from slave buffer at address addr
Returns bytearray containing the slave buffer data
Set the callback function to be executed on slave events.
If function=None
, disables the callback if previously enabled.
import machine
# This will create 8K slave buffer
s=machine.SPI(machine.SPI.SPI_SLAVE, mosi=15, miso=16, sck=10, cs=9, slave_buffer=8192)
# We can also use slave buffer allocated on MicroPython heap
# This, for example, creates 512K bytearray which is used as slave buffer
#sbuffer = bytearray(512*1024)
#s=machine.SPI(machine.SPI.SPI_SLAVE, mosi=15, miso=16, sck=10, cs=9, slave_buffer=sbuffer)
buff = b'12345678abcdefghijklmnoprstuvzABCDEFGHIJKLMNOPRSTUVZ'
s.fillbuffer(ord('@'))
s.setdata(buff, 0)
s.getdata(buff, 0)
# Example callback function
def spicb(res):
cmd = res[0]
err = res[1]
if err == 0:
stat = "OK"
elif err == 1:
stat = "Wrong command"
elif err == 2:
stat = "Csum error"
elif err == 3:
stat = "Data csum error"
elif err == 4:
stat = "Wrong address"
elif err == 5:
stat = "Wrong length"
elif err == 6:
stat = "Timeout"
else:
stat = "Error"
if cmd == 1:
command = "Test"
elif cmd == 2:
command = "Info"
elif cmd == 3:
command = "Status"
elif cmd == 4:
command = "Write"
elif cmd == 5:
command = "Write (crc)"
elif cmd == 6:
command = "Read"
elif cmd == 7:
command = "Read (crc)"
else:
command = "None"
#print(res)
print("SPI command: {}, status: {}".format(command, stat))
if cmd > 4 and err == 0:
print(" Address={}, length={}".format(res[2], res[3]))
s.callback(spicb)
- Maix-M1 schematic
- Maix-Bit schematic
- Maix-Go schematic
- Kendryte K210 datasheet
- RISC-V ISA Design
- RISC-V ISA Manual
- Forum
- MicroPython documentation
If you find this project useful, you can contribute by making a donation