Control serial communication with python and perform I2C communication (using USBGPIO8 device), so please read the I2C edition first.
Although there are basic specifications, I think it is better to refer to the data sheet for each IC. The following is an easy-to-understand explanation of general SPI communication. http://www.picfun.com/f1/f05.html https://lab.fujiele.co.jp/articles/8191/
EEPROM (AT93C46) used in this article has CS (chip select) opposite to normal. ** HIGH to start communication and LOW to end communication. ** ** Generally, LOW starts communication and HIGH ends communication.
I should have experimented with a general IC, but I chose AT93C46 because AT93C46 was the cheapest at 30 yen among ICs that use SPI, and as a result, the article lacked versatility.
Control USBGPIO8 using serial communication with python, control IC (EEPROM) from USBGPIO8, write 2 bytes, then read 2 bytes Confirm that the written value can be read.
Let CS be port 0 of USBGPIO8. Let SK be port 1 of USBGPIO8 (clock) Let the 2nd port of USBGPIO8 be DI Let port 3 of USBGPIO8 be DO
16-bit mode with Vcc connection for No. 6 (ORG) 8-bit mode with No. 6 (ORG) connected to GND This time, we will operate in 16bit mode. In 16-bit mode, 64 addresses x 2 bytes, a total of 128 bytes of data can be saved.
・ EWEN write permission status ・ WRITE write ・ Read READ This time we will use these 3 instructions. In order to write, it is necessary to set to EWEN mode at startup, once it is set to EWEN mode, the mode is maintained until the power is turned off.
The transmitted data is SB + OP + [Data etc ...] It takes the configuration.
SB = [00000001] Fixed OP = [????????] Add the pattern + address, etc. specified by the mode. If there is data etc., add it.
Show a concrete example
EWEN mode
SB[00000001]
OP[00110000]
>0000000100110000
And send continuously
WRITE mode
SB[00000001]
OP[010?????]The lower 5 bits are the write address
Higher byte[????????]
Low byte[????????]
>00000001010?????????????????????
And send continuously
READ mode
SB[00000001]
OP[100?????]The lower 5 bits are the read address
Dummy for high-order byte[00000000]Dummy data to receive from DO
Dummy for low byte[00000000]Dummy data to receive from DO
>00000001100?????0000000000000000
And send continuously
It is the same as Serial communication control with python and I2C communication (using USBGPIO8 device), so refer to that.
# usbgpio8_spi_read_write_sample.py
import serial
import sys
import time
SerialInstance = None
def SerialInit(comString):
global SerialInstance
#SerialInstance = serial.Serial(comString, 115200, timeout=0.01)
SerialInstance = serial.Serial(comString, 19200, timeout=0.1)
def SerialEnd():
SerialInstance.close()
def SerialTalk(cmd, response=False):
readLen = len(cmd) + 1 # gpio read 0\n\r #From the beginning\Because it has r+Not 2+1 do
if response == True:
readLen += 3 # N\n\r
readLen += 1 # >
cnt = SerialInstance.write(cmd.encode())
res = SerialInstance.read(readLen)
res = res.decode("utf-8").strip()
return res
def gpioHigh(n):
SerialTalk("gpio set {}\r".format(n))
def gpioLow(n):
SerialTalk("gpio clear {}\r".format(n))
def gpioRead(n):
res = SerialTalk("gpio read {}\r".format(n), response=True)
return res
def ByteToLH(b):
lh = []
for i in range(8):
if (b << i & 128) == 0:
lh.append(0)
else:
lh.append(1)
return lh
def CS_LOW():
gpioLow(0)
def CS_HIGH():
gpioHigh(0)
def SCK_LOW():
gpioLow(1)
def SCK_HIGH():
gpioHigh(1)
def DI_LOW():
gpioLow(2)
def DI_HIGH():
gpioHigh(2)
def READ_DATA():
return gpioRead(3)
def parseData(all):
res = []
for l in all:
a = l.split("\n\r")
res.append(a[1])
return res
def SPI_CommandExec(cmd):
# start condition
size = len(cmd)
data = []
SCK_LOW()
for i in range(size):
d = cmd[i]
if d == 0:
DI_LOW()
elif d == 1:
DI_HIGH()
SCK_HIGH()
if d == 2:
b = READ_DATA()
data.append(b)
SCK_LOW()
return parseData(data)
def WriteBytes(addr, buffer1, buffer2):
# EWEN command
SB = ByteToLH(0b00000001)
OP = ByteToLH(0b00110000)
cmdEWEN = SB + OP
# exec
CS_HIGH()
resEWEN = SPI_CommandExec(cmdEWEN)
CS_LOW()
# write command
SB = ByteToLH(0b00000001)
OP = ByteToLH(0b01000000 | (addr & 0x3f))
buffer1 = ByteToLH(buffer1)
buffer2 = ByteToLH(buffer2)
cmdWrite = SB + OP + buffer1 + buffer2
# exec
CS_HIGH()
resWrite = SPI_CommandExec(cmdWrite)
CS_LOW()
#Waiting for writing, 5ms by specification, but wait for a long time
time.sleep(0.01)
response = resEWEN + resWrite
return response
def ReadBytes(addr):
# create command
SB = ByteToLH(0b00000001)
OP = ByteToLH(0b10000000 | (addr & 0x3f))
buffer1 = [2] * 8
buffer2 = [2] * 8
cmd = SB + OP + buffer1 + buffer2
CS_HIGH()
response = SPI_CommandExec(cmd)
CS_LOW()
return response
def Test_WriteBytes(comString):
SerialInit(comString)
response = WriteBytes(7, 0x34, 0x56)
print(response)
SerialEnd()
def Test_ReadBytes(comString):
SerialInit(comString)
response = ReadBytes(7)
print(response)
SerialEnd()
def run(comString):
Test_WriteBytes(comString)
Test_ReadBytes(comString)
if __name__ == "__main__":
run(sys.argv[1])
# python usbgpio8_spi_read_write_sample.py COM4
For Linux
python usbgpio8_spi_read_write_sample.py /dev/ttyUSB0
For Windows
python usbgpio8_spi_read_write_sample.py COM4
[] #Nothing in particular when writing
['0', '0', '1', '1', '0', '1', '0', '0', '0', '1', '0', '1', '0', '1', '1', '0'] #The first 8 bits are the read upper byte, and the following 8 bits are the read lower byte.
Recommended Posts