291 lines
15 KiB
C
291 lines
15 KiB
C
/********************************W25 FLASH***********************************
|
||
Данный файл содержит базовые функции для общения с SPI Flash.
|
||
//-------------------Функции-------------------//
|
||
@func users
|
||
- W25_FLASH_Read Считывание FLASH
|
||
- W25_FLASH_Write_Area Запись данных в заданный участок FLASH (с потерей данных в выбраном сектора за пределами этого участка)
|
||
- W25_FLASH_Erase_Sector Очистка сектора FLASH
|
||
- W25_FLASH_Program_Area Программирование FLASH
|
||
|
||
@func initialization
|
||
- W25_Base_Init Инициализация SPI и GPIO для FLASH
|
||
|
||
@func process interaction with flash
|
||
- W25_FLASH_Program_Page Программирование страницы. *есть более общая функция W25_FLASH_Program_Area, которая программирует участки больше страницы
|
||
- W25_WriteEnablingUntilTimeout Разрешение записи, пока не будет ответа или не истек таймаут
|
||
- W25_WaitOnFlagUntilTimeout Ожидание флага пока не истек таймаута
|
||
|
||
@func cmd functions
|
||
- W25_CMD_Read_Status_Register Отправка комманд Read Status Register 1 / Read Status Register 1 (0x05h / 0x35h)
|
||
- W25_CMD_Write_Status_Register Отправка комманды Write Status Register (0x01h)
|
||
- W25_CMD_Write_Enable Отправка комманды Write Enable (0x06h)
|
||
- W25_CMD_Write_Disable Отправка комманды Write Disable (0x04h)
|
||
- W25_CMD_Read_Data Отправка комманды Read Data (0x03h)
|
||
- W25_CMD_Fast_Read Отправка комманды Fast Read (0x0Bh)
|
||
- W25_CMD_Page_Program Отправка комманды Page Program (0x02h)
|
||
- W25_CMD_Erase_Sector Отправка комманды Erase Sector (0x20h)
|
||
- W25_CMD_Read_JEDEC_ID Отправка комманды Read JEDEC ID (0x4Bh)
|
||
- W25_CMD_Read_Device_ID Отправка комманды Read Manufacture / Device Id (0x90)
|
||
|
||
@func SPI functions
|
||
- W25_SPI_Transmit Функция отправки по SPI (содержит только HAL_SPI_Transmit)
|
||
- W25_SPI_Receive Функция приема по SPI (содержит только HAL_SPI_Receive)
|
||
***************************************************************************/
|
||
#include "stm32f4xx_hal.h"
|
||
#include "gpio_general.h"
|
||
|
||
/////////////////////////---USER SETTINGS---/////////////////////////
|
||
|
||
#define W25_Internal_Flash_Buffer_For_reProgram_BankNumber FLASH_BANK_1
|
||
#define W25_Internal_Flash_Buffer_For_reProgram_SectNumber FLASH_SECTOR_11
|
||
#define W25_Internal_Flash_Buffer_For_reProgram_Address 0x08E000000
|
||
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
////////////////////////////---DEFINES---////////////////////////////
|
||
/**
|
||
* @brief Defines for CMD.
|
||
*/
|
||
#define W25_CS_Set(_hw25_) (_hw25_->GPIOs.CS_GPIOx->BSRR = _hw25_->GPIOs.CS_PIN << 16)
|
||
#define W25_CS_Reset(_hw25_) (_hw25_->GPIOs.CS_GPIOx->BSRR = _hw25_->GPIOs.CS_PIN)
|
||
/**
|
||
* @brief Defines for CMD.
|
||
*/
|
||
#define W25_READ_JEDEC_ID 0x9F
|
||
#define W25_READ_UNIQUE_ID 0x4B
|
||
#define W25_WRITE_ENABLE 0x06
|
||
#define W25_WRITE_DISABLE 0x04
|
||
#define W25_WRITE_STATUS_REG 0x01
|
||
|
||
#define W25_ERASE_SECTOR 0x20
|
||
#define W25_PAGE_PROGRAM 0x02
|
||
#define W25_READ_STATUS_REG_1 0x05
|
||
#define W25_READ_STATUS_REG_2 0x35
|
||
#define W25_READ_DATA 0x03
|
||
/**
|
||
* @brief Defines for Status Register.
|
||
*/
|
||
#define W25_Get_Flag(_hw25_,_flag_) (((W25_StatusRegisterTypeDef)(_hw25_->SR))._flag_)
|
||
|
||
#define W25_SR_SUS (1<<15)
|
||
#define W25_SR_QE (1<<9)
|
||
#define W25_SR_SRP1 (1<<8)
|
||
#define W25_SR_SRP0 (1<<7)
|
||
#define W25_SR_SEC (1<<8)
|
||
#define W25_SR_TB (1<<5)
|
||
#define W25_SR_BP2 (1<<4)
|
||
#define W25_SR_BP1 (1<<3)
|
||
#define W25_SR_BP0 (1<<2)
|
||
#define W25_SR_WEL (1<<1)
|
||
#define W25_SR_BUSY (1<<0)
|
||
/**
|
||
* @brief Defines for W25 chip.
|
||
*/
|
||
#define W25_SECTOR_SIZE (0x1000)
|
||
#define W25_PAGE_SIZE (0x100)
|
||
/**
|
||
* @brief Calc dividing including remainder (divide and ceil)
|
||
* @param _val_ - делимое.
|
||
* @param _div_ - делитель.
|
||
* @note Если результат деления без остатка: он возвращается как есть
|
||
Если с остатком - округляется вверх
|
||
*/
|
||
//#define Divide_Up(_val_, _div_) (((_val_)%(_div_))? (_val_)/(_div_)+1 : (_val_)/_div_) /* через тернарный оператор */
|
||
#define Divide_Up(_val_, _div_) ((_val_ - 1) / _div_) + 1 /* через мат выражение */
|
||
|
||
////////////////////////////---DEFINES---////////////////////////////
|
||
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
|
||
typedef struct
|
||
{
|
||
uint8_t *pDataPtr;
|
||
uint32_t Data_Address;
|
||
uint32_t Data_Size;
|
||
|
||
uint32_t Sector_Address;
|
||
uint32_t Sector_Size;
|
||
}W25_reProgramInitTypeDef;
|
||
|
||
typedef struct
|
||
{
|
||
uint16_t SR;
|
||
SPI_HandleTypeDef hspi;
|
||
GPIO_TypeDef *CS_GPIOx;
|
||
uint32_t CS_PIN;
|
||
GPIO_TypeDef *CLK_GPIOx;
|
||
uint32_t CLK_PIN;
|
||
GPIO_TypeDef *MISO_GPIOx;
|
||
uint32_t MISO_PIN;
|
||
GPIO_TypeDef *MOSI_GPIOx;
|
||
uint32_t MOSI_PIN;
|
||
}W25_GPIOTypeDef;
|
||
|
||
typedef struct
|
||
{
|
||
uint16_t SR;
|
||
SPI_HandleTypeDef hspi;
|
||
W25_GPIOTypeDef GPIOs;
|
||
}W25_HandleTypeDef;
|
||
extern W25_HandleTypeDef hw25;
|
||
|
||
///////////////////////---STRUCTURES & ENUMS---//////////////////////
|
||
|
||
/////////////////////////////////////////////////////////////////////
|
||
///////////////////////////---FUNCTIONS---///////////////////////////
|
||
void W25_Base_Init(W25_HandleTypeDef *hw25);
|
||
|
||
/**
|
||
* @brief Read data from external FLASH.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param FLASH_Address - адресс откуда начинать считывание.
|
||
* @param pBuff - куда записывать данные из FLASH.
|
||
* @param Size - сколько байтов считывать.
|
||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||
* @return HAL status.
|
||
* @note Включает в себя проверку на доступность памяти (флаг BUSY)
|
||
*/
|
||
HAL_StatusTypeDef W25_FLASH_Read(W25_HandleTypeDef *hw25, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size, uint32_t Timeout);
|
||
|
||
/**
|
||
* @brief Write data to area in FLASH.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param reProgramInit - указатель на структуру, определяющую участок памяти для записи.
|
||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||
* @return HAL status.
|
||
* @note Позволяет перепрограммировать участок памяти. Можно записывать несколько страниц.
|
||
* Данные в сектора участка, но за пределами участка не сохраняются.
|
||
*/
|
||
HAL_StatusTypeDef W25_FLASH_Write_Area(W25_HandleTypeDef *hw25, W25_reProgramInitTypeDef *reProgramInit, uint32_t Timeout);
|
||
|
||
/**
|
||
* @brief Program area in FLASH.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param reProgramInit - указатель на структуру, определяющую участок памяти для записи.
|
||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||
* @return HAL status.
|
||
* @note Позволяет перепрограммировать участок памяти. Можно записывать несколько страниц.
|
||
* Данные в сектора участка, но за пределами участка не сохраняются.
|
||
*/
|
||
HAL_StatusTypeDef W25_FLASH_Program_Area(W25_HandleTypeDef *hw25, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout);
|
||
|
||
/**
|
||
* @brief Erase FLASH Sector.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param reProgramInit - указатель на структуру, определяющую участок памяти для записи.
|
||
* @param Timeout - время, за которое должно быть осуществлено чтение.
|
||
* @return HAL status.
|
||
* @note Позволяет перепрограммировать участок памяти. Можно записывать несколько страниц.
|
||
* Данные в сектора участка, но за пределами участка не сохраняются.
|
||
*/
|
||
HAL_StatusTypeDef W25_FLASH_Erase_Sector(W25_HandleTypeDef *hw25, uint32_t FLASH_Address, uint32_t Timeout);
|
||
|
||
|
||
HAL_StatusTypeDef W25_FLASH_Program_Page(W25_HandleTypeDef *hw25, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size, uint32_t Timeout, uint32_t tickstart);
|
||
HAL_StatusTypeDef W25_WriteEnablingUntilTimeout(W25_HandleTypeDef *hw25, uint32_t Timeout, uint32_t tickstart);
|
||
HAL_StatusTypeDef W25_WaitOnFlagUntilTimeout(W25_HandleTypeDef *hw25, uint16_t FlagMask, uint16_t FlagStatus, uint32_t Timeout, uint32_t tickstart);
|
||
|
||
/**
|
||
* @brief Send command to read Status Register.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param RequestedBits - какие биты запросить.
|
||
* @return Заполняет Status Register в hw25.
|
||
* @note Всего есть две комманды: на запрос верхнего или нижниго байта.
|
||
* Функция в соответствии с RequestedBits определяет какой байт запросить, или два байта сразу.
|
||
*/
|
||
void W25_CMD_Read_Status_Register(W25_HandleTypeDef *hw25, uint16_t RequestedBits);
|
||
|
||
/**
|
||
* @brief Send command to write bits in Status Register.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param WrittenBits - какие биты запросить.
|
||
* @note Данная команда посылает биты, как сдвинутые на 2 вправо. Т.е. 0-й бит в комманде - 2-й бит BP0.
|
||
Но биты указываются в также как они расположены и регистре. Функция сама выполняет сдвиг.
|
||
*/
|
||
void W25_CMD_Write_Status_Register(W25_HandleTypeDef *hw25, uint16_t WrittenBits);
|
||
|
||
/**
|
||
* @brief Send command to set Write Enable Latch (WEL) in Status Register.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @note Разрешает запись в FLASH, путем высталения WEL в Status Register
|
||
*/
|
||
void W25_CMD_Write_Enable(W25_HandleTypeDef *hw25);
|
||
|
||
/**
|
||
* @brief Send command to read data from FLASH.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param FLASH_Address - адресс откуда начинать считывание.
|
||
* @param pBuff - куда записывать данные из FLASH.
|
||
* @param Size - сколько байтов считывать.
|
||
* @return pBuff.
|
||
*/
|
||
void W25_CMD_Read_Data(W25_HandleTypeDef *hw25, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size);
|
||
|
||
/**
|
||
* @brief Send command to fast read data from FLASH.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param FLASH_Address - адресс откуда начинать считывание.
|
||
* @param pBuff - куда записывать данные из FLASH.
|
||
* @param Size - сколько байтов считывать.
|
||
* @note Данная функция предполагает отправку одного dummy байта после адресса, но у меня поч не работает пока :(
|
||
*/
|
||
void W25_CMD_Fast_Read(W25_HandleTypeDef *hw25, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size);
|
||
|
||
/**
|
||
* @brief Send command to fast page program.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param FLASH_Address - адресс откуда начинать считывание.
|
||
* @param pData - откуда брать данные для записи в FLASH.
|
||
* @param Size - сколько байтов считывать.
|
||
* @note Программирование FLASH только в пределах одной страницы.
|
||
* Т.е. если запись с 0x0, то не больше 256 байт. Если с 0ч40, то не больше 192 байт.
|
||
*/
|
||
void W25_CMD_Page_Program(W25_HandleTypeDef *hw25, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size);
|
||
|
||
/**
|
||
* @brief Send command to erase sector.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param FLASH_Address - адресс где надо данные стереть.
|
||
* @note Микросхема вроде сама высчитывает какой сектор ерейзнуть, в соответствии с заданным адресом.
|
||
*/
|
||
void W25_CMD_Erase_Sector(W25_HandleTypeDef *hw25, uint32_t FLASH_Address);
|
||
|
||
/**
|
||
* @brief Send command to read JEDEC ID.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @return JEDEC ID микросхемы.
|
||
*/
|
||
uint32_t W25_CMD_Read_JEDEC_ID(W25_HandleTypeDef *hw25);
|
||
|
||
/**
|
||
* @brief Send command to read JEDEC ID.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @return Device ID микросхемы.
|
||
*/
|
||
uint64_t W25_CMD_Read_Device_ID(W25_HandleTypeDef *hw25);
|
||
|
||
/**
|
||
* @brief SPI Transmit.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param data - указатель на данные для отправки.
|
||
* @param size - размер данных для отправки.
|
||
* @return Device ID микросхемы.
|
||
* @note Здесь вызывается только функция HAL, и ничего больше.
|
||
*/
|
||
void W25_SPI_Transmit (W25_HandleTypeDef *hw25, uint8_t *data, uint16_t size);
|
||
|
||
/**
|
||
* @brief SPI Receive.
|
||
* @param hw25 - указатель на хендл flash.
|
||
* @param data - указатель на буффер для прниема данных.
|
||
* @param size - размер данных для приема.
|
||
* @return Device ID микросхемы.
|
||
* @note Здесь вызывается только функция HAL, и ничего больше.
|
||
*/
|
||
void W25_SPI_Receive (W25_HandleTypeDef *hw25, uint8_t *data, uint16_t size);
|
||
|
||
///////////////////////////---FUNCTIONS---///////////////////////////
|
||
|