/*C***************************************************************************** * NAME: at45db.c *------------------------------------------------------------------------------- * RELEASE: * REVISION: 1.0 *------------------------------------------------------------------------------- * PURPOSE: * at45Db驱动。 *******************************************************************************/ /*_____ I N C L U D E S ______________________________________________________*/ #include "config.h" //全局声明 u8 FlashType = 0; F_uniGlobal_Typedef F_uniGlobal; #define Data_INIT const u8 initATDB45_Flag = 0x38; const PREXDATA_Type initPREXDATA = {0,0,0,0,0,0,0,0,0}; const AT45DBDataIndex AT45DBTab[20] = { ///FRAM数据1区(数据操作相对不频烦) /// pInitData; upData pData firstAdr; len; Tpye; //(注意,校验增加在数据包尾) {(u8*)&initATDB45_Flag, (u8*)(&buf_ATDB45_Flag), (u8*)(&TXHData.ATDB45_Flag), ATDB45_Flag_FADR, ATDB45_Flag_LEN, ATDB45_Flag_Group, CA_ATDB45_Flag}, {(u8*)&initATDB45_Flag, (u8*)(&buf_Frame), (u8*)(&TXHData.Frame), Frame_FADR, Frame_LEN, Frame_Group, CA_Frame}, {(u8*)&initPREXDATA, (u8*)(&buf_PREXDATA), (u8*)(&TXHData.PREXDATA), PREXDATA_FADR, PREXDATA_LEN, PREXDATA_Group, CA_PREXDATA}, {(u8*)&initATDB45_Flag, (u8*)(&buf_DeviceFrame), (u8*)(&TXHData.Frame), DeviceFrame_FADR, DeviceFrame_LEN, DeviceFrame_Group, CA_DeviceFrame}, }; ////============================================================================== /** * @brief 对指定长度的数据区域进行校验和计算 * * @param pData 指向数据区域的指针 * @param len 数据区域的长度 * @return u8 返回校验和结果 */ u8 AT45DBDataCheck(volatile u8* pData, u16 len) { u8 result; // 校验和变量 result = *pData; // 初始化为第一个字节的值 while(len--) { result += *pData++; // 累加每个字节的值 } return result; // 返回校验和结果 } /**************************************************** 函数名:AT45DB_SendByte 功能 :Flash存储部分用到的SPI发送函数 参数 :dt 要发送的数据 返回值:无 ****************************************************/ u8 AT45DB_SendByte(u8 dt) { while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); SPI_I2S_SendData(SPI1, dt); while(SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); } //F***************************************************************************** //* NAME: ReadDFStatus //*----------------------------------------------------------------------------- //* PURPOSE: //* 读取45db状态 //*----------------------------------------------------------------------------- //* PARAMS: //* return: 如果返回值等0,说明驱动器错误 //*----------------------------------------------------------------------------- //* NOTE: //****************************************************************************** u8 ReadDFStatus (void) { u8 result; CLI(); AT45DB_CS_EN; AT45DB_SendByte(0xd7); result = AT45DB_SendByte(0xff);//要读两次,不然要加10ms延时,暂时不知道为什么 //delay_ms(10); AT45DB_CS_DIS; SEI(); return result; } //F***************************************************************************** //* NAME: ReadDriverID //*----------------------------------------------------------------------------- //* PURPOSE: //* 读取45dbID 判断存储器类型 //*----------------------------------------------------------------------------- //* PARAMS: //* return: Drive ID(Byte 1)Family Code Density Code // 0 0 1((AT45D) 0 0 1 0 0 (4-Mbit) // 0 0 1((AT45D) 0 0 1 1 1 (32-Mbit) //*----------------------------------------------------------------------------- //* NOTE: //****************************************************************************** u16 ii = 0; u8 resultF = 0; u8 ReadDriverID (void) { CLI(); for(ii = 0;ii < 200;ii ++) { if(ReadDFStatus() & 0x80) break; delay_ms(1); } if(ii < 200) { AT45DB_CS_EN; AT45DB_SendByte(0x9F); AT45DB_SendByte(0xFF); resultF = AT45DB_SendByte(0xFF); AT45DB_CS_DIS; SEI(); return resultF; } SEI(); return 0; } u8 AT45DB_SetPageByte (void) { CLI(); for(ii = 0;ii < 200;ii ++) { if(ReadDFStatus() & 0x80) break; delay_ms(1); } if(ii < 200) { AT45DB_CS_EN; AT45DB_SendByte(0x3D); AT45DB_SendByte(0x2A); AT45DB_SendByte(0x80); AT45DB_SendByte(0xA7);//A6:512;A7:528 AT45DB_CS_DIS; SEI(); return 1; } SEI(); return 0; } u8 AT45DB_WriteBuff(u8 *Buff,u16 Len) { u16 i = 0; CLI(); for(ii = 0;ii < 200;ii ++) { if(ReadDFStatus() & 0x80) break; delay_ms(1); } if(ii < 200) { AT45DB_CS_EN; AT45DB_SendByte(0x84); AT45DB_SendByte(0x00); AT45DB_SendByte(0x00); AT45DB_SendByte(0x00); for(i = 0;i < Len;i ++) AT45DB_SendByte(*(Buff + i)); AT45DB_CS_DIS; SEI(); return 1; } SEI(); return 0; } u8 AT45DB_WritePage(u8 *Buff,u16 Page,u16 Len)//len = 10,79us { CLI(); if(AT45DB_WriteBuff(Buff,Len) == 0) return 0; for(ii = 0;ii < 200;ii ++) { if(ReadDFStatus() & 0x80) break; delay_ms(1); } if(ii < 200) { AT45DB_CS_EN; AT45DB_SendByte(0x83); AT45DB_SendByte((u8)(Page >> 6)); AT45DB_SendByte((u8)(Page << 2)); AT45DB_SendByte(0x00); AT45DB_CS_DIS; SEI(); return 1; } SEI(); return 0; } u8 AT45DB_ReadPage(u8 *Buff,u16 Page,u16 Len)//len = 10,75us { u16 i = 0; CLI(); for(ii = 0;ii < 200;ii ++) { if(ReadDFStatus() & 0x80) break; delay_ms(1); } if(ii < 200) { AT45DB_CS_EN; AT45DB_SendByte(0xE8); AT45DB_SendByte((u8)(Page >> 6)); AT45DB_SendByte((u8)(Page << 2)); AT45DB_SendByte(0x00); for(i = 0;i < 4;i ++) AT45DB_SendByte(0x00); for(i = 0;i < Len;i ++) *(Buff + i) = AT45DB_SendByte(0xff); AT45DB_CS_DIS; SEI(); return 1; } SEI(); return 0; } void AT45DB_Data_Init(void) { volatile u16 i = 0,j = 0,Item = 0; u8 Temp_Buff[660]; u8 Temp = 0; for(Item = 0;Item< FramItemEnd;Item ++) { for(i = 0;i < AT45DBTab[Item].Group;i ++) { for(j = 0;j < AT45DBTab[Item].len - checkLen_1;j ++) Temp_Buff[j] = *(AT45DBTab[Item].upData + j) = *(AT45DBTab[Item].pInitData+j); Temp_Buff[AT45DBTab[Item].len - checkLen_1] = AT45DBDataCheck(Temp_Buff,AT45DBTab[Item].len - checkLen_1); AT45DB_WritePage(Temp_Buff,AT45DBTab[Item].firstAdr + i,AT45DBTab[Item].len); } } // __set_FAULTMASK(1); // NVIC_SystemReset(); } u8 AT45DBItemWrite(AT45DBItem Type, u16 Group) { u16 i = 0,j = 0,k = 0; u8 Temp_Buff[660]; u8 Temp = 0; if(Group >= AT45DBTab[Type].Group) return 0; for(i = 0;i < AT45DBTab[Type].len - checkLen_1;i ++) { *(AT45DBTab[Type].upData + i) = *(AT45DBTab[Type].pData + i); Temp_Buff[i] = *(AT45DBTab[Type].upData + i); } Temp_Buff[AT45DBTab[Type].len - checkLen_1] = AT45DBDataCheck(Temp_Buff,AT45DBTab[Type].len - checkLen_1); for(j = 0;j < 6;j ++) { AT45DB_WritePage(Temp_Buff,AT45DBTab[Type].firstAdr + Group,AT45DBTab[Type].len); if(AT45DBItemRead(Type,Group) == 1) { return 1; } delay_ms(100); } // TXHData.ErrState.Flag.e_errFlashParameter = 1; return 0; } u8 CRCTemp = 0; u8 AT45DBItemRead(AT45DBItem Type, u16 Group) { volatile u16 i = 0,j = 0; u8 Temp_Buff[660]; u8 Temp_Buff1[660]; u8 CRCTemp1 = 0; if(Group >= AT45DBTab[Type].Group) return 0; for(j = 0;j < 6;j ++) { AT45DB_ReadPage(FuniGlobal.Global,AT45DBTab[Type].firstAdr + Group,AT45DBTab[Type].len); for(i = 0;i < AT45DBTab[Type].len;i ++) *(Temp_Buff+i) = *(AT45DBTab[Type].upData+i); CRCTemp = AT45DBDataCheck(Temp_Buff,AT45DBTab[Type].len - checkLen_1); if(CRCTemp == Temp_Buff[AT45DBTab[Type].len - checkLen_1]) { for(i = 0;i < AT45DBTab[Type].len - checkLen_1;i ++) *(AT45DBTab[Type].pData+i) = *(AT45DBTab[Type].upData+i); return 1; } delay_ms(100); } // pGun.ErrState.Flag.e_errFlashParameter = 1; return 0; } u8 ExChangeByte(u8 data) { u8 Temp = 0; Temp = data; data = (Temp >> 4) | (Temp << 4); return data; } u8 NotByte(u8 data) { if(data == 0 || data == 0xff) return data; else return ~data; } void AT45DB_Init(void) { volatile u16 Frame = 0; u8* pBuff; u8 Temp_Buff[660]; FlashType = ReadDriverID(); AT45DB_SetPageByte(); switch(FlashType) { case 0x24: TXHData.ATDB45Type = At45DB041;break; case 0x27: TXHData.ATDB45Type = At45DB321;break; case 0x28: TXHData.ATDB45Type = At45DB641;break; } // if(SWF8 == SWF_ON) // { // if(TXHData.ATDB45Type >= At45DB321) // { // for(Frame = 0;Frame < 1024;Frame ++) // { // ReadFlashNx512Btye(&TXHData.Frame[0],FLASH_APP_ADDR + Frame *512); // switch(Frame%8) // { // case 0:TXHData.Frame[2] = ExChangeByte(TXHData.Frame[2]); // TXHData.Frame[54] = NotByte(TXHData.Frame[54]); // TXHData.Frame[288] = ExChangeByte(TXHData.Frame[288]);GPIO_SetBits(GPIOE,GPIO_Pin_2);break; // case 1:TXHData.Frame[469] = NotByte(TXHData.Frame[469]);break; // case 2:TXHData.Frame[104] = ExChangeByte(TXHData.Frame[104]);break; // case 3:break; // case 4:TXHData.Frame[0] = NotByte(TXHData.Frame[0]);break; // case 5:TXHData.Frame[253] = ExChangeByte(TXHData.Frame[253]);GPIO_ResetBits(GPIOE,GPIO_Pin_2);break; // } // AT45DBItemWrite(CA_Frame,Frame + (TXHData.ROM_UpData.ROM_UpData_State.RomAddrNow * 1024)); // } // } // } }