Встроен драйвер I2C памяти
This commit is contained in:
parent
3fa1b4abff
commit
1db9b4700c
@ -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
42
Vinclude/V_i2cMem.h
Normal 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_ */
|
@ -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);
|
||||
}
|
||||
//**********************************************************************************************************************************************************************************************************
|
||||
|
||||
|
@ -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); //Çàùèòû
|
||||
|
@ -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
365
Vsrc/V_i2cMem.c
Normal 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;
|
||||
//}
|
Loading…
Reference in New Issue
Block a user