Guest User

Blinkofant avr-gcc Template

a guest
Jan 6th, 2013
264
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /******************************************************************************
  2. * BLINKOFANT template controller for the Arduino
  3. * https://metalab.at/wiki/Blinkofant
  4. * https://metalab.at/wiki/Datei:Ledmatrix_chained.png
  5. *******************************************************************************
  6. * ATmega328p datasheet:
  7. *   Table 18-5. Relationship Between SCK and the Oscillator Frequency
  8. *   SPI2X   SPR1    SPR0    SCK Frequency
  9. *   0   0   0   fosc/4
  10. *   0   0   1   fosc/16
  11. *   0   1   0   fosc/64
  12. *   0   1   1   fosc/128  <-- We need to be really sluggish
  13. *   1   0   0   fosc/2
  14. *   1   0   1   fosc/8
  15. *   1   1   0   fosc/32
  16. *   1   1   1   fosc/64
  17. *******************************************************************************
  18. * Data and clock lines must be PB3 and PB5 respectively, if we want to use
  19. * hardware SPI.
  20. ******************************************************************************/
  21. #include <avr/io.h>
  22. #include <util/delay.h>
  23.  
  24. #define PANEL_DDR   DDRB
  25. #define PANEL_PORT  PORTB
  26. #define PANEL_CLEAR 2   // Arduino-pin 10
  27. #define PANEL_MOSI  PB3 // Arduino-pin 11
  28. #define PANEL_SCK   PB5 // Arduino-pin 13
  29.  
  30. #define PANELS      1
  31. #define PANEL_DATA_SIZE (10*PANELS)
  32.  
  33. uint8_t panel_data[PANEL_DATA_SIZE];
  34.  
  35. void init()
  36. {
  37.     PANEL_DDR  |=   (1 << PANEL_MOSI) | (1 << PANEL_SCK) | (1 << PANEL_CLEAR);
  38.     PANEL_PORT &=~ ((1 << PANEL_MOSI) | (1 << PANEL_SCK) | (1 << PANEL_CLEAR));
  39.  
  40.     SPCR =
  41.         (1 << SPE)  |   // Enable SPI
  42.         (1 << MSTR) |   // We are the master
  43.         (1 << DORD) |   // LSB first
  44.         (1 << SPR1) |   // Clock divider...
  45.         (1 << SPR0) ;   // ...F_CPU / 128
  46.  
  47.     // Not necessary, is disabled by default:
  48.     // SPSR &=~ (1 << SPI2X);   // Disable double speed mode
  49. }
  50.  
  51. inline void screen_off()
  52. {
  53.     PANEL_PORT &=~ (1 << PANEL_CLEAR);
  54. }
  55.  
  56. inline void screen_on()
  57. {
  58.     PANEL_PORT |=  (1 << PANEL_CLEAR);
  59. }
  60.  
  61. void set_pixel( uint8_t x, uint8_t y, uint8_t value )
  62. {
  63.     uint8_t index   = (x*10) + (y+1);   // y+1 because first bit controls blinking
  64.     uint8_t byte_nr = index >> 3;       // Division by 8
  65.     uint8_t bit_nr  = index & 0b00000111;   // Remainder of division
  66.  
  67.     if (value) {
  68.         panel_data[byte_nr] |=  (1 << bit_nr);
  69.     }
  70.     else {
  71.         panel_data[byte_nr] &=~ (1 << bit_nr);
  72.     }
  73. }
  74.  
  75. void shift_pixel_data()
  76. {
  77.     uint8_t i;
  78.  
  79.     screen_off();
  80.  
  81.     for ( i = 0 ; i < PANEL_DATA_SIZE ; i++ ) {
  82.         SPDR = panel_data[i];
  83.         while (!(SPSR & (1 << SPIF))) /* wait */;
  84.     }
  85.  
  86.     screen_on();
  87. }
  88.  
  89. int main(void)
  90. {
  91.     uint8_t x, y;
  92.     uint8_t state = 0;
  93.  
  94.     init();
  95.  
  96.     while(1) {
  97.         state++;
  98.  
  99.         for( x = 0 ; x < 8*PANELS ; x++ ) {
  100.             for( y = 0 ; y < 9 ; y++ ) {
  101.                 //set_pixel(x, y, ((x>>1) + (y>>1) + state) & 1);
  102.                 float dx = x-4;
  103.                 float dy = y-4;
  104.                 float d = sqrt(dx*dx+dy*dy);
  105.                 int ds = 3*d+state;
  106.                 set_pixel( x, y, ((ds % 20) <= 10) );
  107.             }
  108.         }
  109.  
  110.         shift_pixel_data();
  111.  
  112.         _delay_ms(5);
  113.     }
  114. }
RAW Paste Data