SPI 기반 M95M04 Serial Flash 읽기/쓰기

앞선 글에서는 SPI 인터페이스의 기본 구조와 장치별 확장 클래스 설계 방식을 다루었습니다.
이번 글에서는 이를 실제 예제로 확장하여, M95M04 Serial Flash 장치를 C++ 클래스로 구현하고, SPI를 통해 데이터를 읽고 쓰는 과정을 설명합니다.


M95M04 Serial Flash의 특징

M95M04는 STMicroelectronics에서 제공하는 4Mbit(512KB) 용량의 SPI 기반 시리얼 플래시 메모리입니다.

  • 용량: 4Mbit (512KB)
  • SPI 인터페이스: 최대 20MHz 동작
  • 페이지 크기: 256바이트 단위 쓰기
  • 명령어 세트: Read(0x03), Write(0x02), Write Enable(0x06), Read Status Register(0x05) 등
  • 보존 특성: 20년 이상 데이터 유지, 1,000,000회 이상 쓰기/지우기 보장
  • 보호 기능: WP(Write Protect), HOLD 핀 제공

이러한 특징 덕분에 펌웨어 저장, 로그 기록, 환경 설정 보존 등에 적합합니다.


클래스 설계

M95M04SPI 클래스는 BaseSPI를 상속받아 작성되었으며, M95M04 전용 프로토콜을 구현합니다

주요 멤버 변수

  • pSPI : 사용할 SPI 인터페이스 포인터
  • nCS : Chip Select 핀
  • nWP : Write Protect 핀
  • nHOLD : Hold 핀
  • CTask : 디버깅 로그 출력을 위한 콘솔 태스크

주요 멤버 함수

  • WriteEnable() / WriteDisable() : 쓰기 가능 상태 전환
  • WriteByte(), ReadByte() : 단일 바이트 송수신
  • sendCommand(), sendAddress() : 명령어 및 주소 전송
  • WriteData(addr, buf, len) : 특정 주소에 데이터 쓰기
  • ReadData(addr, buf, len) : 특정 주소에서 데이터 읽기
  • EEPROM_Test(addr, size) : 읽기/쓰기/검증을 포함한 테스트 루틴

코드 예제

1. 객체 선언 및 초기화

#include "M95M04SPI.h"

M95M04SPI eepSpi;

...
void InitSerialFlash(void);
...
/*
 *
 */
void InitSerialFlash(void)
{
#if defined(_SPI_EEP_)
	  eepSpi = M95M04SPI(SPI6, EEP_nCS_1, &CTask);
	  eepSpi.setWPPin(EEP_nWP_1);
	  eepSpi.setHOLDPin(EEP_nHOLD_1);
#endif
}

2. 데이터 쓰기

this->pEEPSPI->WriteData(this->pEEPos->FlashingSize.getPosition(), tmpBuf, this->pEEPos->FlashingSize.getLength());

3. 데이터 읽기

this->pEEPSPI->ReadData(this->pEEPos->bDebug.getPosition(), (uint8_t *)&(this->pSysinfo->General.bDebug), this->pEEPos->bDebug.getLength());

4. 테스트 함수 활용

EEPROM_Test()는 지정한 주소에 데이터를 쓰고, 다시 읽어오는 과정을 자동으로 수행하며 로그를 출력합니다.

void AT24CTask::EEPROMEraseAll(void)
{
	int i, j;

	uint8_t data[32];
	for(i=0; i<32; i++)
		data[i] = 0xFF;

	for(i=0; i<16*1024; i++)
	{
	      this->pEEPSPI->WriteData(32*i, (uint8_t *)&i, 1);
	}

	for(i=0; i<16*1024; i++)
	{
		this->pEEPSPI->ReadData(32*i, data, 32);
		for(j=0; j<32; j++)
			this->CTask->PRINTF((char *)"%02X ", data[j]);
		this->CTask->PRINTF((char *)"\r\n");
		this->CTask->flushTxBuf();
	}

}

트러블슈팅

  1. 쓰기 불가
    • 원인: Write Enable(WREN) 명령어 누락
    • 해결: WriteData() 내부에서 WREN 처리 확인
  2. 데이터 읽기 불일치
    • 원인: 주소 전송 에러(3바이트 주소 처리 문제)
    • 해결: sendAddress() 함수 구현 확인 (24비트 주소 전송)
  3. SPI 응답 없음
    • 원인: CS 핀 제어 오류
    • 해결: csEnable()/csDisable() 함수 확인

마치며

이번 글에서는 BaseSPI를 상속받아 구현한 M95M04SPI 클래스를 통해 실제 SPI Serial Flash 장치를 다뤘습니다.

핵심 포인트:

  • M95M04는 512KB 용량의 SPI 플래시로, 명령어 기반 접근 필요
  • M95M04SPI 클래스에서 읽기/쓰기/테스트 루틴까지 구현
  • 실제 프로젝트에서는 EEPROM_Test() 같은 루틴을 활용하여 데이터 무결성을 쉽게 검증 가능

0개의 댓글

답글 남기기

Avatar placeholder

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

ko_KRKorean