#include //MemCARDuino.ino互換 #define IDENTIFIER "MCDINO" #define VERSION 0x04 //コマンド #define GETID 0xA0 //IDENTIFIERを返す #define GETVER 0xA1 //VERSIONを返す #define MCREAD 0xA2 //メモリ読み出し #define MCWRITE 0xA3 //メモリ書き込み #define ERROR 0xE0 //エラーコード //GND 4pin //VCC 5pin #define DATA 14 //1pin #define CMD 16 //2pin #define ATT 10 //6pin #define CLK 15 //7pin #define ACK 3 //8pin volatile int state = HIGH; bool CompatibleMode = false; byte ReadByte = 0; SPISettings mySPISettings = SPISettings(250000, LSBFIRST, SPI_MODE3); void setup() { pinMode(DATA, INPUT_PULLUP); pinMode(CMD, OUTPUT); pinMode(ATT, OUTPUT); pinMode(CLK, OUTPUT); pinMode(ACK, INPUT_PULLUP); Serial.begin(38400); digitalWrite(CMD, LOW); digitalWrite(ATT, HIGH); digitalWrite(CLK, HIGH); attachInterrupt(digitalPinToInterrupt(ACK), Acknowledge, FALLING); SPI.begin(); } void Acknowledge() { state = !state; } void loop() { if(Serial.available() > 0) { ReadByte = Serial.read(); switch (ReadByte) { default: Serial.write(ERROR); break; case GETID: Serial.write(IDENTIFIER); break; case GETVER: Serial.write(VERSION); break; case MCREAD: SPI.beginTransaction(mySPISettings); delay(5); ReadMemory(Serial.read() | Serial.read() << 8); SPI.endTransaction(); break; case MCWRITE: SPI.beginTransaction(mySPISettings); delay(5); WriteMemory(Serial.read() | Serial.read() << 8); SPI.endTransaction(); break; } } } byte SendCommand(byte command, int Delay) { byte data; if(!CompatibleMode) Delay = 3000; state = HIGH; data = SPI.transfer(command); while(state == HIGH) { Delay--; delayMicroseconds(1); if(Delay == 0) { CompatibleMode = true; break; } } return data; } void ReadMemory(unsigned int address) { byte msb = address & 0xFF; byte lsb = (address >> 8) & 0xFF; CompatibleMode = false; digitalWrite(ATT, LOW); SendCommand(0x81, 500); //メモリカード通信(0x81〜0x84 → スロットA〜D) SendCommand(0x52, 500); //リードコマンド"R" SendCommand(0x00, 500); //メモリカードID1 SendCommand(0x00, 500); //メモリカードID2 SendCommand(msb, 500); //アドレス指定(MSB) SendCommand(lsb, 500); //アドレス指定(LSB) SendCommand(0x00, 2800); //ACK1 SendCommand(0x00, 2800); //ACK2 SendCommand(0x00, 2800); //アドレス確認(MSB) SendCommand(0x00, 2800); //アドレス確認(LSB) //メモリデータ送信 for (int i = 0; i < 128; i++) { Serial.write(SendCommand(0x00, 150)); } Serial.write(SendCommand(0x00, 500)); //チェックサム(MSB xor LSB xor Data) Serial.write(SendCommand(0x00, 500)); //終了ステータス(0x47"G"ならOK) digitalWrite(ATT, HIGH); } void WriteMemory(unsigned int address) { int DelayCounter = 30; byte buff[128]; byte data; byte msb = address & 0xFF; byte lsb = (address >> 8) & 0xFF; CompatibleMode = false; //メモリデータ受信 for (int i = 0; i < 128; i++) { while(!Serial.available()) delay(1); buff[i] = Serial.read(); } digitalWrite(ATT, LOW); SendCommand(0x81, 300); //メモリカード通信(0x81〜0x84 → スロットA〜D) SendCommand(0x57, 300); //ライトコマンド"W" SendCommand(0x00, 300); //メモリカードID1 SendCommand(0x00, 300); //メモリカードID2 SendCommand(msb, 300); //アドレス指定(MSB) SendCommand(lsb, 300); //アドレス指定(LSB) //メモリ書き込み for (int i = 0; i < 128; i++) { SendCommand(buff[i], 150); } //チェックサム受信 while(!Serial.available()) delay(1); SendCommand(Serial.read(), 200); //チェックサム(MSB xor LSB xor Data) SendCommand(0x00, 200); //ACK1 SendCommand(0x00, 200); //ACK2 data = SendCommand(0x00, 200); Serial.write(data); //終了ステータス(0x47"G"ならOK) digitalWrite(ATT, HIGH); }