@@ -36,4 +36,26 @@ const char *sd_cmd_name(uint8_t cmd);
*/
const char *sd_acmd_name(uint8_t cmd);
+/**
+ * sd_crc7:
+ * @data: pointer to the data buffer
+ * @data_len: data length
+ *
+ * Calculate the 7-bit CRC of a SD frame.
+ *
+ * Returns: The frame CRC.
+ */
+uint8_t sd_crc7(const void *data, size_t data_len);
+
+/**
+ * sd_crc16:
+ * @data: pointer to the data buffer
+ * @data_len: data length
+ *
+ * Calculate the 16-bit CRC of a SD data frame.
+ *
+ * Returns: The frame CRC.
+ */
+uint16_t sd_crc16(const void *data, size_t data_len);
+
#endif
@@ -237,43 +237,6 @@ static const int sd_cmd_class[SDMMC_CMD_MAX] = {
7, 7, 10, 7, 9, 9, 9, 8, 8, 10, 8, 8, 8, 8, 8, 8,
};
-static uint8_t sd_crc7(const void *message, size_t width)
-{
- int i, bit;
- uint8_t shift_reg = 0x00;
- const uint8_t *msg = (const uint8_t *)message;
-
- for (i = 0; i < width; i++, msg++) {
- for (bit = 7; bit >= 0; bit--) {
- shift_reg <<= 1;
- if ((shift_reg >> 7) ^ ((*msg >> bit) & 1)) {
- shift_reg ^= 0x89;
- }
- }
- }
-
- return shift_reg;
-}
-
-static uint16_t sd_crc16(const void *message, size_t width)
-{
- int i, bit;
- uint16_t shift_reg = 0x0000;
- const uint16_t *msg = (const uint16_t *)message;
- width <<= 1;
-
- for (i = 0; i < width; i++, msg++) {
- for (bit = 15; bit >= 0; bit--) {
- shift_reg <<= 1;
- if ((shift_reg >> 15) ^ ((*msg >> bit) & 1)) {
- shift_reg ^= 0x1011;
- }
- }
- }
-
- return shift_reg;
-}
-
#define OCR_POWER_DELAY_NS 500000 /* 0.5ms */
FIELD(OCR, VDD_VOLTAGE_WINDOW, 0, 24)
@@ -70,3 +70,41 @@ const char *sd_acmd_name(uint8_t cmd)
return acmd_abbrev[cmd] ? acmd_abbrev[cmd] : "UNKNOWN_ACMD";
}
+
+/* 7 bit CRC with polynomial x^7 + x^3 + 1 */
+uint8_t sd_crc7(const void *message, size_t width)
+{
+ int i, bit;
+ uint8_t shift_reg = 0x00;
+ const uint8_t *msg = (const uint8_t *)message;
+
+ for (i = 0; i < width; i++, msg++) {
+ for (bit = 7; bit >= 0; bit--) {
+ shift_reg <<= 1;
+ if ((shift_reg >> 7) ^ ((*msg >> bit) & 1)) {
+ shift_reg ^= 0x89;
+ }
+ }
+ }
+
+ return shift_reg;
+}
+
+uint16_t sd_crc16(const void *message, size_t width)
+{
+ int i, bit;
+ uint16_t shift_reg = 0x0000;
+ const uint16_t *msg = (const uint16_t *)message;
+ width <<= 1;
+
+ for (i = 0; i < width; i++, msg++) {
+ for (bit = 15; bit >= 0; bit--) {
+ shift_reg <<= 1;
+ if ((shift_reg >> 15) ^ ((*msg >> bit) & 1)) {
+ shift_reg ^= 0x1011;
+ }
+ }
+ }
+
+ return shift_reg;
+}
Take those functions out of hw/sd/sd.c (via "sdmmc-internal.h") to be able to write QTests for them. Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org> --- hw/sd/sdmmc-internal.h | 22 ++++++++++++++++++++++ hw/sd/sd.c | 37 ------------------------------------- hw/sd/sdmmc-internal.c | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 37 deletions(-)