Advertisement
Guest User

Untitled

a guest
Apr 8th, 2018
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.15 KB | None | 0 0
  1. #define F_CPU 6440000UL
  2.  
  3. #include <avr/io.h>
  4. #include <avr/eeprom.h>
  5. #include <util/delay.h>
  6. #include <avr/interrupt.h>
  7.  
  8. ////
  9. //// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  10. ////                ATtiny
  11. ////               25/45/85
  12. ////              +----------+   (-)-------
  13. ////      (RST)---+ PB5  Vcc +---(+)-------
  14. //// --[OWOWOD]---+ PB3  PB2 +---[TWI/SCL]-
  15. ////           ---+ PB4  PB1 +---
  16. //// -------(-)---+ GND  PB0 +---[TWI/SDA]-
  17. ////              +----------+
  18. ////
  19.  
  20. //#define DEBUG
  21. #define SCALE_VALUE 1000
  22. #define ONE 1
  23. #define ZERO 0
  24.  
  25. #define BIT_WAITING 0
  26. #define BIT_STARTED 1
  27. #define BIT_END 2
  28. volatile uint8_t bitState = BIT_WAITING;
  29.  
  30. volatile uint8_t ctr = 0;
  31. volatile uint8_t currentByte = 0;
  32. volatile uint8_t currentBit = 2;
  33. volatile uint16_t scaler = 0;
  34.  
  35. #define IDENTIFIER_1 0x64
  36. #define IDENTIFIER_2 0x46
  37. #define IDENTIFIER_3 0x17
  38.  
  39. #define IDLE 0
  40. #define IDENTIFIER_1_OK 1
  41. #define IDENTIFIER_2_OK 2
  42. #define IDENTIFIER_3_OK 3
  43. #define GOT_COMMAND_BYTE 4
  44. volatile int state = IDLE;
  45.  
  46. ISR(INT0_vect)
  47. {
  48.     switch(bitState) {
  49.         case BIT_WAITING :
  50.             bitState = BIT_STARTED;
  51.             break; 
  52.         case BIT_STARTED :
  53.             if (ctr<8 || ctr>22) {
  54.                 bitState = BIT_WAITING;
  55.             } else {
  56.                 if (ctr<12) {
  57.                     currentBit = ZERO;
  58.                     bitState = BIT_END;
  59.                 } else if (ctr>18) {
  60.                     currentBit = ONE;
  61.                     bitState = BIT_END;
  62.                 } else {
  63.                     bitState = BIT_WAITING;
  64.                 }
  65.                            
  66.             }      
  67.             break;
  68.         case BIT_END :
  69.             bitState = BIT_STARTED;
  70.             break;     
  71.     }
  72.    
  73.     ctr = 0;
  74. }
  75.  
  76. ISR(TIMER1_COMPA_vect)
  77. {
  78.     #ifdef DEBUG
  79.         scaler ++;
  80.         //50usec * 10000 = 500msec
  81.         if (scaler >= SCALE_VALUE) {
  82.             ctr++;
  83.             scaler = 0;
  84.         }
  85.     #else
  86.         ctr++;
  87.     #endif
  88. }
  89.  
  90. void setupTimer1() {
  91.     cli();
  92.     // Clear registers
  93.     TCNT1 = 0;
  94.     TCCR1 = 0;
  95.  
  96.     // 50usec
  97.     // 20000 Hz (6440000/((160+1)*2))
  98.     OCR1C = 160;
  99.     // interrupt COMPA
  100.     OCR1A = OCR1C;
  101.     // CTC
  102.     TCCR1 |= (1 << CTC1);
  103.     // Prescaler 2
  104.     TCCR1 |= (1 << CS11);
  105.     // Output Compare Match A Interrupt Enable
  106.     TIMSK |= (1 << OCIE1A);
  107.     sei();
  108. }
  109.  
  110. void setExternalInterrupt() {
  111.   cli();
  112.   MCUCR = 2 << ISC00; // Set falling edge
  113.   GIMSK = 1 << INT0;  // Enable INT0
  114.   sei();
  115. }
  116.  
  117.  
  118. void setRom(uint8_t kernalIndex) {
  119.     PORTB = (PORTB & 0xF8) | ((kernalIndex & 0x04) <<1) | (kernalIndex & 0x03);
  120. }
  121.  
  122. uint8_t getCurrentRom() {
  123.     uint8_t val = eeprom_read_byte(0);
  124.     return val;
  125. }
  126.  
  127.  
  128. void setCurrentRom() {
  129.     uint8_t val = eeprom_read_byte(0);
  130.     setRom(val);
  131. }
  132.  
  133. void saveRom(uint8_t kernalIndex) {
  134.     eeprom_write_byte(0, kernalIndex);
  135. }
  136.  
  137. void saveAndSwitchRom(uint8_t kernalIndex) {
  138.     setRom(kernalIndex);
  139.     saveRom(kernalIndex);
  140. }
  141.  
  142.  
  143.  
  144. void incrementRom() {
  145.     uint8_t val = getCurrentRom();
  146.     val = (val+1) & 0x07;
  147.     saveAndSwitchRom(val);
  148. }
  149.  
  150. int main(void) {
  151.     //DDRB = (DDRB & 0xF8) | 0x07; //0,1,2 output. 3 input
  152.     DDRB = (DDRB & 0xF0) | 0x0B; //0,1,3 output. 2 input
  153.     uint8_t val = eeprom_read_byte(0);
  154.     //PORTB = (PORTB & 0xF8) | (val & 0x07);   
  155.     PORTB = (PORTB & 0xF8) | ((val & 0x04) <<1) | (val & 0x03);
  156.        
  157.     setExternalInterrupt();
  158.     setupTimer1();
  159.    
  160.     uint8_t bitMask = 1;
  161.     uint8_t currentByte = 0;
  162.     while(1) {
  163.         // Leave this loop only if we got 1 bit of transfer, otherwise restart byte transfer
  164.         while(bitState != BIT_END) {
  165.             while (bitState == BIT_WAITING) {
  166.                 currentByte = 0;
  167.                 bitMask = 1;               
  168.             }
  169.         }
  170.        
  171.         // A bit transfer has been finished
  172.                
  173.         if (currentBit == ONE) {
  174.             currentByte = currentByte | bitMask;
  175.         }
  176.        
  177.         bitMask<<=1;
  178.        
  179.         if (bitMask == 0) {
  180.             switch(state) {
  181.                 case IDLE :
  182.                 if (currentByte == IDENTIFIER_1) state = IDENTIFIER_1_OK;
  183.                 break;
  184.                
  185.                 case IDENTIFIER_1_OK :
  186.                 if (currentByte == IDENTIFIER_2) state = IDENTIFIER_2_OK;
  187.                 break;
  188.  
  189.                 case IDENTIFIER_2_OK :
  190.                 if (currentByte == IDENTIFIER_3) state = IDENTIFIER_3_OK;
  191.                 break;
  192.                
  193.                 case IDENTIFIER_3_OK :
  194.                     //We got command byte, lower 3 bits is the kernal index
  195.                     saveAndSwitchRom(currentByte & 0x07);
  196.                     state = IDLE;                  
  197.                 break;               
  198.             }
  199.            
  200.             bitMask = 1;
  201.             currentByte = 0;
  202.            
  203.         }
  204.        
  205.         // Wait until next bit is transferred or whole process is restarted.
  206.         while(bitState == BIT_END);
  207.     }
  208.  
  209. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement