void user_loop(void) { unsigned char channel; /* loop over all HV channels */ for (channel=0 ; channel<N_HV_CHN ; channel++) { watchdog_refresh(0); if ((user_data[0].control & CONTROL_IDLE) == 0) { /* read back HV and current */ read_hv(channel); read_current(channel); /* check for current trip */ check_current(channel); /* do ramping and regulation */ ramp_hv(channel); regulation(channel); /* set voltage regularly, in case DAC hot HV spike */ set_hv(channel, user_data[channel].u_dac); } } // read_temperature(); }
extern "C" int main() { pinMode(LED_BUILTIN, OUTPUT); leds.begin(); // Announce firmware version serial_begin(BAUD2DIV(115200)); serial_print("Fadecandy v" DEVICE_VER_STRING "\r\n"); // Application main loop while (usb_dfu_state == DFU_appIDLE) { watchdog_refresh(); buffers.handleUSB(); updateDrawBuffer(calculateInterpCoefficient()); leds.show(); // Optionally disable dithering by clearing our residual buffer every frame. if (buffers.flags & CFLAG_NO_DITHERING) { for (unsigned i = 0; i < CHANNELS_TOTAL; ++i) residual[i] = 0; } } // Reboot into DFU bootloader dfu_reboot(); }
int watchdog_deinit() { uchar* ctrl_addr = ( uchar* )HW_ADDR( WATCHDOG_CTRL, 0 ); watchdog_refresh(); *ctrl_addr = 0x00; return ERR_NONE; }
void read_adc24(unsigned char a, unsigned long *d) { unsigned char i, m; /* write to communication register */ ADC_NCS = 0; delay_us(OPT_DELAY); watchdog_refresh(1); /* write zero to !WEN and one to R/!W */ for (i=0 ; i<4 ; i++) { ADC_SCLK = 0; delay_us(OPT_DELAY); ADC_DIN = (i == 1); delay_us(OPT_DELAY); ADC_SCLK = 1; delay_us(OPT_DELAY); watchdog_refresh(1); } /* register address */ for (i=0,m=8 ; i<4 ; i++) { ADC_SCLK = 0; delay_us(OPT_DELAY); ADC_DIN = (a & m) > 0; delay_us(OPT_DELAY); ADC_SCLK = 1; delay_us(OPT_DELAY); m >>= 1; watchdog_refresh(1); } ADC_NCS = 1; delay_us(OPT_DELAY); watchdog_refresh(1); /* read from selected data register */ ADC_NCS = 0; delay_us(OPT_DELAY); watchdog_refresh(1); for (i=0,*d=0 ; i<24 ; i++) { *d <<= 1; ADC_SCLK = 0; delay_us(OPT_DELAY); delay_us(OPT_DELAY); *d |= ADC_DOUT; ADC_SCLK = 1; delay_us(OPT_DELAY); watchdog_refresh(1); } ADC_NCS = 1; delay_us(OPT_DELAY); watchdog_refresh(1); }
void write_adc(unsigned char a, unsigned char d) { unsigned char xdata i, m; /* write to communication register */ ADC_NCS = 0; delay_us(OPT_DELAY); watchdog_refresh(1); /* write zeros to !WEN and R/!W */ for (i=0 ; i<4 ; i++) { ADC_SCLK = 0; delay_us(OPT_DELAY); ADC_DIN = 0; delay_us(OPT_DELAY); ADC_SCLK = 1; delay_us(OPT_DELAY); watchdog_refresh(1); } /* register address */ for (i=0,m=8 ; i<4 ; i++) { ADC_SCLK = 0; delay_us(OPT_DELAY); ADC_DIN = (a & m) > 0; delay_us(OPT_DELAY); ADC_SCLK = 1; delay_us(OPT_DELAY); m >>= 1; watchdog_refresh(1); } ADC_NCS = 1; delay_us(OPT_DELAY); watchdog_refresh(1); /* write to selected data register */ ADC_NCS = 0; delay_us(OPT_DELAY); watchdog_refresh(1); for (i=0,m=0x80 ; i<8 ; i++) { ADC_SCLK = 0; delay_us(OPT_DELAY); ADC_DIN = (d & m) > 0; delay_us(OPT_DELAY); ADC_SCLK = 1; delay_us(OPT_DELAY); m >>= 1; watchdog_refresh(1); } ADC_NCS = 1; delay_us(OPT_DELAY); watchdog_refresh(1); }
void regulation(unsigned char channel) { /* if demand value changed, remember time to avoid current trip sensing for the next few seconds */ if (chn_bits[channel] & DEMAND_CHANGED) t_ramp[channel] = time(); /* only if HV on and not disabled and not ramping */ if ((user_data[channel].control & CONTROL_HV_ON) && !(user_data[channel].status & STATUS_DISABLED) && (chn_bits[channel] & (RAMP_UP | RAMP_DOWN)) == 0 && !(user_data[channel].status & STATUS_ILIMIT)) { if (user_data[channel].control & CONTROL_REGULATION) { u_actual[channel] = user_data[channel].u_demand; /* correct if difference is at least half a LSB */ if (fabs(user_data[channel].u_demand - user_data[channel].u_meas) / DIVIDER / 2.5 * 65536 > 0.5) { user_data[channel].u_dac += user_data[channel].u_demand - user_data[channel].u_meas; /* only allow +-2V fine regulation range */ if (user_data[channel].u_dac < user_data[channel].u_demand - 2) user_data[channel].u_dac = user_data[channel].u_demand - 2; if (user_data[channel].u_dac > user_data[channel].u_demand + 2) user_data[channel].u_dac = user_data[channel].u_demand + 2; chn_bits[channel] &= ~DEMAND_CHANGED; } } else { /* set voltage directly */ if (chn_bits[channel] & DEMAND_CHANGED) { u_actual[channel] = user_data[channel].u_demand; user_data[channel].u_dac = user_data[channel].u_demand; chn_bits[channel] &= ~DEMAND_CHANGED; } } } /* if HV switched off, set DAC to zero */ if (!(user_data[channel].control & CONTROL_HV_ON) && (chn_bits[channel] & DEMAND_CHANGED)) { user_data[channel].u_dac = 0; u_actual[channel] = 0; set_hv(channel, 0); chn_bits[channel] &= ~DEMAND_CHANGED; } watchdog_refresh(1); }
int watchdog_init() { uchar* ctrl_addr = ( uchar* )HW_ADDR( WATCHDOG_CTRL, 0 ); watchdog_refresh(); /* Timeout 8 seconds */ *ctrl_addr = 0x07; DEBUG_PRINT( DBG_WATCHDOG, "watchdog initialized to %c\n", ( uchar* )HW_READ( WATCHDOG_CTRL, 0 ) ); return ERR_NONE; }
void lcd_send(unsigned char *buf, unsigned char len) { unsigned char idata status, i; for (i=0 ; i<10 ; i++) { lcd_sendbuf(buf, len); delay_us(6); status = lcd_io(0xFF); if (status == ACK) break; watchdog_refresh(0); delay_us(10); } }
void lcd_text(unsigned short x, unsigned short y, char align, char *str) { unsigned char status, i, j, cs, len; len = strlen(str); for (j=0 ; j<10 ; j++) { lcd_io(DC1); cs = DC1; lcd_io(len+8); cs += len+8; lcd_io(ESC); cs += ESC; lcd_io('Z'); cs += 'Z'; lcd_io(align); cs += align; lcd_io(x & 0xFF); cs += (x & 0xFF); lcd_io(x >> 8); cs += (x >> 8); lcd_io(y & 0xFF); cs += (y & 0xFF); lcd_io(y >> 8); cs += (y >> 8); for (i=0 ; i<len+1 ; i++) { lcd_io(str[i]); cs += str[i]; } lcd_io(cs); delay_us(6); status = lcd_io(0xFF); if (status == ACK) break; watchdog_refresh(0); delay_us(10); } }
static void dfu_reboot() { // Reboot to the Fadecandy Bootloader boot_token = 0x74624346; // Short delay to allow the host to receive the response to DFU_DETACH. uint32_t deadline = millis() + 10; while (millis() < deadline) { watchdog_refresh(); } // Detach from USB, and use the watchdog to time out a 10ms USB disconnect. __disable_irq(); USB0_CONTROL = 0; while (1); }
void adc_read(channel, float *d) { unsigned long value; unsigned int i, n; float gvalue; AMX0SL = channel & 0x0F; ADC0CF = 0xE0; // 16 system clocks, gain 1 n = 1 << (8 + 4); value = 0; for (i = 0; i < n; i++) { DISABLE_INTERRUPTS; ADCINT = 0; ADBUSY = 1; while (!ADCINT); // wait until conversion ready, does NOT work with ADBUSY! ENABLE_INTERRUPTS; value += (ADC0L | (ADC0H << 8)); watchdog_refresh(); } value >>= 8; /* convert to volts */ gvalue = value / 65536.0 * 2.5; /* external voltage divider */ gvalue *= 0.5 * user_conf.gain_cal; /* convert to Ohms (15V supply, 2kOhm resistor) */ gvalue = (2000 * gvalue) / (15 - gvalue); /* convert Ohms to Celsius, valid -100.100 deg., error <0.04K */ gvalue -= 100; gvalue = 0.0011 * gvalue * gvalue + 2.5558 * gvalue; /* correct for offset */ gvalue += user_conf.ofs_cal; DISABLE_INTERRUPTS; *d = gvalue; ENABLE_INTERRUPTS; }
extern "C" int main() { pinMode(LED_BUILTIN, OUTPUT); leds.begin(); // Announce firmware version serial_begin(BAUD2DIV(115200)); serial_print("Fadecandy v" DEVICE_VER_STRING "\r\n"); // Application main loop while (usb_dfu_state == DFU_appIDLE) { watchdog_refresh(); // Select a different drawing loop based on our firmware config flags switch (buffers.flags & (CFLAG_NO_INTERPOLATION | CFLAG_NO_DITHERING)) { case 0: default: updateDrawBuffer_I1_D1(calculateInterpCoefficient()); break; case CFLAG_NO_INTERPOLATION: updateDrawBuffer_I0_D1(0x10000); break; case CFLAG_NO_DITHERING: updateDrawBuffer_I1_D0(calculateInterpCoefficient()); break; case CFLAG_NO_INTERPOLATION | CFLAG_NO_DITHERING: updateDrawBuffer_I0_D0(0x10000); break; } // Start sending the next frame over DMA leds.show(); // We can switch to the next frame's buffer now. buffers.finalizeFrame(); // Performance counter, for monitoring frame rate externally perf_frameCounter++; } // Reboot into DFU bootloader dfu_reboot(); }
void ramp_hv(unsigned char channel) { unsigned char delta; /* only process ramping when HV is on and not tripped */ if ((user_data[channel].control & CONTROL_HV_ON) && !(user_data[channel].status & STATUS_DISABLED)) { if (chn_bits[channel] & DEMAND_CHANGED) { /* start ramping */ if (user_data[channel].u_demand > u_actual[channel] && user_data[channel].ramp_up > 0) { /* ramp up */ chn_bits[channel] |= RAMP_UP; chn_bits[channel] &= ~RAMP_DOWN; user_data[channel].status |= STATUS_RAMP_UP; user_data[channel].status &= ~STATUS_RAMP_DOWN; user_data[channel].status &= ~STATUS_RILIMIT; chn_bits[channel] &= ~DEMAND_CHANGED; } if (user_data[channel].u_demand < u_actual[channel] && user_data[channel].ramp_down > 0) { /* ramp down */ chn_bits[channel] &= ~RAMP_UP; chn_bits[channel] |= RAMP_DOWN; user_data[channel].status &= ~STATUS_RAMP_UP; user_data[channel].status |= STATUS_RAMP_DOWN; user_data[channel].status &= ~STATUS_RILIMIT; chn_bits[channel] &= ~DEMAND_CHANGED; } /* remember start time */ t_ramp[channel] = time(); } /* ramp up */ if (chn_bits[channel] & RAMP_UP) { delta = time() - t_ramp[channel]; if (user_data[channel].i_meas > user_data[channel].ri_limit) user_data[channel].status |= STATUS_RILIMIT; else user_data[channel].status &= ~STATUS_RILIMIT; if (delta && user_data[channel].i_meas < user_data[channel].ri_limit) { u_actual[channel] += (float) user_data[channel].ramp_up * delta / 100.0; user_data[channel].u_dac = u_actual[channel]; if (u_actual[channel] >= user_data[channel].u_demand) { /* finish ramping */ u_actual[channel] = user_data[channel].u_demand; user_data[channel].u_dac = u_actual[channel]; chn_bits[channel] &= ~RAMP_UP; user_data[channel].status &= ~STATUS_RAMP_UP; user_data[channel].status &= ~STATUS_RILIMIT; } set_hv(channel, user_data[channel].u_dac); t_ramp[channel] = time(); } } /* ramp down */ if (chn_bits[channel] & RAMP_DOWN) { delta = time() - t_ramp[channel]; if (delta) { u_actual[channel] -= (float) user_data[channel].ramp_down * delta / 100.0; user_data[channel].u_dac = u_actual[channel]; /* handle trip ramping */ if (user_data[channel].status & STATUS_ILIMIT) { if (u_actual[channel] <= 0) { /* finish ramping */ u_actual[channel] = 0; user_data[channel].u_dac = 0; chn_bits[channel] &= ~RAMP_DOWN; user_data[channel].status &= ~STATUS_RAMP_DOWN; } } else { if (u_actual[channel] <= user_data[channel].u_demand) { /* finish ramping */ u_actual[channel] = user_data[channel].u_demand; user_data[channel].u_dac = u_actual[channel]; chn_bits[channel] &= ~RAMP_DOWN; user_data[channel].status &= ~STATUS_RAMP_DOWN; } } set_hv(channel, user_data[channel].u_dac); t_ramp[channel] = time(); } } } watchdog_refresh(1); }
void user_loop(void) { unsigned char xdata channel, i; /* loop over all HV channels */ for (channel=0 ; channel<N_HV_CHN ; channel++) { watchdog_refresh(0); if ((user_data[0].control & CONTROL_IDLE) == 0) { /* set current limit if changed */ if (chn_bits[channel] & CUR_LIMIT_CHANGED) { set_current_limit(user_data[channel].i_limit); chn_bits[channel] &= ~CUR_LIMIT_CHANGED; trip_reset = 1; } /* read back HV and current */ read_hv(channel); read_current(channel); /* check for current trip */ check_current(channel); /* do ramping and regulation */ ramp_hv(channel); regulation(channel); /* set voltage regularly, in case DAC got HV spike */ set_hv(channel, user_data[channel].u_dac); } #ifdef HARDWARE_TRIP if (trip_reset) { reset_hardware_trip(); trip_reset = 0; } #endif /* if crate HV switched off, set DAC to zero */ if (SW1) { for (i = 0 ; i<N_HV_CHN ; i++ ) { user_data[i].u_dac = 0; user_data[i].status |= STATUS_DISABLED; u_actual[i] = 0; set_hv(i, 0); } old_sw1 = 1; } /* if crate HV switched on, indicated changed demand value*/ if (!SW1 && old_sw1) { for (i = 0 ; i<N_HV_CHN ; i++ ) { chn_bits[i] |= DEMAND_CHANGED; user_data[i].status &= ~STATUS_DISABLED; } old_sw1 = 0; } } /* reset ADC once all channels have been read */ reset_adc(); // read_temperature(); }
extern "C" int main() { uint32_t last = systick_millis_count; uint32_t lastRender = 0; uint16_t i = 0; uint16_t j = 0; uint8_t index = 0; uint8_t startIndex = 0; pinMode(LED_BUILTIN, OUTPUT); for (i = 0; i < LUT_TOTAL_SIZE; i++) { buffers.lutCurrent.entries[i] = defaultLUT[i] >> 1;// (i % LUT_CH_SIZE) << 7; } #ifdef RAINBOW_LANTERNS int16_t numSteps = 64; #endif leds.begin(); rainbow10[0] = rainbow7[0] = color(0xFF, 0, 0); rainbow10[1] = rainbow7[1] = color(0xFF, 0xA5, 0); rainbow10[2] = rainbow7[2] = color(0xFF, 0xFF, 0); rainbow10[3] = rainbow7[3] = color(0, 0x80, 0); rainbow10[4] = color(0, 0xFF, 0); rainbow10[5] = color(0, 0xA5, 0x80); rainbow10[6] = rainbow7[4] = color(0, 0, 0xFF); rainbow10[7] = rainbow7[5] = color(0x4B, 0, 0x82); rainbow10[8] = rainbow7[6] = color(0xFF, 0, 0xFF); rainbow10[9] = color(0xEE, 0x82, 0xEE); buffers.flags = CFLAG_NO_ACTIVITY_LED; //buffers.flags |= CFLAG_LED_CONTROL; // Announce firmware version serial_begin(BAUD2DIV(115200)); serial_print("Fadecandy v" DEVICE_VER_STRING "\r\n"); //usb_serial_printf("test\n"); // Application main loop while (usb_dfu_state == DFU_appIDLE) { watchdog_refresh(); // Select a different drawing loop based on our firmware config flags switch (buffers.flags & (CFLAG_NO_INTERPOLATION | CFLAG_NO_DITHERING)) { case 0: default: updateDrawBuffer_I1_D1(calculateInterpCoefficient()); break; case CFLAG_NO_INTERPOLATION: updateDrawBuffer_I0_D1(0x10000); break; case CFLAG_NO_DITHERING: updateDrawBuffer_I1_D0(calculateInterpCoefficient()); break; case CFLAG_NO_INTERPOLATION | CFLAG_NO_DITHERING: updateDrawBuffer_I0_D0(0x10000); break; } //buffers.flags |= CFLAG_NO_ACTIVITY_LED; // Start sending the next frame over DMA leds.show(); if ((systick_millis_count - last) > 500) { //buffers.flags ^= CFLAG_LED_CONTROL; last = systick_millis_count; } #ifdef RAINBOW_CIRCLE if ((systick_millis_count - lastRender) > 500) { buffers.flags ^= CFLAG_LED_CONTROL; lastRender = systick_millis_count; index = startIndex; for (i = 0; i < 52/*32*/; i++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * 7 + i); uint32_t color = rainbow7[index]; pixel[0] = RED(color); pixel[1] = GREEN(color); pixel[2] = BLUE(color); index = (index + 1) % 7; } for (i = 0; i < 20; i++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * 6 + i); uint32_t color = rainbow7[index]; pixel[0] = RED(color); pixel[1] = GREEN(color); pixel[2] = BLUE(color); index = (index + 1) % 7; } startIndex = (startIndex + 1) % 7; buffers.finalizeFramebuffer(); } #endif #ifdef RAINBOW_TOPHAT (void)j; if ((systick_millis_count - lastRender) > 500) { buffers.flags ^= CFLAG_LED_CONTROL; lastRender = systick_millis_count; index = startIndex; for (i = 0; i < 52/*32*/; i++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * 7 + i); uint32_t color = rainbow7[index]; pixel[0] = RED(color); pixel[1] = GREEN(color); pixel[2] = BLUE(color); if (i>0 && i % 5 == 0) { index = (index + 1) % 7; } } for (i = 0; i < 20; i++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * 6 + i); uint32_t color = rainbow7[index]; pixel[0] = RED(color); pixel[1] = GREEN(color); pixel[2] = BLUE(color); index = (index + 1) % 7; } startIndex = (startIndex + 1) % 7; buffers.finalizeFramebuffer(); } #endif #ifdef RAINBOW_LANTERNS /*(void)j; (void)index; (void)startIndex; if ((systick_millis_count - lastRender) > 500) { buffers.flags ^= CFLAG_LED_CONTROL; lastRender = systick_millis_count; for (i = 0; i < 20; i++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * 7 + i); int16_t direction = directions[i] < 0 ? -1 : 1; uint32_t color1 = rainbow7[indexes[i]]; int16_t index2 = indexes[i] + direction; if (index2 < 0) { index2 = 6; } else if (index2 >= 7) { index2 = 0; } uint32_t color2 = rainbow7[index2]; int32_t reddiff = RED(color2) - RED(color1); int32_t bluediff = BLUE(color2) - BLUE(color1); int32_t greendiff = GREEN(color2) - BLUE(color1); reddiff *= steps[i]; reddiff /= numSteps; bluediff *= steps[i]; bluediff /= numSteps; greendiff *= steps[i]; greendiff /= numSteps; pixel[0] = RED(color1) + reddiff; pixel[1] = GREEN(color1) + greendiff; pixel[2] = BLUE(color1) + bluediff; steps[i] += abs(directions[i]); if (steps[i] >= numSteps) { steps[i] = 0; indexes[i] = index2; } } buffers.finalizeFramebuffer(); }*/ (void)j; (void)numSteps; if ((systick_millis_count - lastRender) > 5000) { buffers.flags ^= CFLAG_LED_CONTROL; lastRender = systick_millis_count; index = startIndex; for (i = 0; i < 20/*32*/; i++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * 7 + i); uint32_t color = rainbow7[index]; pixel[0] = RED(color); pixel[1] = GREEN(color); pixel[2] = BLUE(color); if (i>0 && i % 2 == 0) { index = (index + 1) % 7; } } for (i = 0; i < 20; i++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * 6 + i); uint32_t color = rainbow7[index]; pixel[0] = RED(color); pixel[1] = GREEN(color); pixel[2] = BLUE(color); index = (index + 1) % 7; } startIndex = (startIndex + 1) % 7; buffers.finalizeFramebuffer(); } #endif #ifdef PARASOL if ((systick_millis_count - lastRender) > 500) { buffers.flags ^= CFLAG_LED_CONTROL; lastRender = systick_millis_count; index = startIndex; for (i = 0; i < 8; i++) { for (j = 0; j < 3; j++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * i + j); uint32_t color = rainbow7[index]; pixel[0] = RED(color); pixel[1] = GREEN(color); pixel[2] = BLUE(color); } index = (index + 1) % 7; } startIndex = (startIndex + 1) % 7; buffers.finalizeFramebuffer(); } #endif #ifdef SMOOTH_RAINBOW (void)startIndex; (void)j; if ((systick_millis_count - lastRender) > 30) { lastRender = systick_millis_count; uint32_t ledIndex = 0; if (index >= 16) { buffers.flags ^= CFLAG_LED_CONTROL; index = 0; } index++; float color1[3]; float color2[3]; for (i = 0; i < 32; i++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * 7 + i); pixel[0] = 0xFF; pixel[1] = 0; pixel[2] = 0; float scaled = ledIndex / 44.0f; //fix16_t noise = 32768; (void)scaled; float noise = .5f + noise2(scaled, time); //float noise = .5f + fbm_noise3(scaled, time, .5f, 4, .25f, 2.0f); noise = fmax(fmin(1, noise), 0); float mult = 9 * noise; float index1 = floor(mult); float index2 = ceil(mult); float percent = mult - index1; uint32_t color = rainbow10[(int)index1]; color1[0] = RED(color); color1[1] = GREEN(color); color1[2] = BLUE(color); color = rainbow10[(int)index2]; color2[0] = RED(color); color2[1] = GREEN(color); color2[2] = BLUE(color); pixel[0] = (uint8_t)((int)(color1[0] + ((color2[0] - color1[0]) * percent)) & 0xFF); pixel[1] = (uint8_t)((int)(color1[1] + ((color2[1] - color1[1]) * percent)) & 0xFF); pixel[2] = (uint8_t)((int)(color1[2] + ((color2[2] - color1[2]) * percent)) & 0xFF); ledIndex++; } /* for (i = 0; i < 12; i++) { uint8_t* pixel = buffers.fbNew->pixel(LEDS_PER_STRIP * 6 + i); pixel[0] = 0xFF; pixel[1] = 0; pixel[2] = 0; float scaled = ledIndex / 44.0f; (void)scaled; float noise = 32768; //noise2(scaled, time); //fix16_t noise = 32768 + noise2(scaled, time); //fix16_t noise = 32768 + fbm_noise3(scaled, time, 0, 4, 16384, 131072); noise = fmax(fmin(noise, 1), 0); float mult = 9 * noise; float index1 = floor(mult); float index2 = ceil(mult); float percent = mult - index1; (void)index2; (void)percent; uint32_t color = rainbow10[1];// fix16_to_int(index1)]; color1[0] = RED(color); color1[1] = GREEN(color); color1[2] = BLUE(color); color = rainbow10[2];// fix16_to_int(index2)]; color2[0] = RED(color); color2[1] = GREEN(color); color2[2] = BLUE(color); pixel[0] = (uint8_t)((int)(color1[0] + ((color2[0] - color1[0]) * percent)) & 0xFF); pixel[1] = (uint8_t)((int)(color1[1] + ((color2[1] - color1[1]) * percent)) & 0xFF); pixel[2] = (uint8_t)((int)(color1[2] + ((color2[2] - color1[2]) * percent)) & 0xFF); ledIndex++; } */ time = (time + timestep); buffers.finalizeFramebuffer(); } #endif // We can switch to the next frame's buffer now. buffers.finalizeFrame(); // Performance counter, for monitoring frame rate externally perf_frameCounter++; } // Reboot into DFU bootloader dfu_reboot(); }