motorcontroldemo_028/Vsrc/V_UserMemory.c
2019-07-29 08:18:57 +03:00

259 lines
8.9 KiB
C

/*!
Copyright 2017 ÀÎ "ÍÈÈÝÒ" è ÎÎÎ "ÍÏÔ ÂÅÊÒÎÐ"
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
\file V_UserMemory.c
\brief Ðàáîòà ñ ïîëüçîâàòåëüñêîé ýíåðãîíåçàâèñèìîé ïàìÿòüþ 1921BK028 (ñì. TUserMemory)
\author Ëàøêåâè÷ Ì.Ì., Øïàê Ä.Ì.
\version v 1.0 21/03/2019
*/
/** \addtogroup TUserMemory */
/*@{*/
#include "main.h"
#include "DSP.h"
//!Èíèöèàëèçàöèÿ
//!Èíèöèàëèçàöèÿ USERMEMORY
//! \memberof TUserMemory
void USERMEMORY_Init(TUserMemory *p)
{
USERMEMORY_ReadToCache(p,0);//÷èòàåì â îïåðàòèâêó íóëåâîé ñòðàíèöû (÷òîáû áûëà òåêóùàÿ ñòðàíèöà è âñå ðàáîòàëî êîððåêòíî äàëüøå)
}
//! Âñïîìîãàòåëüíàÿ ôóíêöèÿ îæèäàíèÿ îïåðàöèè, âîçâðàùåò "0" åñëè âñ¸ ÎÊ, è "1", åñëè íå âñ¸ ÎÊ
Uint16 waitUserFlashBusy (TUserMemory *p) {
p->waitClocks = 0;
__NOP(); // Â äîêóìåíòàöèè ñêàçàëè ïîäîæäàòü ïåðåä ïðîâåðêîé ñòàòóñà
__NOP();
__NOP();
__NOP();
__NOP();
while(NVRFLASH->STAT_bit.BUSY == 0x1){//æäåì
p->waitClocks++;
if (p->waitClocks > USERMEMORY_MAX_WAITCLOCKS){//óñòàëè æäàòü
return 1;
}
}
return 0;
}
//! Ïðîâåðêà, íå íóæíî ëè ñìåíèòü ñòðàíèöó
//! Ïðîâåðÿåò òåêóùèé àäðåñ íà ôëåøêå, ñ êîòîðûì ðàáîòàåò ïîëüçîâàòåëü. Åñëè àäðåñ âûøåë èç òåêóùåé ñòðàíèöû, ñòðàíèöà çàïèñûâàåòñÿ íà ôëåø è ÷èòàåòñÿ â RAM íîâûé
//! \memberof TUserMemory
void USERMEMORY_UpdateCurrentPage(TUserMemory *p, Uint16 spiaddr)
{
Uint16 newPage=spiaddr>>PAGE_SIZE_LOG2;//íîìåð ñòðàíèöû - ýòî âåðõíåå çíà÷åíèå àäðåñà, òàê êàê ñòðàíèöà 256 áàéò
if (newPage!=p->PageInCache){//ñòðàíèöà äðóãàÿ?
if (p->PageRAM_and_FLASH_IdenticalFlag==0)//è åñòü èçìåíåííûå äàííûå â ýòîé ñòðàíèöå â îïåðàòèâêå â êåøå?
USERMEMORY_Flush(p);//çàãîíÿåì ñòðàíèöó íà ôëåø
if (p->receivedCode!=USERMEMORY_OP_OK)//íå âûøëî?
return;
//÷èòàåì â îïåðàòèâêó íîâóþ ñòðàíèöó
USERMEMORY_ReadToCache(p,newPage);
if (p->receivedCode!=USERMEMORY_OP_OK)//íå âûøëî?
return;
}
}
//! Çàïèñü â ïàìÿòü
//!Ìåäëåííàÿ ôóíêöèÿ, çàïèñûâàþùàÿ íà flash çàäàííûå äàííûå.
//!Ðàáîòàåò ñ çàêåøèðîâàííûìè â îïåðàòèâêå äàííûìè, à ôèçè÷åñê ïèøåò íà ôëåø òîëüêî åñëè àäðåñ âûëåç çà ãðàíèöû òåêóùåé ñòðàíèöû
//! Àäðåñ âî ôëåøå spiaddr, àäðåñ 16òè ðàçðÿäíûõ äàííûõ ïîëüçîâàòåëÿ startaddr, ðàçìåð data_length. Âñå â áàéòàõ
//! Ïðè âûïîëåíèè îïåðàöèè startaddr èíêðåìåíòèðóåòñÿ, à spiaddr íåò
//! \memberof TUserMemory
void USERMEMORY_Write(TUserMemory *p)
{
Uint16 i = 0;
Uint16 spiaddrTmp=p->MemStartAddr;//àäðåñ íà ôëåøå â áàéòàõ
p->MCUStartAddr8=(Uint8*)p->MCUStartAddr;//ìåíÿåì óêàçàòåëü íà äàííûå - èç óêàçàòåëÿ íà 16òè ðàçðÿäíûå äàííûå íà óêàçàòåëü íà áàéòû - òàê óäîáíåå
for(i = 0; i < p->data_length; i++){//ïî âñåì äàííûì, ÷òî õî÷åò ïîëüçîâàòåëü
USERMEMORY_UpdateCurrentPage(p,spiaddrTmp);//ñìåíèòü è ïåðå÷èòàòü ñòðàíèöó, åñëè îíà äðóãàÿ
Uint16 addrInPage=spiaddrTmp&0xFFFF;//àäðåñ âíóòðè ñòðàíèöû
if (p->cacheArr[addrInPage] != (*(p->MCUStartAddr8))){//äàííûå íà ñîâïàäàþò ñ òåì, ÷òî óæå â îïåðàòèâêå â ýòîì ìåñòå?
p->cacheArr[addrInPage]=(*(p->MCUStartAddr8));//êëàäåì äàííûå â îïåðàòèâêó
p->PageRAM_and_FLASH_IdenticalFlag=0;//ôëàã, ÷òî äàííûå â îïåðàòèâêå îòëè÷àþòñÿ îò çàïèñàííûõ íà ôëåøå
}
spiaddrTmp++;
p->MCUStartAddr8++;
}
//p->MCUStartAddr=(Uint16*)p->MCUStartAddr8;//÷òîáû àäðåñ íà äàííûå ïîìåíÿëñÿ (íå çíàþ, íàäî ýòî êîìó èëè íåò)
p->receivedCode = USERMEMORY_OP_OK;
}
//! ×òåíèå èç ïàìÿòè
//!Ìåäëåííàÿ ôóíêöèÿ, ñ÷èòûâàþùàÿ èç flash çàäàííûå äàííûå. Ïîäðîáíîñòè ñì. TUserMemory.
//! Àäðåñ âî ôëåøå spiaddr, àäðåñ àäðåñ 16òè ðàçðÿäíûõ äàííûõ ïîëüçîâàòåëÿ startaddr, ðàçìåð data_length. Âñå â áàéòàõ.
//! Ïðè âûïîëåíèè îïåðàöèè startaddr èíêðåìåíòèðóåòñÿ, à spiaddr íåò
//! \memberof TUserMemory
void USERMEMORY_Read(TUserMemory *p)
{
Uint16 i = 0;
Uint16 spiaddrTmp=p->MemStartAddr;
p->MCUStartAddr8=(Uint8*)p->MCUStartAddr;
for(i = 0; i < p->data_length; i++){//ïî âñåì äàííûì, ÷òî õî÷åò ïîëüçîâàòåëü
USERMEMORY_UpdateCurrentPage(p,spiaddrTmp);//ñìåíèòü è ïåðå÷èòàòü ñòðàíèöó, åñëè îíà äðóãàÿ
Uint16 addrInPage=spiaddrTmp&0xFFFF;//àäðåñ âíóòðè ñòðàíèöû
*(p->MCUStartAddr8) = p->cacheArr[addrInPage];//îòäàåì äàííûå èç îïåðàòèâêè, îíè äîëæíû áûòü òàì àêòóàëüíûå ïîñëå USERMEMORY_UpdateCurrentPage
spiaddrTmp++;
p->MCUStartAddr8++;
}
p->MCUStartAddr=(Uint16*)p->MCUStartAddr8;//÷òîáû àäðåñ íà äàííûå ïîìåíÿëñÿ (íå çíàþ, íàäî ýòî êîìó èëè íåò)
p->receivedCode = USERMEMORY_OP_OK;
}
//! Çàïèñûâàåò ñòðàíèöó äàííûå íà ôëåøêó èç êåøà (èç îïåðàòèâêè îäíó ñòðàíèöó)
//! \memberof TUserMemory
void USERMEMORY_WriteFromCache(TUserMemory *p, int16 pageNum)
{
int16 i = 0, readDataWord = 0;
Uint32 *arrayPointer;
Uint16 addrOffset=pageNum*USERMEMORY_PAGE_SIZE;//íà÷àëüíûé àäðåñ íà ôëåøêå (îò íà÷àëà ñòðàíèöû)
NVRFLASH->STAT = 0x3;//ñáðîñ ñòàòóñà
NVRFLASH->ADDR = addrOffset;//àäðåñ íà÷àëà ñòðàíèöû
NVRFLASH->CMD = (USERMEMORY_USERFLASH_KEY | USERMEMORY_CMD_PAGE_ERASE);//ñòèðàåì ñòðàíèöó
if (waitUserFlashBusy(p) != 0){
p->receivedCode = USERMEMORY_WRITE_TIMEOUT;
return;
}
for(i = 0; i < USERMEMORY_PAGE_SIZE; i += NUMBER_OF_BYTE_ON_PAGE){//öèêë ïî ðàçìåðó ñòðàíèöû
NVRFLASH->STAT = 0x3; //ñáðîñ ñòàòóñà
NVRFLASH->ADDR = addrOffset + i; //àäðåñ
arrayPointer = (Uint32*)(&p->cacheArr[i]);
for (readDataWord = 0; readDataWord < NUMBER_OF_32BIT_WORDS_AT_ONCE; readDataWord++){
NVRFLASH->DATA[readDataWord].DATA = *arrayPointer;
arrayPointer++;
}
NVRFLASH->CMD = (USERMEMORY_USERFLASH_KEY | USERMEMORY_CMD_WRITE);//êîìàíäà íà çàïèñü áàéòà
if (waitUserFlashBusy(p) != 0){
p->receivedCode = USERMEMORY_WRITE_TIMEOUT;
return;
}
}
NVRFLASH->STAT = 0x3;//ñáðîñ ñòàòóñà
p->receivedCode = USERMEMORY_OP_OK;//âñå õîðîøî
p->PageRAM_and_FLASH_IdenticalFlag=1;//äàííûå ñòðàíèöû â îïåðàòèâêå è âî ôëåøå òåïåðü èäåíòè÷íû
}
//! ×èòàåò ñòðàíèöó äàííûõ èç ôëåøà â êåø (â îïåðàòèâêó)
//! \memberof TUserMemory
void USERMEMORY_ReadToCache(TUserMemory *p, int16 pageNum)
{
int16 i = 0, readDataWord = 0;
Uint16 addrOffset = pageNum * USERMEMORY_PAGE_SIZE;//íà÷àëüíûé àäðåñ íà ôëåøêå (îò íà÷àëà ñòðàíèöû)
Uint32 *arrayPointer;
for(i = 0; i < USERMEMORY_PAGE_SIZE; i += NUMBER_OF_BYTE_ON_PAGE){//öèêë ïî ðàçìåðó ñòðàíèöû
NVRFLASH->STAT = 0x3;//ñáðîñ ñòàòóñà
NVRFLASH->ADDR = addrOffset + i;//àäðåñ
NVRFLASH->CMD = (USERMEMORY_USERFLASH_KEY | USERMEMORY_CMD_READ);//êîìàíäà íà ÷òåíèå áàéòà
if (waitUserFlashBusy(p) != 0){
p->receivedCode = USERMEMORY_READ_TIMEOUT;
return;
}
arrayPointer = (Uint32*)&(p->cacheArr[i]);
// Ñ÷èòûâàåòñÿ ïî 16 èëè 4 32-ðàçðÿäíûõ ñëîâà{
for (readDataWord = 0; readDataWord < NUMBER_OF_32BIT_WORDS_AT_ONCE; readDataWord++){
*arrayPointer = NVRFLASH->DATA[readDataWord].DATA;//äàííûå (îäèí áàéò) â îïåðàòèâêó
arrayPointer++;
}
}
NVRFLASH->STAT = 0x3;//ñáðîñ ñòàòóñà
p->receivedCode = USERMEMORY_OP_OK;
p->PageInCache=pageNum;//êàêàÿ ñòðàíèöà òåïåðü â êåøå
p->PageRAM_and_FLASH_IdenticalFlag=1;//äàííûå â îïåðàòèâêå (â êåøå) èäåíòè÷íû ñ ôëåøåì
}
//! Ñòåðåòü âñþ ôëåøêó (áóäóò FF)
//! \memberof TUserMemory
void USERMEMORY_Full_Erase(TUserMemory *p){
// Cáðîñ ñòàòóñà, êîìàíäà ñòèðàíèÿ è îæèäàíèå çàâåðøåíèÿ
NVRFLASH->STAT = 0x3;
NVRFLASH->CMD = (USERMEMORY_USERFLASH_KEY | USERMEMORY_CMD_FULL_ERASE);//êîìàíäà íà ñòèðàíèå ôñåé ôëåøè
__NOP(); // Â äîêóìåíòàöèè ñêàçàëè ïîäîæäàòü ïåðåä ïðîâåðêîé ñòàòóñà
__NOP();
__NOP();
__NOP();
__NOP();
while(NVRFLASH->STAT_bit.BUSY == 0x1){};
}
//! Ñáðîñèòü êåø èç îïåðàòèâêè íà ôëåøêó
//! \memberof TUserMemory
void USERMEMORY_Flush(TUserMemory *p){
USERMEMORY_WriteFromCache(p,p->PageInCache);
}
//! Ìåäëåííûé ôîíîâûé ïîñòîÿííûé ðàñ÷åò - íóæåí ïîêà äëÿ ñèñòåìàòè÷åñêîãî ñáðîñà êåøà íà ôëåøêó ïî âðåìåíè
//! \memberof TUserMemory
void USERMEMORY_slow_calc(TUserMemory *p){
if (p->NeedFlushRequest){//íàäî ôëóøèòü?
USERMEMORY_Flush(p);
p->NeedFlushRequest=0;
}
}
//! Ìèëëèñåêóíäíûé ðàñ÷åò - íóæåí ïîêà äëÿ ñèñòåìàòè÷åñêîãî ñáðîñà êåøà íà ôëåøêó ïî âðåìåíè
//! \memberof TUserMemory
void USERMEMORY_ms_calc(TUserMemory *p){
if (!p->PageRAM_and_FLASH_IdenticalFlag)//äàííûå íà ôëåøêå è â îïåðàòèâêå íå èäåíòè÷íû
p->autoFlushCounter++;
if (p->autoFlushCounter>10000) //çèùèòà îò ïåðåïîëíåíèÿ
p->autoFlushCounter=10000;
if (p->autoFlushCounter>500){//äîëãî íå ñáðàñûâàåòñÿ íà ôëåøêó
p->NeedFlushRequest=1;//íàäî ôëóøèòü, íî òóò ýòî äåëàòü íåëüçÿ, èáî ïðåðûâàíèå, ñòàâèì ðåêâåñò ôîíó
p->autoFlushCounter=0;
}
}
/*@}*/