最新情報

ナウいマイコン PSoC4200 の EEPROM(EmEEPROM)(備忘録)

ものによっては
電源OFF時にも、データを記憶しておきたい時があります。

PSoC4200 にもArduino の

EEPROM.write( アドレス , 値 )  // バイト単位でEEPROMに書き込み

ex: EEPROM.write(0x00,100);

のような簡単な命令があればラッキーなんですが・・・・・・・・

 

ちょと探してみましたが
ネット上で見つからなくて困り果てていました(ナウすぎて情報が追い付いてないのかな??)。
メーカーさんからのサンプルがあったので、それを見ていこうと思います。

まずはコンポーネント。

 

 

/******************************************************************************
* File Name: main_cm4.c
*
* Version: 1.0
*
* Description: This example project demonstrates the basic operation the emulated
* EEPROM middleware. On every reset the device reads the EEPROM contents and 
* increments a counter by one.
*
* Related Document: PSoC_Em_EEPROM.pdf
*
* Hardware Dependency: CY8CKIT-062-BLE PSoC 6 BLE Pioneer Kit 
*
******************************************************************************
* Copyright (2017), Cypress Semiconductor Corporation.
******************************************************************************
* This software, including source code, documentation and related materials
* ("Software") is owned by Cypress Semiconductor Corporation (Cypress) and is
* protected by and subject to worldwide patent protection (United States and 
* foreign), United States copyright laws and international treaty provisions. 
* Cypress hereby grants to licensee a personal, non-exclusive, non-transferable
* license to copy, use, modify, create derivative works of, and compile the 
* Cypress source code and derivative works for the sole purpose of creating 
* custom software in support of licensee product, such licensee product to be
* used only in conjunction with Cypress's integrated circuit as specified in the
* applicable agreement. Any reproduction, modification, translation, compilation,
* or representation of this Software except as specified above is prohibited 
* without the express written permission of Cypress.
* 
* Disclaimer: THIS SOFTWARE IS PROVIDED AS-IS, WITH NO WARRANTY OF ANY KIND, 
* EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, NONINFRINGEMENT, IMPLIED 
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* Cypress reserves the right to make changes to the Software without notice. 
* Cypress does not assume any liability arising out of the application or use
* of Software or any product or circuit described in the Software. Cypress does
* not authorize its products for use as critical components in any products 
* where a malfunction or failure may reasonably be expected to result in 
* significant injury or death ("ACTIVE Risk Product"). By including Cypress's 
* product in a ACTIVE Risk Product, the manufacturer of such system or application
* assumes all risk of such use and in doing so indemnifies Cypress against all
* liability. Use of this Software may be limited by and subject to the applicable
* Cypress software license agreement.
*****************************************************************************/
#include "project.h"

/*Funciton protorype for handling errors*/
void HandleError(void);

/*Logical Size of Em_EEPROM*/
#define LOGICAL_EEPROM_SIZE     15u
#define LOGICAL_EEPROM_START    0u

/*location of reset counter in Em_EEPROM*/
#define RESET_COUNT_LOCATION    13u
#define RESET_COUNT_SIZE        2u

/*ASCII "9"*/
#define ASCII_NINE              0x39

/*ASCII "0"*/
#define ASCII_ZERO              0x30

/*ASCII "P"*/
#define ASCII_P                 0x50
/*Return status for EEPROM and UART*/ 
cy_en_em_eeprom_status_t eepromReturnValue;


/* EEPROM storage in work flash, this is defined in Em_EEPROM.c*/
#if defined (__ICCARM__)
#pragma data_alignment = CY_FLASH_SIZEOF_ROW
const uint8_t Em_EEPROM_em_EepromStorage[Em_EEPROM_PHYSICAL_SIZE] = {0u};
#else
const uint8_t Em_EEPROM_em_EepromStorage[Em_EEPROM_PHYSICAL_SIZE]
__ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};
#endif /* defined (__ICCARM__) */


/*RAM arrays for holding EEPROM read and write data*/
uint8_t eepromArray[15];
uint8_t array[15] = { 0x50, 0x6F, 0x77, 0x65, 0x72, 0x20, 0x43, 0x79, 0x63, 0x6C, 0x65, 0x23, 0x20, 0x30, 0x30};
                               /* P     o     w     e     r           C     y     c     l     e     #           0*/

int main(void)
{    
     __enable_irq(); 

    /*Initalize EEPROM with the start address of the memory location*/
    eepromReturnValue = Em_EEPROM_Init((uint32_t)Em_EEPROM_em_EepromStorage);
    if(eepromReturnValue != CY_EM_EEPROM_SUCCESS)
    {
        HandleError();
    }


    
    UART_PutString("EmEEPROM demo \n\r");
       
    /*Read 15 bytes out of EEPROM memory*/
    eepromReturnValue = Em_EEPROM_Read(LOGICAL_EEPROM_START, eepromArray, LOGICAL_EEPROM_SIZE);
    if(eepromReturnValue != CY_EM_EEPROM_SUCCESS)
    {
        HandleError();
    }
    
    /*If first byte of EEPROM isn't 'P' the write data from array*/
    if(eepromArray[0] != ASCII_P)
    {
        /*Write inital data to EEPROM*/
        eepromReturnValue = Em_EEPROM_Write(LOGICAL_EEPROM_START, array, LOGICAL_EEPROM_SIZE); 
        if(eepromReturnValue != CY_EM_EEPROM_SUCCESS)
        {
            HandleError();
        }
    }
    /*Otherwise it has been written update counter*/
    else
    {
        /*Read contents of EEPROM*/
        eepromReturnValue = Em_EEPROM_Read(LOGICAL_EEPROM_START, eepromArray, LOGICAL_EEPROM_SIZE);
        if(eepromReturnValue != CY_EM_EEPROM_SUCCESS)
        {
            HandleError();
        }
        
        /*Increment Counter by 1*/
        eepromArray[RESET_COUNT_LOCATION+1]++; 
        
        /*Counter is in ASCII, so handle overflow*/
        if(eepromArray[RESET_COUNT_LOCATION+1] > ASCII_NINE)
        { 
            /*Set lower digit to zero*/
            eepromArray[RESET_COUNT_LOCATION+1] = ASCII_ZERO;
            /*Increment upper digit*/
            eepromArray[RESET_COUNT_LOCATION]++;
            
            /*only increment to 99*/
            if(eepromArray[RESET_COUNT_LOCATION] > ASCII_NINE)
            {
                eepromArray[RESET_COUNT_LOCATION] = ASCII_NINE;
                eepromArray[RESET_COUNT_LOCATION+1] = ASCII_NINE;
            }
        }
        
        /*Only update the two count values in the EEPROM*/
        eepromReturnValue = Em_EEPROM_Write(RESET_COUNT_LOCATION, &eepromArray[RESET_COUNT_LOCATION], RESET_COUNT_SIZE);
        if(eepromReturnValue != CY_EM_EEPROM_SUCCESS)
        {
            HandleError();
        }
    }
    
    /*Read contents of EEPROM after write*/
    eepromReturnValue = Em_EEPROM_Read(LOGICAL_EEPROM_START, eepromArray, LOGICAL_EEPROM_SIZE);
    if(eepromReturnValue != CY_EM_EEPROM_SUCCESS)
    {
        HandleError();
    }
    
    /*Print EEPROM contents to console*/
    UART_PutArray(eepromArray, LOGICAL_EEPROM_SIZE); 
    UART_PutString("\n\r");

    for(;;)
    {
    
    }
        
}

/*******************************************************************************
* Function Name: HandleError
****************************************************************************//**
*
* This function processes unrecoverable errors such as any component 
* initialization errors etc. In case of such error the system will 
* stay in the infinite loop of this function..
*
*
* \note
* * If error ocuurs interrupts are disabled.
*
*******************************************************************************/
void HandleError(void)
{   
    UART_PutString("Error! \n\r");
     /* Disable all interrupts. */
    __disable_irq();
    
    /* Infinite loop. */
    while(1u) {}
}

/* [] END OF FILE */

パワーサイクル、つまり電源投入回数(リセット含む)を記録し、シリアル出力するソフトのようです。

電源投入(またはリセット)時にEEPROMを読み込んで、最初のデータが「P」なら

電源投入回数を「+1」してEEPROMへ書込んでいるようです。

書込み、読込みの確認の戻り値も

eepromReturnValue = xxxxx

で、きっちりとっていますね、まさに教科書!!

 

Arduino の

EEPROM.write( アドレス , 値 )  // バイト単位でEEPROMに書き込み

これと似ている命令として

Em_EEPROM_Write(LOGICAL_EEPROM_START, array, LOGICAL_EEPROM_SIZE);

があるようです。

LOGICAL_EEPROM_START:書込みアドレス

array:書込みデータ

LOGICAL_EEPROM_SIZE:書込みデータ数

のようです。

//————————————————————————————————-

サンプルコードで、極力EEPROM以外のところをそぎ落として

自分なりに、復習してみました。

EEPROMへ3文字「@xx」(xxは数字)書き込んで
電源投入(リセット)時
先頭データが「@」なら「xx」の数字に1足して、EEPROMへ再書き込みし

そのデータをキャラクタLCDへ表示させます。

 

 

 

#include	"project.h"
#include	<stdio.h>
#include	<stdlib.h>
#include	"I2CLCDDRV.h"


//--------------------------------------------------------

#define EEPROM_START_ADDR	    0u		// EEPROM 書込みアドレス

const uint8_t Em_EEPROM_em_EepromStorage[Em_EEPROM_PHYSICAL_SIZE]		// EEPROM サイズ
__ALIGNED(CY_FLASH_SIZEOF_ROW) = {0u};									// データ配置

// Em_EEPROM_PHYSICAL_SIZE 1024u
// CY_FLASH_SIZEOF_ROW 0x00000080u
//--------------------------------------------------------

uint8 read_EEPROM_data[3];				// 読込みデータ格納場所
char array[3];							// 書込みデータ

//--------------------------------------------------------
	
int main(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */

    /* Place your initialization/startup code here (e.g. MyInst_Start()) */
	CyDelay(100);			// 安定するまで(おまじない程度)
    I2CM_Start();			// I2C 開始
	I2C_LCD_Init();			// I2C LCD 初期化
	
	I2C_LCD_position(1,1);						// LCD X,Y 表示座標
	I2C_LCD_Char_PrintString("EEPROM Test");	// プログラム開始の合図


	Em_EEPROM_Init((uint32_t)Em_EEPROM_em_EepromStorage);	// EEPROM 初期化
	
	Em_EEPROM_Read(EEPROM_START_ADDR, read_EEPROM_data, 3);	// EEPROM 読込み 3byte読込み(3文字)
	
	if (read_EEPROM_data[0]== '@')		// EEPROM読んでみて先頭データが'@'なら
	{
		if(read_EEPROM_data[2] != '9')	// 10進表示用
		{
			read_EEPROM_data[2]++;
		}else{
			read_EEPROM_data[2] = '0';
			read_EEPROM_data[1]++;
		}
		array[0] = read_EEPROM_data[0];
		array[1] = read_EEPROM_data[1];
		array[2] = read_EEPROM_data[2];
		
		Em_EEPROM_Write(EEPROM_START_ADDR, array, 3); 		// EEPROM 書込み 3byte (3文字) (アドレス、書込みデータ、サイズ(byte))
		
		I2C_LCD_position(1,3);
		I2C_LCD_Char_PrintString(array);					// 書込みデータを表示
	}else
	{														// EEPROM読んでみて先頭データが'@'じゃなかったら、初期値書込み
		array[0] = '@';
		array[1] = '0';
		array[2] = '0';
	
		Em_EEPROM_Write(EEPROM_START_ADDR, array, 3); 			// EEPROM 書込み (アドレス、書込みデータ、サイズ(byte))
		Em_EEPROM_Read(EEPROM_START_ADDR, read_EEPROM_data, 3);	// EEPROM 読込み
	}
	
	
//--------------------------------------------------------
	
    for(;;)
    {
        /* Place your application code here. */
		// 何にもしない (ぐるぐる)
    }
//--------------------------------------------------------
}

 

電源投入のたびに、数字が1づつ増えるソフトです。

結果動画。

 

上手くいっているようです。

 

加納 大裕(かのう だいゆう)

 

最新の投稿記事

加納製作所の商品開発

  • 薪ストーブ
  • メッキアノード
  • 粉体塗料
  • ミニトマト選別機

開発でお悩みの方、

まずは新たな発想を生む
私達の開発環境へお越しください。
知識・経験・ノウハウがそのお悩みを解決します。

開発のご相談