Esempio n. 1
0
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));
                }

            }
        }
    }
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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);
}
Esempio n. 4
0
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);
}
Esempio n. 5
0
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();
  }
}
Esempio n. 6
0
/*!
 @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
Esempio n. 7
0
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);
}