diff --git a/spi.c b/spi.c index 8b242e7..7dcd86d 100644 --- a/spi.c +++ b/spi.c @@ -18,6 +18,9 @@ enum ff_spi_quirks { // Don't issue a "Write Enable" command prior to writing // a status register SQ_SKIP_SR_WEL = (1 << 1), + + // Security registers are shifted up by 4 bits + SQ_SECURITY_NYBBLE_SHIFT = (1 << 2), }; struct ff_spi { @@ -334,7 +337,10 @@ uint8_t spiReadStatus(struct ff_spi *spi, uint8_t sr) { return val; } -void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t val) { +void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]) { + + if (spi->quirks & SQ_SECURITY_NYBBLE_SHIFT) + sr <<= 4; spiBegin(spi); spiCommand(spi, 0x06); @@ -342,15 +348,32 @@ void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t val) { spiBegin(spi); spiCommand(spi, 0x42); - spiCommand(spi, 0x00); - spiCommand(spi, sr); - spiCommand(spi, 0x00); - spiCommand(spi, val); + spiCommand(spi, 0x00); // A23-16 + spiCommand(spi, sr); // A15-8 + spiCommand(spi, 0x00); // A0-7 + int i; + for (i = 0; i < 256; i++) + spiCommand(spi, security[i]); spiEnd(spi); spi_get_id(spi); } +void spiReadSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]) { + if (spi->quirks & SQ_SECURITY_NYBBLE_SHIFT) + sr <<= 4; + + spiBegin(spi); + spiCommand(spi, 0x48); // Read security registers + spiCommand(spi, 0x00); // A23-16 + spiCommand(spi, sr); // A15-8 + spiCommand(spi, 0x00); // A0-7 + int i; + for (i = 0; i < 256; i++) + security[i] = spiCommandRx(spi); + spiEnd(spi); +} + void spiWriteStatus(struct ff_spi *spi, uint8_t sr, uint8_t val) { switch (sr) { @@ -495,16 +518,6 @@ static void spi_get_id(struct ff_spi *spi) { spi->id.serial[3] = spiCommandRx(spi); spiEnd(spi); - spiBegin(spi); - spiCommand(spi, 0x48); // Read security registers - spiCommand(spi, 0x00); // Dummy byte 1 - spiCommand(spi, 0x00); // Dummy byte 2 - spiCommand(spi, 0x00); // Dummy byte 3 - spi->id.security[0] = spiCommandRx(spi); - spi->id.security[1] = spiCommandRx(spi); - spi->id.security[2] = spiCommandRx(spi); - spiEnd(spi); - spi_decode_id(spi); return; } @@ -737,7 +750,7 @@ int spiInit(struct ff_spi *spi) { if (spi->id.manufacturer_id == 0x1f) spi->quirks |= SQ_SR2_FROM_SR1; if (spi->id.manufacturer_id == 0xef) - spi->quirks |= SQ_SKIP_SR_WEL; + spi->quirks |= SQ_SKIP_SR_WEL | SQ_SECURITY_NYBBLE_SHIFT; return 0; } diff --git a/spi.h b/spi.h index 4604174..30c3428 100644 --- a/spi.h +++ b/spi.h @@ -42,7 +42,6 @@ struct spi_id { uint8_t memory_size; // Result from 0x9f uint8_t signature; // Result from 0xab uint8_t serial[4]; // Result from 0x4b - uint8_t security[3]; // Result from 0x48 const char *manufacturer; const char *model; const char *capacity; @@ -65,7 +64,8 @@ int spiTx(struct ff_spi *spi, uint8_t word); uint8_t spiRx(struct ff_spi *spi); uint8_t spiReadStatus(struct ff_spi *spi, uint8_t sr); void spiWriteStatus(struct ff_spi *spi, uint8_t sr, uint8_t val); -void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t val); +void spiReadSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]); +void spiWriteSecurity(struct ff_spi *spi, uint8_t sr, uint8_t security[256]); int spiSetType(struct ff_spi *spi, enum spi_type type); int spiRead(struct ff_spi *spi, uint32_t addr, uint8_t *data, unsigned int count);