Ejemplo n.º 1
0
/**
 *  pinMode - Configures either a digital pin or tsi pin as a wakeup source.
 *  
 *  Teensy 3.x (digital pin)
 *  @param pin  - sleep pins(1-33), deepSleep, hibernate pins (2,4,6,7,9,10,11,13,16,21,22,26,30,33)
 *  @param mode - |INPUT|INPUT_PULLUP|OUTPUT|
 *  @param val  - |HIGH|LOW|RISING|FALLING|CHANGE|
 *
 *  Teensy 3.x (tsi pin)
 *  @param pin  - sleep pins(does not work), deepSleep, hibernate pins (0,1,15,16,17,18,19,22,23,25,32,33)
 *  @param mode - |TSI|
 *  @param val  - threshold capacitance value, greater than this value wakes.
 *
 *  Teensy LC (digital pin)
 *  @param pin  - sleep pins(1-33), deepSleep, hibernate pins (2,4,6,7,9,10,11,13,16,21,22,26)
 *  @param mode - |INPUT|INPUT_PULLUP|OUTPUT|
 *  @param val  - |HIGH|LOW|RISING|FALLING|CHANGE|
 *
 *  Teensy LC (tsi pin)
 *  @param pin  - sleep pins(does not work), deepSleep, hibernate pins (0,1,3,4,15,16,17,18,19,22,23)
 *  @param mode - |TSI|
 *  @param val  - threshold capacitance value, greater than this value wakes.
 */
void SnoozeBlock::pinMode( int pin, int mode, int val ) {
    if ( mode == INPUT ) {
        digital_configure_pin_mask( pin, mode, val, &digital_mask );
        llwu_configure_pin_mask( pin, val, &llwu_mask );
    }
    else if ( mode == INPUT_PULLUP ) {
        digital_configure_pin_mask( pin, mode, val, &digital_mask );
        llwu_configure_pin_mask( pin, val, &llwu_mask );
    }
    else if ( mode == OUTPUT ) {
        digital_configure_pin_mask( pin, mode, val, &digital_mask );
        llwu_configure_pin_mask( pin, val, &llwu_mask );
    }
    else if ( mode == TSI ) {
        tsi_configure_pin_mask( pin, val, &tsi_mask );
        llwu_configure_modules_mask( LLWU_TSI_MOD, &llwu_mask );
    }
}
Ejemplo n.º 2
0
/*******************************************************************************
 *  Enable digital interrupt and configure the pin
 *******************************************************************************/
void SnoozeDigital::enableDriver( void ) {
    if ( mode == RUN_LP ) { return; }
#if defined(KINETISK)
    uint64_t _pin = pin;
    isr_pin = pin;
    if ( mode == VLPW || mode == VLPS ) {

        return_isr_a_enabled = NVIC_IS_ENABLED( IRQ_PORTA );
        return_isr_b_enabled = NVIC_IS_ENABLED( IRQ_PORTB );
        return_isr_c_enabled = NVIC_IS_ENABLED( IRQ_PORTC );
        return_isr_d_enabled = NVIC_IS_ENABLED( IRQ_PORTD );
        return_isr_e_enabled = NVIC_IS_ENABLED( IRQ_PORTE );
        NVIC_DISABLE_IRQ(IRQ_PORTA);
        NVIC_DISABLE_IRQ(IRQ_PORTB);
        NVIC_DISABLE_IRQ(IRQ_PORTC);
        NVIC_DISABLE_IRQ(IRQ_PORTD);
        NVIC_DISABLE_IRQ(IRQ_PORTE);
        NVIC_CLEAR_PENDING(IRQ_PORTA);
        NVIC_CLEAR_PENDING(IRQ_PORTB);
        NVIC_CLEAR_PENDING(IRQ_PORTC);
        NVIC_CLEAR_PENDING(IRQ_PORTD);
        NVIC_CLEAR_PENDING(IRQ_PORTE);
        
        int priority = nvic_execution_priority( );// get current priority
        // if running from interrupt set priority higher than current interrupt
        priority = ( priority < 256 ) && ( ( priority - 16 ) > 0 ) ? priority - 16 : 128;
        return_priority_a = NVIC_GET_PRIORITY( IRQ_PORTA );//get current priority
        return_priority_b = NVIC_GET_PRIORITY( IRQ_PORTB );//get current priority
        return_priority_c = NVIC_GET_PRIORITY( IRQ_PORTC );//get current priority
        return_priority_d = NVIC_GET_PRIORITY( IRQ_PORTD );//get current priority
        return_priority_e = NVIC_GET_PRIORITY( IRQ_PORTE );//get current priority
        NVIC_SET_PRIORITY( IRQ_PORTA, priority );//set priority to new level
        NVIC_SET_PRIORITY( IRQ_PORTB, priority );//set priority to new level
        NVIC_SET_PRIORITY( IRQ_PORTC, priority );//set priority to new level
        NVIC_SET_PRIORITY( IRQ_PORTD, priority );//set priority to new level
        NVIC_SET_PRIORITY( IRQ_PORTE, priority );//set priority to new level
        
        __disable_irq( );
        return_porta_irq = _VectorsRam[IRQ_PORTA+16];// save prev isr handler
        return_portb_irq = _VectorsRam[IRQ_PORTB+16];// save prev isr handler
        return_portc_irq = _VectorsRam[IRQ_PORTC+16];// save prev isr handler
        return_portd_irq = _VectorsRam[IRQ_PORTD+16];// save prev isr handler
        return_porte_irq = _VectorsRam[IRQ_PORTE+16];// save prev isr handler
        attachInterruptVector( IRQ_PORTA, isr );// set snooze digA isr
        attachInterruptVector( IRQ_PORTB, isr );// set snooze digB isr
        attachInterruptVector( IRQ_PORTC, isr );// set snooze digC isr
        attachInterruptVector( IRQ_PORTD, isr );// set snooze digD isr
        attachInterruptVector( IRQ_PORTE, isr );// set snooze digE isr
        __enable_irq( );
        
        NVIC_ENABLE_IRQ( IRQ_PORTA );
        NVIC_ENABLE_IRQ( IRQ_PORTB );
        NVIC_ENABLE_IRQ( IRQ_PORTC );
        NVIC_ENABLE_IRQ( IRQ_PORTD );
        NVIC_ENABLE_IRQ( IRQ_PORTE );
    }
    _pin = pin;
    while ( __builtin_popcountll( _pin ) ) {
        uint32_t pinNumber  = 63 - __builtin_clzll( _pin );// get pin
        
        if ( pinNumber > 33 ) break;
        
        uint32_t pin_mode = irqType[pinNumber] >> 4;// get type
        uint32_t pin_type = irqType[pinNumber] & 0x0F;// get mode
        
        volatile uint32_t *config;
        config = portConfigRegister( pinNumber );
        return_core_pin_config[pinNumber] = *config;
        
        if ( pin_mode == INPUT || pin_mode == INPUT_PULLUP ) {// setup pin mode/type/interrupt
            *portModeRegister( pinNumber ) = 0;
            if ( pin_mode == INPUT ) *config = PORT_PCR_MUX( 1 );
            else *config = PORT_PCR_MUX( 1 ) | PORT_PCR_PE | PORT_PCR_PS;// pullup
            if ( mode == VLPW || mode == VLPS ) {
                attachDigitalInterrupt( pinNumber, pin_type );// set pin interrupt
            }
            else {
                llwu_configure_pin_mask( pinNumber, mode );
            }
        } else {
            //pinMode( pinNumber, pin_mode );
            //digitalWriteFast( pinNumber, pin_type );
        }
        _pin &= ~( ( uint64_t )1 << pinNumber );// remove pin from list
    }
#elif defined(KINETISL)
    uint32_t _pin = pin;
    isr_pin = pin;
    if ( mode == VLPW || mode == VLPS ) {// if using sleep must setup pin interrupt to wake
        return_isr_a_enabled  = NVIC_IS_ENABLED( IRQ_PORTA );
        return_isr_cd_enabled = NVIC_IS_ENABLED( IRQ_PORTCD );
        NVIC_DISABLE_IRQ(IRQ_PORTA);
        NVIC_DISABLE_IRQ(IRQ_PORTCD);
        NVIC_CLEAR_PENDING(IRQ_PORTA);
        NVIC_CLEAR_PENDING(IRQ_PORTCD);
        int priority = nvic_execution_priority( );// get current priority
        // if running from interrupt set priority higher than current interrupt
        priority = ( priority < 256 ) && ( ( priority - 16 ) > 0 ) ? priority - 16 : 128;
        return_priority_a = NVIC_GET_PRIORITY( IRQ_PORTA );//get current priority
        return_priority_cd = NVIC_GET_PRIORITY( IRQ_PORTCD );//get current priority
        NVIC_SET_PRIORITY( IRQ_PORTA, priority );//set priority to new level
        NVIC_SET_PRIORITY( IRQ_PORTCD, priority );//set priority to new level
        __disable_irq( );
        return_porta_irq = _VectorsRam[IRQ_PORTA+16];// save prev isr handler
        return_portcd_irq = _VectorsRam[IRQ_PORTCD+16];// save prev isr handler
        attachInterruptVector( IRQ_PORTA, isr );// set snooze isr
        attachInterruptVector( IRQ_PORTCD, isr );// set snooze isr
        __enable_irq( );
        NVIC_ENABLE_IRQ( IRQ_PORTA );
        NVIC_ENABLE_IRQ( IRQ_PORTCD );
    }
    _pin = pin;
    while ( __builtin_popcount( _pin ) ) {
        uint32_t pinNumber  = 31 - __builtin_clz( _pin );// get pin
        
        if ( pinNumber > 33 ) break;
        
        uint32_t pin_mode = irqType[pinNumber] >> 4;// get type
        uint32_t pin_type = irqType[pinNumber] & 0x0F;// get mode
        
        volatile uint32_t *config;
        config = portConfigRegister( pinNumber );
        return_core_pin_config[pinNumber] = *config;
        
        if ( pin_mode == INPUT || pin_mode == INPUT_PULLUP ) {// setup pin mode/type/interrupt
            *portModeRegister( pinNumber ) &= ~digitalPinToBitMask( pinNumber ); // TODO: atomic
            if ( pin_mode == INPUT ) *config = PORT_PCR_MUX( 1 );
            else *config = PORT_PCR_MUX( 1 ) | PORT_PCR_PE | PORT_PCR_PS;// pullup
            if ( pin_mode == VLPW || pin_mode == VLPS ) {
               attachDigitalInterrupt( pinNumber, pin_type );// set pin interrupt
            }
            else {
                llwu_configure_pin_mask( pinNumber, pin_mode );
            }
        } else {
            //pinMode( pinNumber, pin_mode );
            //digitalWriteFast( pinNumber, pin_type );
        }
        _pin &= ~( ( uint32_t )1 << pinNumber );// remove pin from list
    }
#endif
}