#ifndef AT45DB161E_HELPER_H
#define AT45DB161E_HELPER_H
#include "main.h"
#define AT45_NSS_Pin GPIO_PIN_15
#define AT45_NSS_GPIO_Port GPIOA
#define AT45_RESET_Pin GPIO_PIN_10
#define AT45_RESET_GPIO_Port GPIOC
#define AT45_SCK_Pin GPIO_PIN_3
#define AT45_SCK_GPIO_Port GPIOB
#define AT45_MISO_Pin GPIO_PIN_4
#define AT45_MISO_GPIO_Port GPIOB
#define AT45_MOSI_Pin GPIO_PIN_5
#define AT45_MOSI_GPIO_Port GPIOB
#define AT45_FAST_READ 0x0B
#define AT45_FAST_READ_BUFFER1 0xD4
#define AT45_FAST_WRITE_BUFFER1 0x84
#define AT45_READ_REGISTER_STATUS 0xD7
#define AT45_MEM_TO_BUFFER1 0x53
#define AT45_BUFFER1_TO_MEM 0x82
#define __AT45_NSS_HIGH() ((AT45_NSS_GPIO_Port->BSRR) = ((uint32_t)AT45_NSS_Pin))
#define __AT45_NSS_LOW() ((AT45_NSS_GPIO_Port->BRR) = ((uint32_t)AT45_NSS_Pin))
#define __AT45_CLK_HIGH() ((AT45_SCK_GPIO_Port->BSRR) = ((uint32_t)AT45_SCK_Pin))
#define __AT45_CLK_LOW() ((AT45_SCK_GPIO_Port->BRR) = ((uint32_t)AT45_SCK_Pin))
#define __AT45_MOSI_HIGH() ((AT45_MOSI_GPIO_Port->BSRR) = ((uint32_t)AT45_MOSI_Pin))
#define __AT45_MOSI_LOW() ((AT45_MOSI_GPIO_Port->BRR) = ((uint32_t)AT45_MOSI_Pin))
#define __AT45_RESET_HIGH() ((AT45_RESET_GPIO_Port->BSRR) = ((uint32_t)AT45_RESET_Pin))
#define __AT45_RESET_LOW() ((AT45_RESET_GPIO_Port->BRR) = ((uint32_t)AT45_RESET_Pin))
#define __AT45_MISO_STATE() ((AT45_MISO_GPIO_Port->IDR) & (AT45_MISO_Pin))
void AT45DB161E_GPIO_Init(void);
uint8_t AT45DB161E_SendByte(uint8_t data);
uint8_t AT45DB161E_ReadRegisterStatus(void);
void AT45DB161E_WriteData(uint32_t addr, uint8_t *buf, uint32_t bufLen);
void AT45DB161E_ReadData(uint32_t addr, uint8_t *buf, uint32_t bufLen);
void AT45DB161E_WriteBytesToBuffer1(uint32_t addr, uint8_t *buf, uint32_t bufLen);
void AT45DB161E_ReadBytesForBuffer1(uint32_t addr, uint8_t *buf, uint32_t bufLen);
void AT45DB161E_PageToBuffer(uint32_t addr);
void AT45DB161E_BufferToPage(uint32_t addr, uint8_t *buf, uint32_t bufLen);
void AT45DB161E_ChipErase(void);
#endif
#include "at45db161e_helper.h"
void AT45DB161E_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO_InitStruct.Pin = AT45_SCK_Pin | AT45_MOSI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = AT45_MISO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(AT45_MISO_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = AT45_NSS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(AT45_NSS_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = AT45_RESET_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(AT45_RESET_GPIO_Port, &GPIO_InitStruct);
__AT45_RESET_HIGH();
__AT45_NSS_HIGH();
}
uint8_t AT45DB161E_SendByte(uint8_t data)
{
uint8_t recvData= 0;
__AT45_NSS_LOW();
for(uint8_t count = 0; count < 8; count++)
{
__AT45_CLK_LOW();
UserDelay_us(5);
if((data << count) & 0x80)
{
__AT45_MOSI_HIGH();
}
else
{
__AT45_MOSI_LOW();
}
UserDelay_us(1);
__AT45_CLK_HIGH();
UserDelay_us(1);
if(__AT45_MISO_STATE())
{
recvData |= 0x01 << (7 - count);
}
else
{
recvData |= 0x00 << (7 - count);
}
UserDelay_us(3);
}
__AT45_CLK_LOW();
UserDelay_us(10);
return recvData;
}
void AT45DB161E_WriteData(uint32_t addr, uint8_t *buf, uint32_t bufLen)
{
uint32_t availableByte, writeNum;
while(bufLen)
{
AT45DB161E_PageToBuffer(addr);
availableByte = 528 - addr % 528;
if(availableByte >= bufLen)
{
writeNum = bufLen;
}
else
{
writeNum = availableByte;
}
AT45DB161E_BufferToPage(addr, buf, writeNum);
buf += writeNum;
bufLen -= writeNum;
addr += writeNum;
}
}
void AT45DB161E_ReadData(uint32_t addr, uint8_t *buf, uint32_t bufLen)
{
uint8_t addrBuf[3], i;
uint16_t pageAddr, bufferAddr, addrValue;
__AT45_NSS_LOW();
AT45DB161E_SendByte(AT45_FAST_READ);
pageAddr = (addr / 528) << 10;
bufferAddr = addr % 528;
addrValue = pageAddr | bufferAddr;
addrBuf[0] = (char)((addrValue & 0x3FFFFF) >> 16);
addrBuf[1] = (char)((addrValue & 0x3FFFFF) >> 8);
addrBuf[2] = (char)((addrValue & 0x3FFFFF) >> 0);
for(i = 0; i < 3; i++)
{
AT45DB161E_SendByte(addrBuf[i]);
}
AT45DB161E_SendByte(0x00);
while(bufLen--)
{
*buf++ = AT45DB161E_SendByte(0x00);
}
__AT45_NSS_HIGH();
UserDelay_us(10);
}
void AT45DB161E_ReadBytesForBuffer1(uint32_t addr, uint8_t *buf, uint32_t bufLen)
{
uint8_t addrBuf[3], i;
__AT45_NSS_LOW();
AT45DB161E_SendByte(AT45_FAST_READ_BUFFER1);
addrBuf[0] = (char)((addr & 0x03FF) >> 16);
addrBuf[1] = (char)((addr & 0x03FF) >> 8);
addrBuf[2] = (char)((addr & 0x03FF) >> 0);
for(i = 0; i < 3; i++)
{
AT45DB161E_SendByte(addrBuf[i]);
}
AT45DB161E_SendByte(0x00);
while(bufLen--)
{
*buf++ = AT45DB161E_SendByte(0x00);
}
__AT45_NSS_HIGH();
UserDelay_us(10);
}
void AT45DB161E_WriteBytesToBuffer1(uint32_t addr, uint8_t *buf, uint32_t bufLen)
{
uint8_t addrBuf[3], i;
__AT45_NSS_LOW();
AT45DB161E_SendByte(AT45_FAST_WRITE_BUFFER1);
addrBuf[0] = (char)((addr & 0x03FF) >> 16);
addrBuf[1] = (char)((addr & 0x03FF) >> 8);
addrBuf[2] = (char)((addr & 0x03FF) >> 0);
for(i = 0; i < 3; i++)
{
AT45DB161E_SendByte(addrBuf[i]);
}
while(bufLen--)
{
AT45DB161E_SendByte(*buf++);
}
__AT45_NSS_HIGH();
UserDelay_us(10);
}
uint8_t AT45DB161E_ReadRegisterStatus(void)
{
uint8_t status;
__AT45_NSS_LOW();
AT45DB161E_SendByte(AT45_READ_REGISTER_STATUS);
status = AT45DB161E_SendByte(0x00);
__AT45_NSS_HIGH();
UserDelay_us(10);
return status;
}
void AT45DB161E_PageToBuffer(uint32_t addr)
{
uint8_t Add_Buf[3], i;
uint8_t Status;
__AT45_NSS_LOW();
AT45DB161E_SendByte(AT45_MEM_TO_BUFFER1);
addr = (addr / 528) << 10;
Add_Buf[0] = (char)((addr & 0x3FFC00) >> 16);
Add_Buf[1] = (char)((addr & 0x3FFC00) >> 8);
Add_Buf[2] = (char)((addr & 0x3FFC00) >> 0);
for(i = 0; i < 3; i++)
{
AT45DB161E_SendByte(Add_Buf[i]);
}
__AT45_NSS_HIGH();
UserDelay_us(10);
Status = (AT45DB161E_ReadRegisterStatus() & 0x80) >> 7;
while(Status == 0x00)
{
Status = (AT45DB161E_ReadRegisterStatus() & 0x80) >> 7;
}
}
void AT45DB161E_BufferToPage(uint32_t addr, uint8_t *buf, uint32_t bufLen)
{
uint8_t Add_Buf[3],i;
uint8_t Status;
uint32_t Page_Add, Buffer_Add, Add_Value;
__AT45_NSS_LOW();
AT45DB161E_SendByte(AT45_BUFFER1_TO_MEM);
Page_Add = (addr / 528) << 10;
Buffer_Add = addr % 528;
Add_Value = Page_Add | Buffer_Add;
Add_Buf[0] = (char)((Add_Value & 0x3FFFFF) >> 16);
Add_Buf[1] = (char)((Add_Value & 0x3FFFFF) >> 8);
Add_Buf[2] = (char)((Add_Value & 0x3FFFFF) >> 0);
for(i = 0; i < 3; i++)
{
AT45DB161E_SendByte(Add_Buf[i]);
}
while(bufLen--)
{
AT45DB161E_SendByte(*buf++);
}
__AT45_NSS_HIGH();
UserDelay_us(10);
Status = (AT45DB161E_ReadRegisterStatus() & 0x80) >> 7;
while(Status == 0x00)
{
Status = (AT45DB161E_ReadRegisterStatus() & 0x80) >> 7;
}
}
void AT45DB161E_ChipErase(void)
{
uint8_t Status;
__AT45_NSS_LOW();
AT45DB161E_SendByte(0xC7);
AT45DB161E_SendByte(0x94);
AT45DB161E_SendByte(0x80);
AT45DB161E_SendByte(0x9A);
__AT45_NSS_HIGH();
UserDelay_us(10);
Status = (AT45DB161E_ReadRegisterStatus() & 0x80) >> 7;
while(Status == 0x00)
{
Status = (AT45DB161E_ReadRegisterStatus() & 0x80) >> 7;
}
}