firmware/main.c

Go to the documentation of this file.
00001 
00010 #include <avr/io.h>
00011 #include <avr/interrupt.h>
00012 #include <avr/pgmspace.h>
00013 
00014 #include "usbdrv.h"
00015 #include "oddebug.h"
00016 #include "pwm_channels.h"
00017 #include "usbledfader.h"
00018 #include "channels.h"
00019 
00021 static fade_GlobalData fade_globalData;
00022 
00024 static uint8_t usbRead;
00025 
00031 static void timerInterrupt(void)
00032 {
00033     uint8_t i = 0, changed = 0;
00034     for (i = 0; i < CHANNELS; i++) {
00035         fade_LedState *pLed = &(fade_globalData.led[i]);        /* fetch current LED */
00036         pLed->waveNextUpdate--;
00037         if (pLed->waveNextUpdate <= 0) {        /* time to update */
00038             fade_Waveform *pWave = &(pLed->wave[pLed->waveCurrentId]);  /* fetch currently active wave */
00039             pLed->waveCurrentPosition++;        /* go to next position */
00040             if (pLed->waveCurrentPosition > pWave->waveformLength) {
00041                 pLed->waveCurrentPosition = 1;  /* restart wave */
00042                 if (pWave->waveformRepetition == 0) {
00043                     /* repeat this waveform forever */
00044                 } else {
00045                     /* next repetition */
00046                     pLed->waveCurrentRepetition++;
00047                     if (pLed->waveCurrentRepetition >= pWave->waveformRepetition) { /* enough of this wave */
00048                         pLed->waveCurrentRepetition = 0;    /* reset repetition counter */
00049                         switch (pLed->waveCurrentId) {     /* activate next wave */
00050                             case 0:
00051                                 if (pLed->wave[1].waveformDuration > 0) { /* only activate if a wave is set */
00052                                     pLed->waveCurrentId = 1;
00053                                 }
00054                                 break;
00055                             case 1:
00056                                 if (pLed->wave[0].waveformDuration > 0) { /* only activate if a wave is set */
00057                                     pLed->waveCurrentId = 0;
00058                                 }
00059                                 break;
00060                             case 2:
00061                                 /* wave 2 is only to be repeated the given times,
00062                                  * reset and continue with wave 0 */
00063                                 pWave->waveformId = 0;
00064                                 pWave->waveformLength = fade_calculateWaveform(pWave->waveformId, 0);
00065                                 pWave->waveformRepetition = 1;
00066                                 pWave->waveformDuration = 0;
00067                                 pWave->waveformUpdateTime = 1;
00068                                 pLed->waveCurrentId = 0;
00069                                 break;
00070                         }
00071                     }
00072                 }
00073             }
00074             uint8_t newValue = fade_calculateWaveform(pLed->wave[pLed->waveCurrentId].waveformId, pLed->waveCurrentPosition); /* fetch new value */
00075             if (newValue != pLed->waveCurrentValue) {   /* only update if the value has changed */
00076                 pLed->waveCurrentValue = newValue;
00077                 changed = 1;
00078             }
00079             pLed->waveNextUpdate = pLed->wave[pLed->waveCurrentId].waveformUpdateTime; /* next update according to the wave's settings */
00080         }
00081     }
00082     if (changed) {              /* any value has changed, update all LEDs */
00083         pwm_Channels channels;
00084         for (i = 0; i < CHANNELS; i++) {
00085             channels.channel[i] = fade_globalData.led[i].waveCurrentValue;
00086         }
00087         pwm_Channels_show(channels);
00088     }
00089 }
00090 
00099 void fade_startWaveform(uint8_t ledId, uint8_t waveId, uint8_t waveformId, uint8_t periodDuration, uint8_t repetitionCount) {
00100     if ((ledId < CHANNELS) && (waveId < 3)) {
00101         fade_LedState *pLed = &(fade_globalData.led[ledId]);
00102         fade_Waveform *pWave = &(pLed->wave[waveId]);
00103         pLed->waveCurrentId = waveId;
00104         pLed->waveCurrentPosition = 0;
00105         pLed->waveCurrentRepetition = 0;
00106         pLed->waveNextUpdate = 0;
00107         if (periodDuration > 0) {
00108             pWave->waveformId = waveformId;
00109             pWave->waveformLength = fade_calculateWaveform(waveformId, 0);
00110             pWave->waveformRepetition = repetitionCount;
00111             pWave->waveformDuration = periodDuration;
00112             /* waveformUpdateTime in calls of timerInterrupt().
00113              * periodDuration in seconds/10.
00114              * 12000000 cycles per second
00115              * 64 cycles per timer/counter (prescaler)
00116              * 256 timer/counter per interrupt-call
00117              * -> (12000000 / (256 * 64)) = 732 calls per second */
00118             pWave->waveformUpdateTime = ((uint32_t)periodDuration * 12000000 / 256 / 64 / 10 / pWave->waveformLength );
00119         } else {
00120             /* periodDuration = 0, reset the wave */
00121             pWave->waveformId = 0;
00122             pWave->waveformLength = fade_calculateWaveform(pWave->waveformId, 0);
00123             pWave->waveformRepetition = 1;
00124             pWave->waveformDuration = 0;
00125             pWave->waveformUpdateTime = 1;
00126         }
00127     }
00128 }
00129 
00134 void fade_globalData_init(void) {
00135     int i = 0, j = 0;
00136     for (i = 0; i < CHANNELS; i++) {
00137         fade_globalData.led[i].waveCurrentId = 0;
00138         fade_globalData.led[i].waveCurrentPosition = 0;
00139         fade_globalData.led[i].waveCurrentRepetition = 0;
00140         fade_globalData.led[i].waveNextUpdate = 0;
00141         for (j = 0; j < 3; j++) {
00142             fade_globalData.led[i].wave[j].waveformId = 0;
00143             fade_globalData.led[i].wave[j].waveformLength =
00144                 fade_calculateWaveform(fade_globalData.led[i].wave[j].
00145                                        waveformId, 0);
00146             fade_globalData.led[i].wave[j].waveformRepetition = 1;
00147             fade_globalData.led[i].wave[j].waveformDuration = 0;
00148             fade_globalData.led[i].wave[j].waveformUpdateTime = 1;
00149         }
00150     }
00151     /* show that we are ready */
00152     for (i = 0; i < CHANNELS; i++) {
00153         fade_startWaveform(i, 2, 36, 10, 1);
00154     }
00155 }
00156 
00166 uchar usbFunctionRead(uchar *data, uchar len) {
00167     uint8_t i = 0;
00168     uint8_t *p_fade_globalData = (uint8_t*)&fade_globalData;
00169     while ((i < len) && (usbRead < sizeof(fade_GlobalData))) {
00170         data[i] = p_fade_globalData[usbRead];
00171         usbRead++;
00172         i++;
00173     }
00174     return i;
00175 }
00176 
00184 uchar usbFunctionWrite(uchar *data, uchar len) {
00185     /* parameters:
00186      * data[0]: command (0: echo, 1: read status, 2: set status, 3: clear)
00187      * data[1]: ledId
00188      * data[2]: waveId
00189      * data[3]: waveformId
00190      * data[4]: periodDuration
00191      * data[5]: repetitionCount
00192      */
00193     fade_startWaveform(data[1], data[2], data[3], data[4], data[5]);
00194     return 1;
00195 }
00196 
00203 uchar usbFunctionSetup(uchar data[8]) {
00204     int i;
00205     static uchar replyBuffer[8];
00206     uchar replyLength;
00207 
00208     replyBuffer[0] = msgOK;
00209     switch (data[1]) {
00210     case CMD_ECHO:                    /* echo */
00211         replyBuffer[0] = data[2];
00212         replyBuffer[1] = data[3];
00213         replyLength = 2;
00214         break;
00215     case CMD_GET:                    /* read status */
00216         usbRead = 0;
00217         replyLength = 0xff; /* special value, indicates that usbFunctionRead() has to be called */
00218         break;
00219     case CMD_SET:                    /* set status */
00220         replyLength = 0xff; /* special value, indicates that usbFunctionWrite() has to be called */
00221         break;
00222     case CMD_CLEAR:                  /* clear one LED */
00223         for (i = 0; i <= 2; i++) {
00224             /* clear all three waves on this LED */
00225             fade_startWaveform(data[2], i, 0, 0, 0);
00226         }
00227         replyLength = 1;
00228         break;
00229     case CMD_RESET:                  /* reset the device */
00230         fade_globalData_init();
00231         replyLength = 1;
00232         break;
00233     default:                         /* WTF? */
00234         replyBuffer[0] = msgErr;
00235         replyLength = 1;
00236         break;
00237     }
00238     usbMsgPtr = replyBuffer;
00239     return replyLength;
00240 }
00241 
00247 int main(void) {
00248     uchar i, j;
00249     odDebugInit();
00250     DDRD = ~0;                  /* output SE0 for USB reset */
00251     PORTD = 0x00;               /* no pullups on USB pins */
00252     DDRC = 0xff;                /* all outputs */
00253     PORTC = 0x00;
00254 
00255     j = 0;
00256     while (--j) {               /* USB Reset by device only required on Watchdog Reset */
00257         i = 0;
00258         while (--i);            /* delay >10ms for USB reset */
00259     }
00260     DDRD = ~USBMASK;            /* all outputs except USB data */
00261     TCCR0 = 3;                  /* set prescaler to 1/64 */
00262     usbInit();
00263     sei();
00264 
00265     pwm_Channels_init();
00266     fade_globalData_init();
00267 
00268     while (1) {                 /* main event loop */
00269         usbPoll();
00270         if (TIFR & (1 << TOV0)) {
00271             TIFR |= 1 << TOV0;  /* clear pending flag */
00272             timerInterrupt();
00273         }
00274     }
00275     return 0;
00276 }

Generated on Mon Oct 2 19:31:17 2006 for USB-LED-Fader by  doxygen 1.4.7