LPCXpresso Урок 11
Використовуємо схему з минулого уроку з підключенням роз'єму USB і додаємо підключення картки. Для цього нам треба зібрати таку схему:

Доопрацьовуємо код
Завдання універсальності собі ставити не станемо. Робитимемо код під конкретну карту пам'яті (обсяг картки). Як основа для даного проекту візьмемо приклад з минулого уроку і доопрацюємо його. Доопрацювання пройде так:
- Налаштування SPI
- Код для роботи з карткою пам'яті
- Доопрацювання функцій читання/запису USB-диску
Налаштування SPI
У проекті (не бібліотеці, тому що тут ми її не підключали) створюємо файлssp.hз наступним вмістом:
Оскільки картка пам'яті має ініціалізуватися на швидкості 400кГц, а працювати може і на 20МГц, то функцію ініціалізації напишемо з одним параметром, що задає повільний/високошвидкісний режим роботи SPI. Створюємо файлssp.cз реалізацією функцій. Після підключення заголовних файлів додаємо функції длявибору пристрою.Source Fileпишемоssp.cі тиснемоFinish.
Ці функції потрібні, т.к. ми не будемо використовувати наявний апаратний контроль, а вибиратимемо картку самостійно (через деякі обмеження в протоколі роботи з карткою пам'яті). Далі реалізуємо функцію передачі. У ній ми просто заносимо дані передачі в регістр даних DR контролера SPI. Після цього контролер SPI самостійно запускає цикл обміну. Нам залишається тільки чекати його завершення, про що повідомить нам другий біт в регістрі SR контролера SPI. Після закінчення обміну ми виймаємо з регістру даних DR контролера SPI прийняті дані та повертаємо їх як результат роботи функції.
Тепер приступимо до функції ініціалізації:
Крім уже відомих нам дозволу роботи, подачі тактів і вибору висновків функції для роботи з периферією у нас є так само:
- встановлення в регістрSSPCLKDIVдільника тактової частоти для контролера SPI (завдання частоти роботи контролера SPI) 10 або 1, залежно від необхідного режиму;
- встановлення в регістрCR0формату пакета (докладно в документації до контролера) і додаткового дільника (завдання частоти тактової лінії SPI) 8 чи 1, залежно від необхідного режиму;
- встановлення в регістрCPSRдільника частоти для опорної частоти тактової лінії SPI мінімальне значення 2;
- видалення сміття з приймального буфера SPI;
- встановлення в регістрCR1роботи контролера в режимі «майстер» та дозвіл тим самим роботи контролера SPI;
Робота з карткою
Усі імена самі, що були у прикладі. Вкажіть тут кількість блоків вашої картки пам'ятіMSC_BlockCount. Ще раз нагадаю, що SDHC не підтримуються і більше 2Гб не може бути. Також додався виклик ініціалізація картки пам'яті в функціїmainу файліusbmemrom_main.c:
ФункціяSetLedпризначена для цілей діагностики. Так, якщо при ініціалізації карти виникла помилка, то буде запалений світлодіод на платі, індикуючи помилку.
Функції читання/запису
У файліmsccallback.cправимо функції читання та запису блоку диска. Але так як розмір блоку на диску у нас 512 байт, а розмір блоку USB всього 64 байта, то для читання одного блоку диска функція читання буде викликана 8 разів поспіль з різним зміщенням одного і того ж блоку. І так само для запису. Що б не робити кілька читань одного блоку з диска (а тим більше записів), додамо кешування:
Після цього функція читання виглядає дуже просто:
І функція запису така проста, тільки доданий код запису буфера по досягненню кінця блоку:
У коді присутній виклик тієї жSetLedцього разу з метою індикації звернення до карти.
Як зазвичай компілюємо та виправляємо помилки. Післяпідключення доданого роз'єму до комп'ютера світлодіод почне блимати, а в системі з'явиться новий знімний диск. Якщо світлодіод постійно яскраво світиться, що буває, коли на початку був інший код, який збив ініціалізацію карті, то знеструмте плату і знову подайте харчування. Якщо система пропонує вам диск відформатувати, то ймовірно, у вас в коді не вірно вказаний розмір. Хоча можливо, просто картка не була відформатована. Я повторно рекомендую не використовувати картки з важливими для вас даними. Сам я при експериментах вказував і менші і більші розміри, але хто знає як поведеться нестабільна система.
Статистика
Код у Debug версії у мене вийшло 4216 байт коду. Швидкість читання становила 194 кБайт/с, швидкість запису 84 кБайт/с.




Замість ув'язнення
З жалем має визнати, що урок вийшов об'ємним та незрозумілим. При цьому при всьому безпосередньо на тему (SPI) пара жалюгідних абзаців. Навіть виключення принципів роботи з карткою пам'яті хоч і скоротило статтю, але недостатньо. Однак, сподіватимусь, що вивчення минулих прикладів навчило вас розбиратися в коді.