Skip to content

Instantly share code, notes, and snippets.

@ti-nspire
Last active January 16, 2020 07:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ti-nspire/0256dc258622b01a9c7d3e0e8c3c6848 to your computer and use it in GitHub Desktop.
Save ti-nspire/0256dc258622b01a9c7d3e0e8c3c6848 to your computer and use it in GitHub Desktop.
EEPROM25_256_library_for_ATmega328P
#include <avr/io.h>
#include "mySPI.h"
#include "EEPROM25_256.h"
uint8_t EEPROM25_256::isLastElement(uint16_t currentIndex, uint16_t numOfElements){
return (currentIndex == numOfElements - 1);
}
uint8_t EEPROM25_256::isfirstAddressOfPage(uint16_t address){
return address % BYTES_PER_PAGE == 0;
}
uint8_t EEPROM25_256::isLastAddressOfPage(uint16_t address){
return (address + 1) % BYTES_PER_PAGE == 0;
}
uint8_t EEPROM25_256::isWriting(){
return (readStatus() & WRITE_IN_PROGRESS);
}
void EEPROM25_256::preWRITE(uint16_t address){
writeEnable();
selectSlave(_port, _pin);
tradeByte(WRITE);
tradeWord(address);
}
void EEPROM25_256::postWRITE(){
deselectSlave(_port, _pin);
while(isWriting()){;}
}
void EEPROM25_256::preREAD(uint16_t address){
selectSlave(_port, _pin);
tradeByte(READ);
tradeWord(address);
}
uint8_t EEPROM25_256::postREAD(){
deselectSlave(_port, _pin);
return SPDR;
}
uint8_t EEPROM25_256::readStatus(){
selectSlave(_port, _pin);
tradeByte(RDSR);
tradeByte(0);
return postREAD();
}
uint8_t EEPROM25_256::writeStatus(uint8_t byte){
selectSlave(_port, _pin);
tradeByte(WRSR);
tradeByte(byte);
deselectSlave(_port, _pin);
}
void EEPROM25_256::writeEnable(){
selectSlave(_port, _pin);
tradeByte(WREN);
deselectSlave(_port, _pin);
}
void EEPROM25_256::writeDisable(){
selectSlave(_port, _pin);
tradeByte(WRDI);
deselectSlave(_port, _pin);
}
uint8_t EEPROM25_256::readByte(uint16_t address){
preREAD(address);
tradeByte(0);
return postREAD();
}
uint16_t EEPROM25_256::readWord(uint16_t address){
uint16_t word;
preREAD(address);
tradeByte(0); word = (SPDR << 8);
tradeByte(0); word |= SPDR;
deselectSlave(_port, _pin);
return word;
}
void EEPROM25_256::readBytes(uint16_t address, uint16_t n, uint8_t *buff){
preREAD(address);
for(uint16_t i=0; i<n; i++){
tradeByte(0);
buff[i] = SPDR;
}
deselectSlave(_port, _pin);
}
void EEPROM25_256::writeByte(uint16_t address, uint8_t byte){
preWRITE(address);
tradeByte(byte);
postWRITE();
}
void EEPROM25_256::writeWord(uint16_t address, uint16_t word){
if(isLastAddressOfPage(address)){
writeByte(address , (uint8_t)(word >> 8));
writeByte(address + 1, (uint8_t) word);
}else{
preWRITE(address);
tradeWord(word);
postWRITE();
}
}
void EEPROM25_256::writeBytes(uint16_t address, uint16_t n, uint8_t *buff){
uint16_t currentAddress = address;
preWRITE(currentAddress);
for(uint16_t i=0; i<n; i++){
if(isLastAddressOfPage(currentAddress)){ // ページ末尾のアドレスだったら、
tradeByte(buff[i]); // 当該1バイトを転送したあと、
postWRITE(); // 一旦書き込み処理を閉じて、
if(isLastElement(i, n)){break;} // 最後の要素であった場合はそのまま書き込みを終えるが、そうでなければ、
currentAddress++; // アドレスを1つ進めて、
preWRITE(currentAddress); // そのアドレスから書き込みを再開する。
}else{
tradeByte(buff[i]);
currentAddress++;
}
}
postWRITE();
}
void EEPROM25_256::writePage(uint16_t pageNum, uint16_t n, uint8_t *buff){
uint16_t address = pageNum * BYTES_PER_PAGE;
writeBytes(address, n, buff);
}
void EEPROM25_256::clearPage(uint16_t pageNum){
uint8_t buff[BYTES_PER_PAGE] = {};
writePage(pageNum, BYTES_PER_PAGE, buff);
}
void EEPROM25_256::clearAll(){
for(uint16_t pageNum=0; pageNum<PAGES_MAX; pageNum++){
clearPage(pageNum);
}
}
uint8_t EEPROM25_256::getPort(){return _port;}
uint8_t EEPROM25_256::getPin (){return _pin;}
// コンストラクター
EEPROM25_256::EEPROM25_256(uint8_t port, uint8_t pin){
_port = port;
_pin = pin;
setSPIpins(_port, _pin);
}
#include "mySPI.h"
#ifndef EEPROM25_256_H
#define EEPROM25_256_H
// 25LC256の容量
#define BYTES_PER_PAGE 64
#define BITS_MAX 262144 // = 256Kbits (= 2^18)
#define BYTES_MAX 32768 // = (BITS_MAX / 8bits)
#define PAGES_MAX 512 // = (BYTES_MAX / BYTES_PER_PAGE)
// 各種命令
const uint8_t READ = 3; // read命令
const uint8_t WRITE = 2; // write命令
const uint8_t WRDI = 4; // write無効化命令
const uint8_t WREN = 6; // write有効化命令
const uint8_t RDSR = 5; // ステータスレジスタからのread命令
const uint8_t WRSR = 1; // ステータスレジスタへのwrite命令
// ステータスレジスタにおけるビット位置
const uint8_t WRITE_IN_PROGRESS = 0b0001; // read only。
const uint8_t WRITE_ENABLE_LATCH = 0b0010; // read only。
const uint8_t BLOCK_PROTECT_0 = 0b0100; // read/write。upper 1/4 (6000h-7FFFh番地)をwrite protectする。
const uint8_t BLOCK_PROTECT_1 = 0b1000; // read/write。upper 1/2 (4000h-7FFFh番地)をwrite protectする。
const uint8_t BLOCK_PROTECT_ALL = 0b1100; // read/write。all (0000h-7FFFh番地)をwrite protectする。
class EEPROM25_256{
private:
uint8_t _port;
uint8_t _pin;
uint8_t isLastElement(uint16_t currentIndex, uint16_t numOfElements);
uint8_t isfirstAddressOfPage(uint16_t address);
uint8_t isLastAddressOfPage (uint16_t address);
uint8_t isWriting();
void preWRITE(uint16_t address); // メモリーへの書き込み前処理をおこなう。
void postWRITE(); // メモリーへの書き込みを終了する。
void preREAD(uint16_t address); // メモリーからの読み出し前処理をおこなう。
uint8_t postREAD(); // メモリーからの読み出しを終了してAVRのSPDR (SPI Data Register)の値を返す。
uint8_t readStatus(); // ステータスレジスタを読み出す。
uint8_t writeStatus(uint8_t byte); // ステータスレジスタに書き込む。
void writeEnable();
void writeDisable();
public:
uint8_t readByte (uint16_t address);
uint16_t readWord (uint16_t address);
void readBytes(uint16_t address, uint16_t n, uint8_t *buff);
void writeByte (uint16_t address, uint8_t byte);
void writeWord (uint16_t address, uint16_t word);
void writeBytes(uint16_t address, uint16_t n, uint8_t *buff);
void writePage (uint16_t pageNum, uint16_t n, uint8_t *buff);
void clearPage(uint16_t pageNum);
void clearAll();
uint8_t getPort();
uint8_t getPin ();
// コンストラクター
EEPROM25_256(uint8_t port, uint8_t pin);
};
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment