int main(void) { wdt_enable(WDTO_1S); odDebugInit(); DBG1(0x00, 0, 0); /* debug output: main starts */ ppmInit(); usbInit(); usbDeviceDisconnect(); /* enforce re-enumeration, do this while interrupts are disabled! */ uchar i = 0; while(--i){ /* fake USB disconnect for > 250 ms */ wdt_reset(); _delay_ms(1); } usbDeviceConnect(); DDRC|=3; // LEDs: Output sei(); DBG1(0x01, 0, 0); /* debug output: main loop starts */ uchar changed=0; ppmNewData=1; for(;;){ /* main event loop */ DBG1(0x02, 0, 0); /* debug output: main loop iterates */ wdt_reset(); usbPoll(); if (ppmNewData) { ppmNewData=0; for (i=0;i<sizeof(reportBuffer);i++) { unsigned char val=ppmGet(i); if (reportBuffer[i]!=val) { reportBuffer[i]=val; changed=1; } } if (changed) { if(usbInterruptIsReady()){ changed=0; // called after every poll of the interrupt endpoint DBG1(0x03, 0, 0); // debug output: interrupt report prepared usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer)); } } } } }
void ppmInConfig(const timerHardware_t *timerHardwarePtr) { ppmInit(); pwmInputPort_t *p = &pwmInputPorts[FIRST_PWM_PORT]; p->mode = INPUT_MODE_PPM; p->timerHardware = timerHardwarePtr; pwmGPIOConfig(timerHardwarePtr->gpio, timerHardwarePtr->pin, timerHardwarePtr->gpioInputMode); pwmICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising); timerConfigure(timerHardwarePtr, PPM_TIMER_PERIOD, PWM_TIMER_MHZ); configureTimerCaptureCompareInterrupt(timerHardwarePtr, UNUSED_PPM_TIMER_REFERENCE, ppmEdgeCallback, ppmOverflowCallback); }
void ppmInConfig(const timerHardware_t *timerHardwarePtr) { ppmInit(); pwmInputPort_t *self = &pwmInputPorts[FIRST_PWM_PORT]; self->mode = INPUT_MODE_PPM; self->timerHardware = timerHardwarePtr; pwmGPIOConfig(timerHardwarePtr->gpio, timerHardwarePtr->pin, timerHardwarePtr->gpioInputMode); pwmICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising); timerConfigure(timerHardwarePtr, (uint16_t)PPM_TIMER_PERIOD, PWM_TIMER_MHZ); timerChCCHandlerInit(&self->edgeCb, ppmEdgeCallback); timerChOvrHandlerInit(&self->overflowCb, ppmOverflowCallback); timerChConfigCallbacks(timerHardwarePtr, &self->edgeCb, &self->overflowCb); }
void ppmInConfig(const timerHardware_t *timerHardwarePtr) { ppmInit(); pwmInputPort_t *self = &pwmInputPorts[FIRST_PWM_PORT]; self->mode = INPUT_MODE_PPM; self->timerHardware = timerHardwarePtr; IO_t io = IOGetByTag(timerHardwarePtr->tag); IOInit(io, OWNER_PPMINPUT, RESOURCE_INPUT, 0); IOConfigGPIO(io, timerHardwarePtr->ioMode); pwmICConfig(timerHardwarePtr->tim, timerHardwarePtr->channel, TIM_ICPolarity_Rising); timerConfigure(timerHardwarePtr, (uint16_t)PPM_TIMER_PERIOD, PWM_TIMER_MHZ); timerChCCHandlerInit(&self->edgeCb, ppmEdgeCallback); timerChOvrHandlerInit(&self->overflowCb, ppmOverflowCallback); timerChConfigCallbacks(timerHardwarePtr, &self->edgeCb, &self->overflowCb); }
void main() { mode = MODE_LEGACY; //Init the chip ID initId(); //Init the led and set the leds until the usb is not ready #ifndef CRPA ledInit(CR_LED_RED, CR_LED_GREEN); #else ledInit(CRPA_LED_RED, CRPA_LED_GREEN); #endif ledSet(LED_GREEN | LED_RED, true); // Initialise the radio #ifdef CRPA // Enable LNA (PA RX) P0DIR &= ~(1<<CRPA_PA_RXEN); P0 |= (1<<CRPA_PA_RXEN); #endif radioInit(RADIO_MODE_PTX); #ifdef PPM_JOYSTICK // Initialise the PPM acquisition ppmInit(); #endif //PPM_JOYSTICK // Initialise and connect the USB usbInit(); //Globally activate the interruptions IEN0 |= 0x80; //Wait for the USB to be addressed while (usbGetState() != ADDRESS); //Reset the LEDs ledSet(LED_GREEN | LED_RED, false); //Wait for the USB to be ready while (usbGetState() != CONFIGURED); //Activate OUT1 OUT1BC=0xFF; while(1) { if (mode == MODE_LEGACY) { // Run legacy mode legacyRun(); } else if (mode == MODE_CMD) { // Run cmd mode cmdRun(); } else if (mode == MODE_PRX) { // Run PRX mode prxRun(); } //USB vendor setup handling if(usbIsVendorSetup()) handleUsbVendorSetup(); } }
/*! @brief main program of the I2C-slave Initializes the timer/counters and the I2C. Constantly updates the duty cycles of the PPM @return int */ int main(void) { int i; cli(); // Disable interrupts usiTwiSlaveInit(SLAVE_ADDR_ATTINY); // TWI slave init //Initialize rxbuffer rxbuffer[0] = HIGH_BYTE( (dutyCycles[0] - 1*8192) ); rxbuffer[1] = LOW_BYTE( (dutyCycles[0] - 1*8192) ); rxbuffer[2] = HIGH_BYTE( (dutyCycles[1] - 2*8192) ); rxbuffer[3] = LOW_BYTE( (dutyCycles[1] - 2*8192) ); rxbuffer[4] = HIGH_BYTE( (dutyCycles[2] - 3*8192) ); rxbuffer[5] = LOW_BYTE( (dutyCycles[2] - 3*8192) ); rxbuffer[6] = HIGH_BYTE( (dutyCycles[3] - 0*8192) ); rxbuffer[7] = LOW_BYTE( (dutyCycles[3] - 0*8192) ); ppmInit(); sei(); // Re-enable interrupts while(1) { /* receivedNewValue is updated whenever a new value is written to the rxbuffer with the corresponding index As always 2 bytes are used for one dutyCycle the interesting values are 1, 3, 5, 7 Then the corresponding value in the dutyCycle array is updated The new value for a dutyCycle is calculated first in a temp-variable. In a previous version it was directly assigned within the atomic block which caused severs problems that the ucontroller stopped responding to the I2C-master. Therefore now only the assignment to dutyCycles[x] is done in atomic block */ uint16_t temp; switch (receivedNewValue) { case 1: //update dutyCycle for channel 0 receivedNewValue = 0; temp = uniq(rxbuffer[1], rxbuffer[0]) + 1 * 8192; ATOMIC_BLOCK(ATOMIC_FORCEON) { dutyCycles[0] = temp; } txbuffer[0] = rxbuffer[0]; txbuffer[1] = rxbuffer[1]; break; case 3: //update dutyCycle for channel 1 receivedNewValue = 0; temp = uniq(rxbuffer[3], rxbuffer[2]) + 2 * 8192; ATOMIC_BLOCK(ATOMIC_FORCEON) { dutyCycles[1] = temp; } txbuffer[2] = rxbuffer[2]; txbuffer[3] = rxbuffer[3]; break; case 5: //update dutyCycle for channel 2 receivedNewValue = 0; temp = uniq(rxbuffer[5], rxbuffer[4]) + 3 * 8192; ATOMIC_BLOCK(ATOMIC_FORCEON) { dutyCycles[2] = temp; } txbuffer[4] = rxbuffer[4]; txbuffer[5] = rxbuffer[5]; break; case 7: //update dutyCycle for channel 3 receivedNewValue = 0; temp = uniq(rxbuffer[7], rxbuffer[6]) + 0 * 8192; ATOMIC_BLOCK(ATOMIC_FORCEON) { dutyCycles[3] = temp; } txbuffer[6] = rxbuffer[6]; txbuffer[7] = rxbuffer[7]; break; } //end.switch } //end.while } //end.main
void radioInit(void) { uint16_t radioType = (uint16_t)p[RADIO_TYPE]; int i; AQ_NOTICE("Radio init\n"); memset((void *)&radioData, 0, sizeof(radioData)); radioData.mode = (radioType>>12) & 0x0f; for (i = 0; i < RADIO_NUM; i++) { radioInstance_t *r = &radioData.radioInstances[i]; USART_TypeDef *uart; // determine UART switch (i) { case 0: uart = RC1_UART; break; #ifdef RC2_UART case 1: uart = RC2_UART; break; #endif #ifdef RC3_UART case 2: uart = RC3_UART; break; #endif default: uart = 0; break; } r->radioType = (radioType>>(i*4)) & 0x0f; r->channels = &radioData.allChannels[RADIO_MAX_CHANNELS * i]; utilFilterInit(&r->qualityFilter, (1.0f / 50.0f), 0.75f, 0.0f); switch (r->radioType) { case RADIO_TYPE_SPEKTRUM11: case RADIO_TYPE_SPEKTRUM10: case RADIO_TYPE_DELTANG: if (uart) { spektrumInit(r, uart); radioRCSelect(i, 0); AQ_PRINTF("Spektrum on RC port %d\n", i); } break; case RADIO_TYPE_SBUS: if (uart) { futabaInit(r, uart); radioRCSelect(i, 1); AQ_PRINTF("Futaba on RC port %d\n", i); } break; case RADIO_TYPE_PPM: ppmInit(r); AQ_PRINTF("PPM on RC port %d\n", i); break; case RADIO_TYPE_SUMD: if (uart) { grhottInit(r, uart); radioRCSelect(i, 0); AQ_PRINTF("GrHott on RC port %d\n", i); } break; case RADIO_TYPE_MLINK: if (uart) { mlinkrxInit(r, uart); radioRCSelect(i, 0); AQ_PRINTF("Mlink on RC port %d\n", i); } break; case RADIO_TYPE_NONE: break; default: AQ_NOTICE("WARNING: Invalid radio type!\n"); break; } } switch (radioData.mode) { case RADIO_MODE_DIVERSITY: // select first available radio to start with for (i = 0; i < RADIO_NUM; i++) { if (radioData.radioInstances[i].radioType > RADIO_TYPE_NONE) { radioMakeCurrent(&radioData.radioInstances[i]); break; } } break; case RADIO_MODE_SPLIT: radioMakeCurrent(&radioData.radioInstances[0]); break; } // set mode default radioData.channels[(int)p[RADIO_FLAP_CH]] = -700; radioTaskStack = aqStackInit(RADIO_STACK_SIZE, "RADIO"); radioData.radioTask = CoCreateTask(radioTaskCode, (void *)0, RADIO_PRIORITY, &radioTaskStack[RADIO_STACK_SIZE-1], RADIO_STACK_SIZE); }