SHARE
TWEET

SSD1306TEST

a guest Aug 20th, 2019 111 in 151 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <avr/io.h>
  2. #include <avr/pgmspace.h>
  3. #include <util/delay.h>
  4.  
  5. // PB0: D/nC
  6. // PB1: RES
  7. // PB2: CS
  8. // PB3: MOSI
  9. // PB5: CLK
  10.  
  11. #define SCRIPT_STEADY 1
  12. #define SCRIPT_BLINK 2
  13. #define SCRIPT_LEFT 3
  14. #define SCRIPT_RIGHT 4
  15. #define SCRIPT_CENTER 5
  16.  
  17. typedef struct {
  18.     uint8_t command;
  19.     uint8_t duration;
  20. } script_t;
  21.  
  22. const script_t script[] = {
  23.     {SCRIPT_STEADY, 10},
  24.     {SCRIPT_BLINK, 2},
  25.     {SCRIPT_STEADY, 5},
  26.     {SCRIPT_BLINK, 2},
  27.     {SCRIPT_STEADY, 10},
  28.     {SCRIPT_LEFT, 30},
  29.     {SCRIPT_RIGHT, 35},
  30.     {SCRIPT_CENTER, 10},
  31.     {0, 0}
  32. };
  33.  
  34. uint8_t framebuffer[72*5];
  35.  
  36. const uint8_t PROGMEM eye[4*18] = {
  37.     0xC0, 0x30, 0x08, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x04, 0x08, 0x30, 0xC0,
  38.     0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
  39.     0x07, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x10, 0x08, 0x07
  40. };
  41.  
  42. const uint8_t PROGMEM closed[1*18] = {
  43.     0x08, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x08
  44. };
  45.  
  46. const uint8_t PROGMEM nose[2*17] = {
  47.     0xE0, 0xF0, 0xF8, 0xF8, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xF0, 0xE0,
  48.     0x00, 0x01, 0x03, 0x0B, 0x19, 0x3C, 0x3F, 0x7F, 0x7F, 0x7F, 0x3F, 0x3C, 0x19, 0x0B, 0x03, 0x01, 0x00
  49. };
  50.  
  51. const uint8_t PROGMEM dot[1*4] = {
  52.     0x7E, 0xFF, 0xF9, 0x7E
  53. };
  54.  
  55. void spi_tx(const uint8_t v) {
  56.     PORTB &= ~_BV(PB2); // nCS low
  57.     SPDR = v;
  58.     while (!(SPSR & _BV(SPIF))) { };
  59.     PORTB |= _BV(PB2);  // nCS high
  60. }
  61.  
  62. void spi_tx_d(const uint8_t va, const uint8_t vb) {
  63.     PORTB &= ~_BV(PB2); // nCS low
  64.     SPDR = va;
  65.     while (!(SPSR & _BV(SPIF))) { };
  66.     SPDR = vb;
  67.     while (!(SPSR & _BV(SPIF))) { };
  68.     PORTB |= _BV(PB2);  // nCS high
  69. }
  70.  
  71. void spi_tx_t(const uint8_t va, const uint8_t vb, const uint8_t vc) {
  72.     PORTB &= ~_BV(PB2); // nCS low
  73.     SPDR = va;
  74.     while (!(SPSR & _BV(SPIF))) { };
  75.     SPDR = vb;
  76.     while (!(SPSR & _BV(SPIF))) { };
  77.     SPDR = vc;
  78.     while (!(SPSR & _BV(SPIF))) { };
  79.     PORTB |= _BV(PB2);  // nCS high
  80. }
  81.  
  82. void blit_xor(
  83.     const uint8_t px,
  84.     const uint8_t py,
  85.     const uint8_t w,
  86.     const uint8_t h,
  87.     const uint8_t * ptr,
  88.     const uint8_t hflip) {
  89.  
  90.     uint16_t i;
  91.     uint8_t x, y;
  92.  
  93.     PORTB |= _BV(PB0);  // D/C high
  94.  
  95.     i = hflip ? px + w - 1 + py * 72 : px + py * 72;
  96.     for (y = 0; y < h; y++) {
  97.         for (x = 0; x < w; x++) {
  98.             framebuffer[i] ^= pgm_read_byte(ptr++);
  99.             i = hflip ? i-1 : i+1;
  100.         }
  101.         i += hflip ? 72 + w : 72 - w;
  102.     }
  103. }
  104.  
  105. int main(void) {
  106.     uint16_t c;
  107.     uint8_t script_idx = 0, timer = 0;
  108.     uint8_t command;
  109.  
  110.     MCUSR = 0;
  111.     WDTCSR = _BV(WDCE) | _BV(WDE);
  112.     WDTCSR = 0;
  113.  
  114.     _delay_ms(100);
  115.  
  116.     DDRB =  0b00101111;
  117.     DDRC =  0b00000000;
  118.     DDRD =  0b00000000;
  119.  
  120.     PORTB = 0b00000100; // nCS high, D/C low
  121.  
  122.     SPCR = 0b01010001;  // fclk/16
  123.  
  124.     PORTB &= ~_BV(PB1); // RES low
  125.     _delay_ms(20);
  126.     PORTB |= _BV(PB1);  // RES high
  127.     _delay_ms(20);
  128.  
  129.     PORTB &= ~_BV(PB0); // D/C low
  130.  
  131.     spi_tx(0xAE);           // Display OFF
  132.     spi_tx_d(0xA8, 39);     // Mux ratio
  133.     spi_tx_d(0xD3, 0);      // Display offset
  134.     spi_tx(0x40);           // Display start line
  135.     spi_tx_d(0x8D, 0x14);   // Internal charge pump
  136.     spi_tx_d(0x81, 0xD0);   // Contrast
  137.     spi_tx_d(0xD9, 0xF1);
  138.     spi_tx_d(0xDB, 0x40);
  139.     spi_tx_d(0xD5, 0x80);
  140.     spi_tx_d(0x20, 0x00);   // Horizontal addressing mode
  141.     spi_tx(0xA4);           // Normal RAM display
  142.     spi_tx(0xA6);           // No inversion
  143.     spi_tx(0x2E);           // Disable scroll
  144.     spi_tx(0xA1);           // Column remap
  145.     spi_tx(0xC8);           // Line remap
  146.     spi_tx_d(0xDA, 0x12);
  147.     spi_tx(0xAF);           // Display ON
  148.  
  149.     uint8_t anim_x = 0;
  150.  
  151.     for (;;) {
  152.         if (!timer) {
  153.             command = script[script_idx].command;
  154.             if (command == 0) {
  155.                 script_idx = 0;
  156.                 command = script[script_idx].command;
  157.             }
  158.             timer = script[script_idx].duration;
  159.             script_idx++;
  160.         } else {
  161.             timer--;
  162.         }
  163.  
  164.         // Clear
  165.         for (c = 0; c < 72*5; c++) {
  166.             framebuffer[c] = 0xFF;
  167.         }
  168.  
  169.         if (command == SCRIPT_STEADY) {
  170.             anim_x = 5;
  171.             blit_xor(5, 0, 18, 3, eye, 0);
  172.             blit_xor(5+(5>>1)+4, 1, 4, 1, dot, 0);
  173.  
  174.             blit_xor(5+70-18-10, 0, 18, 3, eye, 1);
  175.             blit_xor(5+70-18-10+(5>>1)+4, 1, 4, 1, dot, 0);
  176.  
  177.             blit_xor(16+(5<<1), 3, 17, 2, nose, 1);
  178.         } else if (command == SCRIPT_BLINK) {
  179.             blit_xor(5, 1, 18, 1, closed, 0);
  180.             blit_xor(5+70-18-10, 1, 18, 1, closed, 1);
  181.             blit_xor(16+(5<<1), 3, 17, 2, nose, 1);
  182.         } else if (command == SCRIPT_LEFT) {
  183.             blit_xor(anim_x, 0, 18, 3, eye, 0);
  184.             blit_xor(anim_x+(anim_x>>1)+4, 1, 4, 1, dot, 0);
  185.  
  186.             blit_xor(anim_x+70-18-10, 0, 18, 3, eye, 1);
  187.             blit_xor(anim_x+70-18-10+(anim_x>>1)+4, 1, 4, 1, dot, 0);
  188.  
  189.             blit_xor(16+(anim_x<<1), 3, 17, 2, nose, 1);
  190.  
  191.             if (anim_x > 0) anim_x--;
  192.         } else if (command == SCRIPT_RIGHT) {
  193.             blit_xor(anim_x, 0, 18, 3, eye, 0);
  194.             blit_xor(anim_x+(anim_x>>1)+4, 1, 4, 1, dot, 0);
  195.  
  196.             blit_xor(anim_x+70-18-10, 0, 18, 3, eye, 1);
  197.             blit_xor(anim_x+70-18-10+(anim_x>>1)+4, 1, 4, 1, dot, 0);
  198.  
  199.             blit_xor(16+(anim_x<<1), 3, 17, 2, nose, 1);
  200.  
  201.             if (anim_x < 10) anim_x++;
  202.         } else if (command == SCRIPT_CENTER) {
  203.             blit_xor(anim_x, 0, 18, 3, eye, 0);
  204.             blit_xor(anim_x+(anim_x>>1)+4, 1, 4, 1, dot, 0);
  205.  
  206.             blit_xor(anim_x+70-18-10, 0, 18, 3, eye, 1);
  207.             blit_xor(anim_x+70-18-10+(anim_x>>1)+4, 1, 4, 1, dot, 0);
  208.  
  209.             blit_xor(16+(anim_x<<1), 3, 17, 2, nose, 1);
  210.  
  211.             if (anim_x > 5) anim_x--;
  212.             if (anim_x < 5) anim_x++;
  213.         }
  214.        
  215.         // Copy framebuffer
  216.         PORTB &= ~_BV(PB0); // D/C low
  217.         spi_tx_t(0x21, 28, 28+72-1);
  218.         spi_tx_t(0x22, 0, 4);
  219.         PORTB |= _BV(PB0);  // D/C high
  220.         PORTB &= ~_BV(PB2); // nCS low
  221.         for (c = 0; c < 5*72; c++) {
  222.             SPDR = framebuffer[c];
  223.             while (!(SPSR & _BV(SPIF))) { };
  224.         }
  225.         PORTB |= _BV(PB2);  // nCS high
  226.  
  227.         _delay_ms(20);
  228.     }
  229. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top