Add arduino skecthes
This commit is contained in:
281
arduino/ramcheck/ramcheck.ino
Normal file
281
arduino/ramcheck/ramcheck.ino
Normal file
@@ -0,0 +1,281 @@
|
||||
// See RAM chip pinout here: https://www.digchip.com/datasheets/parts/datasheet/922/MK4116-pdf.php
|
||||
|
||||
const PinName kAddressPins[] = {
|
||||
PA_7,
|
||||
PC_7,
|
||||
PB_6,
|
||||
PB_10,
|
||||
PA_8,
|
||||
PA_9,
|
||||
PB_4,
|
||||
};
|
||||
|
||||
const PinName kRasPin = PA_6;
|
||||
const PinName kWritePin = PB_9;
|
||||
const PinName kDinPin = PB_8;
|
||||
const PinName kDoutPin = PA_10;
|
||||
const PinName kCasPin = PB_3;
|
||||
|
||||
void Timer1Isr();
|
||||
|
||||
void setup() {
|
||||
pinMode(LED_BUILTIN, OUTPUT);
|
||||
Serial.begin(115200);
|
||||
|
||||
for (int i = 0; i < 7; i++) {
|
||||
pinMode(pinNametoDigitalPin(kAddressPins[i]), OUTPUT);
|
||||
}
|
||||
|
||||
pinMode(pinNametoDigitalPin(kRasPin), OUTPUT);
|
||||
pinMode(pinNametoDigitalPin(kCasPin), OUTPUT);
|
||||
pinMode(pinNametoDigitalPin(kWritePin), OUTPUT);
|
||||
pinMode(pinNametoDigitalPin(kDoutPin), INPUT);
|
||||
pinMode(pinNametoDigitalPin(kDinPin), OUTPUT);
|
||||
|
||||
digitalWrite(pinNametoDigitalPin(kRasPin), HIGH);
|
||||
digitalWrite(pinNametoDigitalPin(kCasPin), HIGH);
|
||||
digitalWrite(pinNametoDigitalPin(kWritePin), HIGH);
|
||||
|
||||
// Instantiate HardwareTimer object. Thanks to 'new' instanciation, HardwareTimer is not destructed when setup() function is finished.
|
||||
HardwareTimer *MyTim = new HardwareTimer(TIM1);
|
||||
|
||||
MyTim->setOverflow(1400, MICROSEC_FORMAT);
|
||||
MyTim->attachInterrupt(Timer1Isr);
|
||||
MyTim->resume();
|
||||
}
|
||||
|
||||
#define LV(x) ((x) ? HIGH : LOW)
|
||||
|
||||
void writeAddress(int address) {
|
||||
for (int i = 0; i < 7; i++) {
|
||||
digitalWriteFast(kAddressPins[i], LV(address & (1 << i)));
|
||||
}
|
||||
}
|
||||
|
||||
int read(int address) {
|
||||
int row = address >> 7;
|
||||
int col = address & 0x7f;
|
||||
|
||||
noInterrupts();
|
||||
|
||||
writeAddress(row);
|
||||
digitalWriteFast(kRasPin, LOW);
|
||||
writeAddress(col);
|
||||
digitalWriteFast(kCasPin, LOW);
|
||||
delayMicroseconds(1); // tCAS ish
|
||||
int out = digitalReadFast(kDoutPin);
|
||||
|
||||
digitalWriteFast(kCasPin, HIGH);
|
||||
digitalWriteFast(kRasPin, HIGH);
|
||||
|
||||
interrupts();
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
void write(int address, int data) {
|
||||
int row = address >> 7;
|
||||
int col = address & 0x7f;
|
||||
|
||||
noInterrupts();
|
||||
|
||||
writeAddress(row);
|
||||
digitalWriteFast(kRasPin, LOW);
|
||||
digitalWriteFast(kWritePin, LOW);
|
||||
digitalWriteFast(kDinPin, LV(data));
|
||||
writeAddress(col);
|
||||
digitalWriteFast(kCasPin, LOW);
|
||||
|
||||
for (int i = 0; i < 10; i++) asm volatile(""); // extra delay
|
||||
digitalWriteFast(kWritePin, HIGH);
|
||||
delayMicroseconds(1); // tCAS ish
|
||||
|
||||
digitalWriteFast(kCasPin, HIGH);
|
||||
digitalWriteFast(kRasPin, HIGH);
|
||||
|
||||
interrupts();
|
||||
}
|
||||
|
||||
void writepage(int address, const uint8_t data[16]) {
|
||||
int row = address >> 7;
|
||||
|
||||
noInterrupts();
|
||||
|
||||
writeAddress(row);
|
||||
digitalWriteFast(kRasPin, LOW);
|
||||
for (int col = 0; col < 128; col++) {
|
||||
int b = data[col >> 3] & (1 << (col % 8));
|
||||
digitalWriteFast(kDinPin, LV(b));
|
||||
digitalWriteFast(kWritePin, LOW);
|
||||
writeAddress(col);
|
||||
digitalWriteFast(kCasPin, LOW);
|
||||
|
||||
for (int i = 0; i < 10; i++) asm volatile(""); // extra delay
|
||||
digitalWriteFast(kWritePin, HIGH);
|
||||
delayMicroseconds(1); // tCAS ish
|
||||
|
||||
digitalWriteFast(kCasPin, HIGH);
|
||||
}
|
||||
digitalWriteFast(kRasPin, HIGH);
|
||||
|
||||
interrupts();
|
||||
}
|
||||
|
||||
void readpage(int address, uint8_t data[16]) {
|
||||
int row = address >> 7;
|
||||
|
||||
noInterrupts();
|
||||
|
||||
writeAddress(row);
|
||||
digitalWriteFast(kRasPin, LOW);
|
||||
for (int col = 0; col < 128; col++) {
|
||||
uint8_t& out = data[col >> 3];
|
||||
|
||||
writeAddress(col);
|
||||
digitalWriteFast(kCasPin, LOW);
|
||||
delayMicroseconds(1); // tCAS ish
|
||||
int b = digitalReadFast(kDoutPin);
|
||||
out >>= 1;
|
||||
if (b == HIGH) out |= 0x80;
|
||||
digitalWriteFast(kCasPin, HIGH);
|
||||
}
|
||||
digitalWriteFast(kRasPin, HIGH);
|
||||
|
||||
interrupts();
|
||||
}
|
||||
|
||||
int writeread(int address, int value) {
|
||||
write(address, value);
|
||||
return read(address);
|
||||
}
|
||||
|
||||
void refreshrow(int row) {
|
||||
writeAddress(row);
|
||||
digitalWriteFast(kRasPin, LOW);
|
||||
delayMicroseconds(1);
|
||||
digitalWriteFast(kRasPin, HIGH);
|
||||
}
|
||||
|
||||
void refreshall() {
|
||||
for (int row = 0; row < 128; row++) {
|
||||
refreshrow(row);
|
||||
}
|
||||
}
|
||||
|
||||
void Timer1Isr() {
|
||||
refreshall();
|
||||
}
|
||||
|
||||
int check01(int address) {
|
||||
if (writeread(address, 0) != 0) return -1;
|
||||
if (writeread(address, 1) != 1) return -2;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int checkrow(int row) {
|
||||
int row_address = row << 7;
|
||||
for (int i = 0; i < 128; i++) {
|
||||
int ret = check01(row_address + i);
|
||||
if (ret != 0) {
|
||||
Serial.printf("failure at 0x%04x: %d\n", row_address + i, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int address = 0x007f;
|
||||
int led_count = 0;
|
||||
int led = 0;
|
||||
char cmd = '\0';
|
||||
|
||||
const int kLedInterval = 1000000;
|
||||
|
||||
const uint8_t kSampleData[16] = {
|
||||
'b', 'l', 'a', 'r', 'g', ',', ' ', 'c',
|
||||
'e', 'c', 'i', ' ', 'e', 's', 't', '!',
|
||||
};
|
||||
|
||||
void dump16(int address) {
|
||||
address &= 0x3f80;
|
||||
uint8_t data[16];
|
||||
readpage(address, data);
|
||||
|
||||
Serial.printf("%04x:", address);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
Serial.printf(" %02x", data[i]);
|
||||
}
|
||||
Serial.print(" ");
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (data[i] < 33 || data[i] > 126) {
|
||||
Serial.print(".");
|
||||
} else {
|
||||
Serial.printf("%c", data[i]);
|
||||
}
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
void filltest() {
|
||||
uint8_t data[16];
|
||||
for (int row = 0; row < 128; row++) {
|
||||
snprintf(reinterpret_cast<char*>(data), 16, "testing row %03d", row);
|
||||
writepage(row << 7, data);
|
||||
}
|
||||
for (int row = 0; row < 128; row++) {
|
||||
readpage(row << 7, data);
|
||||
if (atoi(reinterpret_cast<char*>(&data[12])) != row) {
|
||||
Serial.printf("error in row %d\n", row);
|
||||
return;
|
||||
}
|
||||
}
|
||||
Serial.println("fill test ok.");
|
||||
}
|
||||
|
||||
void runcmd(char cmd) {
|
||||
uint8_t dat[16];
|
||||
|
||||
if (cmd == 'p') {
|
||||
writepage(address, kSampleData);
|
||||
dump16(address);
|
||||
} else if (cmd == '\0') {
|
||||
address += 128;
|
||||
dump16(address);
|
||||
} else if (cmd == '0') {
|
||||
address = 0;
|
||||
dump16(address);
|
||||
} else if (cmd == 'f') {
|
||||
filltest();
|
||||
} else if (cmd == 't') {
|
||||
for (int row = 0; row < 128; row++) {
|
||||
Serial.printf("row %d... ", row);
|
||||
int ret = checkrow(row);
|
||||
if (ret != 0) {
|
||||
break;
|
||||
}
|
||||
Serial.println("ok!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void loop() {
|
||||
// put your main code here, to run repeatedly:
|
||||
if (led_count > kLedInterval) {
|
||||
digitalWrite(LED_BUILTIN, LV(led % 2));
|
||||
led += 1;
|
||||
led_count = 0;
|
||||
}
|
||||
led_count += 1;
|
||||
|
||||
if (Serial.available()) {
|
||||
char c = Serial.read();
|
||||
if (c == '\n') {
|
||||
runcmd(cmd);
|
||||
cmd = '\0';
|
||||
} else {
|
||||
cmd = c;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user