Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define F_CPU 6440000UL
- #include <avr/io.h>
- #include <avr/eeprom.h>
- #include <util/delay.h>
- #include <avr/interrupt.h>
- ////
- //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- //// ATtiny
- //// 25/45/85
- //// +----------+ (-)-------
- //// (RST)---+ PB5 Vcc +---(+)-------
- //// --[OWOWOD]---+ PB3 PB2 +---[TWI/SCL]-
- //// ---+ PB4 PB1 +---
- //// -------(-)---+ GND PB0 +---[TWI/SDA]-
- //// +----------+
- ////
- //#define DEBUG
- #define SCALE_VALUE 1000
- #define ONE 1
- #define ZERO 0
- #define BIT_WAITING 0
- #define BIT_STARTED 1
- #define BIT_END 2
- volatile uint8_t bitState = BIT_WAITING;
- volatile uint8_t ctr = 0;
- volatile uint8_t currentByte = 0;
- volatile uint8_t currentBit = 2;
- volatile uint16_t scaler = 0;
- #define IDENTIFIER_1 0x64
- #define IDENTIFIER_2 0x46
- #define IDENTIFIER_3 0x17
- #define IDLE 0
- #define IDENTIFIER_1_OK 1
- #define IDENTIFIER_2_OK 2
- #define IDENTIFIER_3_OK 3
- #define GOT_COMMAND_BYTE 4
- volatile int state = IDLE;
- ISR(INT0_vect)
- {
- switch(bitState) {
- case BIT_WAITING :
- bitState = BIT_STARTED;
- break;
- case BIT_STARTED :
- if (ctr<8 || ctr>22) {
- bitState = BIT_WAITING;
- } else {
- if (ctr<12) {
- currentBit = ZERO;
- bitState = BIT_END;
- } else if (ctr>18) {
- currentBit = ONE;
- bitState = BIT_END;
- } else {
- bitState = BIT_WAITING;
- }
- }
- break;
- case BIT_END :
- bitState = BIT_STARTED;
- break;
- }
- ctr = 0;
- }
- ISR(TIMER1_COMPA_vect)
- {
- #ifdef DEBUG
- scaler ++;
- //50usec * 10000 = 500msec
- if (scaler >= SCALE_VALUE) {
- ctr++;
- scaler = 0;
- }
- #else
- ctr++;
- #endif
- }
- void setupTimer1() {
- cli();
- // Clear registers
- TCNT1 = 0;
- TCCR1 = 0;
- // 50usec
- // 20000 Hz (6440000/((160+1)*2))
- OCR1C = 160;
- // interrupt COMPA
- OCR1A = OCR1C;
- // CTC
- TCCR1 |= (1 << CTC1);
- // Prescaler 2
- TCCR1 |= (1 << CS11);
- // Output Compare Match A Interrupt Enable
- TIMSK |= (1 << OCIE1A);
- sei();
- }
- void setExternalInterrupt() {
- cli();
- MCUCR = 2 << ISC00; // Set falling edge
- GIMSK = 1 << INT0; // Enable INT0
- sei();
- }
- void setRom(uint8_t kernalIndex) {
- PORTB = (PORTB & 0xF8) | ((kernalIndex & 0x04) <<1) | (kernalIndex & 0x03);
- }
- uint8_t getCurrentRom() {
- uint8_t val = eeprom_read_byte(0);
- return val;
- }
- void setCurrentRom() {
- uint8_t val = eeprom_read_byte(0);
- setRom(val);
- }
- void saveRom(uint8_t kernalIndex) {
- eeprom_write_byte(0, kernalIndex);
- }
- void saveAndSwitchRom(uint8_t kernalIndex) {
- setRom(kernalIndex);
- saveRom(kernalIndex);
- }
- void incrementRom() {
- uint8_t val = getCurrentRom();
- val = (val+1) & 0x07;
- saveAndSwitchRom(val);
- }
- int main(void) {
- //DDRB = (DDRB & 0xF8) | 0x07; //0,1,2 output. 3 input
- DDRB = (DDRB & 0xF0) | 0x0B; //0,1,3 output. 2 input
- uint8_t val = eeprom_read_byte(0);
- //PORTB = (PORTB & 0xF8) | (val & 0x07);
- PORTB = (PORTB & 0xF8) | ((val & 0x04) <<1) | (val & 0x03);
- setExternalInterrupt();
- setupTimer1();
- uint8_t bitMask = 1;
- uint8_t currentByte = 0;
- while(1) {
- // Leave this loop only if we got 1 bit of transfer, otherwise restart byte transfer
- while(bitState != BIT_END) {
- while (bitState == BIT_WAITING) {
- currentByte = 0;
- bitMask = 1;
- }
- }
- // A bit transfer has been finished
- if (currentBit == ONE) {
- currentByte = currentByte | bitMask;
- }
- bitMask<<=1;
- if (bitMask == 0) {
- switch(state) {
- case IDLE :
- if (currentByte == IDENTIFIER_1) state = IDENTIFIER_1_OK;
- break;
- case IDENTIFIER_1_OK :
- if (currentByte == IDENTIFIER_2) state = IDENTIFIER_2_OK;
- break;
- case IDENTIFIER_2_OK :
- if (currentByte == IDENTIFIER_3) state = IDENTIFIER_3_OK;
- break;
- case IDENTIFIER_3_OK :
- //We got command byte, lower 3 bits is the kernal index
- saveAndSwitchRom(currentByte & 0x07);
- state = IDLE;
- break;
- }
- bitMask = 1;
- currentByte = 0;
- }
- // Wait until next bit is transferred or whole process is restarted.
- while(bitState == BIT_END);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement