Esempio n. 1
0
static void handle_interrupt_in(void) {
    // Read in all current interrupt registers. We do this once as the
    // GPIO interrupt registers are on the APB bus, and this is slow.
    uint32_t rise0 = LPC_GPIOINT->IO0IntStatR;
    uint32_t fall0 = LPC_GPIOINT->IO0IntStatF;
    uint32_t rise2 = LPC_GPIOINT->IO2IntStatR;
    uint32_t fall2 = LPC_GPIOINT->IO2IntStatF;
    uint8_t bitloc;
    
    while(rise0 > 0) {      //Continue as long as there are interrupts pending
        bitloc = 31 - __CLZ(rise0); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
        if (channel_ids[bitloc] != 0)
            irq_handler(channel_ids[bitloc], IRQ_RISE); //Run that interrupt
        
        //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
        LPC_GPIOINT->IO0IntClr = 1 << bitloc;
        rise0 -= 1<<bitloc;
    }
    
    while(fall0 > 0) {      //Continue as long as there are interrupts pending
        bitloc = 31 - __CLZ(fall0); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
        if (channel_ids[bitloc] != 0)
            irq_handler(channel_ids[bitloc], IRQ_FALL); //Run that interrupt
        
        //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
        LPC_GPIOINT->IO0IntClr = 1 << bitloc;
        fall0 -= 1<<bitloc;
    }
    
    //Same for port 2, only we need to watch the channel_index
    while(rise2 > 0) {      //Continue as long as there are interrupts pending
        bitloc = 31 - __CLZ(rise2); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
        
        if (bitloc < 16)            //Not sure if this is actually needed
            if (channel_ids[bitloc+32] != 0)
                irq_handler(channel_ids[bitloc+32], IRQ_RISE); //Run that interrupt
        
        //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
        LPC_GPIOINT->IO2IntClr = 1 << bitloc;
        rise2 -= 1<<bitloc;
    }
    
    while(fall2 > 0) {      //Continue as long as there are interrupts pending
        bitloc = 31 - __CLZ(fall2); //CLZ returns number of leading zeros, 31 minus that is location of first pending interrupt
        
        if (bitloc < 16)            //Not sure if this is actually needed
            if (channel_ids[bitloc+32] != 0)
                irq_handler(channel_ids[bitloc+32], IRQ_FALL); //Run that interrupt
        
        //Both clear the interrupt with clear register, and remove it from our local copy of the interrupt pending register
        LPC_GPIOINT->IO2IntClr = 1 << bitloc;
        fall2 -= 1<<bitloc;
    }
}
Esempio n. 2
0
static void handle_interrupt_in(PORT_Type *port, int ch_base) {
    uint32_t isfr;
    uint32_t pin;

    while ((isfr = port->ISFR) != 0) {
        pin = 31 - __CLZ(isfr);
        uint32_t id = channel_ids[ch_base + pin];
        if (id == 0) {
            continue;
        }

        GPIO_Type *gpio = PTA;
        gpio_irq_event event = IRQ_NONE;
        uint32_t port_num = (port - PORTA) >> 12;

        switch (port->PCR[pin] & PORT_PCR_IRQC_MASK) {
            case IRQ_RAISING_EDGE:
                event = IRQ_RISE;
                break;
            case IRQ_FALLING_EDGE:
                event = IRQ_FALL;
                break;
            case IRQ_EITHER_EDGE:
                gpio += (port_num * 0x40);
                event = (gpio->PDIR & (1 << pin)) ? (IRQ_RISE) : (IRQ_FALL);
                break;
        }
        if (event != IRQ_NONE) {
            irq_handler(id, event);
        }
        port->ISFR = 1 << pin;
    }
}
Esempio n. 3
0
/* Global  functions ---------------------------------------------------------*/
NWK_PRIVATE bool nwkNewPassiveAck(frame_info_t *const txDelay,
  const ShortAddr_t prevHopAddr, const ShortAddr_t srcAddr,
  const NwkSequenceNumber_t seqNum)
{
	uint8_t index;


	index = __CLZ(__RBIT(~gNwkPassiveAckTable.BitMap));
	if (index>=NWK_MAX_BROADCASR_TABLE_ENTRY)//考虑freelargequeue 只有3个多广播源定时器
		return false;
	gNwkPassiveAckTable.table[index].broacCastFrame = txDelay;
	gNwkPassiveAckTable.table[index].seqNum = seqNum;
	gNwkPassiveAckTable.table[index].srcAddr = srcAddr;
	gNwkPassiveAckTable.amount++;
	gNwkPassiveAckTable.BitMap |= 1<<index;
	gNwkPassiveAckTable.table[index].routerNum = 0;
	gNwkPassiveAckTable.table[index].endDeviceNum = 0;
	gNwkPassiveAckTable.table[index].prevHopAddr = prevHopAddr;
	gNwkPassiveAckTable.table[index].timerID = index+APP_TIMER_BC_DATA;
	if (txDelay == NULL)
		gNwkPassiveAckTable.table[index].end = true;
	else
		gNwkPassiveAckTable.table[index].end = false;
	gNwkPassiveAckTable.table[index].reTryTimes = 0;
#ifndef VANET
	uint8_t i,j=0;    
	if (srcAddr != gNwk_nib.networkAddress)
	{
		gNwkPassiveAckTable.table[index].realyNeighborNum = 1;
		NwkNeighbor_t *tempNeighbor;
		tempNeighbor = NWK_FindNeighborByShortAddr(prevHopAddr);
        if (tempNeighbor != NULL)
        {
        	tempNeighbor->isBroadRelay[index] = true;
        }
	}
	else gNwkPassiveAckTable.table[index].realyNeighborNum = 0;


	if (neighborTable.size != 0)
	{
		for (i=0; i<MAX_NEIGHBOR_TABLE_NUMBER ; i++)
		{
		  if (neighborTableArray[i].table.relationship != RELATIONSHIP_EMPTY)
		  {
			 j++;
			 if (neighborTableArray[i].table.deviceType == DEVICE_TYPE_COORDINATOR || neighborTableArray[i].table.deviceType == DEVICE_TYPE_ROUTER)
				 gNwkPassiveAckTable.table[index].routerNum++;
			 else gNwkPassiveAckTable.table[index].endDeviceNum++;

			 if (j == neighborTable.size)
				 break;
		  }
		}
	}
#endif
    return true;
}
Esempio n. 4
0
/***************************************************************************//**
 * @brief
 *   Configure Timer for this application.
 *******************************************************************************/
void initTimer(void)
{
  /* Use default setting of CTRL register, configure PRESC with different */
  /* BASE_FREQ and system core clock frequency, the BASE_FREQ depends on */
  /* maximum sampling frequency of ADC and DAC */
  TIMER_USED->CTRL |= ((31 - __CLZ(SystemCoreClock/BASE_FREQ)) << _TIMER_CTRL_PRESC_SHIFT);
#if (SPEEX_BAND < WIDEBAND || SPEEX_BAND == NB8KCODEC)
  TIMER_USED->TOP = SAMPLE_8K;
#endif
}
Esempio n. 5
0
uint8_t msm_bus_noc_get_qos_mode(struct msm_bus_noc_info *ninfo,
	uint32_t mport, uint32_t mode, uint32_t perm_mode)
{
	if (NOC_QOS_MODES_ALL_PERM == perm_mode)
		return readl_relaxed(NOC_QOS_MODEn_ADDR(ninfo->base,
			mport)) & NOC_QOS_MODEn_MODE_BMSK;
	else
		return 31 - __CLZ(mode &
			NOC_QOS_MODES_ALL_PERM);
}
uint8_t msm_bus_noc_get_qos_mode(void __iomem *base, uint32_t qos_off,
	uint32_t mport, uint32_t qos_delta, uint32_t mode, uint32_t perm_mode)
{
	if (NOC_QOS_MODES_ALL_PERM == perm_mode)
		return readl_relaxed(NOC_QOS_MODEn_ADDR(base, qos_off,
			mport, qos_delta)) & NOC_QOS_MODEn_MODE_BMSK;
	else
		return 31 - __CLZ(mode &
			NOC_QOS_MODES_ALL_PERM);
}
Esempio n. 7
0
static void timer_init(void) {  
    //CLZ counts the leading zeros, returning number of bits not used by clk_mhz
    timer_ldval = clk_mhz << __CLZ(clk_mhz);

    PIT_TIMER.LDVAL = timer_ldval;  // 1us
    PIT_TIMER.TCTRL |= PIT_TCTRL_TIE_MASK;
    PIT_TIMER.TCTRL |= PIT_TCTRL_TEN_MASK;  // Start timer 0

    NVIC_SetVector(PIT_TIMER_IRQ, (uint32_t)timer_isr);
    NVIC_EnableIRQ(PIT_TIMER_IRQ);
}
Esempio n. 8
0
/***************************************************************************//**
 * @brief Convert dividend to prescaler logarithmic value. Only works for even
 *        numbers equal to 2^n
 * @param[in] div Unscaled dividend,
 * @return Base 2 logarithm of input, as used by fixed prescalers
 ******************************************************************************/
__STATIC_INLINE uint32_t divToLog2(uint32_t div)
{
  uint32_t log2;

  /* Prescaler accepts an argument of 128 or less, valid values being 2^n */
  EFM_ASSERT((div > 0) && (div <= 32768));

  /* Count leading zeroes and "reverse" result, Cortex-M3 intrinsic */
  log2 = (31 - __CLZ(div));

  return log2;
}
Esempio n. 9
0
void vSetupInterruptNestingTest( void )
{
unsigned long ulCompareMatchBits;

	/* Create the semaphore used to communicate between the high frequency
	interrupt and the task. */
	vSemaphoreCreateBinary( xHighFrequencyTimerSemaphore );
	configASSERT( xHighFrequencyTimerSemaphore );
	
	/* Create the task that pends on the semaphore that is given by the
	high frequency interrupt. */
	xTaskCreate( prvHighFrequencyTimerTask, ( signed char * ) "HFTmr", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
	
	/* Setup the interrupt itself.	The STM module clock divider is setup when 
	the tick interrupt is configured - which is when the scheduler is started - 
	so there is no need	to do it here.

	The tick interrupt uses compare match 0, so this test uses compare match
	1, which means shifting up the values by 16 before writing them to the
	register. */
	ulCompareMatchBits = ( 0x1fUL - __CLZ( ulCompareMatchValue ) );
	ulCompareMatchBits <<= 16UL;
	
	/* Write the values to the relevant SMT registers, without changing other
	bits. */
	taskENTER_CRITICAL();
	{
		STM_CMCON.reg &= ~( 0x1fUL << 16UL );
		STM_CMCON.reg |= ulCompareMatchBits;
		STM_CMP1.reg = ulCompareMatchValue;

		if( 0 != _install_int_handler( configHIGH_FREQUENCY_TIMER_PRIORITY, prvPortHighFrequencyTimerHandler, 0 ) )
		{
			/* Set-up the interrupt. */
			STM_SRC1.reg = ( configHIGH_FREQUENCY_TIMER_PRIORITY | 0x00005000UL );
	
			/* Enable the Interrupt. */
			STM_ISRR.reg &= ~( 0x03UL << 2UL );
			STM_ISRR.reg |= ( 0x1UL << 2UL );
			STM_ICR.reg &= ~( 0x07UL << 4UL );
			STM_ICR.reg |= ( 0x5UL << 4UL );
		}
		else
		{
			/* Failed to install the interrupt. */
			configASSERT( ( ( volatile void * ) NULL ) );
		}
	}
	taskEXIT_CRITICAL();
}
Esempio n. 10
0
int8_t add_white_list(uint16_t srcAddr)
{
	int8_t index = -1;
	index = find_white_list(srcAddr);
	if (index != -1)
		return index;	
	index = __CLZ(__RBIT(~whiteBitMap));
	if (index < 32)
	{
		whiteBitMap |= 1 << index;
		whiteTable[index] = srcAddr;
		whiteListCount++;
	}
	return index;
}
Esempio n. 11
0
int8_t add_black_list(uint16_t srcAddr)
{
	int8_t index = -1;
	index = find_black_list(srcAddr);
	if (index != -1)
		return index;
	index = __CLZ(__RBIT(~blackBitMap));
	if (index < 32)
	{
		blackBitMap |= 1 << index;
		blackTable[index] = srcAddr;
		blackListCount++;
	}
	return index;
}
Esempio n. 12
0
uint32_t us_ticker_read() {
    if (!us_ticker_inited)
        us_ticker_init();
        
    uint32_t retval;
    __disable_irq(); 
    retval = (timer_ldval - PIT_TIMER.CVAL) / clk_mhz; //Hardware bits
    retval |= msb_counter << __CLZ(clk_mhz);           //Software bits
    
    if (PIT_TIMER.TFLG == 1) {                         //If overflow bit is set, force it to be handled
        timer_isr();                                   //Handle IRQ, read again to make sure software/hardware bits are synced
        NVIC_ClearPendingIRQ(PIT_TIMER_IRQ);
        return us_ticker_read();
    }

    __enable_irq();
    return retval;
}
Esempio n. 13
0
static void handle_interrupt_in(void) {

    uint8_t picus[PICU_COUNT] =
    {
        CY_GET_REG8(CYREG_PICU0_INTSTAT),
        CY_GET_REG8(CYREG_PICU1_INTSTAT),
        CY_GET_REG8(CYREG_PICU2_INTSTAT),
        CY_GET_REG8(CYREG_PICU3_INTSTAT),
        CY_GET_REG8(CYREG_PICU4_INTSTAT),
        CY_GET_REG8(CYREG_PICU5_INTSTAT),
        CY_GET_REG8(CYREG_PICU6_INTSTAT),
        CY_GET_REG8(CYREG_PICU12_INTSTAT),
        CY_GET_REG8(CYREG_PICU15_INTSTAT)
    };

    uint8_t bitloc;

    for (uint8_t p=0; p<PICU_COUNT;p++)
    {
        while (picus[p] > 0) {
            // get the position of the MSB in INTSTAT register
            bitloc = 31 - __CLZ(picus[p]);

            //test to see if there is an installed interrupt
            if (channel_ids[p*8+bitloc] != 0)
            {
                uint8_t type = 0;
                if (p < 7)
                    type = CY_GET_REG8( CYDEV_PICU_INTTYPE_BASE + (p*8+bitloc) );
                else if (p == 7)
                    type = CY_GET_REG8( CYDEV_PICU_INTTYPE_BASE + (12*8+bitloc) );
                else if (p == 8)
                    type = CY_GET_REG8( CYDEV_PICU_INTTYPE_BASE + (15*8+bitloc) );

                if (type == 1)
                    irq_handler(channel_ids[p*8+bitloc], IRQ_RISE);
                else if (type > 1) //also catches BOTH (change trigger)
                    irq_handler(channel_ids[p*8+bitloc], IRQ_FALL);
            }

            picus[p] -= 1<<bitloc;
        }
    }
}
Esempio n. 14
0
static void prvSetupTimerInterrupt( void )
{
	/* Set-up the clock divider. */
	unlock_wdtcon();
	{
		/* Wait until access to Endint protected register is enabled. */
		while( 0 != ( WDT_CON0.reg & 0x1UL ) );

		/* RMC == 1 so STM Clock == FPI */
		STM_CLC.reg = ( 1UL << 8 );
	}
	lock_wdtcon();

    /* Determine how many bits are used without changing other bits in the CMCON register. */
	STM_CMCON.reg &= ~( 0x1fUL );
	STM_CMCON.reg |= ( 0x1fUL - __CLZ( configPERIPHERAL_CLOCK_HZ / configTICK_RATE_HZ ) );

	/* Take into account the current time so a tick doesn't happen immediately. */
	STM_CMP0.reg = ulCompareMatchValue + STM_TIM0.reg;

	if( 0 != _install_int_handler( configKERNEL_INTERRUPT_PRIORITY, prvSystemTickHandler, 0 ) )
	{
		/* Set-up the interrupt. */
		STM_SRC0.reg = ( configKERNEL_INTERRUPT_PRIORITY | 0x00005000UL );

		/* Enable the Interrupt. */
		STM_ISRR.reg &= ~( 0x03UL );
		STM_ISRR.reg |= 0x1UL;
		STM_ISRR.reg &= ~( 0x07UL );
		STM_ICR.reg |= 0x1UL;
	}
	else
	{
		/* Failed to install the Tick Interrupt. */
		configASSERT( ( ( volatile void * ) NULL ) );
	}
}
Esempio n. 15
0
/**
 * Configure pin(s) according to the pin description
 * @param cfg
 */
void PIO_Cfg(PIN_DESC cfg)
{
	unsigned int pin_pattern, tmpreg, mode, pos;
	GPIO_TypeDef* gpio_port;

	tmpreg = PD_PORT_Get(cfg);
	if (tmpreg <= PD_LAST_PORT)
	{
		RCC->RCC_AHB1ENR |= RCC_AHB1ENR_GPIOAEN << tmpreg;

		gpio_port = PORT_ADDRESS( tmpreg );
		pin_pattern = PD_PINS_Get(cfg);

		//loop pins
		while(pin_pattern)
		{
			pos = 1+ __CLZ(pin_pattern);
			pin_pattern = (pin_pattern << pos) >> pos;
			pos = (32-pos)*2;

			mode = PD_MODE_Get(cfg);

			/* Change AF mapping */
			if(mode == PD_MODE_Get(PD_MODE_AF))
			{
				do
				{
					tmpreg = locked_get_reg(&gpio_port->GPIO_AFR[pos >> 4]);
					tmpreg &= ~GPIO_AFR_AFRy_Msk(pos>>1);
					tmpreg |= GPIO_AFR_AFRy_Set(pos>>1, PD_MUX_Get(cfg));
				} while (locked_set_reg(&gpio_port->GPIO_AFR[pos >> 4], tmpreg));
			}
			/* set default pin level*/
			if(mode == PD_MODE_Get(PD_MODE_OUTPUT))
			{
				gpio_port->GPIO_BSRR = (1<<(pos>>1)) << ((cfg & PD_ACTIVE_HIGH)?16:0);
			}

			/* Change mode */
			do
			{
				tmpreg = locked_get_reg(&gpio_port->GPIO_MODER);
				tmpreg &= ~(0x3 << pos);
				tmpreg |= mode << pos;
			} while (locked_set_reg(&gpio_port->GPIO_MODER, tmpreg));

			/* Change pullup/pulldowns */
			do
			{
				tmpreg = locked_get_reg(&gpio_port->GPIO_PUPDR);
				tmpreg &= ~(0x3 << pos);
				tmpreg |= PD_PULL_Get(cfg) << pos;
			} while (locked_set_reg(&gpio_port->GPIO_PUPDR, tmpreg));

			if(mode == PD_MODE_Get(PD_MODE_OUTPUT) || mode == PD_MODE_Get(PD_MODE_AF))
			{
				/* Change speed */
				do
				{
					tmpreg = locked_get_reg(&gpio_port->GPIO_OSPEEDR);
					tmpreg &= ~(0x3 << pos);
					tmpreg |= PD_OSPEED_Get(cfg) << pos;
				} while (locked_set_reg(&gpio_port->GPIO_OSPEEDR, tmpreg));

				pos /= 2;

				/* Change output type */
				do
				{
					tmpreg = locked_get_reg(&gpio_port->GPIO_OTYPER);
					tmpreg &= ~(0x1 << pos);
					tmpreg |= PD_OTYPE_Get(cfg) << pos;
				} while (locked_set_reg(&gpio_port->GPIO_OTYPER, tmpreg));
			}
		}
Esempio n. 16
0
void SAADC_IRQHandler(void)
{
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_END))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
        if (m_cb.active_channels == 1)
        {
            nrf_drv_saadc_evt_t evt;
            evt.type = NRF_DRV_SAADC_EVT_DONE;
            evt.data.done.p_buffer = (nrf_saadc_value_t *)m_cb.buffer;
            evt.data.done.size = m_cb.buffer_size;

            if (m_cb.p_secondary_buffer == NULL)
            {
                m_cb.adc_state = NRF_SAADC_STATE_IDLE;
            }
            else
            {
                m_cb.buffer = m_cb.p_secondary_buffer;
                m_cb.buffer_size = m_cb.secondary_buffer_size;
                m_cb.p_secondary_buffer = NULL;
                nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
            }

            m_cb.event_handler(&evt);
        }
        else
        {
            //PAN-28: scan mode is not working correctly, emulated by interrupts
            m_cb.buffer_pos++;
            uint16_t buffer_pos = m_cb.buffer_pos;
            if (buffer_pos == m_cb.buffer_size)
            {
                nrf_drv_saadc_evt_t evt;
                evt.type = NRF_DRV_SAADC_EVT_DONE;
                evt.data.done.p_buffer = (nrf_saadc_value_t *)m_cb.buffer;
                evt.data.done.size = m_cb.buffer_size;

                m_cb.adc_state = NRF_SAADC_STATE_IDLE;
                if (m_cb.p_secondary_buffer == NULL)
                {
                    m_cb.adc_state = NRF_SAADC_STATE_IDLE;
                }
                else
                {
                    (void)nrf_drv_saadc_buffer_convert((nrf_saadc_value_t *)m_cb.p_secondary_buffer, (uint16_t)m_cb.secondary_buffer_size);
                }
                m_cb.event_handler(&evt);
            }
            else
            {
                //
                uint8_t current_scan_pos = m_cb.scan_pos;

                nrf_saadc_channel_input_set(current_scan_pos,
                                            NRF_SAADC_INPUT_DISABLED, NRF_SAADC_INPUT_DISABLED);

                nrf_saadc_buffer_init((nrf_saadc_value_t *)(m_cb.buffer + m_cb.buffer_pos), 1);
                // Find the next enabled channel.
                for (++m_cb.scan_pos; m_cb.scan_pos < NRF_SAADC_CHANNEL_COUNT; ++m_cb.scan_pos)
                {
                    if (m_cb.psel[m_cb.scan_pos].pselp)
                    {
                        nrf_saadc_channel_input_set(m_cb.scan_pos,
                                    m_cb.psel[m_cb.scan_pos].pselp, m_cb.psel[m_cb.scan_pos].pseln);
                        nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
                        nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
                        return;
                    }
                }
                //if scanning is done prepare for next round.
                for (uint8_t i = 0; i < NRF_SAADC_CHANNEL_COUNT; ++i)
                {
                    if (m_cb.psel[i].pselp)
                    {
                        m_cb.scan_pos = i;
                        break;
                    }
                }
                nrf_saadc_channel_input_set(m_cb.scan_pos,
                                    m_cb.psel[m_cb.scan_pos].pselp, m_cb.psel[m_cb.scan_pos].pseln);
                nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
            }
        }
    }
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
        m_cb.adc_state = NRF_SAADC_STATE_IDLE;
    }
    else
    {
        uint32_t limit_flags = m_cb.limits_enabled_flags;
        uint32_t flag_idx;
        nrf_saadc_event_t event;
        while (limit_flags)
        {
            flag_idx = __CLZ(limit_flags);
            limit_flags &= ~(0x80000000 >> flag_idx);
            event = FLAG_IDX_TO_EVENT(flag_idx);
            if (nrf_saadc_event_check(event))
            {
                nrf_saadc_event_clear(event);
                nrf_drv_saadc_evt_t evt;
                evt.type = NRF_DRV_SAADC_EVT_LIMIT;
                evt.data.limit.channel = LIMIT_EVENT_TO_CHANNEL(event);
                evt.data.limit.limit_type = LIMIT_EVENT_TO_LIMIT_TYPE(event);
                m_cb.event_handler(&evt);
            }
        }
    }
}
Esempio n. 17
0
/**
 * @brief Function for determining the next analog channel to be read.
 */
__STATIC_INLINE void calculate_next_channel(void)
{
    m_csense.cur_chann_idx = 31 - __CLZ(m_csense.channels_to_read);
}
Esempio n. 18
0
/*!
 * \brief  Find First Set
 *         This function identifies the least significant index or position of the
 *         bits set to one in the word
 *
 * \param [in]  value  Value to find least significant index
 * \retval bitIndex    Index of least significat bit at one
 */
__STATIC_INLINE uint8_t __ffs( uint32_t value )
{
    return( uint32_t )( 32 - __CLZ( value & ( -value ) ) );
}
Esempio n. 19
0
void SAADC_IRQHandler(void)
{
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_END))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_END);

        if (!m_cb.low_power_mode || m_cb.conversions_end)
        {
            nrf_drv_saadc_evt_t evt;
            evt.type               = NRF_DRV_SAADC_EVT_DONE;
            evt.data.done.p_buffer = (nrf_saadc_value_t *)m_cb.p_buffer;
            evt.data.done.size     = m_cb.buffer_size;

            if (m_cb.p_secondary_buffer == NULL)
            {
                m_cb.adc_state = NRF_SAADC_STATE_IDLE;
            }
            else
            {
                m_cb.p_buffer           = m_cb.p_secondary_buffer;
                m_cb.buffer_size        = m_cb.secondary_buffer_size;
                m_cb.p_secondary_buffer = NULL;
                if (!m_cb.low_power_mode)
                {
                    nrf_saadc_task_trigger(NRF_SAADC_TASK_START);
                }
            }
            m_cb.event_handler(&evt);
            m_cb.conversions_end = false;
        }
    }
    if (m_cb.low_power_mode && nrf_saadc_event_check(NRF_SAADC_EVENT_STARTED))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_STARTED);
        if (m_cb.buffer_size_left == 0)
        {
            // Sampling finished, next buffer in progress.
            m_cb.buffer_size_left = m_cb.buffer_size - m_cb.active_channels;
            nrf_saadc_buffer_init((nrf_saadc_value_t *)&m_cb.p_buffer[m_cb.buffer_size -
                                                                      m_cb.buffer_size_left],
                                  m_cb.active_channels);
        }
        else if (m_cb.buffer_size_left > m_cb.active_channels)
        {
            // More samples to convert than for single event.
            m_cb.buffer_size_left -= m_cb.active_channels;
            nrf_saadc_buffer_init((nrf_saadc_value_t *)&m_cb.p_buffer[m_cb.buffer_size -
                                                                      m_cb.buffer_size_left],
                                  m_cb.active_channels);
        }
        else if ((m_cb.buffer_size_left == m_cb.active_channels) &&
                 (m_cb.p_secondary_buffer != NULL))
        {
            // Samples to convert for one event, prepare next buffer.
            m_cb.conversions_end  = true;
            m_cb.buffer_size_left = 0;
            nrf_saadc_buffer_init((nrf_saadc_value_t *)m_cb.p_secondary_buffer,
                                  m_cb.active_channels);
        }
        else if (m_cb.buffer_size_left == m_cb.active_channels)
        {
            // Samples to convert for one event, but no second buffer.
            m_cb.conversions_end  = true;
            m_cb.buffer_size_left = 0;
        }
        nrf_saadc_event_clear(NRF_SAADC_EVENT_END);
        nrf_saadc_task_trigger(NRF_SAADC_TASK_SAMPLE);
    }
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_CALIBRATEDONE))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_CALIBRATEDONE);
        m_cb.adc_state = NRF_SAADC_STATE_IDLE;

        nrf_drv_saadc_evt_t evt;
        evt.type = NRF_DRV_SAADC_EVT_CALIBRATEDONE;
        m_cb.event_handler(&evt);
    }
    if (nrf_saadc_event_check(NRF_SAADC_EVENT_STOPPED))
    {
        nrf_saadc_event_clear(NRF_SAADC_EVENT_STOPPED);
        m_cb.adc_state = NRF_SAADC_STATE_IDLE;
    }
    else
    {
        uint32_t          limit_flags = m_cb.limits_enabled_flags;
        uint32_t          flag_idx;
        nrf_saadc_event_t event;

        while (limit_flags)
        {
            flag_idx     = __CLZ(limit_flags);
            limit_flags &= ~((1UL << 31) >> flag_idx);
            event        = FLAG_IDX_TO_EVENT(flag_idx);
            if (nrf_saadc_event_check(event))
            {
                nrf_saadc_event_clear(event);
                nrf_drv_saadc_evt_t evt;
                evt.type                  = NRF_DRV_SAADC_EVT_LIMIT;
                evt.data.limit.channel    = LIMIT_EVENT_TO_CHANNEL(event);
                evt.data.limit.limit_type = LIMIT_EVENT_TO_LIMIT_TYPE(event);
                m_cb.event_handler(&evt);
            }
        }
    }
}
Esempio n. 20
0
/// Create and Initialize a Message Queue object.
/// \note API identical to osMessageQueueNew
osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
  os_message_queue_t *mq;
  void               *mq_mem;
  uint32_t            mq_size;
  uint32_t            block_size;
  uint32_t            size;
  uint8_t             flags;
  const char         *name;

  // Check parameters
  if ((msg_count == 0U) || (msg_size  == 0U)) {
    EvrRtxMessageQueueError(NULL, osErrorParameter);
    return NULL;
  }
  msg_size = (msg_size + 3U) & ~3UL;
  block_size = msg_size + sizeof(os_message_t);
  if ((__CLZ(msg_count) + __CLZ(block_size)) < 32) {
    EvrRtxMessageQueueError(NULL, osErrorParameter);
    return NULL;
  }

  size = msg_count * block_size;

  // Process attributes
  if (attr != NULL) {
    name    = attr->name;
    mq      = attr->cb_mem;
    mq_mem  = attr->mq_mem;
    mq_size = attr->mq_size;
    if (mq != NULL) {
      if (((uint32_t)mq & 3U) || (attr->cb_size < sizeof(os_message_queue_t))) {
        EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock);
        return NULL;
      }
    } else {
      if (attr->cb_size != 0U) {
        EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock);
        return NULL;
      }
    }
    if (mq_mem != NULL) {
      if (((uint32_t)mq_mem & 3U) || (mq_size < size)) {
        EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory);
        return NULL;
      }
    } else {
      if (mq_size != 0U) {
        EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory);
        return NULL;
      }
    }
  } else {
    name   = NULL;
    mq     = NULL;
    mq_mem = NULL;
  }

  // Allocate object memory if not provided
  if (mq == NULL) {
    if (osRtxInfo.mpi.message_queue != NULL) {
      mq = osRtxMemoryPoolAlloc(osRtxInfo.mpi.message_queue);
    } else {
      mq = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_message_queue_t), 1U);
    }
    if (mq == NULL) {
      EvrRtxMessageQueueError(NULL, osErrorNoMemory);
      return NULL;
    }
    flags = osRtxFlagSystemObject;
  } else {
    flags = 0U;
  }

  // Allocate data memory if not provided
  if (mq_mem == NULL) {
    mq_mem = osRtxMemoryAlloc(osRtxInfo.mem.mq_data, size, 0U);
    if (mq_mem == NULL) {
      EvrRtxMessageQueueError(NULL, osErrorNoMemory);
      if (flags & osRtxFlagSystemObject) {
        if (osRtxInfo.mpi.message_queue != NULL) {
          osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
        } else {
          osRtxMemoryFree(osRtxInfo.mem.common, mq);
        }
      }
      return NULL;
    }
    memset(mq_mem, 0, size);
    flags |= osRtxFlagSystemMemory;
  }

  // Initialize control block
  mq->id          = osRtxIdMessageQueue;
  mq->state       = osRtxObjectActive;
  mq->flags       = flags;
  mq->name        = name;
  mq->thread_list = NULL;
  mq->msg_size    = msg_size;
  mq->msg_count   = 0U;
  mq->msg_first   = NULL;
  mq->msg_last    = NULL;
  osRtxMemoryPoolInit(&mq->mp_info, msg_count, block_size, mq_mem);

  // Register post ISR processing function
  osRtxInfo.post_process.message_queue = osRtxMessageQueuePostProcess;

  EvrRtxMessageQueueCreated(mq);

  return mq;
}
Esempio n. 21
0
void EXTI_DCR(EXTI_DRIVER_INFO* drv_info, unsigned int reason, HANDLE hnd)
{
	EXTI_DRIVER_DATA * drv_data = drv_info->drv_data ;
	const PIN_DESC* pin;
	unsigned int lines;

	switch( reason )
	{
		case DCR_ISR:
		{
			lines = (unsigned int)hnd; //lines with edge

			// loop waiting handles
			for(hnd = drv_data->waiting; hnd; hnd = hnd->next)
			{
				// loop pin description list in the handle
				for(pin = (PIN_DESC*)hnd->mode.as_voidptr; *pin; pin++)
				{
					if(lines & *pin)
					{
						if(hnd->mode0 == PIOHND_WAITING)
						{
							hnd->mode0 = PIOHND_IDLE;
							read_handle(hnd);
							svc_HND_SET_STATUS(hnd, RES_SIG_OK);
						}
						else
							hnd->mode0 = PIOHND_INTPENDING;

						break; //done with this handle
					}
				}
			}
		}
		break;

		case DCR_OPEN:
		{
			//Enable AFIO/SYSCFG...
			RCCPeripheralEnable(drv_info->info.peripheral_indx);

			pin = (PIN_DESC *)hnd->mode.as_voidptr;
			hnd->list_add(drv_data->waiting);
			hnd->mode0 = PIOHND_IDLE;
			while(*pin)
			{
				unsigned int pin_pattern, pos;

				PIO_Cfg(*pin);
				if(PD_MODE_Get(*pin) == PD_MODE_INPUT)
				{
					if(PD_INT_Get(*pin))
					{
						pin_pattern = PD_PINS_Get(*pin);
						while(pin_pattern)
						{
							pos = 31 - __CLZ(pin_pattern);
							lines = 1 << pos;
							pin_pattern ^= lines;

							pos = stm_get_drv_indx(pos);

							// Handles can be open with any EXTI driver, so check
							// here if the actual driver is installed

							int adr = (int)DRV_TABLE[pos];
							adr &= ~3;

							const EXTI_DRIVER_INFO* info;
							info = (const EXTI_DRIVER_INFO*)adr;
							if(info->info.isr == (DRV_ISR)EXTI_ISR)
							{
		        				drv_enable_isr(&info->info);

							    /* Clear Rising Falling edge configuration */
								info->hw_base->EXTI_RTSR &= ~lines;
								info->hw_base->EXTI_FTSR &= ~lines;

								exti_set_line_source(31 - __CLZ(lines), PD_PORT_Get(*pin));

							    /* Select the trigger for the selected external interrupts */
								if(*pin & PD_INT_FE) // falling edge
									info->hw_base->EXTI_FTSR |= lines;
								if(*pin & PD_INT_RE) // rising edge
									info->hw_base->EXTI_RTSR |= lines;

							    /* Enable line interrupt */
								info->hw_base->EXTI_IMR |= lines;
							}
						}
					}
				}
				pin++;
			}
			hnd->res = RES_OK;
		}
		break;

		case DCR_CLOSE:
		{
			PIO_Cfg_List((PIN_DESC*)hnd->mode.as_voidptr);
			hnd->list_remove(drv_data->waiting);
		}
		break;

		case DCR_CANCEL:
			if (hnd->res & FLG_BUSY)
			{
				read_handle(hnd);
				svc_HND_SET_STATUS(hnd, RES_SIG_CANCEL);
			}
			break;

		case DCR_RESET:
			NVIC_DisableIRQ(drv_info->info.drv_index);
			RCCPeripheralReset(drv_info->info.peripheral_indx);
			RCCPeripheralDisable(drv_info->info.peripheral_indx); // turn off
			break;
		default:
			break;
	}
}
Esempio n. 22
0
/**
 * Configure pin(s) according to the pin description
 * @param cfg
 */
void PIO_Cfg(PIN_DESC cfg)
{
	unsigned int pin_pattern, tmpreg, mode, pos;
	GPIO_TypeDef* gpio_port;

	tmpreg = PD_PORT_Get(cfg);
	if (tmpreg <= PD_LAST_PORT)
	{
		RCC->RCC_APB2ENR |= RCC_APB2ENR_IOPAEN << tmpreg;

		gpio_port = PORT_ADDRESS( tmpreg );
		pin_pattern = PD_PINS_Get(cfg);
		mode = PD_MODE_Get(cfg);

		/* calculate CNFx and MODEx bits*/
		switch(mode)
		{
		case 0: //	INPUT
			/* configure pullup/pulldowns*/
			if(cfg & PD_PULL_DOWN)
				gpio_port->GPIO_BRR = pin_pattern;
			if(cfg & PD_PULL_UP)
				gpio_port->GPIO_BSRR = pin_pattern;


			if(cfg & (PD_PULL_UP | PD_PULL_DOWN) )
				mode = GPIO_CRx_MODE_INPUT | GPIO_CRx_CNF_IN_PUPD;
			else
				mode = GPIO_CRx_MODE_INPUT | GPIO_CRx_CNF_IN_GP;
			break;

		case 1: //	OUTPUT
			/* set default pin level*/
			gpio_port->GPIO_BSRR = pin_pattern << ((cfg & PD_ACTIVE_HIGH)?0:16);

			mode = PD_OSPEED_Get(cfg) | (PD_OTYPE_Get(cfg) << 2);
			break;

		case 2: //	AF
			mode = PD_OSPEED_Get(cfg);
			if(mode)
			{
				// when ospeed is set, AD is in output mode
				mode |= GPIO_CRx_CNF_OUT_AF_PP | (PD_OTYPE_Get(cfg) << 2); // PP or OD
			} else
			{
				if(cfg & (PD_PULL_UP | PD_PULL_DOWN) )
					mode |= GPIO_CRx_MODE_INPUT | GPIO_CRx_CNF_IN_PUPD;
				else
					mode |= GPIO_CRx_MODE_INPUT | GPIO_CRx_CNF_IN_GP;
			}
			break;

		default: //	ANALOG
			mode = GPIO_CRx_MODE_INPUT | GPIO_CRx_CNF_IN_AN;
			break;
		}

		/* Configure the eight high port pins */
		if( pin_pattern > 0x80 )
		{
			do	// loop for exclusive access (thread safe)
			{
				tmpreg = locked_get_reg(&gpio_port->GPIO_CRH);

				do // loop pins
				{
					pos = 1+ __CLZ(pin_pattern);
					pin_pattern = (pin_pattern << pos) >> pos;

					pos = (24-pos) << 2;
					tmpreg &= ~(0xF << pos);
					tmpreg |= mode << pos;
				} while(pin_pattern > 0x80);
			} while (locked_set_reg(&gpio_port->GPIO_CRH, tmpreg));
		}

		/* Configure the eight low port pins */
		if( pin_pattern )
		{
			do	// loop for exclusive access (thread safe)
			{
				tmpreg = locked_get_reg(&gpio_port->GPIO_CRL);

				do // loop pins
				{
					pos = 1+ __CLZ(pin_pattern);
					pin_pattern = (pin_pattern << pos) >> pos;

					pos = (32-pos) << 2;
					tmpreg &= ~(0xF << pos);
					tmpreg |= mode << pos;
				} while(pin_pattern);
			} while (locked_set_reg(&gpio_port->GPIO_CRL, tmpreg));
		}
	}