Перейти к содержанию
    

MSP430 + SD-карта

Здравствуйте уважаемые форумчане.

Понадобилось к проекту прикрутить SD-карту с файловой системой.

Выбрал FATFS от Чана, портировал драйвер низкого уровня из его примеров для STM32.

Карты (от Qumo, Transcend, Samsung) ёмкостью 2 - 32 ГБ работают: папки создаются, файлы пишутся и т.д.

Но вот карта от SanDisk на 64 ГБ работать никак не хочет.

Выдаёт ошибку по таймауту (пробовал менять от 1 до 10 секунд) при отправке команды ACMD41 во время инициализации (отметил стрелкой).

Может есть у кого какие соображения куда копать? Код инициализации. 

uint8_t sdcard_initialize(void)
{
    // Если SD-карта отсутствует, то выход
    if (sdcard_status & STA_NODISK)
        return sdcard_status;
    
    // Отключить SD-карту
    sdcard_deselect();
    
    // Инициализация карты всегда производится на низкой скорости SPI (100-400 кГц)
    spi_baud_rate_change(SPI_BAUD_RATE_LOW);
    
    uint8_t n;
    const uint8_t tx_byte = 0xFF;
    
    // Отправить не менее 80 единичных бит (обязательно, иначе карта не инициализируется!)
    for (n = 10; n; n--)
        spi_byte_exchange(tx_byte);
    
    // Тип SD-карты (после инициализации не должен быть нулевым!)
    uint8_t type = 0;
    
    // Перевести SD-карту в состояние SPI/Idle
    if (sdcard_send_cmd(SDCARD_CMD0, 0) == 1)
    {
        // Временная метка начала отсчёта
        const timer_interval_t start = timer_interval_total_get();
        timer_interval_t timer;
        bool_t is_timeout;
        
        // Если тип SD-карты SDC ver. 2 или SDC ver. 2+
        if (sdcard_send_cmd(SDCARD_CMD8, 0x1AA) == 1)
        {
            // Чтение 32-битного регистра R7
            uint8_t ocr[4];
            for (n = 0; n < 4; n++)
                ocr[n] = spi_byte_exchange(tx_byte);
            
            // Если SD-карта поддерживает напряжение питания 2.7-3.6 В
            if (ocr[2] == 0x01 && ocr[3] == 0xAA)
            {
                // Ожидание завершения инициализации командой ACMD41 (HCS бит)
                do
                {
                    timer = timer_interval_total_get() - start;
                    is_timeout = timer >= SDCARD_INITIALIZE_TIMEOUT;
                } while (!is_timeout && sdcard_send_cmd(SDCARD_ACMD41, 1ul << 30)); // <- Зависает на этой строке: всегда возвращает busy = 0x01!
                
                // Проверка CCS бита в OCR
                if (!is_timeout && sdcard_send_cmd(SDCARD_CMD58, 0) == 0)
                {
                    for (n = 0; n < 4; n++)
                        ocr[n] = spi_byte_exchange(tx_byte);
                    
                    // Тип SD-карты SDC ver. 2
                    type = (ocr[0] & 0x40) ?
                        SDCARD_TYPE_SDC2 | SDCARD_TYPE_BLOCK :
                        SDCARD_TYPE_SDC2;
                }
            }
        }
        
        // Иначе...
        else
        {
            uint8_t cmd;
            
            // Тип SD-карты SDC
            if (sdcard_send_cmd(SDCARD_ACMD41, 0) <= 1)
            {
                type = SDCARD_TYPE_SDC1;
                cmd = SDCARD_ACMD41;
            }
            
            // Тип SD-карты MMC ver. 3
            else
            {
                type = SDCARD_TYPE_MMC3;
                cmd = SDCARD_CMD1;
            }
            
            // Ожидание завершения инициализации
            do
            {
                timer = timer_interval_total_get() - start;
                is_timeout = timer >= SDCARD_INITIALIZE_TIMEOUT;
            }
            while (!is_timeout && sdcard_send_cmd(cmd, 0));
            
            // Установить значение блока данных по умолчанию
            if (is_timeout || sdcard_send_cmd(SDCARD_CMD16, SDCARD_SECTOR_SIZE) != 0)
                type = 0;
        }
    }
    
    // Сохранить тип SD-карты
    sdcard_type = type;
    sdcard_deselect();
    if (type)
    {
        // Увеличить скорость обмена по SPI
        spi_baud_rate_change(SPI_BAUD_RATE_HIGH);
        
        // Обновить статус SD-карты
        sdcard_status &= ~STA_NOINIT;
    }
    
    // Ошибка инициализации
    else
        sdcard_status = STA_NOINIT;
    return sdcard_status;
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22.02.2022 в 19:13, aaarrr сказал:

Попробуйте CMD58 перед ACMD41.

К сожалению не помогло. Карта возвращает 0x01 вместо 0x00.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может, паузу добавить? У меня в последнее время появились "странные" карты, которые работают со второго пинка или после задержки. Деталей уже не помню.

У меня везде начало инициализации выглядит так:

delay_sd_tim(160);
SD_CS_bit = 1;
delay_sd_tim(100);
for(i = 0; i < 74; i++) sd_send_byte(0xFF);
delay_sd_tim(1);

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня тоже последние мощные карты лечились паузами.

Я грешу на возросшее потребление. Но добавление емкостей - не помогает.

Может источники питания надо менять...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это точно не БП, т.к. я провожу переинициализацию, и без задержек карта всякий раз затыкается. Можно переинициализировать не глубоко - тогда со второй попытки успех. Хотя, при инициализации и может быть какое-то завышенное потребление - не проверял, БП у меня довольно мощный.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

36 minutes ago, adnega said:

Это точно не БП, т.к. я провожу переинициализацию, и без задержек карта всякий раз затыкается. Можно переинициализировать не глубоко - тогда со второй попытки успех. Хотя, при инициализации и может быть какое-то завышенное потребление - не проверял, БП у меня довольно мощный.

Да, я грешу что у меня БП не справляется с импульсным потреблением. А когда стоит несколько мс между коммандами - БП успевает. Но пока нет времени городить детальный стенд для измерений.

У меня карта от ISSI - после инициализации потребляет меньше, чем при подаче питания...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...