Eliminate arduino_sdef.h, add Group data addresses, other cleanup.

This commit is contained in:
Andrew Makousky 2020-09-04 16:55:26 -05:00
parent 1f8d0f8163
commit fd916b3d5c
2 changed files with 82 additions and 108 deletions

View File

@ -3,7 +3,17 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/sleep.h> #include <avr/sleep.h>
#include "arduino_sdef.h" /********************************************************************/
// Simplified Arduino.h definitions.
typedef bool boolean;
typedef uint8_t byte;
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit))
// END simplified Arduino.h definitions.
/********************************************************************/
/**************************************** /****************************************
* * * *
@ -21,7 +31,7 @@
****************************************/ ****************************************/
/********************************************* /*********************************************
* ATMEL ATTINY85 / ARDUINO * * ATMEL ATTINY85 *
* * * *
* +-\/-+ * * +-\/-+ *
* Ain0 (D 5) PB5 1| |8 Vcc * * Ain0 (D 5) PB5 1| |8 Vcc *
@ -32,25 +42,31 @@
*********************************************/ *********************************************/
const int ONE_SEC_PIN = 5; // A 1Hz square wave on PB5 const int ONE_SEC_PIN = 5; // A 1Hz square wave on PB5
const int RTC_ENABLE_PIN = 0; // Active low chip enable on PB0 const int RTC_ENABLE_PIN = 0; // Active low chip enable on PB0
const int SERIAL_DATA_PIN = 1; // Bi-directional serial data line on PB1 const int SERIAL_DATA_PIN = 1; // Bi-directional serial data line on PB1
const int SERIAL_CLOCK_PIN = 2; // Serial clock input on PB2 const int SERIAL_CLOCK_PIN = 2; // Serial clock input on PB2
#if NoXPRAM #if NoXPRAM
// Models earlier than the Plus had 20 bytes of PRAM // Models earlier than the Plus had 20 bytes of PRAM
const int PRAM_SIZE = 20; const int PRAM_SIZE = 20;
const int group1Base = 0x00;
const int group2Base = 0x10;
#else #else
// Mac Plus used the xPRAM chip with 256 bytes // Mac Plus used the xPRAM chip with 256 bytes
const int PRAM_SIZE = 256; const int PRAM_SIZE = 256;
const int group1Base = 0x10;
const int group2Base = 0x08;
#endif #endif
volatile boolean lastSerClock = 0; volatile boolean lastSerClock = 0;
volatile byte serialBitNum = 0; volatile byte serialBitNum = 0;
volatile byte address = 0; volatile byte address = 0;
volatile byte xaddr = 0; // xPRAM extended address byte
volatile byte serialData = 0; volatile byte serialData = 0;
enum SerialStateType { SERIAL_DISABLED, RECEIVING_COMMAND, enum SerialStateType { SERIAL_DISABLED, RECEIVING_COMMAND,
SENDING_DATA, RECEIVING_DATA }; SENDING_DATA, RECEIVING_DATA,
RECEIVING_XCMD_ADDR, RECEIVING_XCMD_DATA };
volatile SerialStateType serialState = SERIAL_DISABLED; volatile SerialStateType serialState = SERIAL_DISABLED;
// Number of seconds since midnight, January 1, 1904. Clock is // Number of seconds since midnight, January 1, 1904. Clock is
@ -59,13 +75,23 @@ volatile SerialStateType serialState = SERIAL_DISABLED;
volatile unsigned long seconds = 60 * 60 * 24 * (365 * 4 + 1) * 20; volatile unsigned long seconds = 60 * 60 * 24 * (365 * 4 + 1) * 20;
volatile byte pram[PRAM_SIZE] = {}; // PRAM initialized as zeroed data volatile byte pram[PRAM_SIZE] = {}; // PRAM initialized as zeroed data
void setup() { #define shiftReadPB(output, bitNum, portBit) \
noInterrupts(); // Disable interrupts while we set things up bitWrite(output,bitNum, (PINB&_BV(portBit)) ? 1 : 0)
pinModePB(ONE_SEC_PIN, OUTPUT); // The 1Hz square wave (used, I think, for interrupts elsewhere in the system) void setup() {
pinModePB(RTC_ENABLE_PIN, INPUT_PULLUP); // The processor pulls this pin low when it wants access cli(); // Disable interrupts while we set things up
pinModePB(SERIAL_CLOCK_PIN, INPUT_PULLUP); // The serial clock is driven by the processor
pinModePB(SERIAL_DATA_PIN, INPUT_PULLUP); // We'll need to switch this to output when sending data // OUTPUT: The 1Hz square wave (used for interrupts elsewhere in the system)
DDRB |= ONE_SEC_PIN;
// INPUT_PULLUP: The processor pulls this pin low when it wants access
DDRB &= ~RTC_ENABLE_PIN;
PORTB |= RTC_ENABLE_PIN;
// INPUT_PULLUP: The serial clock is driven by the processor
DDRB &= ~SERIAL_CLOCK_PIN;
PORTB |= SERIAL_CLOCK_PIN;
// INPUT_PULLUP: We'll need to switch this to output when sending data
DDRB &= ~SERIAL_DATA_PIN;
PORTB |= SERIAL_DATA_PIN;
wdt_disable(); // Disable watchdog wdt_disable(); // Disable watchdog
bitSet(ACSR,ACD); // Disable Analog Comparator, don't need it, saves power bitSet(ACSR,ACD); // Disable Analog Comparator, don't need it, saves power
@ -83,17 +109,20 @@ void setup() {
TCNT0 = 0; // Clear the counter TCNT0 = 0; // Clear the counter
bitClear(GTCCR,TSM); // Turns timers back on bitClear(GTCCR,TSM); // Turns timers back on
interrupts(); //We're done setting up, enable those interrupts again sei(); //We're done setting up, enable those interrupts again
} }
void clearState() { void clearState() {
// Return the pin to input mode, set pullup resistor // Return the pin to input mode, set pullup resistor
pinModePB(SERIAL_DATA_PIN, INPUT_PULLUP); cli();
serialState = SERIAL_DISABLED; DDRB &= ~SERIAL_DATA_PIN;
lastSerClock = 0; PORTB |= SERIAL_DATA_PIN;
serialBitNum = 0; sei();
address = 0; serialState = SERIAL_DISABLED;
serialData = 0; lastSerClock = 0;
serialBitNum = 0;
address = 0;
serialData = 0;
} }
/* /*
@ -114,7 +143,7 @@ void halfSecondInterrupt() {
void handleRTCEnableInterrupt() { void handleRTCEnableInterrupt() {
if(!(PINB&(1<<RTC_ENABLE_PIN))){ // Simulates a falling interrupt if(!(PINB&(1<<RTC_ENABLE_PIN))){ // Simulates a falling interrupt
serialState = RECEIVING_COMMAND; serialState = RECEIVING_COMMAND;
// enableRTC = true; // enableRTC = true;
} }
} }
@ -134,13 +163,17 @@ void loop() {
// TODO FIXME: We need to implement an artificial delay between // TODO FIXME: We need to implement an artificial delay between
// the clock's rising edge and the update of the data line output // the clock's rising edge and the update of the data line output
// because of a bug in the ROM. Is 10 microseconds a good wait // because of a bug in the ROM. Is 10 microseconds a good wait
// time? // time? Or, here's what we can do. We keep the old value for as
// long as the clock is high, and we only load the new value
// immediately once the clock goes low, i.e. that's how we handle
// the trailing edge event.
if(serClockRising) { if(serClockRising) {
switch(serialState) { switch(serialState) {
case RECEIVING_COMMAND: case RECEIVING_COMMAND:
bitWrite(address,7-serialBitNum,digitalReadPB(SERIAL_DATA_PIN)); shiftReadPB(address,7-serialBitNum,SERIAL_DATA_PIN);
serialBitNum++; serialBitNum++;
if(serialBitNum > 7) { if(serialBitNum > 7) {
boolean writeRequest = address&(1<<7); // the MSB determines if it's a write request or not boolean writeRequest = address&(1<<7); // the MSB determines if it's a write request or not
@ -157,19 +190,22 @@ void loop() {
} }
serialState = SENDING_DATA; serialState = SENDING_DATA;
serialBitNum = 0; serialBitNum = 0;
pinModePB(SERIAL_DATA_PIN, OUTPUT); // Set the pin to output mode // Set the pin to output mode
cli();
DDRB |= SERIAL_DATA_PIN;
sei();
} }
} }
break; break;
case RECEIVING_DATA: case RECEIVING_DATA:
bitWrite(serialData,7-serialBitNum,digitalReadPB(SERIAL_DATA_PIN)); shiftReadPB(serialData,7-serialBitNum,SERIAL_DATA_PIN);
serialBitNum++; serialBitNum++;
if(serialBitNum > 7) { if(serialBitNum > 7) {
if(address < 4) { if(address < 4) {
noInterrupts(); // Don't update the seconds counter while we're updating it, bad stuff could happen cli(); // Don't update the seconds counter while we're updating it, bad stuff could happen
seconds = (seconds & ~(((long)0xff)<<address)) | (((long)serialData)<<address); seconds = (seconds & ~(((long)0xff)<<address)) | (((long)serialData)<<address);
interrupts(); sei();
} else { } else {
pram[address] = serialData; pram[address] = serialData;
} }
@ -178,11 +214,27 @@ void loop() {
break; break;
case SENDING_DATA: case SENDING_DATA:
digitalWritePB(SERIAL_DATA_PIN,bitRead(serialData,7-serialBitNum)); {
uint8_t bit = _BV(SERIAL_DATA_PIN);
uint8_t val = bitRead(serialData,7-serialBitNum);
cli();
if (val == 0)
PORTB &= ~bit;
else
PORTB |= bit;
sei();
}
serialBitNum++; serialBitNum++;
if(serialBitNum > 7) { if(serialBitNum > 7) {
clearState(); clearState();
} }
break;
case RECEIVING_XCMD_ADDR:
break;
case RECEIVING_XCMD_DATA:
break;
} }
} }
} }
@ -192,11 +244,11 @@ void loop() {
* Actually attach the interrupt functions * Actually attach the interrupt functions
*/ */
ISR(PCINT0_vect) { ISR(PCINT0_vect) {
handleRTCEnableInterrupt(); handleRTCEnableInterrupt();
} }
ISR(TIMER0_OVF) { ISR(TIMER0_OVF) {
halfSecondInterrupt(); halfSecondInterrupt();
} }
// Arduino main function. // Arduino main function.

View File

@ -1,78 +0,0 @@
#ifndef ARDUINO_SDEF_H
#define ARDUINO_SDEF_H
/********************************************************************/
// Simplified Arduino.h definitions.
typedef bool boolean;
typedef uint8_t byte;
#define HIGH 0x1
#define LOW 0x0
#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2
#define interrupts() sei()
#define noInterrupts() cli()
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) ((bitvalue) ? bitSet(value, bit) : bitClear(value, bit))
// END simplified Arduino.h definitions.
/********************************************************************/
// Simplified wiring_digital.c definitions.
// Only suitable for single source code file projects.
void pinModePB(uint8_t portbit, uint8_t mode)
{
uint8_t bit = _BV(portbit);
if (mode == INPUT) {
uint8_t oldSREG = SREG;
cli();
DDRB &= ~bit;
PORTB &= ~bit;
SREG = oldSREG;
} else if (mode == INPUT_PULLUP) {
uint8_t oldSREG = SREG;
cli();
DDRB &= ~bit;
PORTB |= bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
DDRB |= bit;
SREG = oldSREG;
}
}
void digitalWritePB(uint8_t portbit, uint8_t val)
{
uint8_t bit = _BV(portbit);
uint8_t oldSREG = SREG;
cli();
if (val == LOW) {
PORTB &= ~bit;
} else {
PORTB |= bit;
}
SREG = oldSREG;
}
int digitalReadPB(uint8_t portbit)
{
uint8_t bit = _BV(portbit);
if (PINB & bit) return HIGH;
return LOW;
}
// END simplified wiring_digital.c definitions.
#endif /* not ARDUINO_SDEF_H */