X-Git-Url: https://sigrok.org/gitweb/?p=libsigrokdecode.git;a=blobdiff_plain;f=decoders%2Fsdcard_spi%2Fpd.py;h=c61c8c25833bd6e277762aaba189eeffe4179bec;hp=5cdea4cfc6bd03b8ed9ecf1d37b7f3b7a2e05deb;hb=780770f1295b7fdeb4481eb42623bad5da1e19a7;hpb=a74855de187198624fefd2c12ef8355e5a869f80 diff --git a/decoders/sdcard_spi/pd.py b/decoders/sdcard_spi/pd.py index 5cdea4c..c61c8c2 100644 --- a/decoders/sdcard_spi/pd.py +++ b/decoders/sdcard_spi/pd.py @@ -69,12 +69,6 @@ cmd_name = { 51: 'SEND_SCR', } -def ann_cmd_list(): - l = [] - for i in range(63 + 1): - l.append(['cmd%d' % i, 'CMD%d' % i]) - return l - class Decoder(srd.Decoder): api_version = 1 id = 'sdcard_spi' @@ -84,20 +78,19 @@ class Decoder(srd.Decoder): license = 'gplv2+' inputs = ['spi'] outputs = ['sdcard_spi'] - probes = [] - optional_probes = [] - options = {} - annotations = ann_cmd_list() + [ - ['cmd-token', 'Command token'], + annotations = \ + [['cmd%d' % i, 'CMD%d' % i] for i in range(63 + 1)] + [ + ['cmd-desc', 'Command description'], ['r1', 'R1 reply'], ['r1b', 'R1B reply'], ['r2', 'R2 reply'], ['r3', 'R3 reply'], ['r7', 'R7 reply'], ['bits', 'Bits'], + ['bit-warnings', 'Bit warnings'], ] annotation_rows = ( - ('bits', 'Bits', (70,)), + ('bits', 'Bits', (70, 71)), ('cmd-reply', 'Commands/replies', tuple(range(0, 63 + 1)) + tuple(range(65, 69 + 1))), ('cmd-token', 'Command tokens', (64,)), @@ -114,6 +107,7 @@ class Decoder(srd.Decoder): self.is_acmd = False # Indicates CMD vs. ACMD self.blocklen = 0 self.read_buf = [] + self.cmd_str = '' def start(self): # self.out_python = self.register(srd.OUTPUT_PYTHON) @@ -122,6 +116,9 @@ class Decoder(srd.Decoder): def putx(self, data): self.put(self.cmd_ss, self.cmd_es, self.out_ann, data) + def putc(self, cmd, desc): + self.putx([cmd, ['%s: %s' % (self.cmd_str, desc)]]) + def putb(self, data): self.put(self.bit_ss, self.bit_es, self.out_ann, data) @@ -141,7 +138,6 @@ class Decoder(srd.Decoder): self.cmd_token.append(mosi) self.cmd_token_bits.append(self.mosi_bits) - # TODO: Record MISO too? # All command tokens are 6 bytes long. if len(self.cmd_token) < 6: @@ -149,35 +145,30 @@ class Decoder(srd.Decoder): self.cmd_es = self.es - # Received all 6 bytes of the command token. Now decode it. - t = self.cmd_token # CMD or ACMD? s = 'ACMD' if self.is_acmd else 'CMD' - # TODO - self.putx([64, [s + ': %02x %02x %02x %02x %02x %02x' % tuple(t)]]) def tb(byte, bit): - return self.cmd_token_bits[5 - byte][7 - bit] + return self.cmd_token_bits[5 - byte][bit] # Bits[47:47]: Start bit (always 0) bit, self.bit_ss, self.bit_es = tb(5, 7)[0], tb(5, 7)[1], tb(5, 7)[2] - self.putb([70, ['Start bit: %d' % bit]]) - if bit != 0: - # TODO - self.putb([1, ['Warning: Start bit != 0']]) + if bit == 0: + self.putb([70, ['Start bit: %d' % bit]]) + else: + self.putb([71, ['Start bit: %s (Warning: Must be 0!)' % bit]]) # Bits[46:46]: Transmitter bit (1 == host) bit, self.bit_ss, self.bit_es = tb(5, 6)[0], tb(5, 6)[1], tb(5, 6)[2] - self.putb([70, ['Transmitter bit: %d' % bit]]) - if bit != 1: - # TODO - self.putb([1, ['Warning: Transmitter bit != 1']]) + if bit == 1: + self.putb([70, ['Transmitter bit: %d' % bit]]) + else: + self.putb([71, ['Transmitter bit: %d (Warning: Must be 1!)' % bit]]) # Bits[45:40]: Command index (BCD; valid: 0-63) - cmd = self.cmd_index = t[5] & 0x3f - # TODO + cmd = self.cmd_index = t[0] & 0x3f self.bit_ss, self.bit_es = tb(5, 5)[1], tb(5, 0)[2] self.putb([70, ['Command: %s%d (%s)' % (s, cmd, cmd_name[cmd])]]) @@ -185,47 +176,51 @@ class Decoder(srd.Decoder): self.arg = (t[1] << 24) | (t[2] << 16) | (t[3] << 8) | t[4] self.bit_ss, self.bit_es = tb(4, 7)[1], tb(1, 0)[2] self.putb([70, ['Argument: 0x%04x' % self.arg]]) - # TODO: Sanity check on argument? Must be per-cmd? - # Bits[7:1]: CRC - # TODO: Check CRC. + # Bits[7:1]: CRC7 + # TODO: Check CRC7. crc = t[5] >> 1 self.bit_ss, self.bit_es = tb(0, 7)[1], tb(0, 1)[2] - self.putb([70, ['CRC: 0x%01x' % crc]]) + self.putb([70, ['CRC7: 0x%01x' % crc]]) # Bits[0:0]: End bit (always 1) bit, self.bit_ss, self.bit_es = tb(0, 0)[0], tb(0, 0)[1], tb(0, 0)[2] self.putb([70, ['End bit: %d' % bit]]) - if bit != 1: - # TODO - self.putb([1, ['Warning: End bit != 1']]) + if bit == 1: + self.putb([70, ['End bit: %d' % bit]]) + else: + self.putb([71, ['End bit: %d (Warning: Must be 1!)' % bit]]) # Handle command. if cmd in (0, 1, 9, 16, 17, 41, 49, 55, 59): self.state = 'HANDLE CMD%d' % cmd + self.cmd_str = '%s%d (%s)' % (s, cmd, cmd_name[cmd]) + else: + self.state = 'HANDLE CMD999' + a = '%s%d: %02x %02x %02x %02x %02x %02x' % ((s, cmd) + tuple(t)) + self.putx([cmd, [a]]) # ... if self.is_acmd and cmd != 55: self.is_acmd = False - self.cmd_token = [] - self.cmd_token_bits = [] - - def handle_cmd0(self, ): + def handle_cmd0(self): # CMD0: GO_IDLE_STATE - # TODO - self.putx([0, ['CMD0: Card reset / idle state']]) + self.putc(0, 'Reset the SD card') self.state = 'GET RESPONSE R1' def handle_cmd1(self): # CMD1: SEND_OP_COND - # TODO + self.putc(1, 'Send HCS info and activate the card init process') hcs = (self.arg & (1 << 30)) >> 30 - self.putb([1, ['HCS bit = %d' % hcs]]) + self.bit_ss = self.cmd_token_bits[5 - 4][6][1] + self.bit_es = self.cmd_token_bits[5 - 4][6][2] + self.putb([70, ['HCS: %d' % hcs]]) self.state = 'GET RESPONSE R1' def handle_cmd9(self): # CMD9: SEND_CSD (128 bits / 16 bytes) + self.putc(9, 'Ask card to send its card specific data (CSD)') if len(self.read_buf) == 0: self.cmd_ss = self.ss self.read_buf.append(self.miso) @@ -243,6 +238,7 @@ class Decoder(srd.Decoder): def handle_cmd10(self): # CMD10: SEND_CID (128 bits / 16 bytes) + self.putc(10, 'Ask card to send its card identification (CID)') self.read_buf.append(self.miso) if len(self.read_buf) < 16: return @@ -253,18 +249,17 @@ class Decoder(srd.Decoder): def handle_cmd16(self): # CMD16: SET_BLOCKLEN - self.blocklen = self.arg # TODO + self.blocklen = self.arg # TODO: Sanity check on block length. - self.putx([16, ['Block length: %d' % self.blocklen]]) + self.putc(16, 'Set the block length to %d bytes' % self.blocklen) self.state = 'GET RESPONSE R1' def handle_cmd17(self): # CMD17: READ_SINGLE_BLOCK + self.putc(17, 'Read a block from address 0x%04x' % self.arg) if len(self.read_buf) == 0: self.cmd_ss = self.ss self.read_buf.append(self.miso) - if len(self.read_buf) == 1: - self.putx([0, ['Read block at address: 0x%04x' % self.arg]]) if len(self.read_buf) < self.blocklen + 2: # FIXME return self.cmd_es = self.es @@ -275,6 +270,7 @@ class Decoder(srd.Decoder): def handle_cmd41(self): # ACMD41: SD_SEND_OP_COND + self.putc(41, 'Send HCS info and activate the card init process') self.state = 'GET RESPONSE R1' def handle_cmd49(self): @@ -282,6 +278,7 @@ class Decoder(srd.Decoder): def handle_cmd55(self): # CMD55: APP_CMD + self.putc(55, 'Next command is an application-specific command') self.is_acmd = True self.state = 'GET RESPONSE R1' @@ -289,7 +286,10 @@ class Decoder(srd.Decoder): # CMD59: CRC_ON_OFF crc_on_off = self.arg & (1 << 0) s = 'on' if crc_on_off == 1 else 'off' - self.putb([59, ['SD card CRC option: %s' % s]]) + self.putc(59, 'Turn the SD card CRC option %s' % s) + self.state = 'GET RESPONSE R1' + + def handle_cmd999(self): self.state = 'GET RESPONSE R1' def handle_cid_register(self): @@ -333,11 +333,11 @@ class Decoder(srd.Decoder): # The R1 response token format (1 byte). # Sent by the card after every command except for SEND_STATUS. - self.cmd_ss, self.cmd_es = self.ss, self.es + self.cmd_ss, self.cmd_es = self.miso_bits[7][1], self.miso_bits[0][2] self.putx([65, ['R1: 0x%02x' % res]]) def putbit(bit, data): - b = self.miso_bits[7 - bit] + b = self.miso_bits[bit] self.bit_ss, self.bit_es = b[1], b[2] self.putb([70, data]) @@ -424,6 +424,8 @@ class Decoder(srd.Decoder): s = 'handle_cmd%s' % self.state[10:].lower() handle_cmd = getattr(self, s) handle_cmd() + self.cmd_token = [] + self.cmd_token_bits = [] elif self.state.startswith('GET RESPONSE'): # Ignore stray 0xff bytes, some devices seem to send those!? if miso == 0xff: # TODO?