Встроен драйвер I2C памяти

This commit is contained in:
Dmitry Shpak 2019-08-15 18:38:50 +03:00
parent 3fa1b4abff
commit 1db9b4700c
6 changed files with 449 additions and 71 deletions

View File

@ -16,9 +16,9 @@
\file V_UserMemory.h
\brief Ðàáîòà ñ ýíåðãîíåçàâèñèìîé ïàìÿòüþ 1921BK01 (ñì. TUserMemory)
\author ÎÎÎ "ÍÏÔ Âåêòîð". http://motorcontrol.ru
\version v 2.0 25/03/2016
\version v 2.0 10/08/2019
\defgroup V_UserMemory Ðàáîòà ñ ýíåðãîíåçàâèñèìîé ïàìÿòüþ (ñì. TUserMemory)
\defgroup V_UserMemory Оболочка для I2CMEM (см. TUserMemory)
@{
*/
@ -35,13 +35,15 @@ extern "C" {
/*! \class TUserMemory
\brief Ðàáîòà ñ ïîëüçîâàòåëüñêîé ýíåðãîíåçàâèñèìîé ïàìÿòüþ ÌÑ01
\brief Работа с пользовательской энергонезависимой памятью I2c
Класс \a TUserMemory, основанный на структуре TUserMemory, представляет собой оболочку для драйвера для работы с
flash памятью по интерфейсу I2C.\n
Оболочка нужна для совместимости с другими проектами, где используется UserMem \n
Êëàññ \a TUserMemory, îñíîâàííûé íà ñòðóêòóðå TUserMemory, ïðåäñòàâëÿåò ñîáîé äðàéâåð äëÿ ðàáîòû ñ
flash ïàìÿòüþ.\n
ïðèìåð èñïîëüçîâàíèÿ:\n
äëÿ èíèöèàëèçàöèè\n
spimem.init.(&spimem);\n
UserMem.init(&UserMem);\n
äëÿ çàïèñè\n
UserMem.spiaddr=0;\n
@ -52,57 +54,28 @@ extern "C" {
*/
//! ñì. TUserMemory
#define USERMEMORY_USERFLASH_KEY 0xA4420000
#define USERMEMORY_MAX_WAITCLOCKS 2000
#define USERMEMORY_WRITE_HARDFAULT 0x1
#define USERMEMORY_WRITE_TIMEOUT 0x2
#define USERMEMORY_READ_HARDFAULT 0x3
#define USERMEMORY_READ_TIMEOUT 0x4
#define USERMEMORY_OP_OK 0x0
#define USERMEMORY_PAGE_SIZE 256
#define USERMEMORY_CMD_WRITE (1<<0)
#define USERMEMORY_CMD_PAGE_ERASE (1<<1)
#define USERMEMORY_CMD_FULL_ERASE (1<2)
#define USERMEMORY_CMD_READ (1<<3)
struct SUserMemory {Uint16 MemStartAddr;//!Àäðåñ íà flash
Uint8 *MCUStartAddr8; //!àäðåñ íà ìàññèâ ñ äàííûìè êàê áàéòîâûé óêàçàòåëü
Uint16 *MCUStartAddr; //!àäðåñ íà ìàññèâ ñ äàííûìè
Uint16 data_length;//!äëèíà äàííûõ
int16 receivedCode;//!Ñòàòóñ îïåðàöèè
Uint16 waitClocks;//!Ñ÷åò÷èê äëÿ îæèäàíèÿ òàéìàóòà îïåðàöèè
Uint16 PageInCache;//!Íîìåð òåêóùåé çàêåøèðîâàííîé ñòðàíèöû
Uint16 autoFlushCounter;//!Ñ÷åò÷èê äëÿ ñîõðàíåíèÿ êåøà íà ôëåø ïî òàéìàóòó
Uint8 PageRAM_and_FLASH_IdenticalFlag;//!Ôëàã î òîì, ÷òî äàííûå â êåøå è íà ôëåøå èäåíòè÷íû
Uint8 NeedFlushRequest;//ôëàã çàïðîñà íà çàïèñü äàííûõ èç êåøà íà ôëåø
Uint8 cacheArr[USERMEMORY_PAGE_SIZE];//êåø äàííûõ - îäíà ñòðàíèöà ïàìÿòè
void (*init)(struct SUserMemory*);
void (*write)(struct SUserMemory*);
void (*read)(struct SUserMemory*);
void (*full_erase)(struct SUserMemory*);
void (*flush)(struct SUserMemory*);
void (*ms_calc)(struct SUserMemory*);
void (*slow_calc)(struct SUserMemory*);
void (*full_erase)(struct SUserMemory*);
};
typedef struct SUserMemory TUserMemory;
//!Èíèöèàëèçàòîð ïî óìîë÷àíèþ
#define USERMEMORY_DEFAULTS {0,0,0,0,0,0,0,0,0,0, \
{0},\
USERMEMORY_Init, \
USERMEMORY_Write,\
USERMEMORY_Read,\
USERMEMORY_Full_Erase,\
USERMEMORY_Flush,\
USERMEMORY_ms_calc,\
USERMEMORY_slow_calc,\
#define USERMEMORY_DEFAULTS {.init = USERMEMORY_Init, \
.write = USERMEMORY_Write,\
.read = USERMEMORY_Read,\
.ms_calc = USERMEMORY_ms_calc,\
.slow_calc = USERMEMORY_slow_calc,\
.full_erase = USERMEMORY_Full_Erase,\
}
@ -115,17 +88,10 @@ void USERMEMORY_Read(TUserMemory*);
//! \memberof TUserMemory
void USERMEMORY_Full_Erase(TUserMemory*);
//! \memberof TUserMemory
void USERMEMORY_ReadToCache(TUserMemory *p, int16 pageNum);
//! \memberof TUserMemory
void USERMEMORY_WriteFromCache(TUserMemory *p, int16 pageNum);
//! \memberof TUserMemory
void USERMEMORY_Flush(TUserMemory *p);
//! \memberof TUserMemory
void USERMEMORY_ms_calc(TUserMemory *p);
//! \memberof TUserMemory
void USERMEMORY_slow_calc(TUserMemory *p);
//! \memberof TUserMemory
void USERMEMORY_UpdateCurrentPage(TUserMemory *p, Uint16 spiaddr);
#ifdef __cplusplus
}

42
Vinclude/V_i2cMem.h Normal file
View File

@ -0,0 +1,42 @@
/*
* V_i2cMem.h
*
* Created on: 15 àâã. 2019 ã.
* Author: Dmitry
*/
#ifndef INCLUDE_V_I2CMEM_H_
#define INCLUDE_V_I2CMEM_H_
#define EEPROM_MEM_LENGTH 32768 //äëèíà ôëåøêè â áàéòàõ (256 êáèò)
struct SI2cMem;
typedef volatile struct SI2cMem TI2cMem;
struct SI2cMem {
Uint16 MEMstartaddr; //! Àäðåñ íà flash
Uint16 data_length; //! Äëèíà äàííûõ â áàéòàõ
Uint16 *DSPstartaddr; //! Àäðåñ íà ìàññèâ ñ äàííûìè
Uint16 LastErr; //! Êîä îøèáêè (åñëè âîçíèêëà)
void (*init)(TI2cMem*);
void (*write)(TI2cMem*);
void (*read)(TI2cMem*);
void (*clearMem)(TI2cMem*);
};
void I2CMEM_Init(TI2cMem*);
void I2CMEM_Write(TI2cMem*);
void I2CMEM_Read(TI2cMem*);
void I2CMEM_Clear(TI2cMem*);
//!Èíèöèàëèçàòîð ïî óìîë÷àíèþ
#define I2CMEM_DEFAULTS { .init = I2CMEM_Init, \
.write = I2CMEM_Write,\
.read = I2CMEM_Read,\
.clearMem = I2CMEM_Clear,\
}
extern TI2cMem i2cMem;
#endif /* INCLUDE_V_I2CMEM_H_ */

View File

@ -102,18 +102,18 @@ void co_CAN2GpioInit()
//Ñ òî÷êè çðåíèÿ äðàéâåðà CANOpen ôóíêöèè ðåàëèçóþò ïîáàéòîâîå ÷òåíèå è çàïèñü èç/â ÝíÎÇÓ
void co_UserMemoryRead (const T_UserMemoryContext *p)
{
// UserMem.MemStartAddr = p->MemStartAddr;
// UserMem.MCUStartAddr = p->MCUStartAddr;
// UserMem.data_length = p->data_length;
// UserMem.read(&UserMem);
UserMem.MemStartAddr = p->MemStartAddr;
UserMem.MCUStartAddr = p->MCUStartAddr;
UserMem.data_length = p->data_length;
UserMem.read(&UserMem);
}
void co_UserMemoryWrite (const T_UserMemoryContext *p)
{
// UserMem.MemStartAddr = p->MemStartAddr;
// UserMem.MCUStartAddr = p->MCUStartAddr;
// UserMem.data_length = p->data_length;
// UserMem.write(&UserMem);
UserMem.MemStartAddr = p->MemStartAddr;
UserMem.MCUStartAddr = p->MCUStartAddr;
UserMem.data_length = p->data_length;
UserMem.write(&UserMem);
}
//**********************************************************************************************************************************************************************************************************

View File

@ -46,7 +46,7 @@ void SM_Sys_Init(TSM_Sys *p) {
#endif
cmd.all = 0;
drv_status.all = 0;
UserMem.init(&UserMem);
sm_net.init(&sm_net); //Ñåòåâàÿ ÷àñòü
adc.init(&adc); //Èíèöèàëèçàöèÿ ÀÖÏ
sm_prot.init(&sm_prot); //Çàùèòû

View File

@ -14,17 +14,17 @@
limitations under the License.
\file V_UserMemory.c
\brief Ðàáîòà ñ ïîëüçîâàòåëüñêîé ýíåðãîíåçàâèñèìîé ïàìÿòüþ 1921BK01 (ñì. TUserMemory)
\brief Îá¸đňęŕ äë˙ I2C ďŕě˙ňč
\author Ëàøêåâè÷ Ì.Ì., Øïàê Ä.Ì.
\version v 1.0 18/12/2014
\version v 1.0 10/08/2019
*/
/** \addtogroup TUserMemory */
/*@{*/
#include <V_UserMemory.h>
#include "V_UserMemory.h"
#include "DSP.h"
#include "V_i2cMem.h"
@ -34,10 +34,7 @@
//! \memberof TUserMemory
void USERMEMORY_Init(TUserMemory *p)
{
I2C->CTL1_bit.ENABLE = 1;
I2C->CTL1_bit.SCLFRQ = 63; // Divider: 100 000 000 / (63 * 4) ~ 400 êÃö
I2C->CTL3_bit.SCLFRQ = 0; // Divider
i2cMem.init(&i2cMem);
}
@ -61,7 +58,11 @@ void USERMEMORY_UpdateCurrentPage(TUserMemory *p, Uint16 spiaddr)
//! \memberof TUserMemory
void USERMEMORY_Write(TUserMemory *p)
{
i2cMem.DSPstartaddr = p->MCUStartAddr;
i2cMem.MEMstartaddr = p->MemStartAddr;
i2cMem.data_length = p->data_length;
i2cMem.write(&i2cMem);
p->receivedCode = i2cMem.LastErr;
}
@ -74,7 +75,11 @@ void USERMEMORY_Write(TUserMemory *p)
//! \memberof TUserMemory
void USERMEMORY_Read(TUserMemory *p)
{
i2cMem.DSPstartaddr = p->MCUStartAddr;
i2cMem.MEMstartaddr = p->MemStartAddr;
i2cMem.data_length = p->data_length;
i2cMem.read(&i2cMem);
p->receivedCode = i2cMem.LastErr;
}
@ -101,7 +106,7 @@ void USERMEMORY_ReadToCache(TUserMemory *p, int16 pageNum)
//! \memberof TUserMemory
void USERMEMORY_Full_Erase(TUserMemory *p){
i2cMem.clearMem(&i2cMem);
}

365
Vsrc/V_i2cMem.c Normal file
View File

@ -0,0 +1,365 @@
/*
* V_i2cMem.c
*
* Created on: 15 àâã. 2019 ã.
* Author: Dmitry
*/
#include "main.h"
#include "V_i2cmem.h"
#define I2C_MEM_ERROR_OK 0
#define I2C_MEM_ERROR_WRITE_HW_ERR 1
#define I2C_MEM_ERROR_READ_HW_ERR 2
#define I2C_MEM_ERROR_TIMEOUT 3
TI2cMem i2cMem = I2CMEM_DEFAULTS;
// Ôóíêöèÿ îæèäàíèÿ âûïîëíåíèÿ êîìàíäû
Uint16 i2c_waitIdle() {
Uint32 idle = 0;
while ((I2C->ST & I2C_ST_MODE_Msk) == I2C_ST_MODE_IDLE){
idle++;
if (idle > 10000000)
return 1;
};
return 0;
}
// Ôóíêöèÿ æä¸ò, ïîêà çàêîí÷èòñÿ âíóòðåííèé öèêë çàïèñè â ïàìÿòè
// Åñëè äîëæàëèñü, ïîêà ìèêðîñõåìà îñâîáîäèòñÿ, òî íà âûõîäå èç ôóíêöèè îíà áóäåò â ñîñòîÿíèè
// îæèäàíèÿ ïðè¸ìà âíóòðåííåãî àäðåñà (òî åñòü å¸ ïîñëàí ñòàðò è àäðåñ óñòðîéñòâà ñ áèòîì "Write")
Uint16 i2c_waitMemBusyAndSendAddWr () {
volatile Uint32 waitCycles = 0;
// Ïîñûëàåì ñòàðò è æä¸ì, ïîêà îí ñäåëàåòñÿ
I2C->CTL0 = I2C_CTL0_START_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_STDONE)
return I2C_MEM_ERROR_TIMEOUT;
do {
// Ïîñëàòü àäðåñ óñòðîéñòâà + Write, ïîäîæäàòü, ïîêà ïåðåäàñòñÿ
I2C->SDA = 0b10100000;
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Ñìîòðèì, ÷òî ïðèñëàëî óñòðîéñòâî. Åñëè ïðèñëàëî "4" - çíà÷èò âíóòðåííèé öèêë çàïèñè
// îêîí÷åí è ìîæíî åõàòü äàëüøå. Âîçâðàùàåì 0
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTADPA){
// Èíà÷å ñìîòðèì, êîòîðûé ðàç óæå ïûòàåìñÿ äîæäàòüñÿ îòâåòà. Åñëè ñëèøêîì äîëãî - óõîäèì îòñþäà
waitCycles++;
if (waitCycles > 10000000) {
I2C->CTL0 = I2C_CTL0_STOP_Msk | I2C_CTL0_CLRST_Msk;
return I2C_MEM_ERROR_TIMEOUT;
}
// Åñëè íå ñëèøêîì äîëãî - âûñûëàåì ïîâòîðíûé ñòàðò
I2C->CTL0 = I2C_CTL0_START_Msk;
I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_RSDONE)
return I2C_MEM_ERROR_TIMEOUT;
}
} while ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTADPA);
return I2C_MEM_ERROR_OK;
}
// Èíèò/ïåðåèíèò çàïèñè ìàññèâà, êîòîðûé íàäî âûçûâàòü ïðè äîñòèæåíèè ãðàíèöû ñòðàíèöû (64 áàéòà)
Uint16 i2c_initWriteArray (Uint16 address) {
Uint16 retVal;
// Æä¸ì, ïîêà ïàìÿòü ïàìÿòü çàêîí÷èí âíóòðåííåå ñîõðàíåíèå
retVal = i2c_waitMemBusyAndSendAddWr();
if (retVal != I2C_MEM_ERROR_OK)
return retVal;
// Ñòðàøèé áàéò àäðåñà 0x0000____
I2C->SDA = (address >> 8) & 0xFF;
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Åñëè íå êâèòèðîâàí - îøèáêà
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
return I2C_MEM_ERROR_WRITE_HW_ERR;
// Ìëàäøèé áàéò àäðåñà 0x____0000
I2C->SDA = (address >> 0) & 0xFF;
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Åñëè íå êâèòèðîâàí - îøèáêà
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
return I2C_MEM_ERROR_WRITE_HW_ERR;
// Âñ¸ õîðîøî
return I2C_MEM_ERROR_OK;
}
// Çàïèñü ìàññèâà
Uint16 i2c_writeArray(Uint16 address, Uint16 *dataPtr_u16, Uint16 length_u8) {
// Òóò âíóòðè ïðîùå ðàáîòàòü ñ áàéòàìè
Uint8* dataPtr_u8 = (Uint8*)dataPtr_u16;
i2c_initWriteArray(address);
// Ïîåõàëè äàííûå
while (length_u8 > 0) {
// Äàííûå
I2C->SDA = *dataPtr_u8;
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Åñëè íå êâèòèðîâàí - îøèáêà
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
return I2C_MEM_ERROR_WRITE_HW_ERR;
// Ñìîòðèì, íå äîøëè ëè äî êîíöà ñòðàíèöû âíóòðè ïàìÿòè/
// Åñëè äîøëè - íàäî ñäåëàòü ñòîï è ïîäîæäàòü, ïîêà äàííûå ïðîïèøóòñÿ
length_u8--;
dataPtr_u8++;
address++;
if ((address & 0x3F) == 0) {
// Ôîðìèðóåì ñòîï è ïåðåçàïóñêàåì çàïèñûâàëêó íà íîâûé àäðåñ
I2C->CTL0 = I2C_CTL0_STOP_Msk;
I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
i2c_initWriteArray(address);
}
}
// Çàêîí÷èëè - ôîðìèðóåì ñòîï
I2C->CTL0 = I2C_CTL0_STOP_Msk;
I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
return I2C_MEM_ERROR_OK;
}
// ×òåíèå ìàññèâà 16-ðàçðÿäíûõ ñëîâ
Uint16 i2c_readArray(Uint16 address, Uint16* readDataPtr_u16, Uint16 length_u8){
// Òóò âíóòðè ïðîùå ðàáîòàòü ñ áàéòàìè
Uint8* readDataPtr_u8 = (Uint8*)readDataPtr_u16;
Uint16 retVal;
// Æä¸ì, ïîêà ïàìÿòü ïàìÿòü çàêîí÷èí âíóòðåííåå ñîõðàíåíèå
retVal = i2c_waitMemBusyAndSendAddWr();
if (retVal != I2C_MEM_ERROR_OK)
return retVal;
// Ñòðàøèé áàéò àäðåñà 0x0000____
I2C->SDA = (address >> 8) & 0xFF;
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Åñëè íå êâèòèðîâàí - îøèáêà
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
return I2C_MEM_ERROR_READ_HW_ERR;
// Ìëàäøèé áàéò àäðåñà 0x____0000
I2C->SDA = (address >> 0) & 0xFF;
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Åñëè íå êâèòèðîâàí - îøèáêà
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
return I2C_MEM_ERROR_READ_HW_ERR;
// Ïîâòîðíûé ñòàðò, ÷òîáû ïåðåéòè â ðåæèì ìàñòåðà-ïðè¸ìíèêà
I2C->CTL0 = I2C_CTL0_START_Msk;
I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Åñëè ðåæèì íåïðàâèëüíûé - îøèáêà
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_RSDONE)
return I2C_MEM_ERROR_READ_HW_ERR;
// Àäðåñ óñòðîéñòâà + Read
I2C->SDA = 0b10100001;
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Åñëè ïåðåäà÷à àäðåñà óñòðîéñòâà íå êâèòèðîâàíà - îøèáêà
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MRADPA)
return I2C_MEM_ERROR_READ_HW_ERR;
while (length_u8 > 1) {
// Ïðèíèìàåì áàéò, è êâèòèðóåì
I2C->CTL0 = I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Åñëè ðåæèì íå ñòàë ïðàâèëüíûì - îøèáêà
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MRDAPA)
return I2C_MEM_ERROR_READ_HW_ERR;
*readDataPtr_u8 = I2C->SDA;
readDataPtr_u8++;
length_u8--;
}
// Ïîñëåäíèé áàéò ïðèíèìàåì, íî íå êâèòèðóåì
I2C->CTL0 = I2C_CTL0_ACK_Msk; // Reset + NACK
I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
// Åñëè ðåæèì íå ñòàë ïðàâèëüíûì - îøèáêà
if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MRDANA)
return I2C_MEM_ERROR_READ_HW_ERR;
*readDataPtr_u8 = I2C->SDA;
// Ôîðìèðóåì ñòîï
I2C->CTL0 = I2C_CTL0_STOP_Msk | I2C_CTL0_CLRST_Msk;
return I2C_MEM_ERROR_OK;
}
// Æåëàåìàÿ ÷àñòîòà øèíû I2C â êèëîãåðöàõ
#define I2CMEM_FREQUENCY_KHZ 400
void I2CMEM_Init(TI2cMem*p){
// Ðàçðåøàåì ðàáîòó 0 è 1 íîæåê ïîðòà À è ïåðåâîäèì èõ â ïåðèôåðèéíûé ðåæèì
GPIOA->DENSET |= 0x3;
GPIOA->ALTFUNCSET |= 0x3;
// Ðàçðåøàåì ðàáîòó I2C ìîäóëÿ è ñòàâèì åìó ñêîðîñòü
// Fi2c = Fcpu / (4 * SCLFRQ), à Fcpu äëÿ 035 = 100 ÌÃö
I2C->CTL1 |= I2C_CTL1_ENABLE_Msk;
I2C->CTL1 |= (25000 / I2CMEM_FREQUENCY_KHZ) << I2C_CTL1_SCLFRQ_Pos;
}
void I2CMEM_Write(TI2cMem*p){
// Çàïèñü
p->LastErr = i2c_writeArray(p->MEMstartaddr, p->DSPstartaddr, p->data_length);
}
void I2CMEM_Read(TI2cMem*p){
// ×òåíèå
p->LastErr = i2c_readArray(p->MEMstartaddr, p->DSPstartaddr, p->data_length);
}
void I2CMEM_Clear(TI2cMem*p){
// Ñòèðàíèå
Uint32 i = 0;
Uint16 ffArr[32];
for (i = 0; i < 32; i++) {
ffArr[i] = 0xFFFF;
}
for (i = 0; i < EEPROM_MEM_LENGTH; i += 0x40){
p->MEMstartaddr = i;
p->DSPstartaddr = ffArr;
p->data_length = 0x40;
p->LastErr = i2c_writeArray(p->MEMstartaddr, p->DSPstartaddr, p->data_length);
if (p->LastErr != I2C_MEM_ERROR_OK)
return;
}
}
/****** Äåïðåêåéòåä, êàê ãîâîðèòñÿ *******/
//// Çàïèñü â ïàìÿòü îäíîãî áàéòà è "ñòîï"
//Uint16 i2c_writeSingleByteAndStop(Uint16 address, Uint8 data)
//{
// Uint16 retVal;
// // Æä¸ì, ïîêà ïàìÿòü ïàìÿòü çàêîí÷èí âíóòðåííåå ñîõðàíåíèå
// retVal = i2c_waitMemBusyAndSendAddWr();
// if (retVal != I2C_MEM_ERROR_OK)
// return retVal;
//
// // Ñòðàøèé áàéò àäðåñà 0x0000____
// I2C->SDA = (address >> 8) & 0xFF;
// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
//
// // Åñëè íå êâèòèðîâàí - îøèáêà
// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
// return I2C_MEM_ERROR_WRITE_HW_ERR;
//
// // Ìëàäøèé áàéò àäðåñà 0x____0000
// I2C->SDA = (address >> 0) & 0xFF;
// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
//
// // Åñëè íå êâèòèðîâàí - îøèáêà
// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
// return I2C_MEM_ERROR_WRITE_HW_ERR;
//
// // Äàííûå
// I2C->SDA = data;
// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
//
// // Åñëè íå êâèòèðîâàí - îøèáêà
// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
// return I2C_MEM_ERROR_WRITE_HW_ERR;
//
// // Ôîðìèðóåì ñòîï
// I2C->CTL0 = I2C_CTL0_STOP_Msk;
// I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
// return I2C_MEM_ERROR_OK;
//}
//
//
//// ×òåíèå îäíîãî áàéòà è ñòîï
//Uint8 i2c_readSingleByteAndStop(Uint16 address, Uint16* readData)
//{
// Uint16 retVal;
//
// // Æä¸ì, ïîêà ïàìÿòü ïàìÿòü çàêîí÷èí âíóòðåííåå ñîõðàíåíèå
// retVal = i2c_waitMemBusyAndSendAddWr();
// if (retVal != I2C_MEM_ERROR_OK)
// return retVal;
//
// // Ñòðàøèé áàéò àäðåñà 0x0000____
// I2C->SDA = (address >> 8) & 0xFF;
// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
//
// // Åñëè íå êâèòèðîâàí - îøèáêà
// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
// return I2C_MEM_ERROR_READ_HW_ERR;
//
// // Ìëàäøèé áàéò àäðåñà 0x____0000
// I2C->SDA = (address >> 0) & 0xFF;
// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
//
// // Åñëè íå êâèòèðîâàí - îøèáêà
// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MTDAPA)
// return I2C_MEM_ERROR_READ_HW_ERR;
//
// // Ïîâòîðíûé ñòàðò, ÷òîáû ïåðåéòè â ðåæèì ìàñòåðà-ïðè¸ìíèêà
// I2C->CTL0 = I2C_CTL0_START_Msk;
// I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
//
// // Åñëè ðåæèì íåïðàâèëüíûé - îøèáêà
// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_RSDONE)
// return I2C_MEM_ERROR_READ_HW_ERR;
//
// // Àäðåñ óñòðîéñòâà + Read
// I2C->SDA = 0b10100001;
// I2C->CTL0 = I2C_CTL0_CLRST_Msk;
// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
//
// // Åñëè ïåðåäà÷à àäðåñà óñòðîéñòâà íå êâèòèðîâàíà - îøèáêà
// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MRADPA)
// return I2C_MEM_ERROR_READ_HW_ERR;
//
// // Ïðèíèìàåì áàéò, íî íå êâèòèðóåì
// I2C->CTL0 = I2C_CTL0_ACK_Msk; // Reset + NACK
// I2C->CTL0 |= I2C_CTL0_CLRST_Msk;
// if (i2c_waitIdle() != 0) return I2C_MEM_ERROR_TIMEOUT;
//
// // Åñëè ðåæèì íå ñòàë ïðàâèëüíûì - îøèáêà
// if ((I2C->ST & I2C_ST_MODE_Msk) != I2C_ST_MODE_MRDANA)
// return I2C_MEM_ERROR_READ_HW_ERR;
//
// *readData = I2C->SDA;
// // Ôîðìèðóåì ñòîï
// I2C->CTL0 = I2C_CTL0_STOP_Msk | I2C_CTL0_CLRST_Msk;
//
// return I2C_MEM_ERROR_OK;
//}