Начало работы над прерываниями

This commit is contained in:
alexey
2024-08-14 18:27:50 +03:00
parent 981dbf9bfa
commit fd7d230e10
3 changed files with 598 additions and 42 deletions

View File

@@ -1,5 +1,6 @@
/********************************PERIPH************************************* /********************************PERIPH*************************************
Данный файл содержит инклюды и дефайны для всех библиотек базовой перефирии. Данный файл содержит инклюды и дефайны для всех библиотек базовой перефирии.
Для использования библиотеки для периферии нужно подключить этот файл.
***************************************************************************/ ***************************************************************************/
#ifndef __PERIPH_GENERAL_H_ #ifndef __PERIPH_GENERAL_H_
#define __PERIPH_GENERAL_H_ #define __PERIPH_GENERAL_H_

View File

@@ -34,8 +34,8 @@
#include "memory_spi.h" #include "memory_spi.h"
uint8_t sector_buff[MEMSPI_SECTOR_SIZE]; uint8_t sector_buff[MEMSPI_SECTOR_SIZE];
//------------------------------------------------------------- //-------------------------------------------------------------------
//--------------------------FOR USER--------------------------- //-----------------------------FOR USER------------------------------
/** /**
* @brief Initialize SPI and GPIO for MEMSPI FLASH. * @brief Initialize SPI and GPIO for MEMSPI FLASH.
* @param hmemspi - указатель на структуру с настройками SPI и GPIO портов. * @param hmemspi - указатель на структуру с настройками SPI и GPIO портов.
@@ -72,7 +72,29 @@ void MEMSPI_Base_Init(MEMSPI_HandleTypeDef *hmemspi)
HAL_GPIO_Init(hmemspi->CS_GPIOx, &GPIO_InitStruct); HAL_GPIO_Init(hmemspi->CS_GPIOx, &GPIO_InitStruct);
} }
//-----------------------INTERRUPT MODE FUNCTIONS--------------------
/**
* @brief Read external FLASH/EEPROM with interrupt.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс откуда начинать считывание.
* @param pBuff - куда записывать данные из FLASH.
* @param Size - сколько байтов считывать.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return HAL status.
*/
HAL_StatusTypeDef MEMSPI_Read_Memory_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size)
{
HAL_StatusTypeDef MEMSPI_Status;
uint32_t tickstart = HAL_GetTick();
MEMSPI_Status = MEMSPI_CMD_Read_Data_IT(hmemspi, FLASH_Address, pBuff, Size);
if(MEMSPI_Status != HAL_OK)
return MEMSPI_Status;
return HAL_OK;
}
//-----------------------BLOCKING MODE FUNCTIONS---------------------
/** /**
* @brief Read external FLASH/EEPROM. * @brief Read external FLASH/EEPROM.
* @param hmemspi - указатель на хендл внешней памяти. * @param hmemspi - указатель на хендл внешней памяти.
@@ -190,7 +212,6 @@ HAL_StatusTypeDef MEMSPI_FLASH_Write(MEMSPI_HandleTypeDef *hmemspi, MEMSPI_Write
// WRITE FLASH WITH SAVING PREVIOUS DATA // WRITE FLASH WITH SAVING PREVIOUS DATA
if(WriteInit->fSavePrevoisData) if(WriteInit->fSavePrevoisData)
{ {
// uint8_t sector_buff[WriteInit->Sector_Size];
// store data from flash // store data from flash
MEMSPI_Status = MEMSPI_Read_Memory(hmemspi, WriteInit->Sector_Address, sector_buff, WriteInit->Sector_Size, Timeout); MEMSPI_Status = MEMSPI_Read_Memory(hmemspi, WriteInit->Sector_Address, sector_buff, WriteInit->Sector_Size, Timeout);
if(MEMSPI_Status != HAL_OK) if(MEMSPI_Status != HAL_OK)
@@ -346,8 +367,90 @@ HAL_StatusTypeDef MEMSPI_FLASH_Erase(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLA
} }
//------------------------------------------------------------- //-------------------------------------------------------------------
//----------------------SERVICE FUNCTIONS---------------------- //-------------------------SERVICE FUNCTIONS-------------------------
//----------------------INTERRUPT MODE FUNCTIONS---------------------
/**
* @brief Handler for SPI FLASH/EEPROM.
* @param hmemspi - указатель на хендл внешней памяти.
* @return HAL status.
* @note Включает в себя проверку на доступность памяти (флаг BUSY)
*/
void MEMSPI_Handler(MEMSPI_HandleTypeDef *hmemspi)
{
HAL_SPI_StateTypeDef active_line = hmemspi->sspi.hspi.State;
HAL_SPI_IRQHandler(&hmemspi->sspi.hspi);
/* RX Callback */
if (( hmemspi->sspi.hspi.RxXferCount == 0U) && (hmemspi->MEM_State == MEM_RECEIVE_DATA) && // if all bytes are received and receive is active
hmemspi->sspi.hspi.State != HAL_SPI_STATE_BUSY_RX) // also check that receive "REALLY" isnt busy
MEM_SPI_OperationCplt_Handler(hmemspi);
/* TX Callback */
if (( hmemspi->sspi.hspi.TxXferCount == 0U) && (hmemspi->MEM_State == MEM_SEND_COMMAND) && // if all bytes are transmited and transmit is active
hmemspi->sspi.hspi.State != HAL_SPI_STATE_BUSY_TX) // also check that transmit "REALLY" isnt busy
MEM_SPI_TransmitCommandCplt_Handler(hmemspi);
}
/**
* @brief Handler for transmit SPI command to EEPROM/FLASH.
* @param hmemspi - указатель на хендл внешней памяти.
* @return HAL status.
* @note После отправки комманды - инициализирует прием ответа если надо или завершает команду.
*/
void MEM_SPI_TransmitCommandCplt_Handler(MEMSPI_HandleTypeDef *hmemspi)
{
__HAL_UNLOCK(&hmemspi->sspi.hspi);
uint8_t endcmd = 0;
hmemspi->MEM_State = MEM_RECEIVE_DATA;
switch(hmemspi->Active_CMD)
{
case WRITE_ENABLE: endcmd = 1; break;
case WRITE_DISABLE: endcmd = 1; break;
case WRITE_STATUS_REG: endcmd = 1; break;
case ERASE_SECTOR: endcmd = 1; break;
case PAGE_PROGRAM: endcmd = 1; break;
case READ_STATUS_REG: MEMSPI_SPI_Receive_IT(hmemspi, (uint8_t *)&hmemspi->SR, 1); break;
case READ_DATA: MEMSPI_SPI_Receive_IT(hmemspi, hmemspi->pRxBuffPtr, hmemspi->RxXferSize); break;
case READ_JEDEC_ID: MEMSPI_SPI_Receive_IT(hmemspi, &hmemspi->pRxBuffPtr[1], 3); break;
case READ_UNIQUE_ID: MEMSPI_SPI_Receive_IT(hmemspi, hmemspi->pRxBuffPtr, 8); break;
default: break;
}
}
/**
* @brief Handler for receive SPI response from EEPROM/FLASH.
* @param hmemspi - указатель на хендл внешней памяти.
* @return HAL status.
* @note Завершает общение с памятью.
*/
void MEM_SPI_OperationCplt_Handler(MEMSPI_HandleTypeDef *hmemspi)
{
__HAL_UNLOCK(&hmemspi->sspi.hspi);
uint64_t return_val_LO;
uint64_t return_val_HI;
switch(hmemspi->Active_CMD)
{
case READ_JEDEC_ID:
*(uint32_t *)hmemspi->pRxBuffPtr = __REV((*(uint64_t *)hmemspi->pRxBuffPtr)) & 0xFFFFFF;
break;
case READ_UNIQUE_ID:
return_val_LO = (*(uint64_t *)hmemspi->pRxBuffPtr) >> 32;
return_val_HI = (*(uint64_t *)hmemspi->pRxBuffPtr) & 0xFFFFFFFF;
*(uint64_t *)hmemspi->pRxBuffPtr = ((uint64_t)__REV(return_val_HI) << 32) | __REV(return_val_LO);
break;
default: break;
}
hmemspi->Active_CMD = WAIT_FOR_CMD;
MEMSPI_Deselect(hmemspi);
}
//-----------------------BLOCKING MODE FUNCTIONS--------------------
/** /**
* @brief Write page in external EEPROM. * @brief Write page in external EEPROM.
* @param hmemspi - указатель на хендл внешней памяти. * @param hmemspi - указатель на хендл внешней памяти.
@@ -508,6 +611,54 @@ HAL_StatusTypeDef MEMSPI_WriteEnablingUntilTimeout(MEMSPI_HandleTypeDef *hmemspi
* @note Считывает флаги до тех пор, пока они не будут в состоянии FlagStatus или до тех пор, пока таймаут не истечет. * @note Считывает флаги до тех пор, пока они не будут в состоянии FlagStatus или до тех пор, пока таймаут не истечет.
*/ */
HAL_StatusTypeDef MEMSPI_WaitOnFlagsUntilTimeout(MEMSPI_HandleTypeDef *hmemspi, uint16_t FlagMask, uint16_t FlagStatus, uint32_t *Timeout, uint32_t *tickstart) HAL_StatusTypeDef MEMSPI_WaitOnFlagsUntilTimeout(MEMSPI_HandleTypeDef *hmemspi, uint16_t FlagMask, uint16_t FlagStatus, uint32_t *Timeout, uint32_t *tickstart)
{
HAL_StatusTypeDef MEMSPI_Status;
uint32_t tickstart_reserve;
uint32_t max_delay = HAL_MAX_DELAY;
if(tickstart == NULL)
tickstart = &tickstart_reserve;
if(Timeout == NULL)
Timeout = &max_delay;
// check flags
do{
if(hmemspi->sspi.hspi.State == HAL_SPI_STATE_READY)
MEMSPI_Status = MEMSPI_CMD_Read_Status_Register(hmemspi, FlagMask, 0, *Timeout);
}while(((HAL_GetTick() - *tickstart) < *Timeout) && (MEMSPI_Status != HAL_OK));
while((hmemspi->SR&FlagMask) != FlagStatus)
{
// check flags
// MEMSPI_Status = MEMSPI_CMD_Read_Status_Register(hmemspi, FlagMask, *Timeout);
MEMSPI_Status = MEMSPI_SPI_Receive(hmemspi, (uint8_t *)&hmemspi->SR, 1, *Timeout); // receive response
if(MEMSPI_Status != HAL_OK)
{
MEMSPI_Deselect(hmemspi);
return MEMSPI_Status;
}
if((HAL_GetTick() - *tickstart) >= *Timeout) // if time is out
{
MEMSPI_Deselect(hmemspi);
return HAL_TIMEOUT; // set timeout
}
}
MEMSPI_Deselect(hmemspi);
MEMSPI_Update_Timeout_Variables(Timeout, tickstart);
return HAL_OK; // if all ok return HAL_OK
}
/**
* @brief Wait for flag until timeout in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FlagMask - маска для флагов, какие флаги считывать.
* @param FlagStatus - какое состояние должно быть у выбранных флагов.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @param tickstart - время, относительно которого надо отсчитывать таймаут.
* @return HAL status.
* @note Считывает флаги до тех пор, пока они не будут в состоянии FlagStatus или до тех пор, пока таймаут не истечет.
*/
HAL_StatusTypeDef MEMSPI_WaitOnFlagsUntilTimeout_IT(MEMSPI_HandleTypeDef *hmemspi, uint16_t FlagMask, uint16_t FlagStatus, uint32_t *Timeout, uint32_t *tickstart)
{ {
HAL_StatusTypeDef MEMSPI_Status; HAL_StatusTypeDef MEMSPI_Status;
// check flags // check flags
@@ -547,8 +698,9 @@ void MEMSPI_Update_Timeout_Variables(uint32_t *Timeout, uint32_t *tickstart)
*Timeout -= timeoutcnt; *Timeout -= timeoutcnt;
*tickstart += timeoutcnt; *tickstart += timeoutcnt;
} }
//------------------------------------------------------------- //-------------------------------------------------------------------
//----------------------COMMAND FUNCTIONS---------------------- //-------------------------COMMAND FUNCTIONS-------------------------
//------------------------------BLOCKING-----------------------------
/** /**
* @brief Send command to read Status Register. * @brief Send command to read Status Register.
* @param hmemspi - указатель на хендл внешней памяти. * @param hmemspi - указатель на хендл внешней памяти.
@@ -618,10 +770,8 @@ HAL_StatusTypeDef MEMSPI_CMD_Write_Status_Register(MEMSPI_HandleTypeDef *hmemspi
command[1] = WrittenBits; command[1] = WrittenBits;
command[2] = WrittenBits >> 8; command[2] = WrittenBits >> 8;
size = 3;
MEMSPI_Select(hmemspi); MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit(hmemspi, command, size, Timeout); SPI_RES = MEMSPI_SPI_Transmit(hmemspi, command, 3, Timeout);
MEMSPI_Deselect(hmemspi); MEMSPI_Deselect(hmemspi);
return SPI_RES; return SPI_RES;
@@ -645,7 +795,6 @@ HAL_StatusTypeDef MEMSPI_CMD_Write_Enable(MEMSPI_HandleTypeDef *hmemspi, uint32_
return SPI_RES; return SPI_RES;
} }
/** /**
* @brief Send command to read data from FLASH/EEPROM. * @brief Send command to read data from FLASH/EEPROM.
* @param hmemspi - указатель на хендл внешней памяти. * @param hmemspi - указатель на хендл внешней памяти.
@@ -659,7 +808,6 @@ HAL_StatusTypeDef MEMSPI_CMD_Read_Data(MEMSPI_HandleTypeDef *hmemspi, uint32_t F
{ {
HAL_StatusTypeDef SPI_RES; HAL_StatusTypeDef SPI_RES;
uint8_t command[4]; uint8_t command[4];
uint8_t response[2] = {0};
command[0] = MEMSPI_READ_DATA; command[0] = MEMSPI_READ_DATA;
command[1] = FLASH_Address >> 16 & 0xFF; command[1] = FLASH_Address >> 16 & 0xFF;
@@ -837,5 +985,250 @@ HAL_StatusTypeDef MEMSPI_CMD_Fast_Read(MEMSPI_HandleTypeDef *hmemspi, uint32_t F
return SPI_RES; return SPI_RES;
} }
//-------------------------------------------------------------
//-------------------------------------------------------------------
//-------------------------COMMAND FUNCTIONS-------------------------
//-----------------------------INTERRUPT-----------------------------
/**
* @brief Send command to read Status Register.
* @param hmemspi - указатель на хендл внешней памяти.
* @param RequestedBits - какие биты запросить.
* @param EndCMD - завершать комманду или нет. (очистка Chip Selected пина)
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return Заполняет Status Register в hmemspi.
* @note Всего есть две комманды: на запрос верхнего или нижниго байта.
* Функция в соответствии с RequestedBits определяет какой байт запросить, или два байта сразу.
*/
HAL_StatusTypeDef MEMSPI_CMD_Read_Status_Register_IT(MEMSPI_HandleTypeDef *hmemspi, uint16_t RequestedBits, uint8_t EndCMD)
{
HAL_StatusTypeDef SPI_RES;
uint8_t command[2];
uint8_t *pSRPtr = 0;
uint8_t size = 1;
command[0] = MEMSPI_READ_STATUS_REG;
hmemspi->Active_OP = command[0];
hmemspi->MEM_State = MEM_SEND_COMMAND;
MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit_IT(hmemspi, command, 1); // send insctruction to read SR
return SPI_RES;
}
/**
* @brief Send command to write bits in Status Register.
* @param hmemspi - указатель на хендл внешней памяти.
* @param WrittenBits - какие биты запросить.
* @note Данная команда посылает биты, как сдвинутые на 2 вправо. Т.е. 0-й бит в комманде - 2-й бит BP0.
Но биты указываются в также как они расположены и регистре. Функция сама выполняет сдвиг.
*/
HAL_StatusTypeDef MEMSPI_CMD_Write_Status_Register_IT(MEMSPI_HandleTypeDef *hmemspi, uint16_t WrittenBits)
{
HAL_StatusTypeDef SPI_RES;
uint8_t command[3];
uint8_t size;
command[0] = MEMSPI_WRITE_STATUS_REG;
command[1] = WrittenBits;
command[2] = WrittenBits >> 8;
hmemspi->Active_CMD = command[0];
hmemspi->MEM_State = MEM_SEND_COMMAND;
MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit_IT(hmemspi, command, 3);
return SPI_RES;
}
/**
* @brief Send command to set Write Enable Latch (WEL) in Status Register.
* @param hmemspi - указатель на хендл внешней памяти.
* @note Разрешает запись в FLASH, путем высталения WEL в Status Register
*/
HAL_StatusTypeDef MEMSPI_CMD_Write_Enable_IT(MEMSPI_HandleTypeDef *hmemspi)
{
HAL_StatusTypeDef SPI_RES;
uint8_t command[1];
command[0] = MEMSPI_WRITE_ENABLE;
hmemspi->Active_CMD = command[0];
hmemspi->MEM_State = MEM_SEND_COMMAND;
MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit_IT(hmemspi, command, 1);
return SPI_RES;
}
/**
* @brief Send command to read data from FLASH/EEPROM.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс откуда начинать считывание.
* @param pBuff - куда записывать данные из FLASH.
* @param Size - сколько байтов считывать.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return pBuff.
*/
HAL_StatusTypeDef MEMSPI_CMD_Read_Data_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size)
{
HAL_StatusTypeDef SPI_RES;
uint8_t command[4];
command[0] = MEMSPI_READ_DATA;
command[1] = FLASH_Address >> 16 & 0xFF;
command[2] = FLASH_Address >> 8 & 0xFF;
command[3] = FLASH_Address & 0xFF;
hmemspi->Active_CMD = command[0];
hmemspi->MEM_State = MEM_SEND_COMMAND;
hmemspi->pRxBuffPtr = pBuff;
hmemspi->RxXferSize = Size;
MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit_IT(hmemspi, command, 4);
return SPI_RES;
}
/**
* @brief Send command to write eeprom.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс куда начинать записывать.
* @param pData - откуда брать данные для записи в FLASH.
* @param Size - сколько байтов записать.
* @param Timeout - время, за которое должна быть осуществлена запись.
* @note Рзамер данных для записи в EEPROM без ограничений.
*/
HAL_StatusTypeDef MEMSPI_CMD_EEPROM_Write_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size)
{
HAL_StatusTypeDef SPI_RES;
// 1 command byte + 3 address bytes + 256 data bytes
uint8_t command[1+3+MEMSPI_PAGE_SIZE];
FLASH_Address = FLASH_Address & 0xFFFFFF;
command[0] = MEMSPI_WRITE_EEPROM;
command[1] = FLASH_Address >> 16 & 0xFF;
command[2] = FLASH_Address >> 8 & 0xFF;
command[3] = FLASH_Address & 0xFF;
// check if data range is placed at one page
if((FLASH_Address/MEMSPI_PAGE_SIZE) != ((FLASH_Address+Size-1)/MEMSPI_PAGE_SIZE)) // if page of first byte isnt equal page of last byte
return HAL_ERROR; // return error
for(int i = 0; i < Size; i++)
command[4+i] = pData[i];
hmemspi->Active_CMD = command[0];
hmemspi->MEM_State = MEM_SEND_COMMAND;
MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit_IT(hmemspi, command, Size+4); // send insctruction+data to write
return SPI_RES;
}
/**
* @brief Send command to page program in FLASH.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс куда начинать записывать.
* @param pData - откуда брать данные для записи в FLASH.
* @param Size - сколько байтов записать.
* @param Timeout - время, за которое должна быть осуществлена запись.
* @note Программирование FLASH только в пределах одной страницы.
* Т.е. если запись с 0x0, то не больше 256 байт. Если с 0ч40, то не больше 192 байт.
*/
HAL_StatusTypeDef MEMSPI_CMD_FLASH_Page_Program_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size)
{
HAL_StatusTypeDef SPI_RES;
// 1 command byte + 3 address bytes + 256 data bytes
uint8_t command[1+3+MEMSPI_PAGE_SIZE];
FLASH_Address = FLASH_Address & 0xFFFFFF;
command[0] = MEMSPI_PAGE_PROGRAM;
command[1] = FLASH_Address >> 16 & 0xFF;
command[2] = FLASH_Address >> 8 & 0xFF;
command[3] = FLASH_Address & 0xFF;
// check if data range is placed at one page
if((FLASH_Address/MEMSPI_PAGE_SIZE) != ((FLASH_Address+Size-1)/MEMSPI_PAGE_SIZE)) // if page of first byte isnt equal page of last byte
return HAL_ERROR; // return error
for(int i = 0; i < Size; i++)
command[4+i] = pData[i];
hmemspi->Active_CMD = command[0];
hmemspi->MEM_State = MEM_SEND_COMMAND;
MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit_IT(hmemspi, command, Size+4); // send insctruction+data to write
return SPI_RES;
}
/**
* @brief Send command to erase sector.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс где надо данные стереть.
* @param Timeout - время, за которое должна быть осуществлена очистка.
* @note Микросхема вроде сама высчитывает какой сектор ерейзнуть, в соответствии с заданным адресом.
*/
HAL_StatusTypeDef MEMSPI_CMD_FLASH_Erase_Sector_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address)
{
HAL_StatusTypeDef SPI_RES;
uint8_t command[4];
uint8_t response[8];
FLASH_Address = FLASH_Address & 0xFFFFFF;
command[0] = MEMSPI_ERASE_SECTOR;
command[1] = FLASH_Address >> 16;
command[2] = FLASH_Address >> 8;
command[3] = FLASH_Address;
hmemspi->Active_CMD = command[0];
hmemspi->MEM_State = MEM_SEND_COMMAND;
MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit_IT(hmemspi, command, 4);
return SPI_RES;
}
/**
* @brief Send command to read JEDEC ID.
* @param hmemspi - указатель на хендл внешней памяти.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return JEDEC ID микросхемы.
*/
HAL_StatusTypeDef MEMSPI_CMD_Read_JEDEC_ID_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t *JEDEC_ID_var)
{
HAL_StatusTypeDef SPI_RES;
uint8_t command[1] = {0};
command[0] = MEMSPI_READ_JEDEC_ID;
hmemspi->Active_CMD = command[0];
hmemspi->MEM_State = MEM_SEND_COMMAND;
hmemspi->pRxBuffPtr = (uint8_t *)&JEDEC_ID_var[0];
hmemspi->RxXferSize = 4;
MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit_IT(hmemspi, command, 1);
return SPI_RES;
}
/**
* @brief Send command to read JEDEC ID.
* @param hmemspi - указатель на хендл внешней памяти.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return Device ID микросхемы.
*/
HAL_StatusTypeDef MEMSPI_CMD_Read_Device_ID_IT(MEMSPI_HandleTypeDef *hmemspi, uint64_t *Device_ID_var)
{
HAL_StatusTypeDef SPI_RES;
uint8_t command[1] = {0};
uint8_t receive[8] = {0};
command[0] = MEMSPI_READ_UNIQUE_ID;
hmemspi->Active_CMD = command[0];
hmemspi->MEM_State = MEM_SEND_COMMAND;
hmemspi->pRxBuffPtr = (uint8_t *)&Device_ID_var[0];
hmemspi->RxXferSize = 8;
MEMSPI_Select(hmemspi);
SPI_RES = MEMSPI_SPI_Transmit_IT(hmemspi, command, 1);
return SPI_RES;
}

View File

@@ -21,21 +21,23 @@
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
////////////////////////////---DEFINES---//////////////////////////// ////////////////////////////---DEFINES---////////////////////////////
/**
* @brief SPI Transmit IT.
* @note Здесь вызывается только функция HAL, и ничего больше.
*/
#define MEMSPI_SPI_Transmit_IT(_hmemspi_, _data_, _size_) HAL_SPI_Transmit_IT(&_hmemspi_->sspi.hspi, _data_, _size_)
/**
* @brief SPI Receive IT.
* @note Здесь вызывается только функция HAL, и ничего больше.
*/
#define MEMSPI_SPI_Receive_IT(_hmemspi_, _data_, _size_) HAL_SPI_Receive_IT(&_hmemspi_->sspi.hspi, _data_, _size_)
/** /**
* @brief SPI Transmit. * @brief SPI Transmit.
* @param _hmemspi_ - указатель на хендл внешней памяти.
* @param _data_ - указатель на данные для отправки.
* @param _size_ - размер данных для отправки.
* @param _timeout_ - время, за которое должна быть осуществлена отправка.
* @note Здесь вызывается только функция HAL, и ничего больше. * @note Здесь вызывается только функция HAL, и ничего больше.
*/ */
#define MEMSPI_SPI_Transmit(_hmemspi_, _data_, _size_, _timeout_) HAL_SPI_Transmit(&_hmemspi_->sspi.hspi, _data_, _size_, _timeout_) #define MEMSPI_SPI_Transmit(_hmemspi_, _data_, _size_, _timeout_) HAL_SPI_Transmit(&_hmemspi_->sspi.hspi, _data_, _size_, _timeout_)
/** /**
* @brief SPI Receive. * @brief SPI Receive.
* @param _hmemspi_ - указатель на хендл внешней памяти.
* @param _data_ - указатель на буффер для прниема данных.
* @param _size_ - размер данных для приема.
* @param _timeout_ - время, за которое должен быть осуществлен прием.
* @note Здесь вызывается только функция HAL, и ничего больше. * @note Здесь вызывается только функция HAL, и ничего больше.
*/ */
#define MEMSPI_SPI_Receive(_hmemspi_, _data_, _size_, _timeout_) HAL_SPI_Receive(&_hmemspi_->sspi.hspi, _data_, _size_, _timeout_) #define MEMSPI_SPI_Receive(_hmemspi_, _data_, _size_, _timeout_) HAL_SPI_Receive(&_hmemspi_->sspi.hspi, _data_, _size_, _timeout_)
@@ -111,27 +113,55 @@ typedef struct
unsigned fSavePrevoisData:1; unsigned fSavePrevoisData:1;
}MEMSPI_WriteInitTypeDef; }MEMSPI_WriteInitTypeDef;
typedef struct typedef enum
{ {
uint16_t SR; WAIT_FOR_CMD = 0x00,
SPI_HandleTypeDef hspi; WRITE_ENABLE = MEMSPI_WRITE_ENABLE,
GPIO_TypeDef *CS_GPIOx; WRITE_DISABLE = MEMSPI_WRITE_DISABLE,
uint32_t CS_PIN; WRITE_STATUS_REG = MEMSPI_WRITE_STATUS_REG,
GPIO_TypeDef *CLK_GPIOx;
uint32_t CLK_PIN; READ_DATA = MEMSPI_READ_DATA,
GPIO_TypeDef *MISO_GPIOx;
uint32_t MISO_PIN; ERASE_SECTOR = MEMSPI_ERASE_SECTOR,
GPIO_TypeDef *MOSI_GPIOx; PAGE_PROGRAM = MEMSPI_PAGE_PROGRAM,
uint32_t MOSI_PIN; WRITE_EEPROM = MEMSPI_WRITE_EEPROM,
}MEMSPI_GPIOTypeDef; READ_STATUS_REG = MEMSPI_READ_STATUS_REG,
READ_JEDEC_ID = MEMSPI_READ_JEDEC_ID,
READ_UNIQUE_ID = MEMSPI_READ_UNIQUE_ID,
}MEMSPI_CommandsTypeDef;
typedef enum
{
WAIT_FOR_UNBUSY,
READ_MEMORY,
EEPROM_WRITE,
FLASH_PROGRAM,
FLASH_ERASE,
}MEM_OperationsTypeDef;
typedef enum
{
MEM_READY = 0x00,
MEM_SEND_COMMAND = 0x01,
MEM_RECEIVE_DATA = 0x02,
}MEM_StateTypeDef;
typedef struct typedef struct
{ {
uint16_t SR; uint16_t SR;
SPI_SettingsTypeDef sspi; SPI_SettingsTypeDef sspi;
// MEMSPI_GPIOTypeDef GPIOs;
GPIO_TypeDef *CS_GPIOx; GPIO_TypeDef *CS_GPIOx;
uint32_t CS_PIN; uint32_t CS_PIN;
MEM_OperationsTypeDef Active_OP;
MEMSPI_CommandsTypeDef Active_CMD;
MEM_StateTypeDef MEM_State;
uint8_t *pRxBuffPtr;
uint16_t RxXferSize;
uint32_t hNextAddr; uint32_t hNextAddr;
uint16_t hNextPage; uint16_t hNextPage;
uint16_t hNextSector; uint16_t hNextSector;
@@ -148,6 +178,17 @@ extern MEMSPI_HandleTypeDef hmemspi;
*/ */
void MEMSPI_Base_Init(MEMSPI_HandleTypeDef *hmemspi); void MEMSPI_Base_Init(MEMSPI_HandleTypeDef *hmemspi);
/**
* @brief Read external FLASH/EEPROM with interrupt.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс откуда начинать считывание.
* @param pBuff - куда записывать данные из FLASH.
* @param Size - сколько байтов считывать.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return HAL status.
*/
HAL_StatusTypeDef MEMSPI_Read_Memory_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size);
/** /**
* @brief Read external FLASH. * @brief Read external FLASH.
* @param hmemspi - указатель на хендл внешней памяти. * @param hmemspi - указатель на хендл внешней памяти.
@@ -285,8 +326,36 @@ HAL_StatusTypeDef MEMSPI_WaitOnFlagsUntilTimeout(MEMSPI_HandleTypeDef *hmemspi,
void MEMSPI_Update_Timeout_Variables(uint32_t *Timeout, uint32_t *tickstart); void MEMSPI_Update_Timeout_Variables(uint32_t *Timeout, uint32_t *tickstart);
////////////////////////---SERVICE FUNCTIONS---////////////////////// ////////////////////////---SERVICE FUNCTIONS---//////////////////////
/////////////////////////////////////////////////////////////////////
///////////////////////---HANDLERS FUNCTIONS---//////////////////////
/**
* @brief Handler for SPI FLASH/EEPROM.
* @param hmemspi - указатель на хендл внешней памяти.
* @return HAL status.
* @note Включает в себя проверку на доступность памяти (флаг BUSY)
*/
void MEMSPI_Handler(MEMSPI_HandleTypeDef *hmemspi);
/**
* @brief Handler for transmit SPI command to EEPROM/FLASH.
* @param hmemspi - указатель на хендл внешней памяти.
* @return HAL status.
* @note После отправки комманды - инициализирует прием ответа если надо или завершает команду.
*/
void MEM_SPI_TransmitCommandCplt_Handler(MEMSPI_HandleTypeDef *hmemspi);
/**
* @brief Handler for receive SPI response from EEPROM/FLASH.
* @param hmemspi - указатель на хендл внешней памяти.
* @return HAL status.
* @note Завершает общение с памятью.
*/
void MEM_SPI_OperationCplt_Handler(MEMSPI_HandleTypeDef *hmemspi);
///////////////////////---HANDLERS FUNCTIONS---//////////////////////
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
//////////////////////---FUNCTION FOR COMMAND---///////////////////// //////////////////////---FUNCTION FOR COMMAND---/////////////////////
////////////////////////////---BLOCKING---///////////////////////////
/** /**
* @brief Send command to read Status Register. * @brief Send command to read Status Register.
* @param hmemspi - указатель на хендл внешней памяти. * @param hmemspi - указатель на хендл внешней памяти.
@@ -383,7 +452,100 @@ uint64_t MEMSPI_CMD_Read_Device_ID(MEMSPI_HandleTypeDef *hmemspi, uint32_t Timeo
* @note Данная функция предполагает отправку одного dummy байта после адресса, но у меня поч не работает пока :( * @note Данная функция предполагает отправку одного dummy байта после адресса, но у меня поч не работает пока :(
*/ */
HAL_StatusTypeDef MEMSPI_CMD_Fast_Read(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size, uint32_t Timeout); HAL_StatusTypeDef MEMSPI_CMD_Fast_Read(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size, uint32_t Timeout);
////////////////////////////---BLOCKING---///////////////////////////
//////////////////////---FUNCTION FOR COMMAND---///////////////////// //////////////////////---FUNCTION FOR COMMAND---/////////////////////
/////////////////////////////////////////////////////////////////////
//////////////////////---FUNCTION FOR COMMAND---/////////////////////
///////////////////////////---INTERRUPT---///////////////////////////
/**
* @brief Send command to read Status Register in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param RequestedBits - какие биты запросить.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return Заполняет Status Register в hmemspi.
* @note Всего есть две комманды: на запрос верхнего или нижниго байта.
* Функция в соответствии с RequestedBits определяет какой байт запросить, или два байта сразу.
*/
HAL_StatusTypeDef MEMSPI_CMD_Read_Status_Register_IT(MEMSPI_HandleTypeDef *hmemspi, uint16_t RequestedBits, uint8_t EndCMD);
/**
* @brief Send command to write bits in Status Register in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param WrittenBits - какие биты запросить.
* @param Timeout - время, за которое должна быть осуществлена запись.
* @note Данная команда посылает биты, как сдвинутые на 2 вправо. Т.е. 0-й бит в комманде - 2-й бит BP0.
Но биты указываются в также как они расположены и регистре. Функция сама выполняет сдвиг.
*/
HAL_StatusTypeDef MEMSPI_CMD_Write_Status_Register_IT(MEMSPI_HandleTypeDef *hmemspi, uint16_t WrittenBits);
/**
* @brief Send command to set Write Enable Latch (WEL) in Status Register in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param Timeout - время, за которое должна быть осуществлена запись.
* @note Разрешает запись в FLASH, путем высталения WEL в Status Register
*/
HAL_StatusTypeDef MEMSPI_CMD_Write_Enable_IT(MEMSPI_HandleTypeDef *hmemspi);
/**
* @brief Send command to read data from FLASH/EEPROM in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс откуда начинать считывание.
* @param pBuff - куда записывать данные из FLASH.
* @param Size - сколько байтов считывать.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return pBuff.
*/
HAL_StatusTypeDef MEMSPI_CMD_Read_Data_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pBuff, uint16_t Size);
/**
* @brief Send command to write eeprom in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс куда начинать записывать.
* @param pData - откуда брать данные для записи в FLASH.
* @param Size - сколько байтов записать.
* @param Timeout - время, за которое должна быть осуществлена запись.
* @note Рзамер данных для записи в EEPROM без ограничений.
*/
HAL_StatusTypeDef MEMSPI_CMD_EEPROM_Write_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size);
/**
* @brief Send command to page program in FLASH in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс куда начинать записывать.
* @param pData - откуда брать данные для записи в FLASH.
* @param Size - сколько байтов записать.
* @param Timeout - время, за которое должна быть осуществлена запись.
* @note Программирование FLASH только в пределах одной страницы.
* Т.е. если запись с 0x0, то не больше 256 байт. Если с 0ч40, то не больше 192 байт.
*/
HAL_StatusTypeDef MEMSPI_CMD_FLASH_Page_Program_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address, uint8_t *pData, uint16_t Size);
/**
* @brief Send command to erase sector of FLASH in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param FLASH_Address - адресс где надо данные стереть.
* @param Timeout - время, за которое должна быть осуществлена очистка.
* @note Микросхема вроде сама высчитывает какой сектор ерейзнуть, в соответствии с заданным адресом.
*/
HAL_StatusTypeDef MEMSPI_CMD_FLASH_Erase_Sector_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t FLASH_Address);
/**
* @brief Send command to read JEDEC ID in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return JEDEC ID микросхемы.
*/
HAL_StatusTypeDef MEMSPI_CMD_Read_JEDEC_ID_IT(MEMSPI_HandleTypeDef *hmemspi, uint32_t *JEDEC_ID_var);
/**
* @brief Send command to read JEDEC ID in interrupt mode.
* @param hmemspi - указатель на хендл внешней памяти.
* @param Timeout - время, за которое должно быть осуществлено чтение.
* @return Device ID микросхемы.
*/
HAL_StatusTypeDef MEMSPI_CMD_Read_Device_ID_IT(MEMSPI_HandleTypeDef *hmemspi, uint64_t *Device_ID_var);
///////////////////////////---INTERRUPT---///////////////////////////
//////////////////////---FUNCTION FOR COMMAND---/////////////////////
#endif // __SPI_MEMORY_H_ #endif // __SPI_MEMORY_H_