# Библиотеки для работы с внешними FLASH, EEPROM

Папка _CubeKeil Example_ содержит проект, который демонстрирует работу с библиотеками.

Папка _memory_spi_ содержит библиотеку для SPI памяти (FLASH/EEPROM): два файла "_memory_spi.c/.h_".

## Функции SPI MEMORY
Общение с памятью на уровне железа выполняют [функции для команд](#функции-для-команд). 
Координацию команд выполняют [функции для внутреннего использования](#функции-для-внутреннего-использования). 
А запросы на запись/чтение/очистку произвольного кол-ва байт выполняют [функции для пользователя](#функции-для-пользователя).


## 	Пример

```c
	MEMSPI_HandleTypeDef hmemspi;
	HAL_StatusTypeDef MEMSPI_RES;

	hmemspi.CS_GPIOx = GPIOC;
	hmemspi.CS_PIN = GPIO_PIN_4;
	MEMSPI_Base_Init(&hmemspi, &hspi3);
  
	MEMSPI_RES = MEMSPI_EEPROM_Write(&hmemspi, mem_adr, write_buff, buff_size, Timeout, 1);
	MEMSPI_RES = MEMSPI_Read_Memory(&hmemspi, mem_adr, read_buff, buff_size, Timeout);
```


### Функции для пользователя
    - MEMSPI_Base_Init()                        Инициализация переферии SPI и GPIO для внешней памяти
	- MEMSPI_Read_Memory()						Считывание внешней FLASH/EEPROM
	- MEMSPI_EEPROM_Write()						Запись данных в внешнюю EEPROM
	- MEMSPI_FLASH_Write()						Запись данных в внешнюю FLASH   (функция сама очищает нужные сектора, и если надо сохраняет выбранные данные)
	- MEMSPI_FLASH_Program()				    Программирование внешней FLASH  (выбранный участок FLASH должен быть очищен)
	- MEMSPI_FLASH_Erase()						Очистка внешней FLASH

С помощью данных функций предлагается управлять внещней памятью. Эти функции имеют "неограниченый" доступ к памяти. Т.е. они могут записывать данные размером больше страницы и очищать несколько секторов за один вызов.
При вызове этих функций проверяется свободно ли устройство. И если свободно то начинают с ним соответсвующую работу. Возможно также ожидание в конце, когда нужная операция выполниться.

Функция инициализации **MEMSPI_Base_Init()** содержит базовые настройки для перефирии SPI и GPIO. Пользователь только настраивает SPI Instance, BaudratePrescaler и порты ввода/вывода для общения с памятью.

### Функции для внутреннего использования
	- MEMSPI_EEPROM_Write_Page()					Запись страницы в EEPROM 		
	- MEMSPI_FLASH_Erase_Sector()					Очистка сектора FLASH.
	- MEMSPI_FLASH_Program_Page()					Программирование страницы.
	- MEMSPI_WriteEnablingUntilTimeout()	        Разрешение записи, пока не будет ответа или не истек таймаут
	- MEMSPI_WaitOnFlagsUntilTimeout()			    Ожидание флага пока не истек таймаута

Функции **Write**, **Erase**, **Program** работают напрямую с командами SPI для памяти. Соответственно имеют те же ограничения, что и команды: запись памяти только в пределах страницы, и очистка памяти только по секторам. 
Они проверяют свободно ли устройство (бит **BUSY** в **Status Register**). И если да, отправляют команду на разрешение записи. И если запись разрешена (бит **WEL** в **Status Register**), начинают с ней работать. Также эти функциии в конце могут ожидать, пока устройство не выполнит нужную операцию с памятью (бит **BUSY** в **Status Register**) ИЛИ просто выйти из функции не дожидаясь конца операции.

Функции UntilTimeout нужны для ожидания некоторого события до истечения таймаута:
- WriteEnabling:        посылает команду для разрешения записи и ожидает когда запись разрешится ИЛИ когда истечет таймаут
- WaitOnFlags:          ожидает выставления выбранных флагов ИЛИ когда истечет таймаут

### Функции для команд
Данные функции начинаются с **MEMSPI_CMD_...()**. Они посылают соответствующие команды и принимают ответ. Также на время команды все функции выставляют Chip Select для выбранного устройства. А функция **MEMSPI_CMD_Read_Status_Register()** имеет параметр, который позволяет не убирать Chip Select после команды для постоянного мониторинга Status Register. Прием с помощью **MEMSPI_SPI_Receive()**.