示例#1
0
/*!
 * Check tx message queue to see if any messages are pending.
 *
 * \retvalue    ERR_OK          Transmission started successfully.
 *              ERR_NOTAVAIL    No channel available.
 *              ERR_VALUE       Invalid tx type selected.
 *              ERR_DISABLED    Device was remotely disable (MaxDCycle setting).
 *              ERR_RXEMPTY     Message queue is empty.
 */
static uint8_t CheckTx( void )
{
    LoRaPhy_ChannelParams_t channel;
    uint8_t flags;
    uint8_t TxDataBuffer[LORAPHY_BUFFER_SIZE];

    if ( GetTxMsg(TxDataBuffer, sizeof(TxDataBuffer)) == ERR_OK ) {
#if 0
        if ( SetNextChannel() != ERR_OK ) {
            return ERR_NOTAVAIL;
        }
#endif
        flags = LORAPHY_BUF_FLAGS(TxDataBuffer);
        channel = Channels[pLoRaDevice->currChannelIndex];

        if ( flags & LORAPHY_PACKET_FLAGS_JOIN_REQ ) {
            pLoRaDevice->rxWindow1Delay = JoinAcceptDelay1 - RADIO_WAKEUP_TIME;
            pLoRaDevice->rxWindow2Delay = JoinAcceptDelay2 - RADIO_WAKEUP_TIME;
        } else {
            pLoRaDevice->rxWindow1Delay = ReceiveDelay1 - RADIO_WAKEUP_TIME;
            pLoRaDevice->rxWindow2Delay = ReceiveDelay2 - RADIO_WAKEUP_TIME;
        }

        Radio.SetChannel(channel.Frequency);
        Radio.SetMaxPayloadLength(MODEM_LORA, LORAPHY_BUF_SIZE(TxDataBuffer));

        if ( pLoRaDevice->currDataRateIndex == DR_7 ) {   // High Speed FSK channel
            Radio.SetTxConfig(MODEM_FSK, TxPowers[pLoRaDevice->currTxPowerIndex], 25e3, 0,
                    Datarates[pLoRaDevice->currDataRateIndex] * 1e3, 0, 5, false, true, 0, 0, false,
                    TX_TIMEOUT);
            TxTimeOnAir = Radio.TimeOnAir(MODEM_FSK, LORAPHY_BUF_SIZE(TxDataBuffer));
        } else if ( pLoRaDevice->currDataRateIndex == DR_6 ) {   // High speed LoRa channel
            Radio.SetTxConfig(MODEM_LORA, TxPowers[pLoRaDevice->currTxPowerIndex], 0, 1,
                    Datarates[pLoRaDevice->currDataRateIndex], 1, 8, false, true, 0, 0, false,
                    TX_TIMEOUT);
            TxTimeOnAir = Radio.TimeOnAir(MODEM_LORA, LORAPHY_BUF_SIZE(TxDataBuffer));
        } else {   // Normal LoRa channel
            Radio.SetTxConfig(MODEM_LORA, TxPowers[pLoRaDevice->currTxPowerIndex], 0, 0,
                    Datarates[pLoRaDevice->currDataRateIndex], 1, 8, false, true, 0, 0, false,
                    TX_TIMEOUT);
            TxTimeOnAir = Radio.TimeOnAir(MODEM_LORA, LORAPHY_BUF_SIZE(TxDataBuffer));
        }

        if ( MaxDCycle == 255 ) {
            return ERR_DISABLED;
        }
        if ( MaxDCycle == 0 ) {
            AggregatedTimeOff = 0;
        }

        if ( MAX(Bands[channel.Band].TimeOff, AggregatedTimeOff) > (TimerGetCurrentTime()) ) {
            // Schedule transmission
            LOG_TRACE("Send in %d ticks on channel %d (DR: %u).",
                    MAX(Bands[channel.Band].TimeOff, AggregatedTimeOff), channel.Frequency,
                    pLoRaDevice->currDataRateIndex);
            vTaskDelay(
                    MAX(Bands[channel.Band].TimeOff, AggregatedTimeOff)
                            / MAX(Bands[channel.Band].TimeOff, AggregatedTimeOff));
        } else {
            // Send now
            LOG_TRACE("Sending at %u ms on channel %d (DR: %u).",
                    (uint32_t)(TimerGetCurrentTime() * portTICK_PERIOD_MS), channel.Frequency,
                    pLoRaDevice->currDataRateIndex);
            Radio.Send(LORAPHY_BUF_PAYLOAD_START(TxDataBuffer), LORAPHY_BUF_SIZE(TxDataBuffer));
//            LOG_DEBUG("Send data on channel with frequency %u Hz", channel.Frequency);
        }

        if ( (flags & LORAPHY_PACKET_FLAGS_FRM_MASK) == LORAPHY_PACKET_FLAGS_FRM_ADVERTISING ) {
            phyFlags.Bits.TxType = LORAPHY_TXTYPE_ADVERTISING;
        } else if ( (flags & LORAPHY_PACKET_FLAGS_FRM_MASK) == LORAPHY_PACKET_FLAGS_FRM_REGULAR ) {
            phyFlags.Bits.TxType = LORAPHY_TXTYPE_REGULAR;
        } else if ( (flags & LORAPHY_PACKET_FLAGS_FRM_MASK)
                == LORAPHY_PACKET_FLAGS_FRM_MULTICAST ) {
            phyFlags.Bits.TxType = LORAPHY_TXTYPE_MULTICAST;
        } else {
            return ERR_VALUE;
        }

        return ERR_OK;
    }
    return ERR_NOTAVAIL; /* no data to send? */
}
示例#2
0
void ReadCTMU( void )
{
    int                     current_ipl;
    int                     i;
    int                     j;
    volatile unsigned int   tempADch;


    tempADch            = AD1CHS0;      //store the current A/D mux channel selected

    AD1CON1             = 0x0000;       // Unsigned integer format
    AD1CSSL             = 0x0000;
    AD1CON3             = 0x0002;
    AD1CON2             = 0x0000;
    AD1CON1bits.ADON    = 1;            // Start A/D in continuous mode

    for(i = 0; i < NUM_TOUCHPADS; i++)
    {
        // Get the raw sensor reading.
        AD1CHS0                 = STARTING_ADC_CHANNEL + buttonIndex; //select A/D channel

        // Make sure touch circuit is completely discharged
        IFS0bits.AD1IF          = 0;
        AD1CON1bits.DONE        = 0;
        AD1CON1bits.SAMP        = 1;        // Manually start the conversion
        // Wait for the A/D converter to begin sampling
        Nop();    Nop();    Nop();    Nop();    Nop();    Nop();    Nop();    Nop();
        CTMUCONbits.IDISSEN     = 1;        // Drain any charge on the circuit
        Nop();    Nop();    Nop();    Nop();    Nop();
        CTMUCONbits.IDISSEN     = 0;
        Nop();    Nop();    Nop();    Nop();    Nop();
        IFS0bits.AD1IF          = 0;
        AD1CON1bits.SAMP        = 0;
        while(!IFS0bits.AD1IF);             // Wait for the A/D conversion to finish
                                            // Note: This A/D conversion not used.
                                            // A/D mux must connect to the channel
                                            // for CTMU to drain charge

        // Charge touch circuit

        // Since the charge is time dependent, set the CPU priority such
        // that we will not be interrupted during the read.
        SET_AND_SAVE_CPU_IPL( current_ipl, 7 );

        IFS0bits.AD1IF          = 0;

        AD1CON1bits.SAMP        = 1;        // Manually start the conversion
        CTMUCONbits.EDG2STAT    = 0;        // Make sure edge2 is 0
        CTMUCONbits.EDG1STAT    = 1;        // Set edge1 - Start Charge

        for (j = 0; j < CHARGE_TIME_COUNT; j++);    // Delay for CTMU charge time

        CTMUCONbits.EDG1STAT    = 0;        // Clear edge1 - Stop Charge

        // Re-enable interrupts.
        RESTORE_CPU_IPL( current_ipl );

        IFS0bits.AD1IF          = 0;
        AD1CON1bits.SAMP        = 0;
        while(!IFS0bits.AD1IF);             // Wait for the A/D conversion to finish

        value                   = ADC1BUF0; // Read the value from the A/D conversion


        //Discharge the touch circuit
        IFS0bits.AD1IF          = 0;
        AD1CON1bits.SAMP        = 1;        // Manually start the conversion

        // Wait for A/D conversion to begin
        Nop();    Nop();    Nop();    Nop();    Nop();    Nop();    Nop();    Nop();
        CTMUCONbits.IDISSEN     = 1;        // Drain any charge on the circuit
        Nop();    Nop();    Nop();    Nop();    Nop();
        CTMUCONbits.IDISSEN     = 0;        // End charge drain
        Nop();    Nop();    Nop();    Nop();
        IFS0bits.AD1IF          = 0;
        AD1CON1bits.SAMP        = 0;        // Perform conversion
        while(!IFS0bits.AD1IF);             // Wait for the A/D conversion to finish
        IFS0bits.AD1IF          = 0;
        AD1CON1bits.DONE        = 0;        // Note: The A/D conversion not used
                                            // A/D mux must connect to the channel
                                            // for CTMU to drain charge
        //End of CTMU read


        bigVal                  = value  * 16;                  // bigVal is current measurement left shifted 4 bits
        smallAvg                = average[buttonIndex]  / 16;   // smallAvg is the current average right shifted 4 bits
        rawCTMU[buttonIndex]    = bigVal;                       // raw array holds the most recent bigVal values

        // On power-up, reach steady-state readings

        if (first > 0)
        {
            first--;
            average[buttonIndex] = bigVal;
            SetNextChannel();
            break;
        }

        // Is a keypad button pressed or released?

        if (bigVal < (average[buttonIndex] - trip[buttonIndex]))
        {
            // Pressed
            switch(buttonIndex)
            {
                case TOUCHPAD1:    buttons.BTN1  = 1;  break;
                case TOUCHPAD2:    buttons.BTN2  = 1;  break;
                case TOUCHPAD3:    buttons.BTN3  = 1;  break;
                case TOUCHPAD4:    buttons.BTN4  = 1;  break;
                case TOUCHPAD5:    buttons.BTN5  = 1;  break;
            }

        }
        else if (bigVal > (average[buttonIndex] - trip[buttonIndex] + hyst[buttonIndex]))
        {
            // Released
            switch(buttonIndex)
            {
                case TOUCHPAD1:    buttons.BTN1  = 0;  break;
                case TOUCHPAD2:    buttons.BTN2  = 0;  break;
                case TOUCHPAD3:    buttons.BTN3  = 0;  break;
                case TOUCHPAD4:    buttons.BTN4  = 0;  break;
                case TOUCHPAD5:    buttons.BTN5  = 0;  break;
            }
        }

        // Implement quick-release for a released button

        if (bigVal  > average[buttonIndex])
        {
            average[buttonIndex] = bigVal;                                      // If raw is above Average, reset to high average.
        }

        // Average in the new value.  Always Average (all buttons)
        // Counting 0..8 has effect of every 9th count cycling the next button.
        // Counting 0..4 will average faster and also can use 0..4*m, m=0,1,2,3..
        if(i == 0)
        {
            if (AvgIndex < AVG_DELAY)
            {
                AvgIndex++;
            }
            else
            {
                AvgIndex = 0;
            }
        }

        if (AvgIndex == AVG_DELAY)
        {
            // Average in raw value.
            average[buttonIndex] = average[buttonIndex] + (value - smallAvg);
        }

        // Determine next sensor to test.

        SetNextChannel();

    }

    if((screenState == SCREEN_GRAPH) || (screenState == SCREEN_CAPTURE))
    {
        // Read the potentiometer and store it for the demo.
        GraphReadPotentiometer();
    }

    #ifdef USE_TOUCHPAD_STATE_MACHINE
        GestureStateMachine();
    #endif

    AD1CHS0 = tempADch;  //restore A/D channel select
}