diff --git a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino index 5d67cedf..7df0e0d9 100644 --- a/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino +++ b/dependencies/LightberryHDUSBAPA1021.1/LightberryHDUSBAPA1021.1.ino @@ -71,7 +71,7 @@ // XOR 0x55). LED data follows, 3 bytes per LED, in order R, G, B, // where 0 = off and 255 = max brightness. -static const uint8_t magic[] = {'A','d','a'}; +static const uint8_t magic[] = {'A', 'd', 'a'}; #define MAGICSIZE sizeof(magic) #define HEADERSIZE (MAGICSIZE + 3) @@ -96,31 +96,31 @@ void setup() // masking and/or conditional code every time one of these indices // needs to change, slowing things down tremendously. uint8_t - buffer[256], - indexIn = 0, - indexOut = 0, - mode = MODE_HEADER, - hi, lo, chk, i, spiFlag; + buffer[256], + indexIn = 0, + indexOut = 0, + mode = MODE_HEADER, + hi, lo, chk, i, spiFlag; int16_t - bytesBuffered = 0, - hold = 0, - c; + bytesBuffered = 0, + hold = 0, + c; int32_t - bytesRemaining; + bytesRemaining; unsigned long - startTime, - lastByteTime, - lastAckTime, - t; - bool - data_in_led = false, - spi_out_led = false; - + startTime, + lastByteTime, + lastAckTime, + t; + bool + data_in_led = false, + spi_out_led = false; + LED_DDR |= LED_PIN; // Enable output for LED LED_PORT &= ~LED_PIN; // LED off pinMode(DATA_LED, OUTPUT); //data in led pinMode(SPI_LED, OUTPUT); //data out led - + Serial.begin(115200); // Teensy/32u4 disregards baud rate; is OK! SPI.begin(); @@ -135,18 +135,18 @@ void setup() // green, blue, then off. Once you're confident everything is working // end-to-end, it's OK to comment this out and reprogram the Arduino. uint8_t testcolor[] = { 0, 0, 0, 255, 0, 0 }; - for(int i=0; i<4; i++){ //Start Frame - for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + for (int i = 0; i < 4; i++) { //Start Frame + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); } - for(char n=3; n>=0; n--) { - for(c=0; c<25000; c++) { - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness byte - for(i=0; i<3; i++) { - for(SPDR = testcolor[n + i]; !(SPSR & _BV(SPIF)); ); //BGR + for (char n = 3; n >= 0; n--) { + for (c = 0; c < 25000; c++) { + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness byte + for (i = 0; i < 3; i++) { + for (SPDR = testcolor[n + i]; !(SPSR & _BV(SPIF)); ); //BGR } } - for(int i=0; i<4; i++){ //Stop Frame - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); + for (int i = 0; i < 4; i++) { //Stop Frame + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); } delay(1); // One millisecond pause = latch digitalWrite(SPI_LED, spi_out_led = !spi_out_led); @@ -160,109 +160,109 @@ void setup() // loop() is avoided as even that small bit of function overhead // has a measurable impact on this code's overall throughput. - for(;;) { + for (;;) { digitalWrite(DATA_LED, LOW); digitalWrite(SPI_LED, LOW); // Implementation is a simple finite-state machine. // Regardless of mode, check for serial input each time: t = millis(); - if((bytesBuffered < 256) && ((c = Serial.read()) >= 0)) { + if ((bytesBuffered < 256) && ((c = Serial.read()) >= 0)) { buffer[indexIn++] = c; bytesBuffered++; lastByteTime = lastAckTime = t; // Reset timeout counters } else { // No data received. If this persists, send an ACK packet // to host once every second to alert it to our presence. - if((t - lastAckTime) > 1000) { + if ((t - lastAckTime) > 1000) { Serial.print("Ada\n"); // Send ACK string to host lastAckTime = t; // Reset counter } // If no data received for an extended time, turn off all LEDs. - if((t - lastByteTime) > serialTimeout) { - for(i=0;i<4;i++) { //Start Frame - for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); + if ((t - lastByteTime) > serialTimeout) { + for (i = 0; i < 4; i++) { //Start Frame + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); } - for(c=0; c<25000; c++) { - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness Byte - for(i=0; i<3; i++) { - for(SPDR = 0x00; !(SPSR & _BV(SPIF)); ); //BGR + for (c = 0; c < 25000; c++) { + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); //Brightness Byte + for (i = 0; i < 3; i++) { + for (SPDR = 0x00; !(SPSR & _BV(SPIF)); ); //BGR } } - for(i=0;i<4;i++) { //Stop Frame - for(SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); + for (i = 0; i < 4; i++) { //Stop Frame + for (SPDR = 0xFF; !(SPSR & _BV(SPIF)); ); } delay(1); // One millisecond pause = latch lastByteTime = t; // Reset counter } } - switch(mode) { + switch (mode) { - case MODE_HEADER: + case MODE_HEADER: - // In header-seeking mode. Is there enough data to check? - if(bytesBuffered >= HEADERSIZE) { - // Indeed. Check for a 'magic word' match. - for(i=0; (i 0) and multiply by 3 for R,G,B. - bytesRemaining = 4L * (256L * (long)hi + (long)lo) +4L + (256L *(long)hi + (long)lo +15)/16; - bytesBuffered -= 3; - spiFlag = 0; // No data out yet - mode = MODE_HOLD; // Proceed to latch wait mode - digitalWrite(DATA_LED, data_in_led = !data_in_led); - } else { - // Checksum didn't match; search resumes after magic word. - indexOut -= 3; // Rewind - } - } // else no header match. Resume at first mismatched byte. - bytesBuffered -= i; - } - break; - - case MODE_HOLD: - - // Ostensibly "waiting for the latch from the prior frame - // to complete" mode, but may also revert to this mode when - // underrun prevention necessitates a delay. - - if((micros() - startTime) < hold) break; // Still holding; keep buffering - - // Latch/delay complete. Advance to data-issuing mode... - LED_PORT &= ~LED_PIN; // LED off - mode = MODE_DATA; // ...and fall through (no break): - - case MODE_DATA: - digitalWrite(SPI_LED, spi_out_led = !spi_out_led); - while(spiFlag && !(SPSR & _BV(SPIF))); // Wait for prior byte - if(bytesRemaining > 0) { - if(bytesBuffered > 0) { - SPDR = buffer[indexOut++]; // Issue next byte - bytesBuffered--; - bytesRemaining--; - spiFlag = 1; + // In header-seeking mode. Is there enough data to check? + if (bytesBuffered >= HEADERSIZE) { + // Indeed. Check for a 'magic word' match. + for (i = 0; (i < MAGICSIZE) && (buffer[indexOut++] == magic[i++]);); + if (i == MAGICSIZE) { + // Magic word matches. Now how about the checksum? + hi = buffer[indexOut++]; + lo = buffer[indexOut++]; + chk = buffer[indexOut++]; + if (chk == (hi ^ lo ^ 0x55)) { + // Checksum looks valid. Get 16-bit LED count, add 1 + // (# LEDs is always > 0) and multiply by 3 for R,G,B. + bytesRemaining = 4L * (256L * (long)hi + (long)lo) + 4L + (256L * (long)hi + (long)lo + 15) / 16; + bytesBuffered -= 3; + spiFlag = 0; // No data out yet + mode = MODE_HOLD; // Proceed to latch wait mode + digitalWrite(DATA_LED, data_in_led = !data_in_led); + } else { + // Checksum didn't match; search resumes after magic word. + indexOut -= 3; // Rewind + } + } // else no header match. Resume at first mismatched byte. + bytesBuffered -= i; + } + break; + + case MODE_HOLD: + + // Ostensibly "waiting for the latch from the prior frame + // to complete" mode, but may also revert to this mode when + // underrun prevention necessitates a delay. + + if ((micros() - startTime) < hold) break; // Still holding; keep buffering + + // Latch/delay complete. Advance to data-issuing mode... + LED_PORT &= ~LED_PIN; // LED off + mode = MODE_DATA; // ...and fall through (no break): + + case MODE_DATA: + digitalWrite(SPI_LED, spi_out_led = !spi_out_led); + while (spiFlag && !(SPSR & _BV(SPIF))); // Wait for prior byte + if (bytesRemaining > 0) { + if (bytesBuffered > 0) { + SPDR = buffer[indexOut++]; // Issue next byte + bytesBuffered--; + bytesRemaining--; + spiFlag = 1; + } + // If serial buffer is threatening to underrun, start + // introducing progressively longer pauses to allow more + // data to arrive (up to a point). + // if((bytesBuffered < 32) && (bytesRemaining > bytesBuffered)) { + // startTime = micros(); + // hold = 100 + (32 - bytesBuffered) * 10; + // mode = MODE_HOLD; + //} + } else { + // End of data -- issue latch: + startTime = micros(); + hold = 1000; // Latch duration = 1000 uS + LED_PORT |= LED_PIN; // LED on + mode = MODE_HEADER; // Begin next header search } - // If serial buffer is threatening to underrun, start - // introducing progressively longer pauses to allow more - // data to arrive (up to a point). - // if((bytesBuffered < 32) && (bytesRemaining > bytesBuffered)) { - // startTime = micros(); - // hold = 100 + (32 - bytesBuffered) * 10; - // mode = MODE_HOLD; -//} - } else { - // End of data -- issue latch: - startTime = micros(); - hold = 1000; // Latch duration = 1000 uS - LED_PORT |= LED_PIN; // LED on - mode = MODE_HEADER; // Begin next header search - } } // end switch } // end for(;;) }