Files
SyncHome/trunk/Arduino/libraries/ram/ram.c
2023-03-17 11:59:21 +00:00

123 lines
2.7 KiB
C

/*
* Arduino RAM library : interface with 30-pin SIMM RAM modules
*
* Copyright (C) 2014 Rafael Ignacio Zurita <rafaelignacio.zurita@gmail.com>
*
* This ram library is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* You should have received a copy of the GNU Library General Public
* License along with this software (check COPYING); if not, write to the Free
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <Arduino.h>
#include <avr/wdt.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/boot.h>
#include <math.h>
#include <stdarg.h>
#include <stdio.h>
void __vector_13() {
int cycles = 4096;
do{
PORTC = PORTC & B11111110; /* CAS = 0 */
PORTC = PORTC & B11111011; /* RAS = 0 */
PORTC = PORTC | B00000001; /* CAS = 1 */
PORTC = PORTC | B00000100; /* RAS = 1 */
}while(--cycles);
}
unsigned char ram_read(unsigned char row, unsigned char col) {
unsigned char buf;
cli();
PORTB = row;
PORTC = PORTC & B11111011; /* RAS = 0 */
PORTB = col;
PORTC = PORTC & B11111110; /* CAS = 0 */
PORTC = PORTC | B00000100; /* RAS = 1 */
PORTC = PORTC | B00000001; /* CAS = 1 */
buf = PIND;
sei();
return buf;
}
void ram_write(unsigned char row, unsigned char col, unsigned char val) {
cli();
DDRD = B11111111; /* DATA output */
PORTB = row;
PORTC = PORTC & B11111011; /* RAS = 0 */
PORTD = val;
PORTC = PORTC & B11111101; /* WE = 0 */
PORTB = col;
PORTC = PORTC & B11111110; /* CAS = 0 */
PORTC = PORTC | B00000001; /* CAS = 1 */
PORTC = PORTC | B00000010; /* WE = 1 */
//asm("nop");
PORTC = PORTC | B00000100; /* RAS = 1 */
DDRD = B00000000; /* DATA input */
sei();
}
void ram_init() {
cli();
asm("cli");
/* timer for refresh */
TCCR1A = 0x00;
TCCR1B = 0x0B; //reset on match with OCR1A, clk= clk/64 -> overflow every 13.1 ms (faster than 4x as fast as we need to refresh)
OCR1A = 0x493E; //match every 60ms
TIMSK1 = 2; //interrupt when we match
/* conf RAM port */
DDRB |= 0x3F; //out: A0..A7
PORTB |= 0xC0; //lo: A0..A7 - portb 0x25 -
DDRC |= 0x04; //out: nRAS
DDRC |= 0x02; //out: nWE
DDRC |= 0x01; //out: nCAS
DDRC |= 0x08; //out: led
PORTC |= 0x04; //hi: nRAS - 0x28 - pinc 0x06
PORTC |= 0x01; //hi: nCAS
PORTC |= 0x02; //hi: nWE
DDRD &= 0x00; //in: D0..D7
PORTD = 0x00; //no pullups: data portd 0x2b - pind 0x09
unsigned char t;
/* init SIMM RAM */
_delay_us(200); //as per init instructions
for(t = 0; t < 8; t++) __vector_13();
sei(); //enable refresh
}