1+ //go:generate stringer -type sdStateCode
2+
13package sd
24
35import "fmt"
46
7+ type sdStateCode uint8
8+
59// states
610const (
7- sCmd = iota // expect command
8- sArg // expect argument
9- sChk // expect checksum
10- sData // sending data until misoQueue empty.
11+ sCommand sdStateCode = iota // expect command
12+ sArgument // expect argument
13+ sChecksum // expect checksum
14+ sData // sending data until misoQueue empty.
1115)
1216
1317const (
@@ -22,7 +26,7 @@ const (
2226
2327// sdState is the state of SD protocol (layer above SPI protocol).
2428type sdState struct {
25- state uint8
29+ state sdStateCode
2630 acmd bool // next command is an application-specific command
2731 cmd uint8
2832 arg uint32
@@ -39,23 +43,28 @@ func newSdState() (s *sdState) {
3943 }
4044}
4145
46+ func (s * sdState ) enter (state sdStateCode ) {
47+ fmt .Printf ("SD state %s -> %s\n " , s .state , state )
48+ s .state = state
49+ }
50+
4251func (s * sdState ) consumeByte (b byte ) {
4352 switch s .state {
44- case sCmd :
53+ case sCommand :
4554 if b >> 6 == 1 {
4655 s .cmd = b & (0xFF >> 2 )
47- s .state = sArg
56+ s .enter ( sArgument )
4857 s .arg = 0x00000000
4958 s .argByte = 0
5059 }
51- case sArg :
60+ case sArgument :
5261 s .arg |= uint32 (b ) << ((3 - s .argByte ) * 8 )
5362 if s .argByte == 3 {
54- s .state = sChk
63+ s .enter ( sChecksum )
5564 } else {
5665 s .argByte ++
5766 }
58- case sChk :
67+ case sChecksum :
5968 if s .acmd {
6069 s .handleAcmd ()
6170 } else {
@@ -75,19 +84,19 @@ func (s *sdState) handleCmd() {
7584 case 0 : // GO_IDLE_STATE
7685 fmt .Println ("SD CMD0 response: r1_idle" )
7786 s .queueMisoBytes (0xFF , 0xFF , r1_idle ) // busy then idle
78- s .state = sCmd
87+ s .enter ( sCommand )
7988 case 17 : // READ_SINGLE_BLOCK
8089 fmt .Println ("SD CMD17 response: r1_ready, data start block, data" )
8190 s .queueMisoBytes (0xFF , 0xFF , r1_ready ) // busy then ready
8291 s .queueMisoBytes (0xFF , 0xFF , 0xFF , 0xFF ) // time before data block
8392 s .queueMisoBytes (0xFE ) // data start block
8493 s .queueMisoBytes (s .readBlock (s .arg )... )
85- s .state = sData
94+ s .enter ( sData )
8695 case 55 : // APP_CMD
8796 fmt .Println ("SD CMD55 response: r1_idle" )
8897 s .queueMisoBytes (r1_idle ) // busy then idle
8998 s .acmd = true
90- s .state = sCmd
99+ s .enter ( sCommand )
91100 default :
92101 panic (fmt .Sprintf ("Unhandled CMD%d" , s .cmd ))
93102 }
@@ -107,7 +116,7 @@ func (s *sdState) handleAcmd() {
107116 fmt .Println ("SD ACMD41 response: r1_idle" )
108117 s .queueMisoBytes (0xFF , 0xFF , r1_idle )
109118 }
110- s .state = sCmd
119+ s .enter ( sCommand )
111120 default :
112121 panic (fmt .Sprintf ("Unhandled ACMD%d" , s .cmd ))
113122 }
@@ -124,8 +133,8 @@ func (s *sdState) shiftMiso() (b byte) {
124133 b = s .misoQueue [0 ]
125134 s .misoQueue = s .misoQueue [1 :len (s .misoQueue )]
126135 if len (s .misoQueue ) == 0 && s .state == sData {
127- // transition from sData to sCmd when all data sent.
128- s .state = sCmd
136+ // transition from sData to sCommand when all data sent.
137+ s .enter ( sCommand )
129138 }
130139 } else {
131140 b = 0x00 // default to low for empty buffer.
0 commit comments