responses = '1 1b 2 3 6 7'.split()
+Pin = SrdIntEnum.from_str('Pin', 'CMD CLK DAT0 DAT1 DAT2 DAT3')
+
a = ['CMD%d' % i for i in range(64)] + ['ACMD%d' % i for i in range(64)] + \
['R' + r.upper() for r in responses] + \
['F_' + f for f in 'START TRANSM CMD ARG CRC END'.split()] + \
self.put(self.token[47 - 8 - e][0], self.token[47 - 8 - s][1],
self.out_ann, data)
- def putc(self, cmd, desc):
+ def putc(self, desc):
+ cmd = Ann.ACMD0 + self.cmd if self.is_acmd else self.cmd
self.last_cmd = cmd
self.putt([cmd, ['%s: %s' % (self.cmd_str, desc), self.cmd_str,
self.cmd_str.split(' ')[0]]])
c = acmd_names if self.is_acmd else cmd_names
return c.get(cmd, 'Unknown')
- def get_token_bits(self, cmd, n):
+ def get_token_bits(self, cmd_pin, n):
# Get a bit, return True if we already got 'n' bits, False otherwise.
- self.token.append([self.samplenum, self.samplenum, cmd])
+ self.token.append([self.samplenum, self.samplenum, cmd_pin])
if len(self.token) > 0:
self.token[len(self.token) - 2][1] = self.samplenum
if len(self.token) < n:
# CMD[00:00]: End bit (always 1)
self.putf(47, 47, [Ann.F_END, ['End bit', 'End', 'E']])
- def get_command_token(self, cmd):
+ def get_command_token(self, cmd_pin):
# Command tokens (48 bits) are sent serially (MSB-first) by the host
# (over the CMD line), either to one SD card or to multiple ones.
#
# - Bits[07:01]: CRC7
# - Bits[00:00]: End bit (always 1)
- if not self.get_token_bits(cmd, 48):
+ if not self.get_token_bits(cmd_pin, 48):
return
self.handle_common_token_fields()
# Handle command.
s = 'ACMD' if self.is_acmd else 'CMD'
self.cmd_str = '%s%d (%s)' % (s, self.cmd, self.cmd_name(self.cmd))
- if self.cmd in (0, 2, 3, 6, 7, 8, 9, 10, 13, 41, 51, 55):
+ if hasattr(self, 'handle_%s%d' % (s.lower(), self.cmd)):
self.state = St['HANDLE_CMD%d' % self.cmd]
else:
self.state = St.HANDLE_CMD999
- self.putc(self.cmd, '%s%d' % (s, self.cmd))
+ self.putc('%s%d' % (s, self.cmd))
def handle_cmd0(self):
# CMD0 (GO_IDLE_STATE) -> no response
self.puta(0, 31, [Ann.DECODED_F, ['Stuff bits', 'Stuff', 'SB', 'S']])
- self.putc(Ann.CMD0, 'Reset all SD cards')
+ self.putc('Reset all SD cards')
self.token, self.state = [], St.GET_COMMAND_TOKEN
def handle_cmd2(self):
# CMD2 (ALL_SEND_CID) -> R2
self.puta(0, 31, [Ann.DECODED_F, ['Stuff bits', 'Stuff', 'SB', 'S']])
- self.putc(Ann.CMD2, 'Ask card for CID number')
+ self.putc('Ask card for CID number')
self.token, self.state = [], St.GET_RESPONSE_R2
def handle_cmd3(self):
# CMD3 (SEND_RELATIVE_ADDR) -> R6
self.puta(0, 31, [Ann.DECODED_F, ['Stuff bits', 'Stuff', 'SB', 'S']])
- self.putc(Ann.CMD3, 'Ask card for new relative card address (RCA)')
+ self.putc('Ask card for new relative card address (RCA)')
self.token, self.state = [], St.GET_RESPONSE_R6
def handle_cmd6(self):
# CMD6 (SWITCH_FUNC) -> R1
- self.putc(Ann.CMD6, 'Switch/check card function')
+ self.putc('Switch/check card function')
self.token, self.state = [], St.GET_RESPONSE_R1
def handle_cmd7(self):
# CMD7 (SELECT/DESELECT_CARD) -> R1b
- self.putc(Ann.CMD7, 'Select / deselect card')
+ self.putc('Select / deselect card')
self.token, self.state = [], St.GET_RESPONSE_R6
def handle_cmd8(self):
self.puta(12, 31, [Ann.DECODED_F, ['Reserved', 'Res', 'R']])
self.puta(8, 11, [Ann.DECODED_F, ['Supply voltage', 'Voltage', 'VHS', 'V']])
self.puta(0, 7, [Ann.DECODED_F, ['Check pattern', 'Check pat', 'Check', 'C']])
- self.putc(Ann.CMD8, 'Send interface condition to card')
+ self.putc('Send interface condition to card')
self.token, self.state = [], St.GET_RESPONSE_R7
# TODO: Handle case when card doesn't reply with R7 (no reply at all).
# CMD9 (SEND_CSD) -> R2
self.puta(16, 31, [Ann.DECODED_F, ['RCA', 'R']])
self.puta(0, 15, [Ann.DECODED_F, ['Stuff bits', 'Stuff', 'SB', 'S']])
- self.putc(Ann.CMD9, 'Send card-specific data (CSD)')
+ self.putc('Send card-specific data (CSD)')
self.token, self.state = [], St.GET_RESPONSE_R2
def handle_cmd10(self):
# CMD10 (SEND_CID) -> R2
self.puta(16, 31, [Ann.DECODED_F, ['RCA', 'R']])
self.puta(0, 15, [Ann.DECODED_F, ['Stuff bits', 'Stuff', 'SB', 'S']])
- self.putc(Ann.CMD10, 'Send card identification data (CID)')
+ self.putc('Send card identification data (CID)')
self.token, self.state = [], St.GET_RESPONSE_R2
def handle_cmd13(self):
# CMD13 (SEND_STATUS) -> R1
self.puta(16, 31, [Ann.DECODED_F, ['RCA', 'R']])
self.puta(0, 15, [Ann.DECODED_F, ['Stuff bits', 'Stuff', 'SB', 'S']])
- self.putc(Ann.CMD13, 'Send card status register')
+ self.putc('Send card status register')
self.token, self.state = [], St.GET_RESPONSE_R1
def handle_cmd16(self):
# CMD16 (SET_BLOCKLEN) -> R1
self.puta(0, 31, [Ann.DECODED_F, ['Block length', 'Blocklen', 'BL', 'B']])
- self.putc(Ann.CMD16, 'Set the block length to %d bytes' % self.arg)
+ self.putc('Set the block length to %d bytes' % self.arg)
self.token, self.state = [], St.GET_RESPONSE_R1
def handle_cmd55(self):
# CMD55 (APP_CMD) -> R1
self.puta(16, 31, [Ann.DECODED_F, ['RCA', 'R']])
self.puta(0, 15, [Ann.DECODED_F, ['Stuff bits', 'Stuff', 'SB', 'S']])
- self.putc(Ann.CMD55, 'Next command is an application-specific command')
+ self.putc('Next command is an application-specific command')
self.is_acmd = True
self.token, self.state = [], St.GET_RESPONSE_R1
def handle_acmd6(self):
# ACMD6 (SET_BUS_WIDTH) -> R1
- self.putc(Ann.ACMD6, 'Read SD config register (SCR)')
+ self.putc('Read SD config register (SCR)')
self.token, self.state = [], St.GET_RESPONSE_R1
def handle_acmd13(self):
# ACMD13 (SD_STATUS) -> R1
self.puta(0, 31, [Ann.DECODED_F, ['Stuff bits', 'Stuff', 'SB', 'S']])
- self.putc(Ann.ACMD13, 'Set SD status')
+ self.putc('Set SD status')
self.token, self.state = [], St.GET_RESPONSE_R1
def handle_acmd41(self):
self.puta(30, 30, [Ann.DECODED_F,
['Host capacity support info', 'Host capacity', 'HCS', 'H']])
self.puta(31, 31, [Ann.DECODED_F, ['Reserved', 'Res', 'R']])
- self.putc(Ann.ACMD41, 'Send HCS info and activate the card init process')
+ self.putc('Send HCS info and activate the card init process')
self.token, self.state = [], St.GET_RESPONSE_R3
def handle_acmd51(self):
# ACMD51 (SEND_SCR) -> R1
- self.putc(Ann.ACMD51, 'Read SD config register (SCR)')
+ self.putc('Read SD config register (SCR)')
self.token, self.state = [], St.GET_RESPONSE_R1
def handle_cmd999(self):
# They're sent serially (MSB-first) by the card that the host
# addressed previously, or (synchronously) by all connected cards.
- def handle_response_r1(self, cmd):
+ def handle_response_r1(self, cmd_pin):
# R1: Normal response command
# - Bits[47:47]: Start bit (always 0)
# - Bits[46:46]: Transmission bit (0 == card)
# - Bits[39:08]: Card status
# - Bits[07:01]: CRC7
# - Bits[00:00]: End bit (always 1)
- if not self.get_token_bits(cmd, 48):
+ if not self.get_token_bits(cmd_pin, 48):
return
self.handle_common_token_fields()
self.putr(Ann.R1)
self.putbit(8 + i, [card_status[31 - i]])
self.token, self.state = [], St.GET_COMMAND_TOKEN
- def handle_response_r1b(self, cmd):
+ def handle_response_r1b(self, cmd_pin):
# R1b: Same as R1 with an optional busy signal (on the data line)
- if not self.get_token_bits(cmd, 48):
+ if not self.get_token_bits(cmd_pin, 48):
return
self.handle_common_token_fields()
self.puta(0, 31, [Ann.DECODED_F, ['Card status', 'Status', 'S']])
self.putr(Ann.R1B)
self.token, self.state = [], St.GET_COMMAND_TOKEN
- def handle_response_r2(self, cmd):
+ def handle_response_r2(self, cmd_pin):
# R2: CID/CSD register
# - Bits[135:135]: Start bit (always 0)
# - Bits[134:134]: Transmission bit (0 == card)
# - Bits[133:128]: Reserved (always 0b111111)
# - Bits[127:001]: CID or CSD register including internal CRC7
# - Bits[000:000]: End bit (always 1)
- if not self.get_token_bits(cmd, 136):
+ if not self.get_token_bits(cmd_pin, 136):
return
# Annotations for each individual bit.
for bit in range(len(self.token)):
self.putf(8, 134, [Ann.F_ARG, ['Argument', 'Arg', 'A']])
self.putf(135, 135, [Ann.F_END, ['End bit', 'End', 'E']])
self.putf(8, 134, [Ann.DECODED_F, ['CID/CSD register', 'CID/CSD', 'C']])
- self.putf(0, 135, [55, ['R2']])
+ self.putf(0, 135, [Ann.R2, ['R2']])
self.token, self.state = [], St.GET_COMMAND_TOKEN
- def handle_response_r3(self, cmd):
+ def handle_response_r3(self, cmd_pin):
# R3: OCR register
# - Bits[47:47]: Start bit (always 0)
# - Bits[46:46]: Transmission bit (0 == card)
# - Bits[39:08]: OCR register
# - Bits[07:01]: Reserved (always 0b111111)
# - Bits[00:00]: End bit (always 1)
- if not self.get_token_bits(cmd, 48):
+ if not self.get_token_bits(cmd_pin, 48):
return
self.putr(Ann.R3)
# Annotations for each individual bit.
self.puta(0, 31, [Ann.DECODED_F, ['OCR register', 'OCR reg', 'OCR', 'O']])
self.token, self.state = [], St.GET_COMMAND_TOKEN
- def handle_response_r6(self, cmd):
+ def handle_response_r6(self, cmd_pin):
# R6: Published RCA response
# - Bits[47:47]: Start bit (always 0)
# - Bits[46:46]: Transmission bit (0 == card)
# - Bits[23:08]: Argument[15:0]: Card status bits
# - Bits[07:01]: CRC7
# - Bits[00:00]: End bit (always 1)
- if not self.get_token_bits(cmd, 48):
+ if not self.get_token_bits(cmd_pin, 48):
return
self.handle_common_token_fields()
self.puta(0, 15, [Ann.DECODED_F, ['Card status bits', 'Status', 'S']])
self.putr(Ann.R6)
self.token, self.state = [], St.GET_COMMAND_TOKEN
- def handle_response_r7(self, cmd):
+ def handle_response_r7(self, cmd_pin):
# R7: Card interface condition
# - Bits[47:47]: Start bit (always 0)
# - Bits[46:46]: Transmission bit (0 == card)
# - Bits[15:08]: Echo-back of check pattern
# - Bits[07:01]: CRC7
# - Bits[00:00]: End bit (always 1)
- if not self.get_token_bits(cmd, 48):
+ if not self.get_token_bits(cmd_pin, 48):
return
self.handle_common_token_fields()
def decode(self):
while True:
# Wait for a rising CLK edge.
- (cmd, clk, dat0, dat1, dat2, dat3) = self.wait({1: 'r'})
+ (cmd_pin, clk, dat0, dat1, dat2, dat3) = self.wait({Pin.CLK: 'r'})
# State machine.
if self.state == St.GET_COMMAND_TOKEN:
if len(self.token) == 0:
# Wait for start bit (CMD = 0).
- if cmd != 0:
+ if cmd_pin != 0:
continue
- self.get_command_token(cmd)
+ self.get_command_token(cmd_pin)
elif self.state.value.startswith('HANDLE_CMD'):
# Call the respective handler method for the command.
a, cmdstr = 'a' if self.is_acmd else '', self.state.value[10:].lower()
elif self.state.value.startswith('GET_RESPONSE'):
if len(self.token) == 0:
# Wait for start bit (CMD = 0).
- if cmd != 0:
+ if cmd_pin != 0:
continue
# Call the respective handler method for the response.
s = 'handle_response_%s' % self.state.value[13:].lower()
handle_response = getattr(self, s)
- handle_response(cmd)
+ handle_response(cmd_pin)