Первая итерация
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
# Драйвер внешней Flash-памяти DS_W25X40CL
|
||||
|
||||
Низкоуровневая библиотека на Си для работы с энергонезависимой NOR Flash-памятью **Winbond W25X40CL** (объем 4 Мбит / 512 Килобайт) по интерфейсу SPI. Память разбита на 8 блоков, 128 секторов по 4 КБ и 2048 страниц по 256 байт.
|
||||
|
||||
## 📌 Особенности реализации
|
||||
* **Блочная очистка и запись**: Реализована поддержка постраничной записи (Page Program, до 256 байт) и посекторного стирания (Sector Erase, 4 КБ), что является обязательным требованием для NOR Flash архитектуры.
|
||||
* **Контроль занятости (Busy Checking)**: Функции записи и стирания автоматически опрашивают первый регистр статуса памяти (Status Register 1, бит `BUSY`), блокируя выполнение до тех пор, пока чип физически не завершит операцию во внутренней памяти.
|
||||
* **Идентификация чипа**: Наличие функции чтения JEDEC ID позволяет программно проверить подлинность микросхемы и успешность подключения по шине SPI при старте системы.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Способ добавления в проект (Git Submodule)
|
||||
|
||||
Драйвер подключается к вашему текущему проекту как подмодуль Git, изолируя код управления памятью от прикладной логики.
|
||||
|
||||
### 1. Подключение подмодуля
|
||||
Выполните команду в корневом каталоге вашего проекта:
|
||||
```bash
|
||||
git submodule add https://domstudent.ru Library/DS_W25X40CL
|
||||
```
|
||||
|
||||
### 2. Автоматическое обновление CMake
|
||||
Запустите PowerShell-скрипт для автоматического добавления путей `Inc` и файлов `Src` подмодуля памяти в структуру сборки проекта:
|
||||
```powershell
|
||||
cd tools/
|
||||
./UpdateCMakeList.ps1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Схема подключения (SPI)
|
||||
|
||||
Интерфейс SPI настраивается в CubeMX в режиме `Full-Duplex Master` (или `Transmit Only`, если чтение не требуется, но для памяти чтение обязательно), `Data Size: 8 Bits`, `First Bit: MSB First`. Режим SPI: `CPOL = Low (0)`, `CPHA = 1 Edge (0)` (SPI Mode 0) или `CPOL = High`, `CPHA = 2 Edge` (SPI Mode 3).
|
||||
|
||||
| Вывод микросхемы W25X40CL | Вывод STM32 | Назначение |
|
||||
| :--- | :--- | :--- |
|
||||
| **/CS** (Pin 1) | Любой GPIO_Output | Выбор чипа (Chip Select, активен в 0) |
|
||||
| **DO (IO1)** (Pin 2) | SPIx_MISO | Выход данных (Master Input Slave Output) |
|
||||
| **/WP** (Pin 3) | 3.3V или GPIO | Защита от записи (Write Protect, притянуть к 3.3В) |
|
||||
| **GND** (Pin 4) | GND | Общая земля |
|
||||
| **DI (IO0)** (Pin 5) | SPIx_MOSI | Вход данных (Master Output Slave Input) |
|
||||
| **CLK** (Pin 6) | SPIx_SCK | Тактовая линия шины SPI |
|
||||
| **/HOLD** (Pin 7) | 3.3V или GPIO | Удержание шины (Hold, притянуть к 3.3В) |
|
||||
| **VCC** (Pin 8) | 3.3V | Питание микросхемы (2.3V — 3.6V) |
|
||||
|
||||
---
|
||||
|
||||
## 💻 Пример использования в `main.c`
|
||||
|
||||
Помните специфику NOR Flash: перед записью данных в любую область памяти, этот сектор **обязательно нужно стереть**, иначе новые данные логически смешаются со старыми.
|
||||
|
||||
```c
|
||||
#include "DS_W25X40CL.h"
|
||||
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
DS_W25X40CL external_flash;
|
||||
|
||||
uint8_t write_buffer[256];
|
||||
uint8_t read_buffer[256];
|
||||
|
||||
int main(void) {
|
||||
// ... Автоматическая инициализация HAL, GPIO, SPI ...
|
||||
|
||||
/* 1. Инициализация дескриптора памяти */
|
||||
DS_W25X40CL_Init(&external_flash, &hspi1, GPIOA, GPIO_PIN_4);
|
||||
|
||||
/* 2. Проверка связи с чипом (Чтение Manufacturer и Device ID) */
|
||||
uint32_t jedec_id = DS_W25X40CL_ReadID(&external_flash);
|
||||
if (jedec_id == 0xEF3013) { // 0xEF - Winbond, 0x3013 - W25X40CL
|
||||
// Память успешно опознана контроллером!
|
||||
}
|
||||
|
||||
/* 3. Запись и чтение данных (Пример работы с Сектором 0, Адрес 0x000000) */
|
||||
// Подготовка тестовых данных
|
||||
for(uint16_t i=0; i<256; i++) write_buffer[i] = i;
|
||||
|
||||
// ШАГ A: Стираем сектор (4 КБ) перед записью
|
||||
DS_W25X40CL_EraseSector(&external_flash, 0x000000);
|
||||
|
||||
// ШАГ Б: Записываем страницу памяти (макс 256 байт)
|
||||
DS_W25X40CL_WritePage(&external_flash, 0x000000, write_buffer, 256);
|
||||
|
||||
// ШАГ В: Считываем данные обратно для проверки
|
||||
DS_W25X40CL_ReadData(&external_flash, 0x000000, read_buffer, 256);
|
||||
|
||||
while (1) {
|
||||
// Основной цикл
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 Справочник API функций
|
||||
|
||||
### `void DS_W25X40CL_Init(DS_W25X40CL *flash, SPI_HandleTypeDef *hspi, GPIO_TypeDef *CS_Port, uint16_t CS_Pin)`
|
||||
Выполняет логическую инициализацию структуры драйвера, привязывает к ней шину SPI и программный пин управления защелкой `/CS`.
|
||||
|
||||
### `uint32_t DS_W25X40CL_ReadID(DS_W25X40CL *flash)`
|
||||
Отправляет команду `0x9F` (Read JEDEC ID) и вычитывает 3 байта ответа. Возвращает упакованное 24-битное число, содержащее ID производителя и емкость чипа.
|
||||
|
||||
### `void DS_W25X40CL_EraseSector(DS_W25X40CL *flash, uint32_t SectorAddress)`
|
||||
Отправляет команду разрешения записи `0x06` (Write Enable), затем команду стирания сектора `0x20` и его 24-битный адрес. Ожидает окончания процесса стирания через опрос регистра статуса.
|
||||
|
||||
### `void DS_W25X40CL_WritePage(DS_W25X40CL *flash, uint32_t PageAddress, uint8_t *pData, uint16_t Size)`
|
||||
Записывает массив данных размером до 256 байт в пределах одной физической страницы памяти (команда `0x02`). Автоматически контролирует бит готовности чипа.
|
||||
|
||||
### `void DS_W25X40CL_ReadData(DS_W25X40CL *flash, uint32_t Address, uint8_t *pData, uint16_t Size)`
|
||||
Выполняет непрерывное чтение данных любого объема, начиная с указанного 24-битного адреса памяти (команда `0x03`). Автоматически инкрементирует адрес на стороне чипа во время удержания линии `/CS`.
|
||||
Reference in New Issue
Block a user