Rewrote Adalight code to no longer use 256 byte buffer

The buffer was only being used to store the header information before
processing, otherwise data was retrieved immediately. Buffer and support
variables were causing more problems than anything else.
This commit is contained in:
David Madison 2017-03-27 19:20:55 -04:00
parent 672f401a4d
commit a766fb4910
1 changed files with 71 additions and 79 deletions

View File

@ -52,7 +52,11 @@ uint8_t * ledsRaw = (uint8_t *)leds;
static const uint8_t magic[] = { static const uint8_t magic[] = {
'A','d','a'}; 'A','d','a'};
#define MAGICSIZE sizeof(magic) #define MAGICSIZE sizeof(magic)
#define HEADERSIZE (MAGICSIZE + 3)
// Check values are header byte # - 1, as they are indexed from 0
#define HICHECK (MAGICSIZE)
#define LOCHECK (MAGICSIZE + 1)
#define CHECKSUM (MAGICSIZE + 2)
#define MODE_HEADER 0 #define MODE_HEADER 0
#define MODE_DATA 2 #define MODE_DATA 2
@ -76,23 +80,12 @@ void setup(){
} }
void adalight(){ void adalight(){
// Dirty trick: the circular buffer for serial data is 256 bytes,
// and the "in" and "out" indices are unsigned 8-bit types -- this
// much simplifies the cases where in/out need to "wrap around" the
// beginning/end of the buffer. Otherwise there'd be a ton of bit-
// masking and/or conditional code every time one of these indices
// needs to change, slowing things down tremendously.
uint8_t uint8_t
buffer[256],
indexIn = 0,
indexOut = 0,
mode = MODE_HEADER, mode = MODE_HEADER,
hi, lo, chk, i; headPos,
hi, lo, chk;
int16_t int16_t
c; c;
uint16_t
bytesBuffered = 0;
uint32_t uint32_t
bytesRemaining, bytesRemaining,
outPos; outPos;
@ -113,11 +106,69 @@ void adalight(){
// Implementation is a simple finite-state machine. // Implementation is a simple finite-state machine.
// Regardless of mode, check for serial input each time: // Regardless of mode, check for serial input each time:
t = millis(); t = millis();
if((bytesBuffered < 256) && ((c = Serial.read()) >= 0)) {
buffer[indexIn++] = c; if((c = Serial.read()) >= 0){
bytesBuffered++;
lastByteTime = lastAckTime = t; // Reset timeout counters lastByteTime = lastAckTime = t; // Reset timeout counters
switch(mode) {
case MODE_HEADER:
if(headPos < MAGICSIZE){
if(c == magic[headPos]) headPos++;
else headPos = 0;
} }
else{
switch(headPos){
case HICHECK:
hi = c;
headPos++;
break;
case LOCHECK:
lo = c;
headPos++;
break;
case CHECKSUM:
chk = c;
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 = 3L * (256L * (long)hi + (long)lo + 1L);
outPos = 0;
memset(leds, 0, Num_Leds * sizeof(struct CRGB));
mode = MODE_DATA; // Proceed to latch wait mode
}
headPos = 0; // Reset header position regardless of checksum result
break;
}
}
break;
case MODE_DATA:
if(bytesRemaining > 0) {
if (outPos < sizeof(leds)){
#ifdef CALIBRATE
if(outPos < 3)
ledsRaw[outPos++] = c;
else{
ledsRaw[outPos] = ledsRaw[outPos%3]; // Sets RGB data to first LED color
outPos++;
}
#else
ledsRaw[outPos++] = c; // Issue next byte
#endif
}
bytesRemaining--;
}
else {
// End of data -- issue latch:
mode = MODE_HEADER; // Begin next header search
FastLED.show();
}
break;
} // end switch
} // end serial if
else { else {
// No data received. If this persists, send an ACK packet // No data received. If this persists, send an ACK packet
// to host once every second to alert it to our presence. // to host once every second to alert it to our presence.
@ -131,66 +182,7 @@ void adalight(){
FastLED.show(); FastLED.show();
lastByteTime = t; // Reset counter lastByteTime = t; // Reset counter
} }
} } // end else
switch(mode) {
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<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 = 3L * (256L * (long)hi + (long)lo + 1L);
bytesBuffered -= 3;
outPos = 0;
memset(leds, 0, Num_Leds * sizeof(struct CRGB));
mode = MODE_DATA; // Proceed to latch wait mode
}
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_DATA:
if(bytesRemaining > 0) {
if(bytesBuffered > 0) {
if (outPos < sizeof(leds)){
#ifdef CALIBRATE
if(outPos < 3)
ledsRaw[outPos++] = buffer[indexOut++];
else{
ledsRaw[outPos] = ledsRaw[outPos%3]; // Sets RGB data to first LED color
outPos++;
indexOut++;
}
#else
ledsRaw[outPos++] = buffer[indexOut++]; // Issue next byte
#endif
}
bytesBuffered--;
bytesRemaining--;
}
}
else {
// End of data -- issue latch:
mode = MODE_HEADER; // Begin next header search
FastLED.show();
}
} // end switch
} // end for(;;) } // end for(;;)
} }