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; } }
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; } }
/* 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; }
/***************************************************************************//** * @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 }
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); }
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); }
/***************************************************************************//** * @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; }
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(); }
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; }
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; }
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; }
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; } } }
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 ) ); } }
/** * 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)); } }
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); } } } }
/** * @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); }
/*! * \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 ) ) ); }
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); } } } }
/// 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; }
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; } }
/** * 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)); } }