Guest User

Arduboy2.cpp Smart XE version (with display invert sym key)

a guest
Jul 31st, 2018
702
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.73 KB | None | 0 0
  1. /**
  2.  * @file Arduboy2Core.cpp
  3.  * \brief
  4.  * The Arduboy2Core class for Arduboy hardware initilization and control.
  5.  * SMART XE Version - now includes power off button
  6.  * Also includes display inversion on the SYM key
  7.  */
  8.  
  9. #include "Arduboy2Core.h"
  10. #define powerPin 20
  11. bool invertDisplay = false;
  12. void Arduboy2Core::lcdBootProgram()
  13. {
  14.     sendLCDCommand(0x01); // Soft reset
  15.     delay(5);
  16.    
  17.     //OK
  18.     sendLCDCommand(0x011); // Sleep Out
  19.     sendLCDCommand(0x028); // Display OFF
  20.     delay(25); // Delay 50 ms
  21.  
  22.     //OK
  23.     sendLCDCommand(0xC0);
  24.     sendLCDData(0xF0);
  25.     sendLCDData(0x00);// Vop = F0h
  26.  
  27.     //OK
  28.     sendLCDCommand(0xC3);
  29.     sendLCDData(0x004); // BIAS = 1/14
  30.  
  31.     //OK
  32.     sendLCDCommand(0xC4);
  33.     sendLCDData(0x005); // Booster = x8
  34.  
  35.     //OK
  36.     sendLCDCommand(0xD0);
  37.     sendLCDData(0x01D); // Enable Analog Circuit
  38.  
  39.     //OK
  40.     sendLCDCommand(0xB3);
  41.     sendLCDData(0x00); // Set FOSC divider
  42.  
  43.     //OK
  44.     sendLCDCommand(0xB5);
  45.     sendLCDData(0x8B); // N-Line = 0
  46.  
  47.     //OK Select mode
  48.     sendLCDCommand(0x39); // 0x39 Monochrome mode. 0x38 - gray Mode
  49.  
  50.     //OK
  51.     sendLCDCommand(0x3A); // Enable DDRAM Interface
  52.     sendLCDData(0x02); // monochrome and 4-level
  53.  
  54.     //OK
  55.     sendLCDCommand(0x36); // Scan Direction Setting
  56.     sendLCDData(0x00); //
  57.  
  58.     //OK
  59.     sendLCDCommand(0xB0); // Duty Setting
  60.     sendLCDData(0x9F); //0x87
  61.  
  62.  
  63.     sendLCDCommand(0xF1); // Frame rate monochrome
  64.     sendLCDData(0x07);
  65.     sendLCDData(0x07);
  66.     sendLCDData(0x07);
  67.     sendLCDData(0x07);
  68.  
  69.  
  70. if (invertDisplay)sendLCDCommand(0x21); // Display inversion off
  71.             else
  72.       sendLCDCommand(0x20); // Display inversion off
  73.  
  74.     sendLCDCommand(0x2A); // Column Address Setting
  75.     sendLCDData(0x00); // SEG0 -> SEG240
  76.     sendLCDData(0x00); // SEG8*3=24
  77.     sendLCDData(0x00);
  78.     sendLCDData(0x7f); // SEG128*3=384  seg x(dont use)  seg n  seg n
  79.  
  80.     sendLCDCommand(0x2B); // Row Address Setting
  81.     sendLCDData(0x00); // COM0 -> COM160
  82.     sendLCDData(0x00); //
  83.     sendLCDData(0x00); //
  84.     sendLCDData(0x87); //HEIGHT-1
  85.  
  86.     sendLCDCommand(0x29); // Display ON
  87.     /* end of sequence */
  88.    
  89. }
  90.  
  91.  
  92. Arduboy2Core::Arduboy2Core() { }
  93.  
  94. void Arduboy2Core::boot()
  95. {
  96.   #ifdef ARDUBOY_SET_CPU_8MHZ
  97.   // ARDUBOY_SET_CPU_8MHZ will be set by the IDE using boards.txt
  98.   setCPUSpeed8MHz();
  99.   #endif
  100.  
  101.   // Select the ADC input here so a delay isn't required in initRandomSeed()
  102.   ADMUX = RAND_SEED_IN_ADMUX;
  103.  
  104.   bootPins();
  105.   bootSPI();
  106.   bootOLED();
  107.   bootPowerSaving();
  108. }
  109.  
  110. #ifdef ARDUBOY_SET_CPU_8MHZ
  111. // If we're compiling for 8MHz we need to slow the CPU down because the
  112. // hardware clock on the Arduboy is 16MHz.
  113. // We also need to readjust the PLL prescaler because the Arduino USB code
  114. // likely will have incorrectly set it for an 8MHz hardware clock.
  115. void Arduboy2Core::setCPUSpeed8MHz()
  116. {
  117.   uint8_t oldSREG = SREG;
  118.   cli();                // suspend interrupts
  119.   PLLCSR = _BV(PINDIV); // dissable the PLL and set prescale for 16MHz)
  120.   CLKPR = _BV(CLKPCE);  // allow reprogramming clock
  121.   CLKPR = 1;            // set clock divisor to 2 (0b0001)
  122.   PLLCSR = _BV(PLLE) | _BV(PINDIV); // enable the PLL (with 16MHz prescale)
  123.   SREG = oldSREG;       // restore interrupts
  124. }
  125. #endif
  126.  
  127. // Pins are set to the proper modes and levels for the specific hardware.
  128. // This routine must be modified if any pins are moved to a different port
  129. void Arduboy2Core::bootPins()
  130. {
  131.    
  132. #ifdef ARDUBOY_10
  133.   #define PWR_BIT PORTD2
  134.   // Port B INPUT_PULLUP or HIGH
  135.   //PORTB |= _BV(RED_LED_BIT) | _BV(GREEN_LED_BIT) | _BV(BLUE_LED_BIT) |
  136.   //         _BV(B_BUTTON_BIT);
  137.   // Port B INPUT or LOW (none)
  138.   // Port B inputs
  139.   DDRB &= ~(_BV(B_BUTTON_BIT) | _BV(SPI_MISO_BIT));
  140.   // Port B outputs
  141.   DDRB |= _BV(SPI_MOSI_BIT) | _BV(SPI_SCK_BIT) | _BV(SPI_SS_BIT);
  142.  
  143.   // Port C
  144.   // Speaker: Not set here. Controlled by audio class
  145.  
  146.   // Port D INPUT_PULLUP or HIGH
  147.   PORTD |= (_BV(CS_BIT)|_BV(PWR_BIT));
  148.   // Port D INPUT or LOW
  149.   PORTD &= ~(_BV(RST_BIT));
  150.   // Port D inputs (none)
  151.   DDRD |= ~(_BV(PWR_BIT));
  152.   // Port D outputs
  153.   DDRD &= _BV(RST_BIT) | _BV(CS_BIT) | _BV(DC_BIT);
  154.   //pinMode(powerPin,INPUT_PULLUP);//power switch
  155.  
  156.   // Port E INPUT_PULLUP or HIGH
  157.   //PORTE |= _BV(A_BUTTON_BIT);
  158.   // Port E INPUT or LOW (none)
  159.   // Port E inputs
  160.   //DDRE &= ~(_BV(A_BUTTON_BIT));
  161.   // Port E outputs (none)
  162.  
  163.   // Port F INPUT_PULLUP or HIGH
  164.   //PORTF |= _BV(LEFT_BUTTON_BIT) | _BV(RIGHT_BUTTON_BIT) |
  165.    //        _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT);
  166.   // Port F INPUT or LOW
  167.   //PORTF &= ~(_BV(RAND_SEED_IN_BIT));
  168.   // Port F inputs
  169.   //DDRF &= ~(_BV(LEFT_BUTTON_BIT) | _BV(RIGHT_BUTTON_BIT) |
  170.    //         _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT) |
  171.    //         _BV(RAND_SEED_IN_BIT));
  172.   // Port F outputs (none)
  173. pinMode(8,INPUT_PULLUP);
  174. pinMode(9,INPUT_PULLUP);
  175. pinMode(35,INPUT_PULLUP);
  176. pinMode(34,INPUT_PULLUP);
  177. #elif defined(AB_DEVKIT)
  178.  
  179.   // Port B INPUT_PULLUP or HIGH
  180.   PORTB |= _BV(LEFT_BUTTON_BIT) | _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT) |
  181.            _BV(BLUE_LED_BIT);
  182.   // Port B INPUT or LOW (none)
  183.   // Port B inputs
  184.   DDRB &= ~(_BV(LEFT_BUTTON_BIT) | _BV(UP_BUTTON_BIT) | _BV(DOWN_BUTTON_BIT) |
  185.             _BV(SPI_MISO_BIT));
  186.   // Port B outputs
  187.   DDRB |= _BV(SPI_MOSI_BIT) | _BV(SPI_SCK_BIT) | _BV(SPI_SS_BIT) |
  188.           _BV(BLUE_LED_BIT);
  189.  
  190.   // Port C INPUT_PULLUP or HIGH
  191.   PORTC |= _BV(RIGHT_BUTTON_BIT);
  192.   // Port C INPUT or LOW (none)
  193.   // Port C inputs
  194.   DDRC &= ~(_BV(RIGHT_BUTTON_BIT));
  195.   // Port C outputs (none)
  196.  
  197.   // Port D INPUT_PULLUP or HIGH
  198.   PORTD |= _BV(CS_BIT);
  199.   // Port D INPUT or LOW
  200.   PORTD &= ~(_BV(RST_BIT));
  201.   // Port D inputs (none)
  202.   // Port D outputs
  203.   DDRD |= _BV(RST_BIT) | _BV(CS_BIT) | _BV(DC_BIT);
  204.  
  205.   // Port E (none)
  206.  
  207.   // Port F INPUT_PULLUP or HIGH
  208.   PORTF |= _BV(A_BUTTON_BIT) | _BV(B_BUTTON_BIT);
  209.   // Port F INPUT or LOW
  210.   PORTF &= ~(_BV(RAND_SEED_IN_BIT));
  211.   // Port F inputs
  212.   DDRF &= ~(_BV(A_BUTTON_BIT) | _BV(B_BUTTON_BIT) | _BV(RAND_SEED_IN_BIT));
  213.   // Port F outputs (none)
  214.   // Speaker: Not set here. Controlled by audio class
  215.  
  216. #endif
  217.  
  218. }
  219.  
  220. void Arduboy2Core::bootOLED()
  221. {
  222.   // reset the display
  223.   delayShort(5); // reset pin should be low here. let it stay low a while
  224.   bitSet(RST_PORT, RST_BIT); // set high to come out of reset
  225.   delayShort(5); // wait a while
  226.  
  227.   // select the display (permanently, since nothing else is using SPI)
  228.   bitClear(CS_PORT, CS_BIT);
  229.  
  230.   // run our customized boot-up command sequence against the
  231.   // OLED to initialize it properly for Arduboy
  232.  
  233.   lcdBootProgram();
  234.   blank();
  235. }
  236.  
  237. void Arduboy2Core::LCDDataMode()
  238. {
  239.   bitSet(DC_PORT, DC_BIT);
  240. }
  241.  
  242. void Arduboy2Core::LCDCommandMode()
  243. {
  244.   bitClear(DC_PORT, DC_BIT);
  245. }
  246.  
  247. // Initialize the SPI interface for the display
  248. void Arduboy2Core::bootSPI()
  249. {
  250. // master, mode 0, MSB first, CPU clock / 2 (8MHz)
  251.   SPCR = _BV(SPE) | _BV(MSTR);
  252.   SPSR = _BV(SPI2X);
  253. }
  254.  
  255. // Write to the SPI bus (MOSI pin)
  256. void Arduboy2Core::SPItransfer(uint8_t data)
  257. {
  258.   SPDR = data;
  259.   /*
  260.    * The following NOP introduces a small delay that can prevent the wait
  261.    * loop form iterating when running at the maximum speed. This gives
  262.    * about 10% more speed, even if it seems counter-intuitive. At lower
  263.    * speeds it is unnoticed.
  264.    */
  265.   asm volatile("nop");
  266.   while (!(SPSR & _BV(SPIF))) { } // wait
  267. }
  268.  
  269. void Arduboy2Core::safeMode()
  270. {
  271.   if (buttonsState() == UP_BUTTON)
  272.   {
  273.     digitalWriteRGB(RED_LED, RGB_ON);
  274.  
  275. #ifndef ARDUBOY_CORE // for Arduboy core timer 0 should remain enabled
  276.     // prevent the bootloader magic number from being overwritten by timer 0
  277.     // when a timer variable overlaps the magic number location
  278.     power_timer0_disable();
  279. #endif
  280.  
  281.     while (true) { }
  282.   }
  283. }
  284.  
  285.  
  286. /* Power Management */
  287.  
  288. void Arduboy2Core::idle()
  289. {
  290.   SMCR = _BV(SE); // select idle mode and enable sleeping
  291.   sleep_cpu();
  292.   SMCR = 0; // disable sleeping
  293. }
  294.  
  295. void Arduboy2Core::bootPowerSaving()
  296. {
  297.   // disable Two Wire Interface (I2C) and the ADC
  298.   // All other bits will be written with 0 so will be enabled
  299.   PRR0 = _BV(PRTWI) | _BV(PRADC);
  300.   // disable USART1
  301.   PRR1 |= _BV(PRUSART1);
  302. }
  303.  
  304. // Shut down the display
  305. void Arduboy2Core::displayOff()
  306. {
  307.     SPItransfer(0x28);
  308.     SPItransfer(0x10);
  309.     delayShort(250);
  310.     bitClear(RST_PORT, RST_BIT);
  311.    
  312. }
  313.  
  314.  
  315. void Arduboy2Core::SleepNow()
  316. {
  317.     displayOff();
  318.     attachInterrupt(4,wakeUpNow, LOW);
  319.     delay(100);
  320.     set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  321.   sleep_enable();  
  322.   sleep_mode();
  323.    
  324.   sleep_disable();
  325.   displayOn();
  326.  
  327.  
  328.   //power on beep
  329.     int pp = 0;
  330.     for(pp=0;pp<100;pp++)
  331.   {
  332.   digitalWrite(3,HIGH);
  333.   delay(1);
  334.   digitalWrite(3,LOW);
  335.   delay(1);
  336.   }  
  337.  
  338.  
  339. }
  340.  
  341. void Arduboy2Core::wakeUpNow()
  342. {
  343.       detachInterrupt(4);
  344. }
  345.  
  346. // Restart the display after a displayOff()
  347. void Arduboy2Core::displayOn()
  348. {
  349.   bootOLED();
  350. }
  351.  
  352. uint8_t Arduboy2Core::width() { return WIDTH; }
  353.  
  354. uint8_t Arduboy2Core::height() { return HEIGHT; }
  355.  
  356.  
  357. /* Drawing */
  358.  
  359. void Arduboy2Core::paint8Pixels(uint8_t pixels)
  360. {
  361. /*
  362.   SPItransfer(pixels);
  363. */
  364. }
  365.  
  366. void Arduboy2Core::paintScreen(const uint8_t *image)
  367. {
  368.     /*
  369.   for (int i = 0; i < (HEIGHT*WIDTH)/8; i++)
  370.   {
  371.     SPItransfer(pgm_read_byte(image + i));
  372.   }
  373.   */
  374. }
  375.  
  376. // paint from a memory buffer, this should be FAST as it's likely what
  377. // will be used by any buffer based subclass
  378. //
  379. // The following assembly code runs "open loop". It relies on instruction
  380. // execution times to allow time for each byte of data to be clocked out.
  381. // It is specifically tuned for a 16MHz CPU clock and SPI clocking at 8MHz.
  382. #if 0
  383. void Arduboy2Core::paintScreen(uint8_t image[], bool clear)
  384. {
  385.   uint16_t count;
  386.  
  387.   asm volatile (
  388.     "   ldi   %A[count], %[len_lsb]               \n\t" //for (len = WIDTH * HEIGHT / 8)
  389.     "   ldi   %B[count], %[len_msb]               \n\t"
  390.     "1: ld    __tmp_reg__, %a[ptr]      ;2        \n\t" //tmp = *(image)
  391.     "   out   %[spdr], __tmp_reg__      ;1        \n\t" //SPDR = tmp
  392.     "   cpse  %[clear], __zero_reg__    ;1/2      \n\t" //if (clear) tmp = 0;
  393.     "   mov   __tmp_reg__, __zero_reg__ ;1        \n\t"
  394.     "2: sbiw  %A[count], 1              ;2        \n\t" //len --
  395.     "   sbrc  %A[count], 0              ;1/2      \n\t" //loop twice for cheap delay
  396.     "   rjmp  2b                        ;2        \n\t"
  397.     "   st    %a[ptr]+, __tmp_reg__     ;2        \n\t" //*(image++) = tmp
  398.     "   brne  1b                        ;1/2 :18  \n\t" //len > 0
  399.     "   in    __tmp_reg__, %[spsr]                \n\t" //read SPSR to clear SPIF
  400.     : [ptr]     "+&e" (image),
  401.       [count]   "=&w" (count)
  402.     : [spdr]    "I"   (_SFR_IO_ADDR(SPDR)),
  403.       [spsr]    "I"   (_SFR_IO_ADDR(SPSR)),
  404.       [len_msb] "M"   (WIDTH * (HEIGHT / 8 * 2) >> 8),   // 8: pixels per byte
  405.       [len_lsb] "M"   (WIDTH * (HEIGHT / 8 * 2) & 0xFF), // 2: for delay loop multiplier
  406.       [clear]   "r"   (clear)
  407.   );
  408. }
  409. #endif
  410.  
  411. // For reference, this is the "closed loop" C++ version of paintScreen()
  412. // used prior to the above version.
  413. void Arduboy2Core::paintScreen(uint8_t image[], bool clear)
  414. {
  415.     if (clear)
  416.         {
  417.             blank();
  418.             return;
  419.         }
  420.    
  421.     int y = 0;
  422.     int i=0;
  423.   int z = 0;
  424.   uint8_t byte;
  425.   int x = 0;
  426.   int j = 0;
  427.     while (y < (HEIGHT*2) )
  428.   {
  429.     uint8_t bit =0x1;
  430.     for (z=0; z<8; z++)
  431.     {
  432.       sendLCDCommand(0x2B); // Row Address Setting (height)
  433.       sendLCDData(0x00); // COM0 -> COM160
  434.       sendLCDData(0x00+y); //
  435.       sendLCDData(0x00); //
  436.       sendLCDData(0x87); //HEIGHT-1
  437.       sendLCDCommand(0x2C);
  438.      
  439.       //double up the lines
  440.       int count = 0;
  441.       while (count < 2)
  442.       {
  443.    
  444.       for (x=0; x<(WIDTH); x++)
  445.       {
  446.       uint8_t a = image[i+x];
  447.         byte = 0;
  448.         if (a & bit) byte = 0xFF;
  449.         SPDR = byte;
  450.         while (!(SPSR & _BV(SPIF))) { }
  451.       }
  452.       count++;
  453.     }
  454.      
  455.      
  456. /*    //1 pixel per pixel  
  457.       for (x=0; x<(WIDTH); x+=3)
  458.       {
  459.       uint8_t a = image[i+x];
  460.       uint8_t b = image[i+1+x];
  461.       uint8_t c = image[i+2+x];
  462.         byte = 0;
  463.         if (a & bit)          // if bit 23
  464.             byte = byte | 0b11000000;  //set pixel 1
  465.         if (b & bit)          // if bit 22
  466.             byte = byte | 0b00011000;  //set pixel 2
  467.         if (c & bit)          // if bit 22
  468.             byte = byte | 0b00000011;  //set pixel 3
  469.        
  470.         SPDR = byte;
  471.         while (!(SPSR & _BV(SPIF))) { }
  472.       }
  473.  */    
  474.      
  475.     bit <<=1;
  476.     y+=2;
  477.     }      
  478.     i += WIDTH;
  479.   }
  480.   while (!(SPSR & _BV(SPIF))) { } // wait for the last byte to be sent
  481. }
  482.  
  483.  
  484. void Arduboy2Core::blank()
  485. {
  486.       sendLCDCommand(0x2B); // Row Address Setting (height)
  487.       sendLCDData(0x00); // COM0 -> COM160
  488.       sendLCDData(0x00); //
  489.       sendLCDData(0x00); //
  490.       sendLCDData(0x87); //HEIGHT-1
  491.       sendLCDCommand(0x2C);
  492.   for (int i = 0; i < (0x80*0x88); i++)
  493.   {
  494.     SPItransfer(0x00);
  495.   }
  496. }
  497.  
  498. void Arduboy2Core::sendLCDCommand(uint8_t command)
  499. {
  500.   LCDCommandMode();
  501.   SPItransfer(command);
  502.   LCDDataMode();
  503. }
  504.  
  505. void Arduboy2Core::sendLCDData(uint8_t data)
  506. {
  507.   SPItransfer(data);
  508. }
  509.  
  510. // invert the display or set to normal
  511. // when inverted, a pixel set to 0 will be on
  512. void Arduboy2Core::invert(bool inverse)
  513. {
  514.   sendLCDCommand(inverse ? OLED_PIXELS_INVERTED : OLED_PIXELS_NORMAL);
  515. }
  516.  
  517. // turn all display pixels on, ignoring buffer contents
  518. // or set to normal buffer display
  519. void Arduboy2Core::allPixelsOn(bool on)
  520. {
  521.   sendLCDCommand(on ? OLED_ALL_PIXELS_ON : OLED_PIXELS_FROM_RAM);
  522. }
  523.  
  524. // flip the display vertically or set to normal
  525. void Arduboy2Core::flipVertical(bool flipped)
  526. {
  527.   sendLCDCommand(flipped ? OLED_VERTICAL_FLIPPED : OLED_VERTICAL_NORMAL);
  528. }
  529.  
  530. // flip the display horizontally or set to normal
  531. void Arduboy2Core::flipHorizontal(bool flipped)
  532. {
  533.   sendLCDCommand(flipped ? OLED_HORIZ_FLIPPED : OLED_HORIZ_NORMAL);
  534. }
  535.  
  536. /* RGB LED */
  537.  
  538. void Arduboy2Core::setRGBled(uint8_t red, uint8_t green, uint8_t blue)
  539. {
  540.  
  541. }
  542.  
  543. void Arduboy2Core::setRGBled(uint8_t color, uint8_t val)
  544. {
  545.    
  546. }
  547.  
  548. void Arduboy2Core::freeRGBled()
  549. {
  550.  
  551. }
  552.  
  553. void Arduboy2Core::digitalWriteRGB(uint8_t red, uint8_t green, uint8_t blue)
  554. {
  555.  
  556. }
  557.  
  558. void Arduboy2Core::digitalWriteRGB(uint8_t color, uint8_t val)
  559. {
  560. }
  561.  
  562. /* Buttons */
  563.  
  564. uint8_t Arduboy2Core::buttonsState()
  565. {
  566. uint8_t buttons;
  567. //char rowPins[4] = {35,34,8,9};
  568. //35 = portB(7)
  569. //34 = portB(6)
  570. //8 = portB (5)
  571. //9 = portB (4)
  572. char columnPins[4]={23,19,22,4};
  573.  
  574. buttons =0;
  575. int c=0;
  576. for (c=0; c<4; c++) {
  577.         pinMode(columnPins[c],OUTPUT);
  578.         digitalWrite(columnPins[c], LOW);   // Begin column pulse output.
  579.             switch (columnPins[c])
  580.             {
  581.                 case 23:
  582.                 if ((~PINB) &_BV(4)) buttons = buttons | LEFT_BUTTON;          
  583.                 break;
  584.                 case 19:
  585.                 if ((~PINB) &_BV(5)) buttons = buttons | DOWN_BUTTON;
  586.                 break;
  587.                 case 22:
  588.                 if ((~PINB) &_BV(5)) buttons = buttons | UP_BUTTON;
  589.                 if ((~PINB) &_BV(4)) buttons = buttons | RIGHT_BUTTON; 
  590.                 break;         
  591.                 case 4:
  592.                 if ((~PINB) &_BV(7)) buttons = buttons | B_BUTTON;
  593.                 if ((~PINB) &_BV(6)) buttons = buttons | A_BUTTON;
  594.                   if ((~PINB) &_BV(4))
  595.                     {
  596.                     delay(250);                
  597.                     invertDisplay = !invertDisplay;
  598.                     if (invertDisplay) sendLCDCommand(0x21); // Display inversion off
  599.                         else
  600.                       sendLCDCommand(0x20); // Display inversion off
  601.                     }                  
  602.             }
  603.    
  604.         // Set pin to high impedance input. Effectively ends column pulse.
  605.         digitalWrite(columnPins[c],HIGH);
  606.         pinMode(columnPins[c],INPUT);
  607.   }
  608.   if ((~PIND) &_BV(2)) SleepNow();//power button
  609.   return buttons;
  610. }
  611.  
  612. // delay in ms with 16 bit duration
  613. void Arduboy2Core::delayShort(uint16_t ms)
  614. {
  615.   delay((unsigned long) ms);
  616. }
  617.  
  618. void Arduboy2Core::exitToBootloader()
  619. {
  620.  
  621. }
  622.  
  623. // Replacement main() that eliminates the USB stack code.
  624. // Used by the ARDUBOY_NO_USB macro. This should not be called
  625. // directly from a sketch.
  626.  
  627. void Arduboy2Core::mainNoUSB()
  628. {
  629.  
  630. }
Advertisement
Add Comment
Please, Sign In to add comment