Files
templates/c/spi-nor/Inc/spi_nor.h

141 lines
5.4 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef PORTABLE_SPI_NOR_H
#define PORTABLE_SPI_NOR_H
/*
* Переносимое ядро SPI NOR.
*
* Ядро знает только стандартные SPI-команды и callbacks платформы. Оно не
* включает HAL, регистры MCU, GPIO проекта, Modbus или код приложения. Каждый
* экземпляр хранит собственное состояние и поэтому не использует глобальные
* изменяемые переменные.
*/
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Поддерживаемые микросхемы ограничены устройствами с 24-битной адресацией. */
typedef enum
{
SPI_NOR_MODEL_NONE = 0,
SPI_NOR_MODEL_W25Q64,
SPI_NOR_MODEL_W25Q128,
SPI_NOR_MODEL_SST25VF016B
} spi_nor_model_t;
/* Ошибки протокола не зависят от кодов конкретного HAL. */
typedef enum
{
SPI_NOR_OK = 0,
SPI_NOR_E_ARGUMENT = -1,
SPI_NOR_E_IO = -2,
SPI_NOR_E_TIMEOUT = -3,
SPI_NOR_E_NOT_FOUND = -4,
SPI_NOR_E_UNSUPPORTED = -5,
SPI_NOR_E_BOUNDS = -6,
SPI_NOR_E_ALIGNMENT = -7,
SPI_NOR_E_VERIFY = -8,
SPI_NOR_E_BUSY = -9
} spi_nor_status_t;
/* Callback SPI возвращает только переносимый результат физического обмена. */
typedef enum
{
SPI_NOR_IO_OK = 0,
SPI_NOR_IO_ERROR = -1,
SPI_NOR_IO_TIMEOUT = -2
} spi_nor_io_status_t;
/* Геометрия и JEDEC доступны приложению только как копируемая диагностика. */
typedef struct
{
spi_nor_model_t model;
uint8_t manufacturer_id;
uint8_t memory_type;
uint8_t capacity_code;
uint32_t capacity_bytes;
uint32_t sector_size;
uint16_t page_size;
} spi_nor_info_t;
/*
* Контракт платформы описывает одну SPI-шину и один сигнал CS.
*
* transfer выполняется при уже активном CS. NULL в tx означает передачу
* dummy-байтов, NULL в rx — игнорирование принятого потока. lock/unlock
* необязательны; RTOS-порт может ими сериализовать полную read/program/erase
* операцию, а не отдельный SPI пакет.
*/
typedef struct
{
void *context;
spi_nor_io_status_t (*transfer)(void *context, const uint8_t *tx,
uint8_t *rx, size_t size,
uint32_t timeout_ms);
void (*chip_select)(void *context, uint8_t active);
uint32_t (*tick_ms)(void *context);
void (*delay_ms)(void *context, uint32_t delay_ms);
spi_nor_io_status_t (*lock)(void *context, uint32_t timeout_ms);
void (*unlock)(void *context);
} spi_nor_io_t;
/* Тайм-ауты вынесены в конфигурацию для медленных шин и разных RTOS. */
typedef struct
{
uint32_t io_timeout_ms;
uint32_t lock_timeout_ms;
uint32_t program_timeout_ms;
uint32_t erase_timeout_ms;
uint32_t ready_poll_delay_ms;
} spi_nor_config_t;
/* Контекст полностью принадлежит вызывающему коду и не требует malloc. */
typedef struct
{
spi_nor_io_t io;
spi_nor_config_t config;
spi_nor_info_t info;
uint8_t initialized;
uint8_t detected;
uint8_t busy;
} spi_nor_t;
/* Возвращает документированные безопасные тайм-ауты библиотеки. */
spi_nor_config_t spi_nor_default_config(void);
/* Инициализация только копирует callbacks и не обращается к физической шине. */
spi_nor_status_t spi_nor_init(spi_nor_t *device, const spi_nor_io_t *io,
const spi_nor_config_t *config);
/* Probe будит память, читает JEDEC и разрешает работу известной геометрии. */
spi_nor_status_t spi_nor_probe(spi_nor_t *device);
/* Операции используют физические смещения микросхемы, начиная с нуля. */
spi_nor_status_t spi_nor_read(spi_nor_t *device, uint32_t address,
void *data, size_t size);
spi_nor_status_t spi_nor_program(spi_nor_t *device, uint32_t address,
const void *data, size_t size);
spi_nor_status_t spi_nor_erase(spi_nor_t *device, uint32_t address,
size_t size);
/* Информация выдаётся только после успешного распознавания поддержанной модели. */
spi_nor_status_t spi_nor_get_info(const spi_nor_t *device,
spi_nor_info_t *info);
/* Последний JEDEC доступен и для различения пустой шины и неизвестной модели. */
spi_nor_status_t spi_nor_get_last_jedec(const spi_nor_t *device,
uint8_t jedec[3]);
/* Read-only диагностика возвращает status register 1 под общей блокировкой. */
spi_nor_status_t spi_nor_read_status_register(spi_nor_t *device,
uint8_t *status);
#ifdef __cplusplus
}
#endif
#endif /* PORTABLE_SPI_NOR_H */