Skip to content

Commit 04d67e9

Browse files
committed
spi: refactor bit banging code
1 parent babbad0 commit 04d67e9

File tree

1 file changed

+150
-100
lines changed

1 file changed

+150
-100
lines changed

src/main/scala/spi/SerialSpiTest.scala

Lines changed: 150 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,22 @@ package spi
22

33
import com.fazecast.jSerialComm._
44

5-
class SerialSpiTest {
6-
7-
}
8-
9-
object SerialSpiTest extends App {
5+
/**
6+
* A simple test for SPI communication.
7+
* @param id (Adx, Flash, SRAM)
8+
*/
9+
class SerialSpiTest(id: Int, portName: String = "/dev/tty.usbserial-210292B408601") {
10+
11+
// TODO: fix the hard coded port name
12+
val port = SerialPort.getCommPort(portName)
13+
port.openPort()
14+
port.setBaudRate(115200)
15+
// port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0)
16+
port.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 0, 0)
17+
val out = port.getOutputStream
18+
csHigh()
1019

11-
def writeRead(s: String): String = {
20+
def writeReadSerial(s: String): String = {
1221
for (c <- s) {
1322
out.write(c.toByte)
1423
}
@@ -29,7 +38,7 @@ object SerialSpiTest extends App {
2938
ret
3039
}
3140

32-
def setCmd(id: Int, v: Int): String = {
41+
def setCmd(v: Int): String = {
3342
val cmd = v.toHexString
3443
id match {
3544
case 0 => "w44" + cmd + "\r"
@@ -38,152 +47,193 @@ object SerialSpiTest extends App {
3847
}
3948
}
4049

41-
def writeByte(id: Int, v: Int) = {
50+
def writeByte(v: Int) = {
4251
for (i <- 0 until 8) {
4352
val bits = ((v >> (7-i)) & 1) << 1
4453
// clock off, set data
45-
writeRead(setCmd(id, bits)) // clock off, set data
54+
writeReadSerial(setCmd(bits)) // clock off, set data
4655
// clock on, keep data
47-
writeRead(setCmd(id, bits + 1)) // clock on, keep data
56+
writeReadSerial(setCmd(bits + 1)) // clock on, keep data
4857
}
4958
// not now, writeRead("w440\r") // clock off
5059
}
5160

52-
def readByte(id: Int) = {
61+
def readByte() = {
5362
var v = 0
5463
for (i <- 0 until 8) {
55-
writeRead(setCmd(id, 0)) // clock off
64+
writeReadSerial(setCmd(0)) // clock off
5665
// data changes after neg edge
57-
writeRead(setCmd(id, 1)) // clock on
66+
writeReadSerial(setCmd(1)) // clock on
5867
// sample on pos edge
59-
val rx = writeRead("r")
60-
// println("received: " + rx(8))
61-
// '8' is bit set
68+
val rx = writeReadSerial("r")
69+
// '8' is MISO bit set
6270
val bit = if (rx(8 - id) == '8') 1 else 0
6371
v = (v << 1) | bit
6472
}
65-
writeRead(setCmd(id, 0)) // clock off (maybe?), does not hurt on multibyte read
73+
writeReadSerial(setCmd(0)) // clock off (maybe?), does not hurt on multibyte read
6674
v
6775
}
6876

77+
def csLow() = writeReadSerial(setCmd(0))
78+
79+
def csHigh() = writeReadSerial(setCmd(4))
80+
6981
def readAdx(cmd: Int): Int = {
70-
writeRead(setCmd(0, 4))
71-
writeRead(setCmd(0, 0)) // CS low
72-
writeByte(0, cmd)
73-
writeByte(0, 0)
74-
val ret = readByte(0)
75-
writeRead(setCmd(0, 4)) // CS high
82+
csHigh()
83+
csLow()
84+
writeByte(cmd)
85+
writeByte(0)
86+
val ret = readByte()
87+
csHigh()
7688
ret
7789
}
7890

79-
def readJedecId(id: Int) = {
80-
writeRead(setCmd(id, 0)) // CS low
81-
writeByte(id, 0x9f)
82-
val v = readByte(id)
91+
def readJedecId() = {
92+
csLow()
93+
writeByte(0x9f)
94+
val v = readByte()
8395
println("Manufacturer is 0x" + v.toHexString)
84-
println("Device type is 0x" + readByte(id).toHexString)
85-
println("Device id is 0x" + readByte(id).toHexString)
86-
writeRead(setCmd(id, 4)) // CS high
96+
println("Device type is 0x" + readByte().toHexString)
97+
println("Device id is 0x" + readByte().toHexString)
98+
csHigh()
8799
v
88100
}
89101

90-
def readStatusRegister(id: Int) = {
91-
writeRead(setCmd(id, 0)) // CS low
92-
writeByte(id, 0x05)
93-
val v = readByte(id)
102+
def readStatusRegister() = {
103+
csLow()
104+
writeByte(0x05)
105+
val v = readByte()
94106
println("Status register is 0x" + v.toHexString)
95-
writeRead(setCmd(id, 4)) // CS high
107+
csHigh()
96108
v
97109
}
98110

99-
def readMemory(id: Int, addr: Int) = {
100-
writeRead(setCmd(id, 0)) // CS low
101-
writeByte(id, 0x03)
102-
writeByte(id, (addr >> 16) & 0xff)
103-
writeByte(id, (addr >> 8) & 0xff)
104-
writeByte(id, addr & 0xff)
105-
val v = readByte(id)
111+
def readMemory(addr: Int) = {
112+
113+
println("Reading Memory of " + id + " at 0x" + addr.toHexString)
114+
csLow()
115+
writeByte(0x03)
116+
writeByte((addr >> 16) & 0xff)
117+
writeByte((addr >> 8) & 0xff)
118+
writeByte(addr & 0xff)
119+
val v = readByte()
106120
println("Memory of " + id + " at 0x" + addr.toHexString + " is 0x" + v.toHexString)
107-
writeRead(setCmd(id, 4)) // CS high
121+
csHigh()
108122
v
109123
}
110124

111-
def readSram(id: Int, addr: Int) = {
112-
writeRead(setCmd(id, 0)) // CS low
113-
writeByte(id, 0x03)
114-
writeByte(id, (addr >> 8) & 0xff)
115-
writeByte(id, addr & 0xff)
116-
val v = readByte(id)
125+
def readMemory(addr: Int, buf: Array[Byte]) = {
126+
127+
println("Reading Memory of " + id + " from 0x" + addr.toHexString)
128+
csLow()
129+
writeByte(0x03)
130+
writeByte((addr >> 16) & 0xff)
131+
writeByte((addr >> 8) & 0xff)
132+
writeByte(addr & 0xff)
133+
for (i <- 0 until buf.length) {
134+
buf(i) = readByte().toByte
135+
}
136+
csHigh()
137+
}
138+
139+
def readSram(addr: Int) = {
140+
csLow()
141+
writeByte(0x03)
142+
writeByte((addr >> 8) & 0xff)
143+
writeByte(addr & 0xff)
144+
val v = readByte()
117145
println("SRAM of " + id + " at 0x" + addr.toHexString + " is 0x" + v.toHexString)
118-
writeRead(setCmd(id, 4)) // CS high
146+
csHigh()
119147
v
120148
}
121149

122-
def programFlash(id: Int, addr: Int, data: Array[Byte]) = {
123-
124-
readStatusRegister(id)
125-
126-
writeRead(setCmd(id, 0)) // CS low
127-
writeByte(id, 0x01) // write status register
128-
writeByte(id, 0x00) // write status register
129-
writeRead(setCmd(id, 4)) // CS high
130-
131-
readStatusRegister(id)
132-
133-
writeRead(setCmd(id, 0)) // CS low
134-
writeByte(id, 0x06) // write enable
135-
writeRead(setCmd(id, 4)) // CS high
150+
def writeCmd(v: Int) = {
151+
csLow()
152+
writeByte(v)
153+
csHigh()
154+
}
155+
def writeCmd(v: Int, d: Int) = {
156+
csLow()
157+
writeByte(v)
158+
writeByte(d)
159+
csHigh()
160+
}
136161

137-
readStatusRegister(id)
162+
def eraseFlash() = {
163+
164+
println("Erasing Flash")
165+
writeCmd(0x06) // write enable
166+
writeCmd(0x01, 0x00) // write 0 into status register
167+
writeCmd(0x06) // write enable
168+
readStatusRegister()
169+
writeCmd(0x60) // chip erase
170+
readStatusRegister()
171+
Thread.sleep(1000)
172+
readStatusRegister()
173+
}
174+
def programFlash(id: Int, addr: Int, data: Array[Byte]) = {
138175

139-
writeRead(setCmd(id, 0)) // CS low
140-
writeByte(id, 0x02)
141-
writeByte(id, (addr >> 16) & 0xff)
142-
writeByte(id, (addr >> 8) & 0xff)
143-
writeByte(id, addr & 0xff)
176+
println("Programming Flash at 0x" + addr.toHexString)
177+
readStatusRegister()
178+
writeCmd(0x06) // write enable
179+
readStatusRegister()
180+
writeCmd(0x01, 0x00) // write 0 into status register
181+
readStatusRegister()
182+
writeCmd(0x06) // write enable
183+
readStatusRegister()
184+
185+
csLow()
186+
writeByte(0x02)
187+
writeByte((addr >> 16) & 0xff)
188+
writeByte((addr >> 8) & 0xff)
189+
writeByte(addr & 0xff)
144190
for (d <- data) {
145191
println("Writing 0x" + d.toHexString)
146-
writeByte(id, d)
192+
writeByte(d)
147193
}
148-
// writeByte(id, 0x04) // write disable
149-
writeRead(setCmd(id, 4)) // CS high
194+
csHigh()
150195

151-
readStatusRegister(id)
152-
Thread.sleep(300)
153-
readStatusRegister(id)
196+
writeCmd(0x04) // write disable
154197

198+
readStatusRegister()
199+
Thread.sleep(300)
200+
readStatusRegister()
155201
}
202+
}
156203

204+
object SerialSpiTest extends App {
157205

158-
// TODO: fix this hard coded thing
159-
val port = SerialPort.getCommPort("/dev/tty.usbserial-210292B408601")
160-
port.openPort()
161-
port.setBaudRate(115200)
162-
// port.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 0, 0)
163-
port.setComPortTimeouts(SerialPort.TIMEOUT_NONBLOCKING, 0, 0)
164-
val out = port.getOutputStream
165206

166-
print(writeRead(setCmd(0, 4))) // all CS high
167-
print(writeRead(setCmd(0, 0))) // CS low for ADX
168-
print(writeRead("r"))
169-
val v = readAdx(0x0b) // dev id
170-
println("device id is 0x" + v.toHexString)
171-
readJedecId(1) // Flash
172-
readStatusRegister(2) // SRAM
173-
readMemory(1, 0)
174-
readSram(2, 0)
175-
176-
val s = "Hello, World!\n"
207+
val spi = new SerialSpiTest(1) // Flash
208+
209+
spi.csLow()
210+
print(spi.writeReadSerial("r"))
211+
spi.csHigh()
212+
// val v = spi.readAdx(0x0b) // dev id
213+
// println("device id is 0x" + v.toHexString)
214+
spi.readJedecId() // Flash
215+
spi.readStatusRegister()
216+
spi.readMemory(0)
217+
218+
// spi.readSram(0)
219+
220+
// spi.eraseFlash()
221+
val s = "Hello Wildcat!\n"
177222
val data = s.getBytes
178-
// programFlash(1, 0, data)
223+
// spi.programFlash(1, 0, data)
179224
Thread.sleep(1000)
180225

181-
for (i <- 0 until 8) {
182-
print(readMemory(1, i).toChar)
226+
val buf = new Array[Byte](20)
227+
spi.readMemory(0, buf)
228+
println(new String(buf))
229+
/*
230+
for (i <- 0 until 20) {
231+
print(spi.readMemory(i).toChar)
183232
}
184233
println()
234+
*/
185235

186-
print(writeRead(setCmd(0, 4))) // all CS high
187-
out.close()
188-
port.closePort()
236+
print(spi.writeReadSerial(spi.setCmd(4))) // all CS high
237+
spi.out.close()
238+
spi.port.closePort()
189239
}

0 commit comments

Comments
 (0)