Имеется LPC2368, на его аппаратном контроллере MCI реализованы чтение-запись карточек MMC/SD/SDHC, все нормально и беспроблемно работает. Теперь потребовалось реализовать функцию парольной защиты карт памяти. Для этого на карту следует послать команду LOCK_UNLOCK, дождаться статуса и затем послать некоторый блок данных (с паролем), длина которого для разных парольных операций может составлять от 1 до 34 байтов. Этот блок данных должен сопровождаться CRC, после чего карта отвечает статусом приема и переходит на некоторое время в состояние занятости - все эти парольные операции LOCk_UNLOCK полностью аналогичны записи одиночного блока данных.
В чем проблема - контроллер MCI, похоже, не позволяет посылать блоки данных произвольной длины. В режиме контроллера BLOCK_MODE длина блока должна быть степенью 2 - 1/2/4/8... 2048 байт. После отсылки блока указанной длины автоматически отсылается CRC. То есть передать например 5 байт + CRC никак не получается. В режиме контролллера STREAM_MODE можно передать произвольное число байтов, но в этом режиме CRC контроллером MCI не посылается.
В итоге было принято решение дополнить посылаемый блок данных нулями до кратного степени 2 размера и работать в BLOCK_MODE. Карты SDHC (я подозреваю что все карты спецификации SD v2+) в таком режиме работают нормально, а вот обычные SD - нет. Для них работают нормально все команды установки/стирания пароля, а вот собственно команда разблокировки - не работает - грит UNLOCK_FAILED. Причем, если длину пароля подобрать так что длина посылаемого блока точно кратна степени 2, то все тоже работает.
Сижу вот теперь и думаю - это контроллер MCI в LPC23xx кривой и реально не позволяет передать блок нужной длины с CRC, или я чего-то упускаю? NXP традиционно на вопросы не отвечает ((
Дополню пост диаграммами посылки блока данных пароля для блочного и потокового режимов.
В потоковом режиме посылается 6 байт 0x00, 0x04, 0x30, 0x31, 0x32, 0x33, как видно контрольной суммы нет и карта не переходит в Busy.
В блочном режиме данные дополнены до 8 байт 0x00, 0x04, 0x30, 0x31, 0x32, 0x33, 0x00, 0x00 и видно что контроллер посылает CRC. Лишние два 0x00 никак не мешают SDHC картам, и также не мешают SD картам кроме собственно разблокировки (а вот установить/стереть пароль/глобально стереть при помощи такой команды можно)