/** * @brief Enables EXTI IRQ sources. * * @notapi */ void ext_lld_exti_irq_enable(void) { nvicEnableVector(EXTI0_IRQn, STM32_EXT_EXTI0_IRQ_PRIORITY); nvicEnableVector(EXTI1_IRQn, STM32_EXT_EXTI1_IRQ_PRIORITY); nvicEnableVector(EXTI2_IRQn, STM32_EXT_EXTI2_IRQ_PRIORITY); nvicEnableVector(EXTI3_IRQn, STM32_EXT_EXTI3_IRQ_PRIORITY); nvicEnableVector(EXTI4_IRQn, STM32_EXT_EXTI4_IRQ_PRIORITY); nvicEnableVector(EXTI9_5_IRQn, STM32_EXT_EXTI5_9_IRQ_PRIORITY); nvicEnableVector(EXTI15_10_IRQn, STM32_EXT_EXTI10_15_IRQ_PRIORITY); nvicEnableVector(PVD_IRQn, STM32_EXT_EXTI16_IRQ_PRIORITY); nvicEnableVector(RTC_Alarm_IRQn, STM32_EXT_EXTI17_IRQ_PRIORITY); nvicEnableVector(USB_FS_WKUP_IRQn, STM32_EXT_EXTI18_IRQ_PRIORITY); nvicEnableVector(TAMPER_STAMP_IRQn, STM32_EXT_EXTI19_IRQ_PRIORITY); nvicEnableVector(RTC_WKUP_IRQn, STM32_EXT_EXTI20_IRQ_PRIORITY); nvicEnableVector(COMP_IRQn, STM32_EXT_EXTI21_22_IRQ_PRIORITY); #if STM32_EXTI_NUM_LINES > 23 nvicEnableVector(COMP_ACQ_IRQn, STM32_EXT_EXTI23_IRQ_PRIORITY); #endif }
/** * @brief Enables EXTI IRQ sources. * * @notapi */ void ext_lld_exti_irq_enable(void) { nvicEnableVector(EXTI0_IRQn, STM32_EXT_EXTI0_IRQ_PRIORITY); nvicEnableVector(EXTI1_IRQn, STM32_EXT_EXTI1_IRQ_PRIORITY); nvicEnableVector(EXTI2_TSC_IRQn, STM32_EXT_EXTI2_IRQ_PRIORITY); nvicEnableVector(EXTI3_IRQn, STM32_EXT_EXTI3_IRQ_PRIORITY); nvicEnableVector(EXTI4_IRQn, STM32_EXT_EXTI4_IRQ_PRIORITY); nvicEnableVector(EXTI9_5_IRQn, STM32_EXT_EXTI5_9_IRQ_PRIORITY); nvicEnableVector(EXTI15_10_IRQn, STM32_EXT_EXTI10_15_IRQ_PRIORITY); nvicEnableVector(PVD_IRQn, STM32_EXT_EXTI16_IRQ_PRIORITY); nvicEnableVector(RTC_Alarm_IRQn, STM32_EXT_EXTI17_IRQ_PRIORITY); #if STM32_HAS_USB nvicEnableVector(USBWakeUp_IRQn, STM32_EXT_EXTI18_IRQ_PRIORITY); #endif nvicEnableVector(TAMP_STAMP_IRQn, STM32_EXT_EXTI19_IRQ_PRIORITY); nvicEnableVector(RTC_WKUP_IRQn, STM32_EXT_EXTI20_IRQ_PRIORITY); nvicEnableVector(COMP1_2_3_IRQn, STM32_EXT_EXTI21_22_29_IRQ_PRIORITY); nvicEnableVector(COMP4_5_6_IRQn, STM32_EXT_EXTI30_32_IRQ_PRIORITY); #if STM32_EXTI_NUM_LINES >= 34 nvicEnableVector(COMP7_IRQn, STM32_EXT_EXTI33_IRQ_PRIORITY); #endif }
/** * @brief Configures and activates the I2C peripheral. * * @param[in] i2cp pointer to the @p I2CDriver object * * @notapi */ void i2c_lld_start(I2CDriver *i2cp) { I2C_TypeDef *dp = i2cp->i2c; i2cp->dmamode = STM32_DMA_CR_PSIZE_BYTE | STM32_DMA_CR_MSIZE_BYTE | STM32_DMA_CR_MINC | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE | STM32_DMA_CR_TCIE; /* If in stopped state then enables the I2C and DMA clocks.*/ if (i2cp->state == I2C_STOP) { #if STM32_I2C_USE_I2C1 if (&I2CD1 == i2cp) { bool_t b; rccResetI2C1(); b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C1_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #1", "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C1_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #2", "stream already allocated"); rccEnableI2C1(FALSE); nvicEnableVector(I2C1_EV_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); nvicEnableVector(I2C1_ER_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); i2cp->dmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); } #endif /* STM32_I2C_USE_I2C1 */ #if STM32_I2C_USE_I2C2 if (&I2CD2 == i2cp) { bool_t b; rccResetI2C2(); b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C2_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #3", "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C2_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #4", "stream already allocated"); rccEnableI2C2(FALSE); nvicEnableVector(I2C2_EV_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); nvicEnableVector(I2C2_ER_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); i2cp->dmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); } #endif /* STM32_I2C_USE_I2C2 */ #if STM32_I2C_USE_I2C3 if (&I2CD3 == i2cp) { bool_t b; rccResetI2C3(); b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C3_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #5", "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C3_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #6", "stream already allocated"); rccEnableI2C3(FALSE); nvicEnableVector(I2C3_EV_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C3_IRQ_PRIORITY)); nvicEnableVector(I2C3_ER_IRQn, CORTEX_PRIORITY_MASK(STM32_I2C_I2C3_IRQ_PRIORITY)); i2cp->dmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY); } #endif /* STM32_I2C_USE_I2C3 */ } /* DMA streams mode preparation in advance.*/ dmaStreamSetMode(i2cp->dmatx, i2cp->dmamode | STM32_DMA_CR_DIR_M2P); dmaStreamSetMode(i2cp->dmarx, i2cp->dmamode | STM32_DMA_CR_DIR_P2M); /* I2C registers pointed by the DMA.*/ dmaStreamSetPeripheral(i2cp->dmarx, &dp->DR); dmaStreamSetPeripheral(i2cp->dmatx, &dp->DR); /* Reset i2c peripheral.*/ dp->CR1 = I2C_CR1_SWRST; dp->CR1 = 0; dp->CR2 = I2C_CR2_ITERREN | I2C_CR2_DMAEN; /* Setup I2C parameters.*/ i2c_lld_set_clock(i2cp); i2c_lld_set_opmode(i2cp); /* Ready to go.*/ dp->CR1 |= I2C_CR1_PE; }
/** * @brief Configures and activates the ICU peripheral. * * @param[in] icup pointer to the @p ICUDriver object * * @notapi */ void icu_lld_start(ICUDriver *icup) { uint32_t psc; osalDbgAssert((icup->config->channel == ICU_CHANNEL_1) || (icup->config->channel == ICU_CHANNEL_2), "invalid input"); if (icup->state == ICU_STOP) { /* Clock activation and timer reset.*/ #if STM32_ICU_USE_TIM1 if (&ICUD1 == icup) { rccEnableTIM1(FALSE); rccResetTIM1(); nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY); nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_ICU_TIM1_IRQ_PRIORITY); icup->clock = STM32_TIMCLK2; } #endif #if STM32_ICU_USE_TIM2 if (&ICUD2 == icup) { rccEnableTIM2(FALSE); rccResetTIM2(); nvicEnableVector(STM32_TIM2_NUMBER, STM32_ICU_TIM2_IRQ_PRIORITY); icup->clock = STM32_TIMCLK1; } #endif #if STM32_ICU_USE_TIM3 if (&ICUD3 == icup) { rccEnableTIM3(FALSE); rccResetTIM3(); nvicEnableVector(STM32_TIM3_NUMBER, STM32_ICU_TIM3_IRQ_PRIORITY); icup->clock = STM32_TIMCLK1; } #endif #if STM32_ICU_USE_TIM4 if (&ICUD4 == icup) { rccEnableTIM4(FALSE); rccResetTIM4(); nvicEnableVector(STM32_TIM4_NUMBER, STM32_ICU_TIM4_IRQ_PRIORITY); icup->clock = STM32_TIMCLK1; } #endif #if STM32_ICU_USE_TIM5 if (&ICUD5 == icup) { rccEnableTIM5(FALSE); rccResetTIM5(); nvicEnableVector(STM32_TIM5_NUMBER, STM32_ICU_TIM5_IRQ_PRIORITY); icup->clock = STM32_TIMCLK1; } #endif #if STM32_ICU_USE_TIM8 if (&ICUD8 == icup) { rccEnableTIM8(FALSE); rccResetTIM8(); nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY); nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_ICU_TIM8_IRQ_PRIORITY); icup->clock = STM32_TIMCLK2; } #endif #if STM32_ICU_USE_TIM9 if (&ICUD9 == icup) { rccEnableTIM9(FALSE); rccResetTIM9(); nvicEnableVector(STM32_TIM9_NUMBER, STM32_ICU_TIM9_IRQ_PRIORITY); icup->clock = STM32_TIMCLK1; } #endif } else { /* Driver re-configuration scenario, it must be stopped first.*/ icup->tim->CR1 = 0; /* Timer disabled. */ icup->tim->DIER = icup->config->dier &/* DMA-related DIER settings. */ ~STM32_TIM_DIER_IRQ_MASK; icup->tim->SR = 0; /* Clear eventual pending IRQs. */ icup->tim->CCR[0] = 0; /* Comparator 1 disabled. */ icup->tim->CCR[1] = 0; /* Comparator 2 disabled. */ icup->tim->CNT = 0; /* Counter reset to zero. */ } /* Timer configuration.*/ psc = (icup->clock / icup->config->frequency) - 1; osalDbgAssert((psc <= 0xFFFF) && ((psc + 1) * icup->config->frequency) == icup->clock, "invalid frequency"); icup->tim->PSC = (uint16_t)psc; icup->tim->ARR = 0xFFFF; if (icup->config->channel == ICU_CHANNEL_1) { /* Selected input 1. CCMR1_CC1S = 01 = CH1 Input on TI1. CCMR1_CC2S = 10 = CH2 Input on TI1.*/ icup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(1) | STM32_TIM_CCMR1_CC2S(2); /* SMCR_TS = 101, input is TI1FP1. SMCR_SMS = 100, reset on rising edge.*/ icup->tim->SMCR = STM32_TIM_SMCR_TS(5) | STM32_TIM_SMCR_SMS(4); /* The CCER settings depend on the selected trigger mode. ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge. ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/ if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH) icup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P; else icup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P | STM32_TIM_CCER_CC2E; /* Direct pointers to the capture registers in order to make reading data faster from within callbacks.*/ icup->wccrp = &icup->tim->CCR[1]; icup->pccrp = &icup->tim->CCR[0]; } else { /* Selected input 2. CCMR1_CC1S = 10 = CH1 Input on TI2. CCMR1_CC2S = 01 = CH2 Input on TI2.*/ icup->tim->CCMR1 = STM32_TIM_CCMR1_CC1S(2) | STM32_TIM_CCMR1_CC2S(1); /* SMCR_TS = 110, input is TI2FP2. SMCR_SMS = 100, reset on rising edge.*/ icup->tim->SMCR = STM32_TIM_SMCR_TS(6) | STM32_TIM_SMCR_SMS(4); /* The CCER settings depend on the selected trigger mode. ICU_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge. ICU_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/ if (icup->config->mode == ICU_INPUT_ACTIVE_HIGH) icup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P | STM32_TIM_CCER_CC2E; else icup->tim->CCER = STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P; /* Direct pointers to the capture registers in order to make reading data faster from within callbacks.*/ icup->wccrp = &icup->tim->CCR[0]; icup->pccrp = &icup->tim->CCR[1]; } }
/** * @brief Configures and activates the UART peripheral. * * @param[in] uartp pointer to the @p UARTDriver object * * @notapi */ void uart_lld_start(UARTDriver *uartp) { if (uartp->state == UART_STOP) { #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { bool b; b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART1_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART1_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); rccEnableUSART1(FALSE); nvicEnableVector(STM32_USART1_NUMBER, STM32_UART_USART1_IRQ_PRIORITY); uartp->dmamode |= STM32_DMA_CR_CHSEL(USART1_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY); } #endif #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { bool b; b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART2_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART2_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); rccEnableUSART2(FALSE); nvicEnableVector(STM32_USART2_NUMBER, STM32_UART_USART2_IRQ_PRIORITY); uartp->dmamode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY); } #endif #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { bool b; b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART3_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART3_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); rccEnableUSART3(FALSE); nvicEnableVector(STM32_USART3_NUMBER, STM32_UART_USART3_IRQ_PRIORITY); uartp->dmamode |= STM32_DMA_CR_CHSEL(USART3_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY); } #endif #if STM32_UART_USE_UART4 if (&UARTD4 == uartp) { bool b; chDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0, "specified invalid bits in UART4 CR2 register settings"); chDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0, "specified invalid bits in UART4 CR3 register settings"); b = dmaStreamAllocate(uartp->dmarx, STM32_UART_UART4_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_UART4_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); rccEnableUART4(FALSE); nvicEnableVector(STM32_UART4_NUMBER, STM32_UART_UART4_IRQ_PRIORITY); uartp->dmamode |= STM32_DMA_CR_CHSEL(UART4_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_UART4_DMA_PRIORITY); } #endif #if STM32_UART_USE_UART5 if (&UARTD5 == uartp) { bool b; chDbgAssert((uartp->config->cr2 & STM32_UART45_CR2_CHECK_MASK) == 0, "specified invalid bits in UART5 CR2 register settings"); chDbgAssert((uartp->config->cr3 & STM32_UART45_CR3_CHECK_MASK) == 0, "specified invalid bits in UART5 CR3 register settings"); b = dmaStreamAllocate(uartp->dmarx, STM32_UART_UART5_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_UART5_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); rccEnableUART5(FALSE); nvicEnableVector(STM32_UART5_NUMBER, STM32_UART_UART5_IRQ_PRIORITY); uartp->dmamode |= STM32_DMA_CR_CHSEL(UART5_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_UART5_DMA_PRIORITY); } #endif #if STM32_UART_USE_USART6 if (&UARTD6 == uartp) { bool b; b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART6_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART6_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); osalDbgAssert(!b, "stream already allocated"); rccEnableUSART6(FALSE); nvicEnableVector(STM32_USART6_NUMBER, STM32_UART_USART6_IRQ_PRIORITY); uartp->dmamode |= STM32_DMA_CR_CHSEL(USART6_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY); } #endif /* Static DMA setup, the transfer size depends on the USART settings, it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/ if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR); dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR); uartp->rxbuf = 0; } uartp->rxstate = UART_RX_IDLE; uartp->txstate = UART_TX_IDLE; usart_start(uartp); }
/** * @brief Low level ADC driver initialization. * * @notapi */ void adc_lld_init(void) { clkmask = 0; #if STM32_ADC_USE_ADC1 /* Driver initialization.*/ adcObjectInit(&ADCD1); #if defined(ADC1_2_COMMON) ADCD1.adcc = ADC1_2_COMMON; #elif defined(ADC123_COMMON) ADCD1.adcc = ADC123_COMMON; #else ADCD1.adcc = ADC1_COMMON; #endif ADCD1.adcm = ADC1; #if STM32_ADC_DUAL_MODE ADCD1.adcs = ADC2; #endif ADCD1.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC1_DMA_STREAM); ADCD1.dmamode = ADC_DMA_SIZE | STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif /* STM32_ADC_USE_ADC1 */ #if STM32_ADC_USE_ADC2 /* Driver initialization.*/ adcObjectInit(&ADCD2); #if defined(ADC1_2_COMMON) ADCD2.adcc = ADC1_2_COMMON; #elif defined(ADC123_COMMON) ADCD2.adcc = ADC123_COMMON; #endif ADCD2.adcm = ADC2; ADCD2.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC2_DMA_STREAM); ADCD2.dmamode = ADC_DMA_SIZE | STM32_DMA_CR_PL(STM32_ADC_ADC2_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif /* STM32_ADC_USE_ADC2 */ #if STM32_ADC_USE_ADC3 /* Driver initialization.*/ adcObjectInit(&ADCD3); #if defined(ADC3_4_COMMON) ADCD3.adcc = ADC3_4_COMMON; #elif defined(ADC123_COMMON) ADCD1.adcc = ADC123_COMMON; #else ADCD3.adcc = ADC3_COMMON; #endif ADCD3.adcm = ADC3; #if STM32_ADC_DUAL_MODE ADCD3.adcs = ADC4; #endif ADCD3.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC3_DMA_STREAM); ADCD3.dmamode = ADC_DMA_SIZE | STM32_DMA_CR_PL(STM32_ADC_ADC3_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif /* STM32_ADC_USE_ADC3 */ #if STM32_ADC_USE_ADC4 /* Driver initialization.*/ adcObjectInit(&ADCD4); ADCD4.adcc = ADC3_4_COMMON; ADCD4.adcm = ADC4; ADCD4.dmastp = STM32_DMA_STREAM(STM32_ADC_ADC4_DMA_STREAM); ADCD4.dmamode = ADC_DMA_SIZE | STM32_DMA_CR_PL(STM32_ADC_ADC4_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; #endif /* STM32_ADC_USE_ADC4 */ /* IRQs setup.*/ #if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 nvicEnableVector(STM32_ADC1_NUMBER, STM32_ADC_ADC12_IRQ_PRIORITY); #endif #if STM32_ADC_USE_ADC3 nvicEnableVector(STM32_ADC3_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY); #if STM32_ADC_DUAL_MODE nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY); #endif #endif #if STM32_ADC_USE_ADC4 nvicEnableVector(STM32_ADC4_NUMBER, STM32_ADC_ADC3_IRQ_PRIORITY); #endif /* ADC units pre-initializations.*/ #if defined(STM32F3XX) #if STM32_HAS_ADC1 && STM32_HAS_ADC2 #if STM32_ADC_USE_ADC1 || STM32_ADC_USE_ADC2 rccEnableADC12(FALSE); rccResetADC12(); ADC1_2_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA; rccDisableADC12(FALSE); #endif #else #if STM32_ADC_USE_ADC1 rccEnableADC12(FALSE); rccResetADC12(); ADC1_COMMON->CCR = STM32_ADC_ADC12_CLOCK_MODE | ADC_DMA_MDMA; rccDisableADC12(FALSE); #endif #endif #if STM32_ADC_USE_ADC3 || STM32_ADC_USE_ADC4 rccEnableADC34(FALSE); rccResetADC34(); ADC3_4_COMMON->CCR = STM32_ADC_ADC34_CLOCK_MODE | ADC_DMA_MDMA; rccDisableADC34(FALSE); #endif #endif #if defined(STM32L4XX) rccEnableADC123(FALSE); rccResetADC123(); ADC123_COMMON->CCR = STM32_ADC_ADC123_CLOCK_MODE | ADC_DMA_MDMA; rccDisableADC123(FALSE); #endif }
/** * @brief Configures and activates the I2C peripheral. * * @param[in] i2cp pointer to the @p I2CDriver object * * @notapi */ void i2c_lld_start(I2CDriver *i2cp) { I2C_TypeDef *dp = i2cp->i2c; #if STM32_I2C_USE_DMA == TRUE /* Common DMA modes.*/ i2cp->txdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_M2P; i2cp->rxdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_P2M; #endif /* Make sure I2C peripheral is disabled */ dp->CR1 &= ~I2C_CR1_PE; /* If in stopped state then enables the I2C and DMA clocks.*/ if (i2cp->state == I2C_STOP) { #if STM32_I2C_USE_I2C1 if (&I2CD1 == i2cp) { rccResetI2C1(); rccEnableI2C1(FALSE); #if STM32_I2C_USE_DMA == TRUE { bool b; b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C1_IRQ_PRIORITY, NULL, (void *)i2cp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C1_IRQ_PRIORITY, NULL, (void *)i2cp); osalDbgAssert(!b, "stream already allocated"); i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); } #endif /* STM32_I2C_USE_DMA == TRUE */ #if defined(STM32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__) nvicEnableVector(STM32_I2C1_GLOBAL_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY); #elif defined(STM32_I2C1_EVENT_NUMBER) && defined(STM32_I2C1_ERROR_NUMBER) nvicEnableVector(STM32_I2C1_EVENT_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY); nvicEnableVector(STM32_I2C1_ERROR_NUMBER, STM32_I2C_I2C1_IRQ_PRIORITY); #else #error "I2C1 interrupt numbers not defined" #endif } #endif /* STM32_I2C_USE_I2C1 */ #if STM32_I2C_USE_I2C2 if (&I2CD2 == i2cp) { rccResetI2C2(); rccEnableI2C2(FALSE); #if STM32_I2C_USE_DMA == TRUE { bool b; b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C2_IRQ_PRIORITY, NULL, (void *)i2cp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C2_IRQ_PRIORITY, NULL, (void *)i2cp); osalDbgAssert(!b, "stream already allocated"); i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); } #endif /*STM32_I2C_USE_DMA == TRUE */ #if defined(STM32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__) nvicEnableVector(STM32_I2C2_GLOBAL_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY); #elif defined(STM32_I2C2_EVENT_NUMBER) && defined(STM32_I2C2_ERROR_NUMBER) nvicEnableVector(STM32_I2C2_EVENT_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY); nvicEnableVector(STM32_I2C2_ERROR_NUMBER, STM32_I2C_I2C2_IRQ_PRIORITY); #else #error "I2C2 interrupt numbers not defined" #endif } #endif /* STM32_I2C_USE_I2C2 */ #if STM32_I2C_USE_I2C3 if (&I2CD3 == i2cp) { rccResetI2C3(); rccEnableI2C3(FALSE); #if STM32_I2C_USE_DMA == TRUE { bool b; b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C3_IRQ_PRIORITY, NULL, (void *)i2cp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C3_IRQ_PRIORITY, NULL, (void *)i2cp); osalDbgAssert(!b, "stream already allocated"); i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C3_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY); i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C3_TX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C3_DMA_PRIORITY); } #endif /*STM32_I2C_USE_DMA == TRUE */ #if defined(STM32_I2C3_GLOBAL_NUMBER) || defined(__DOXYGEN__) nvicEnableVector(STM32_I2C3_GLOBAL_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY); #elif defined(STM32_I2C3_EVENT_NUMBER) && defined(STM32_I2C3_ERROR_NUMBER) nvicEnableVector(STM32_I2C3_EVENT_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY); nvicEnableVector(STM32_I2C3_ERROR_NUMBER, STM32_I2C_I2C3_IRQ_PRIORITY); #else #error "I2C3 interrupt numbers not defined" #endif } #endif /* STM32_I2C_USE_I2C3 */ #if STM32_I2C_USE_I2C4 if (&I2CD4 == i2cp) { rccResetI2C4(); rccEnableI2C4(FALSE); #if STM32_I2C_USE_DMA == TRUE { bool b; b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C4_IRQ_PRIORITY, NULL, (void *)i2cp); osalDbgAssert(!b, "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C4_IRQ_PRIORITY, NULL, (void *)i2cp); osalDbgAssert(!b, "stream already allocated"); i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C4_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY); i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C4_TX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C4_DMA_PRIORITY); } #endif /*STM32_I2C_USE_DMA == TRUE */ #if defined(STM32_I2C4_GLOBAL_NUMBER) || defined(__DOXYGEN__) nvicEnableVector(STM32_I2C4_GLOBAL_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY); #elif defined(STM32_I2C4_EVENT_NUMBER) && defined(STM32_I2C4_ERROR_NUMBER) nvicEnableVector(STM32_I2C4_EVENT_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY); nvicEnableVector(STM32_I2C4_ERROR_NUMBER, STM32_I2C_I2C4_IRQ_PRIORITY); #else #error "I2C4 interrupt numbers not defined" #endif } #endif /* STM32_I2C_USE_I2C4 */ } #if STM32_I2C_USE_DMA == TRUE /* I2C registers pointed by the DMA.*/ dmaStreamSetPeripheral(i2cp->dmarx, &dp->RXDR); dmaStreamSetPeripheral(i2cp->dmatx, &dp->TXDR); #endif /* Reset i2c peripheral, the TCIE bit will be handled separately.*/ dp->CR1 = i2cp->config->cr1 | #if STM32_I2C_USE_DMA == TRUE I2C_CR1_TXDMAEN | I2C_CR1_RXDMAEN | /* Enable only if using DMA */ #endif I2C_CR1_ERRIE | I2C_CR1_NACKIE; /* Setup I2C parameters.*/ dp->TIMINGR = i2cp->config->timingr; /* Ready to go.*/ dp->CR1 |= I2C_CR1_PE; }
/** * @brief Configures and activates the EICU peripheral. * * @param[in] eicup Pointer to the @p EICUDriver object * * @notapi */ void eicu_lld_start(EICUDriver *eicup) { uint32_t psc; size_t ch; osalDbgAssert((eicup->config->iccfgp[0] != NULL) || (eicup->config->iccfgp[1] != NULL) || (eicup->config->iccfgp[2] != NULL) || (eicup->config->iccfgp[3] != NULL), "invalid input configuration"); if (eicup->state == EICU_STOP) { /* Clock activation and timer reset.*/ #if STM32_EICU_USE_TIM1 if (&EICUD1 == eicup) { rccEnableTIM1(FALSE); rccResetTIM1(); nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_EICU_TIM1_IRQ_PRIORITY); nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_EICU_TIM1_IRQ_PRIORITY); eicup->channels = 4; #if defined(STM32_TIM1CLK) eicup->clock = STM32_TIM1CLK; #else eicup->clock = STM32_TIMCLK2; #endif } #endif #if STM32_EICU_USE_TIM2 if (&EICUD2 == eicup) { rccEnableTIM2(FALSE); rccResetTIM2(); nvicEnableVector(STM32_TIM2_NUMBER, STM32_EICU_TIM2_IRQ_PRIORITY); eicup->channels = 4; eicup->clock = STM32_TIMCLK1; } #endif #if STM32_EICU_USE_TIM3 if (&EICUD3 == eicup) { rccEnableTIM3(FALSE); rccResetTIM3(); nvicEnableVector(STM32_TIM3_NUMBER, STM32_EICU_TIM3_IRQ_PRIORITY); eicup->channels = 4; eicup->clock = STM32_TIMCLK1; } #endif #if STM32_EICU_USE_TIM4 if (&EICUD4 == eicup) { rccEnableTIM4(FALSE); rccResetTIM4(); nvicEnableVector(STM32_TIM4_NUMBER, STM32_EICU_TIM4_IRQ_PRIORITY); eicup->channels = 4; eicup->clock = STM32_TIMCLK1; } #endif #if STM32_EICU_USE_TIM5 if (&EICUD5 == eicup) { rccEnableTIM5(FALSE); rccResetTIM5(); nvicEnableVector(STM32_TIM5_NUMBER, STM32_EICU_TIM5_IRQ_PRIORITY); eicup->channels = 4; eicup->clock = STM32_TIMCLK1; } #endif #if STM32_EICU_USE_TIM8 if (&EICUD8 == eicup) { rccEnableTIM8(FALSE); rccResetTIM8(); nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_EICU_TIM8_IRQ_PRIORITY); nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_EICU_TIM8_IRQ_PRIORITY); eicup->channels = 4; #if defined(STM32_TIM8CLK) eicup->clock = STM32_TIM8CLK; #else eicup->clock = STM32_TIMCLK2; #endif } #endif #if STM32_EICU_USE_TIM9 if (&EICUD9 == eicup) { rccEnableTIM9(FALSE); rccResetTIM9(); nvicEnableVector(STM32_TIM9_NUMBER, STM32_EICU_TIM9_IRQ_PRIORITY); eicup->channels = 2; eicup->clock = STM32_TIMCLK2; } #endif #if STM32_EICU_USE_TIM12 if (&EICUD12 == eicup) { rccEnableTIM12(FALSE); rccResetTIM12(); nvicEnableVector(STM32_TIM12_NUMBER, STM32_EICU_TIM12_IRQ_PRIORITY); eicup->channels = 2; eicup->clock = STM32_TIMCLK1; } #endif #if STM32_EICU_USE_TIM10 if (&EICUD10 == eicup) { rccEnableTIM10(FALSE); rccResetTIM10(); nvicEnableVector(STM32_TIM10_NUMBER, STM32_EICU_TIM10_IRQ_PRIORITY); eicup->channels = 1; eicup->clock = STM32_TIMCLK2; } #endif #if STM32_EICU_USE_TIM11 if (&EICUD11 == eicup) { rccEnableTIM11(FALSE); rccResetTIM11(); nvicEnableVector(STM32_TIM11_NUMBER, STM32_EICU_TIM11_IRQ_PRIORITY); eicup->channels = 1; eicup->clock = STM32_TIMCLK2; } #endif #if STM32_EICU_USE_TIM13 if (&EICUD13 == eicup) { rccEnableTIM13(FALSE); rccResetTIM13(); nvicEnableVector(STM32_TIM13_NUMBER, STM32_EICU_TIM13_IRQ_PRIORITY); eicup->channels = 1; eicup->clock = STM32_TIMCLK1; } #endif #if STM32_EICU_USE_TIM14 if (&EICUD14 == eicup) { rccEnableTIM14(FALSE); rccResetTIM14(); nvicEnableVector(STM32_TIM14_NUMBER, STM32_EICU_TIM14_IRQ_PRIORITY); eicup->channels = 1; eicup->clock = STM32_TIMCLK1; } #endif } else { /* Driver re-configuration scenario, it must be stopped first.*/ eicup->tim->CR1 = 0; /* Timer disabled. */ eicup->tim->DIER = eicup->config->dier &/* DMA-related DIER settings. */ ~STM32_TIM_DIER_IRQ_MASK; eicup->tim->SR = 0; /* Clear eventual pending IRQs. */ eicup->tim->CCR[0] = 0; /* Comparator 1 disabled. */ eicup->tim->CCR[1] = 0; /* Comparator 2 disabled. */ eicup->tim->CNT = 0; /* Counter reset to zero. */ } /* Timer configuration.*/ psc = (eicup->clock / eicup->config->frequency) - 1; chDbgAssert((psc <= 0xFFFF) && ((psc + 1) * eicup->config->frequency) == eicup->clock, "invalid frequency"); eicup->tim->PSC = (uint16_t)psc; eicup->tim->ARR = (eicucnt_t)-1; /* Detect width.*/ if (0xFFFFFFFF == eicup->tim->ARR) eicup->width = EICU_WIDTH_32; else if (0xFFFF == eicup->tim->ARR) eicup->width = EICU_WIDTH_16; else osalSysHalt("Unsupported width"); /* Reset registers */ eicup->tim->SMCR = 0; eicup->tim->CCMR1 = 0; if (eicup->channels > 2) eicup->tim->CCMR2 = 0; /* clean channel structures and set pointers to channel configs */ for (ch=0; ch<EICU_CHANNEL_ENUM_END; ch++) { eicup->channel[ch].last_active = 0; eicup->channel[ch].last_idle = 0; eicup->channel[ch].config = eicup->config->iccfgp[ch]; eicup->channel[ch].state = EICU_CH_IDLE; } /* TIM9 and TIM12 have only 2 channels.*/ if (eicup->channels == 2) { osalDbgCheck((eicup->config->iccfgp[2] == NULL) && (eicup->config->iccfgp[3] == NULL)); } /* TIM10, TIM11, TIM13 and TIM14 have only 1 channel.*/ if (eicup->channels == 1) { osalDbgCheck((eicup->config->iccfgp[1] == NULL) && (eicup->config->iccfgp[2] == NULL) && (eicup->config->iccfgp[3] == NULL)); } start_channels(eicup); }
/** * @brief Enables IRQ sources. * * @notapi */ void irqInit(void) { #if HAL_USE_PAL nvicEnableVector(GPIOTE_IRQn, NRF5_IRQ_GPIOTE_PRIORITY); #endif }
/** Setup the USART for transmission with DMA. * This function sets up the DMA controller and additional USART parameters for * DMA transmit. The USART must already be configured for normal operation. * * \param s The USART DMA state structure. * \oaram usart The USART base address. * \param dma The DMA controller base address. * \param stream The DMA stream number to use. * \param channel The DMA channel to use. The stream and channel must * correspond to a USART RX channel. */ void usart_tx_dma_setup(usart_tx_dma_state* s, u32 usart, u32 dma, u8 stream, u8 channel) { s->dma = dma; s->usart = usart; s->stream = stream; s->channel = channel; s->byte_counter = 0; s->last_byte_ticks = chTimeNow(); /* Enable clock to DMA peripheral. */ if (dma == DMA1) RCC_AHB1ENR |= RCC_AHB1ENR_DMA1EN; else if (dma == DMA2) RCC_AHB1ENR |= RCC_AHB1ENR_DMA2EN; /* Enable TX DMA on the USART. */ usart_enable_tx_dma(usart); /* Make sure stream is disabled to start. */ DMA_SCR(dma, stream) &= ~DMA_SxCR_EN; /* Configure the DMA controller. */ DMA_SCR(dma, stream) = 0; DMA_SCR(dma, stream) = /* Error interrupts. */ DMA_SxCR_DMEIE | DMA_SxCR_TEIE | /* Transfer complete interrupt. */ DMA_SxCR_TCIE | DMA_SxCR_DIR_MEM_TO_PERIPHERAL | /* Increment the memory address after each transfer. */ DMA_SxCR_MINC | /* 4 bytes written to the FIFO from memory at a time */ DMA_SxCR_MBURST_INCR4 | /* 8 bit transfers from USART peripheral. */ DMA_SxCR_PSIZE_8BIT | /* and to memory. */ DMA_SxCR_MSIZE_8BIT | /* TODO: what priority level is necessary? */ /* Very high priority. */ DMA_SxCR_PL_VERY_HIGH | /* The channel selects which request line will trigger a transfer. * (see CD00225773.pdf Table 23). */ DMA_SxCR_CHSEL(channel); /* For now, don't transfer any number of datas * (will be set in the initiating function). */ DMA_SNDTR(dma, stream) = 0; /* DMA into the USART data register... */ DMA_SPAR(dma, stream) = &USART_DR(usart); /* ...from the TX buffer. */ DMA_SM0AR(dma, stream) = s->buff; /* TODO: Investigate more about the best FIFO settings. */ DMA_SFCR(dma, stream) = DMA_SxFCR_DMDIS | /* Enable DMA stream FIFO. */ DMA_SxFCR_FTH_2_4_FULL | /* Trigger level 2/4 full. */ DMA_SxFCR_FEIE; /* Enable FIFO error interrupt. */ s->wr = s->rd = 0; /* Buffer is empty to begin with. */ /* Enable DMA interrupts for this stream with the NVIC. */ if (dma == DMA1) nvicEnableVector(dma_irq_lookup[0][stream], CORTEX_PRIORITY_MASK(USART_DMA_ISR_PRIORITY)); else if (dma == DMA2) nvicEnableVector(dma_irq_lookup[1][stream], CORTEX_PRIORITY_MASK(USART_DMA_ISR_PRIORITY)); }
/** * @brief Low level ADC driver initialization. * * @notapi */ void adc_lld_init(void) { #if STM32_ADC_USE_ADC1 /* Driver initialization.*/ adcObjectInit(&ADCD1); ADCD1.adc = ADC1; #if STM32_ADC_USE_SDADC ADCD1.sdadc = NULL; #endif ADCD1.dmastp = STM32_DMA1_STREAM1; ADCD1.dmamode = STM32_DMA_CR_CHSEL(ADC1_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_ADC_ADC1_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; nvicEnableVector(ADC1_IRQn, CORTEX_PRIORITY_MASK(STM32_ADC_ADC1_IRQ_PRIORITY)); #endif #if STM32_ADC_USE_SDADC1 /* Driver initialization.*/ adcObjectInit(&SDADCD1); #if STM32_ADC_USE_ADC SDADCD1.adc = NULL; #endif SDADCD1.sdadc = SDADC1; SDADCD1.dmastp = STM32_DMA2_STREAM3; SDADCD1.dmamode = STM32_DMA_CR_CHSEL(SDADC1_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_ADC_SDADC1_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; nvicEnableVector(SDADC1_IRQn, CORTEX_PRIORITY_MASK(STM32_ADC_SDADC1_IRQ_PRIORITY)); #endif #if STM32_ADC_USE_SDADC2 /* Driver initialization.*/ adcObjectInit(&SDADCD2); #if STM32_ADC_USE_ADC SDADCD2.adc = NULL; #endif SDADCD2.sdadc = SDADC2; SDADCD2.dmastp = STM32_DMA2_STREAM4; SDADCD2.dmamode = STM32_DMA_CR_CHSEL(SDADC2_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_ADC_SDADC2_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; nvicEnableVector(SDADC2_IRQn, CORTEX_PRIORITY_MASK(STM32_ADC_SDADC2_IRQ_PRIORITY)); #endif #if STM32_ADC_USE_SDADC3 /* Driver initialization.*/ adcObjectInit(&SDADCD3); #if STM32_ADC_USE_ADC SDADCD3.adc = NULL; #endif SDADCD3.sdadc = SDADC3; SDADCD3.dmastp = STM32_DMA2_STREAM5; SDADCD3.dmamode = STM32_DMA_CR_CHSEL(SDADC3_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_ADC_SDADC3_DMA_PRIORITY) | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE | STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; nvicEnableVector(SDADC3_IRQn, CORTEX_PRIORITY_MASK(STM32_ADC_SDADC3_IRQ_PRIORITY)); #endif }
/** * @brief Enables EXTI IRQ sources. * * @notapi */ void ext_lld_exti_irq_enable(void) { nvicEnableVector(EXTI0_IRQn, STM32_EXT_EXTI0_IRQ_PRIORITY); nvicEnableVector(EXTI1_IRQn, STM32_EXT_EXTI1_IRQ_PRIORITY); nvicEnableVector(EXTI2_IRQn, STM32_EXT_EXTI2_IRQ_PRIORITY); nvicEnableVector(EXTI3_IRQn, STM32_EXT_EXTI3_IRQ_PRIORITY); nvicEnableVector(EXTI4_IRQn, STM32_EXT_EXTI4_IRQ_PRIORITY); nvicEnableVector(EXTI9_5_IRQn, STM32_EXT_EXTI5_9_IRQ_PRIORITY); nvicEnableVector(EXTI15_10_IRQn, STM32_EXT_EXTI10_15_IRQ_PRIORITY); nvicEnableVector(PVD_IRQn, STM32_EXT_EXTI16_IRQ_PRIORITY); nvicEnableVector(RTC_Alarm_IRQn, STM32_EXT_EXTI17_IRQ_PRIORITY); nvicEnableVector(OTG_FS_WKUP_IRQn, STM32_EXT_EXTI18_IRQ_PRIORITY); #if STM32_HAS_ETH nvicEnableVector(ETH_WKUP_IRQn, STM32_EXT_EXTI19_IRQ_PRIORITY); #endif #if STM32_HAS_OTG2 nvicEnableVector(OTG_HS_WKUP_IRQn, STM32_EXT_EXTI20_IRQ_PRIORITY); #endif #if !defined(STM32F401xx) nvicEnableVector(TAMP_STAMP_IRQn, STM32_EXT_EXTI21_IRQ_PRIORITY); #endif /* !defined(STM32F401xx) */ nvicEnableVector(RTC_WKUP_IRQn, STM32_EXT_EXTI22_IRQ_PRIORITY); }
/** * @brief Enables GPIO IRQ sources. * * @notapi */ static void ext_lld_irq_enable(void) { #if TIVA_HAS_GPIOA nvicEnableVector(TIVA_GPIOA_NUMBER, TIVA_EXT_GPIOA_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOB nvicEnableVector(TIVA_GPIOB_NUMBER, TIVA_EXT_GPIOB_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOC nvicEnableVector(TIVA_GPIOC_NUMBER, TIVA_EXT_GPIOC_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOD nvicEnableVector(TIVA_GPIOD_NUMBER, TIVA_EXT_GPIOD_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOE nvicEnableVector(TIVA_GPIOE_NUMBER, TIVA_EXT_GPIOE_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOF nvicEnableVector(TIVA_GPIOF_NUMBER, TIVA_EXT_GPIOF_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOG nvicEnableVector(TIVA_GPIOG_NUMBER, TIVA_EXT_GPIOG_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOH nvicEnableVector(TIVA_GPIOH_NUMBER, TIVA_EXT_GPIOH_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOJ nvicEnableVector(TIVA_GPIOJ_NUMBER, TIVA_EXT_GPIOJ_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOK nvicEnableVector(TIVA_GPIOK_NUMBER, TIVA_EXT_GPIOK_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOL nvicEnableVector(TIVA_GPIOL_NUMBER, TIVA_EXT_GPIOL_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOM nvicEnableVector(TIVA_GPIOM_NUMBER, TIVA_EXT_GPIOM_IRQ_PRIORITY); #endif #if TIVA_HAS_GPION nvicEnableVector(TIVA_GPION_NUMBER, TIVA_EXT_GPION_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOP nvicEnableVector(TIVA_GPIOP0_NUMBER, TIVA_EXT_GPIOP0_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOP1_NUMBER, TIVA_EXT_GPIOP1_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOP2_NUMBER, TIVA_EXT_GPIOP2_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOP3_NUMBER, TIVA_EXT_GPIOP3_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOP4_NUMBER, TIVA_EXT_GPIOP4_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOP5_NUMBER, TIVA_EXT_GPIOP5_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOP6_NUMBER, TIVA_EXT_GPIOP6_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOP7_NUMBER, TIVA_EXT_GPIOP7_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOQ nvicEnableVector(TIVA_GPIOQ0_NUMBER, TIVA_EXT_GPIOQ0_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOQ1_NUMBER, TIVA_EXT_GPIOQ1_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOQ2_NUMBER, TIVA_EXT_GPIOQ2_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOQ3_NUMBER, TIVA_EXT_GPIOQ3_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOQ4_NUMBER, TIVA_EXT_GPIOQ4_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOQ5_NUMBER, TIVA_EXT_GPIOQ5_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOQ6_NUMBER, TIVA_EXT_GPIOQ6_IRQ_PRIORITY); nvicEnableVector(TIVA_GPIOQ7_NUMBER, TIVA_EXT_GPIOQ7_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOR nvicEnableVector(TIVA_GPIOR_NUMBER, TIVA_EXT_GPIOR_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOS nvicEnableVector(TIVA_GPIOS_NUMBER, TIVA_EXT_GPIOS_IRQ_PRIORITY); #endif #if TIVA_HAS_GPIOT nvicEnableVector(TIVA_GPIOT_NUMBER, TIVA_EXT_GPIOT_IRQ_PRIORITY); #endif }
/** * @brief Configures and activates the I2C peripheral. * * @param[in] i2cp pointer to the @p I2CDriver object * * @notapi */ void i2c_lld_start(I2CDriver *i2cp) { I2C_TypeDef *dp = i2cp->i2c; i2cp->txdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_M2P; i2cp->rxdmamode = DMAMODE_COMMON | STM32_DMA_CR_DIR_P2M; /* Make sure I2C peripheral is disabled */ dp->CR1 &= ~I2C_CR1_PE; /* If in stopped state then enables the I2C and DMA clocks.*/ if (i2cp->state == I2C_STOP) { #if STM32_I2C_USE_I2C1 if (&I2CD1 == i2cp) { bool_t b; rccResetI2C1(); b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C1_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #1", "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C1_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #2", "stream already allocated"); rccEnableI2C1(FALSE); #if defined(STM32_I2C1_GLOBAL_NUMBER) || defined(__DOXYGEN__) nvicEnableVector(STM32_I2C1_GLOBAL_NUMBER, CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); #elif defined(STM32_I2C1_EVENT_NUMBER) && defined(STM32_I2C1_ERROR_NUMBER) nvicEnableVector(STM32_I2C1_EVENT_NUMBER, CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); nvicEnableVector(STM32_I2C1_ERROR_NUMBER, CORTEX_PRIORITY_MASK(STM32_I2C_I2C1_IRQ_PRIORITY)); #else #error "I2C1 interrupt numbers not defined" #endif i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C1_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C1_TX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C1_DMA_PRIORITY); } #endif /* STM32_I2C_USE_I2C1 */ #if STM32_I2C_USE_I2C2 if (&I2CD2 == i2cp) { bool_t b; rccResetI2C2(); b = dmaStreamAllocate(i2cp->dmarx, STM32_I2C_I2C2_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_rx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #3", "stream already allocated"); b = dmaStreamAllocate(i2cp->dmatx, STM32_I2C_I2C2_IRQ_PRIORITY, (stm32_dmaisr_t)i2c_lld_serve_tx_end_irq, (void *)i2cp); chDbgAssert(!b, "i2c_lld_start(), #4", "stream already allocated"); rccEnableI2C2(FALSE); #if defined(STM32_I2C2_GLOBAL_NUMBER) || defined(__DOXYGEN__) nvicEnableVector(STM32_I2C2_GLOBAL_NUMBER, CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); #elif defined(STM32_I2C2_EVENT_NUMBER) && defined(STM32_I2C2_ERROR_NUMBER) nvicEnableVector(STM32_I2C2_EVENT_NUMBER, CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); nvicEnableVector(STM32_I2C2_ERROR_NUMBER, CORTEX_PRIORITY_MASK(STM32_I2C_I2C2_IRQ_PRIORITY)); #else #error "I2C2 interrupt numbers not defined" #endif i2cp->rxdmamode |= STM32_DMA_CR_CHSEL(I2C2_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); i2cp->txdmamode |= STM32_DMA_CR_CHSEL(I2C2_TX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_I2C_I2C2_DMA_PRIORITY); } #endif /* STM32_I2C_USE_I2C2 */ } /* I2C registers pointed by the DMA.*/ dmaStreamSetPeripheral(i2cp->dmarx, &dp->RXDR); dmaStreamSetPeripheral(i2cp->dmatx, &dp->TXDR); /* Reset i2c peripheral, the TCIE bit will be handled separately.*/ dp->CR1 = i2cp->config->cr1 | I2C_CR1_ERRIE | I2C_CR1_STOPIE | I2C_CR1_NACKIE | I2C_CR1_TXDMAEN | I2C_CR1_RXDMAEN; /* Set slave address field (master mode) */ dp->CR2 = (i2cp->config->cr2 & ~I2C_CR2_SADD); /* Setup I2C parameters.*/ dp->TIMINGR = i2cp->config->timingr; /* Ready to go.*/ dp->CR1 |= I2C_CR1_PE; }
/** * @brief Configures and activates the GPT peripheral. * * @param[in] gptp pointer to the @p GPTDriver object * * @notapi */ void gpt_lld_start(GPTDriver *gptp) { if (gptp->state == GPT_STOP) { /* Clock activation.*/ #if TIVA_GPT_USE_GPT0 if (&GPTD1 == gptp) { SYSCTL->RCGCTIMER |= (1 << 0); nvicEnableVector(TIVA_GPT0A_NUMBER, TIVA_GPT_GPT0A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_GPT1 if (&GPTD2 == gptp) { SYSCTL->RCGCTIMER |= (1 << 1); nvicEnableVector(TIVA_GPT1A_NUMBER, TIVA_GPT_GPT1A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_GPT2 if (&GPTD3 == gptp) { SYSCTL->RCGCTIMER |= (1 << 2); nvicEnableVector(TIVA_GPT2A_NUMBER, TIVA_GPT_GPT2A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_GPT3 if (&GPTD4 == gptp) { SYSCTL->RCGCTIMER |= (1 << 3); nvicEnableVector(TIVA_GPT3A_NUMBER, TIVA_GPT_GPT3A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_GPT4 if (&GPTD5 == gptp) { SYSCTL->RCGCTIMER |= (1 << 4); nvicEnableVector(TIVA_GPT4A_NUMBER, TIVA_GPT_GPT4A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_GPT5 if (&GPTD6 == gptp) { SYSCTL->RCGCTIMER |= (1 << 5); nvicEnableVector(TIVA_GPT5A_NUMBER, TIVA_GPT_GPT5A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_WGPT0 if (&GPTD7 == gptp) { SYSCTL->RCGCWTIMER |= (1 << 0); nvicEnableVector(TIVA_WGPT0A_NUMBER, TIVA_GPT_WGPT0A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_WGPT1 if (&GPTD8 == gptp) { SYSCTL->RCGCWTIMER |= (1 << 1); nvicEnableVector(TIVA_WGPT1A_NUMBER, TIVA_GPT_WGPT1A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_WGPT2 if (&GPTD9 == gptp) { SYSCTL->RCGCWTIMER |= (1 << 2); nvicEnableVector(TIVA_WGPT2A_NUMBER, TIVA_GPT_WGPT2A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_WGPT3 if (&GPTD10 == gptp) { SYSCTL->RCGCWTIMER |= (1 << 3); nvicEnableVector(TIVA_WGPT3A_NUMBER, TIVA_GPT_WGPT3A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_WGPT4 if (&GPTD11 == gptp) { SYSCTL->RCGCWTIMER |= (1 << 4); nvicEnableVector(TIVA_WGPT4A_NUMBER, TIVA_GPT_WGPT4A_IRQ_PRIORITY); } #endif #if TIVA_GPT_USE_WGPT5 if (&GPTD12 == gptp) { SYSCTL->RCGCWTIMER |= (1 << 5); nvicEnableVector(TIVA_WGPT5A_NUMBER, TIVA_GPT_WGPT5A_IRQ_PRIORITY); } #endif } /* Timer configuration.*/ gptp->gpt->CTL = 0; gptp->gpt->CFG = GPTM_CFG_CFG_SPLIT; gptp->gpt->TAPR = ((TIVA_SYSCLK / gptp->config->frequency) - 1); }
/** * @brief Configures and activates the PWM peripheral. * @note Starting a driver that is already in the @p PWM_READY state * disables all the active channels. * * @param[in] pwmp pointer to a @p PWMDriver object * * @notapi */ void pwm_lld_start(PWMDriver *pwmp) { /* Prescaler value calculation: ftimer = 16MHz / 2^PRESCALER */ uint16_t psc_ratio = NRF5_HFCLK_FREQUENCY / pwmp->config->frequency; /* Prescaler ratio must be between 1 and 512, and a power of two. */ osalDbgAssert(psc_ratio <= 512 && !(psc_ratio & (psc_ratio - 1)), "invalid frequency"); /* Prescaler value as a power of 2, must be 0..9 */ uint32_t psc_value; for (psc_value = 0; psc_value < 10; psc_value++) if (psc_ratio == (unsigned)(1 << psc_value)) break; /* Configure as 16bits timer (only TIMER0 support 32bits) */ pwmp->timer->BITMODE = TIMER_BITMODE_BITMODE_16Bit; pwmp->timer->MODE = TIMER_MODE_MODE_Timer; /* With clear shortcuts for period */ pwmp->timer->SHORTS = 0x1UL << (TIMER_SHORTS_COMPARE0_CLEAR_Pos + pwmp->channels); /* Disable and reset interrupts for compare events */ pwmp->timer->INTENCLR = (TIMER_INTENCLR_COMPARE0_Msk | TIMER_INTENCLR_COMPARE1_Msk | TIMER_INTENCLR_COMPARE2_Msk | TIMER_INTENCLR_COMPARE3_Msk ); pwmp->timer->EVENTS_COMPARE[0] = 0; pwmp->timer->EVENTS_COMPARE[1] = 0; pwmp->timer->EVENTS_COMPARE[2] = 0; pwmp->timer->EVENTS_COMPARE[3] = 0; /* Set prescaler */ pwmp->timer->PRESCALER = psc_value; /* Set period */ pwmp->timer->CC[pwmp->channels] = pwmp->period; /* Clear everything */ pwmp->timer->TASKS_CLEAR = 1; /* Enable interrupt */ #if NRF5_PWM_USE_TIMER0 if (&PWMD1 == pwmp) { nvicEnableVector(TIMER0_IRQn, NRF5_PWM_TIMER0_PRIORITY); } #endif #if NRF5_PWM_USE_TIMER1 if (&PWMD2 == pwmp) { nvicEnableVector(TIMER1_IRQn, NRF5_PWM_TIMER1_PRIORITY); } #endif #if NRF5_PWM_USE_TIMER2 if (&PWMD3 == pwmp) { nvicEnableVector(TIMER2_IRQn, NRF5_PWM_TIMER2_PRIORITY); } #endif /* Start timer */ pwmp->timer->TASKS_START = 1; }
/* * Application entry point. */ int main(void) { unsigned i; gptcnt_t interval, threshold, worst; /* Enables FPU exceptions.*/ nvicEnableVector(FPU_IRQn, 1); /* * System initializations. * - HAL initialization, this also initializes the configured device drivers * and performs the board-specific initializations. * - Kernel initialization, the main() function becomes a thread and the * RTOS is active. */ halInit(); chSysInit(); /* * Prepares the Serial driver 2 and GPT drivers 4 and 3. */ sdStart(&SD2, NULL); /* Default is 38400-8-N-1.*/ palSetPadMode(GPIOA, 2, PAL_MODE_ALTERNATE(7)); palSetPadMode(GPIOA, 3, PAL_MODE_ALTERNATE(7)); gptStart(&GPTD4, &gpt4cfg); gptStart(&GPTD3, &gpt3cfg); /* * Enabling TIM1 as a fast interrupts source. */ rccEnableTIM1(false); nvicEnableVector(STM32_TIM1_UP_NUMBER, 0); TIM1->ARR = 10000; TIM1->PSC = 0; TIM1->CNT = 0; TIM1->DIER = TIM_DIER_UIE; TIM1->CR1 = TIM_CR1_CEN; /* * Initializes the worker threads. */ chThdCreateStatic(waWorkerThread, sizeof waWorkerThread, NORMALPRIO - 20, WorkerThread, NULL); chThdCreateStatic(waPeriodicThread, sizeof waPeriodicThread, NORMALPRIO - 10, PeriodicThread, NULL); /* * Test procedure. */ println(""); println("*** ChibiOS/RT IRQ-STORM-FPU long duration test"); println("***"); print("*** Kernel: "); println(CH_KERNEL_VERSION); print("*** Compiled: "); println(__DATE__ " - " __TIME__); #ifdef PORT_COMPILER_NAME print("*** Compiler: "); println(PORT_COMPILER_NAME); #endif print("*** Architecture: "); println(PORT_ARCHITECTURE_NAME); #ifdef PORT_CORE_VARIANT_NAME print("*** Core Variant: "); println(PORT_CORE_VARIANT_NAME); #endif #ifdef PORT_INFO print("*** Port Info: "); println(PORT_INFO); #endif #ifdef PLATFORM_NAME print("*** Platform: "); println(PLATFORM_NAME); #endif #ifdef BOARD_NAME print("*** Test Board: "); println(BOARD_NAME); #endif println("***"); print("*** System Clock: "); printn(STM32_SYSCLK); println(""); print("*** Iterations: "); printn(ITERATIONS); println(""); print("*** Randomize: "); printn(RANDOMIZE); println(""); println(""); worst = 0; for (i = 1; i <= ITERATIONS; i++){ print("Iteration "); printn(i); println(""); saturated = FALSE; threshold = 0; for (interval = 2000; interval >= 10; interval -= interval / 10) { gptStartContinuous(&GPTD4, interval - 1); /* Slightly out of phase.*/ gptStartContinuous(&GPTD3, interval + 1); /* Slightly out of phase.*/ chThdSleepMilliseconds(1000); gptStopTimer(&GPTD4); gptStopTimer(&GPTD3); if (!saturated) print("."); else { print("#"); if (threshold == 0) threshold = interval; } } /* Gives the worker threads a chance to empty the mailboxes before next cycle.*/ chThdSleepMilliseconds(20); println(""); print("Saturated at "); printn(threshold); println(" uS"); println(""); if (threshold > worst) worst = threshold; } gptStopTimer(&GPTD4); gptStopTimer(&GPTD3); print("Worst case at "); printn(worst); println(" uS"); println(""); println("Test Complete"); /* * Normal main() thread activity, nothing in this test. */ while (true) { chThdSleepMilliseconds(5000); } }
/** * @brief Configures and activates the TIMCAP peripheral. * * @param[in] timcapp pointer to the @p TIMCAPDriver object * * @notapi */ void timcap_lld_start(TIMCAPDriver *timcapp) { uint32_t psc; const timcapchannel_t tim_max_channel = timcap_get_max_timer_channel(timcapp); if (timcapp->state == TIMCAP_STOP) { /* Clock activation and timer reset.*/ #if STM32_TIMCAP_USE_TIM1 if (&TIMCAPD1 == timcapp) { rccEnableTIM1(FALSE); rccResetTIM1(); nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_TIMCAP_TIM1_IRQ_PRIORITY); nvicEnableVector(STM32_TIM1_CC_NUMBER, STM32_TIMCAP_TIM1_IRQ_PRIORITY); #if defined(STM32_TIM1CLK) timcapp->clock = STM32_TIM1CLK; #else timcapp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_TIMCAP_USE_TIM2 if (&TIMCAPD2 == timcapp) { rccEnableTIM2(FALSE); rccResetTIM2(); nvicEnableVector(STM32_TIM2_NUMBER, STM32_TIMCAP_TIM2_IRQ_PRIORITY); timcapp->clock = STM32_TIMCLK1; } #endif #if STM32_TIMCAP_USE_TIM3 if (&TIMCAPD3 == timcapp) { rccEnableTIM3(FALSE); rccResetTIM3(); nvicEnableVector(STM32_TIM3_NUMBER, STM32_TIMCAP_TIM3_IRQ_PRIORITY); timcapp->clock = STM32_TIMCLK1; } #endif #if STM32_TIMCAP_USE_TIM4 if (&TIMCAPD4 == timcapp) { rccEnableTIM4(FALSE); rccResetTIM4(); nvicEnableVector(STM32_TIM4_NUMBER, STM32_TIMCAP_TIM4_IRQ_PRIORITY); timcapp->clock = STM32_TIMCLK1; } #endif #if STM32_TIMCAP_USE_TIM5 if (&TIMCAPD5 == timcapp) { rccEnableTIM5(FALSE); rccResetTIM5(); nvicEnableVector(STM32_TIM5_NUMBER, STM32_TIMCAP_TIM5_IRQ_PRIORITY); timcapp->clock = STM32_TIMCLK1; } #endif #if STM32_TIMCAP_USE_TIM8 if (&TIMCAPD8 == timcapp) { rccEnableTIM8(FALSE); rccResetTIM8(); nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_TIMCAP_TIM8_IRQ_PRIORITY); nvicEnableVector(STM32_TIM8_CC_NUMBER, STM32_TIMCAP_TIM8_IRQ_PRIORITY); #if defined(STM32_TIM8CLK) timcapp->clock = STM32_TIM8CLK; #else timcapp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_TIMCAP_USE_TIM9 if (&TIMCAPD9 == timcapp) { rccEnableTIM9(FALSE); rccResetTIM9(); nvicEnableVector(STM32_TIM9_NUMBER, STM32_TIMCAP_TIM9_IRQ_PRIORITY); timcapp->clock = STM32_TIMCLK1; } #endif } else { /* Driver re-configuration scenario, it must be stopped first.*/ timcapp->tim->CR1 = 0; /* Timer disabled. */ timcapp->tim->DIER = timcapp->config->dier &/* DMA-related DIER settings. */ ~STM32_TIM_DIER_IRQ_MASK; timcapp->tim->SR = 0; /* Clear eventual pending IRQs. */ timcapp->tim->CCR[0] = 0; /* Comparator 1 disabled. */ timcapp->tim->CCR[1] = 0; /* Comparator 2 disabled. */ if( tim_max_channel >= TIMCAP_CHANNEL_3 ) timcapp->tim->CCR[2] = 0; /* Comparator 3 disabled. */ if( tim_max_channel >= TIMCAP_CHANNEL_4 ) timcapp->tim->CCR[3] = 0; /* Comparator 4 disabled. */ timcapp->tim->CNT = 0; /* Counter reset to zero. */ } /* Timer configuration.*/ psc = (timcapp->clock / timcapp->config->frequency) - 1; osalDbgAssert((psc <= 0xFFFF) && ((psc + 1) * timcapp->config->frequency) == timcapp->clock, "invalid frequency"); timcapp->tim->PSC = (uint16_t)psc; timcapp->tim->ARR = timcap_get_max_arr(timcapp); timcapp->tim->CCMR1 = 0; timcapp->tim->CCMR2 = 0; timcapp->tim->CCER = 0; timcapchannel_t chan = TIMCAP_CHANNEL_1; /*go through each non-NULL callback channel and enable the capture register on rising/falling edge*/ for( chan = TIMCAP_CHANNEL_1; chan <= tim_max_channel; chan++ ) { if( timcapp->config->capture_cb_array[chan] == NULL ) { continue; } switch (chan) { case TIMCAP_CHANNEL_1: /*CCMR1_CC1S = 01 = CH1 Input on TI1.*/ timcapp->tim->CCMR1 |= STM32_TIM_CCMR1_CC1S(1); break; case TIMCAP_CHANNEL_2: /*CCMR1_CC2S = 10 = CH2 Input on TI1.*/ timcapp->tim->CCMR1 |= STM32_TIM_CCMR1_CC2S(1); break; case TIMCAP_CHANNEL_3: timcapp->tim->CCMR2 |= STM32_TIM_CCMR2_CC3S(1); break; case TIMCAP_CHANNEL_4: timcapp->tim->CCMR2 |= STM32_TIM_CCMR2_CC4S(1); break; } /* The CCER settings depend on the selected trigger mode. TIMCAP_INPUT_DISABLED: Input not used. TIMCAP_INPUT_ACTIVE_HIGH: Active on rising edge, idle on falling edge. TIMCAP_INPUT_ACTIVE_LOW: Active on falling edge, idle on rising edge.*/ if (timcapp->config->modes[chan] == TIMCAP_INPUT_ACTIVE_HIGH) { switch (chan) { case TIMCAP_CHANNEL_1: timcapp->tim->CCER |= STM32_TIM_CCER_CC1E; break; case TIMCAP_CHANNEL_2: timcapp->tim->CCER |= STM32_TIM_CCER_CC2E; break; case TIMCAP_CHANNEL_3: timcapp->tim->CCER |= STM32_TIM_CCER_CC3E; break; case TIMCAP_CHANNEL_4: timcapp->tim->CCER |= STM32_TIM_CCER_CC4E; break; } } else if (timcapp->config->modes[chan] == TIMCAP_INPUT_ACTIVE_LOW) { switch (chan) { case TIMCAP_CHANNEL_1: timcapp->tim->CCER |= STM32_TIM_CCER_CC1E | STM32_TIM_CCER_CC1P; break; case TIMCAP_CHANNEL_2: timcapp->tim->CCER |= STM32_TIM_CCER_CC2E | STM32_TIM_CCER_CC2P; break; case TIMCAP_CHANNEL_3: timcapp->tim->CCER |= STM32_TIM_CCER_CC3E | STM32_TIM_CCER_CC3P; break; case TIMCAP_CHANNEL_4: timcapp->tim->CCER |= STM32_TIM_CCER_CC4E | STM32_TIM_CCER_CC4P; break; } } else { switch (chan) { case TIMCAP_CHANNEL_1: timcapp->tim->CCER &= ~STM32_TIM_CCER_CC1E; break; case TIMCAP_CHANNEL_2: timcapp->tim->CCER &= ~STM32_TIM_CCER_CC2E; break; case TIMCAP_CHANNEL_3: timcapp->tim->CCER &= ~STM32_TIM_CCER_CC3E; break; case TIMCAP_CHANNEL_4: timcapp->tim->CCER &= ~STM32_TIM_CCER_CC4E; break; } } /* Direct pointers to the capture registers in order to make reading data faster from within callbacks.*/ timcapp->ccr_p[chan] = &timcapp->tim->CCR[chan]; } /* SMCR_TS = 101, input is TI1FP1.*/ timcapp->tim->SMCR = STM32_TIM_SMCR_TS(5); }
/** * @brief Configures and activates the PWM peripheral. * @note Starting a driver that is already in the @p PWM_READY state * disables all the active channels. * * @param[in] pwmp pointer to a @p PWMDriver object * * @notapi */ void pwm_lld_start(PWMDriver *pwmp) { uint32_t psc; uint32_t ccer; if (pwmp->state == PWM_STOP) { /* Clock activation and timer reset.*/ #if STM32_PWM_USE_TIM1 if (&PWMD1 == pwmp) { rccEnableTIM1(FALSE); rccResetTIM1(); nvicEnableVector(STM32_TIM1_UP_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY)); nvicEnableVector(STM32_TIM1_CC_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM1_IRQ_PRIORITY)); #if defined(STM32_TIM1CLK) pwmp->clock = STM32_TIM1CLK; #else pwmp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_PWM_USE_TIM2 if (&PWMD2 == pwmp) { rccEnableTIM2(FALSE); rccResetTIM2(); nvicEnableVector(STM32_TIM2_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM2_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM3 if (&PWMD3 == pwmp) { rccEnableTIM3(FALSE); rccResetTIM3(); nvicEnableVector(STM32_TIM3_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM3_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM4 if (&PWMD4 == pwmp) { rccEnableTIM4(FALSE); rccResetTIM4(); nvicEnableVector(STM32_TIM4_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM4_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM5 if (&PWMD5 == pwmp) { rccEnableTIM5(FALSE); rccResetTIM5(); nvicEnableVector(STM32_TIM5_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM5_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK1; } #endif #if STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { rccEnableTIM8(FALSE); rccResetTIM8(); nvicEnableVector(STM32_TIM8_UP_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); nvicEnableVector(STM32_TIM8_CC_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM8_IRQ_PRIORITY)); #if defined(STM32_TIM8CLK) pwmp->clock = STM32_TIM8CLK; #else pwmp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_PWM_USE_TIM9 if (&PWMD9 == pwmp) { rccEnableTIM9(FALSE); rccResetTIM9(); nvicEnableVector(STM32_TIM9_NUMBER, CORTEX_PRIORITY_MASK(STM32_PWM_TIM9_IRQ_PRIORITY)); pwmp->clock = STM32_TIMCLK2; } #endif /* All channels configured in PWM1 mode with preload enabled and will stay that way until the driver is stopped.*/ pwmp->tim->CCMR1 = STM32_TIM_CCMR1_OC1M(6) | STM32_TIM_CCMR1_OC1PE | STM32_TIM_CCMR1_OC2M(6) | STM32_TIM_CCMR1_OC2PE; pwmp->tim->CCMR2 = STM32_TIM_CCMR2_OC3M(6) | STM32_TIM_CCMR2_OC3PE | STM32_TIM_CCMR2_OC4M(6) | STM32_TIM_CCMR2_OC4PE; } else { /* Driver re-configuration scenario, it must be stopped first.*/ pwmp->tim->CR1 = 0; /* Timer disabled. */ pwmp->tim->CCR[0] = 0; /* Comparator 1 disabled. */ pwmp->tim->CCR[1] = 0; /* Comparator 2 disabled. */ pwmp->tim->CCR[2] = 0; /* Comparator 3 disabled. */ pwmp->tim->CCR[3] = 0; /* Comparator 4 disabled. */ pwmp->tim->CNT = 0; /* Counter reset to zero. */ } /* Timer configuration.*/ psc = (pwmp->clock / pwmp->config->frequency) - 1; chDbgAssert((psc <= 0xFFFF) && ((psc + 1) * pwmp->config->frequency) == pwmp->clock, "pwm_lld_start(), #1", "invalid frequency"); pwmp->tim->PSC = (uint16_t)psc; pwmp->tim->ARR = (uint16_t)(pwmp->period - 1); pwmp->tim->CR2 = pwmp->config->cr2; /* Output enables and polarities setup.*/ ccer = 0; switch (pwmp->config->channels[0].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC1P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC1E; default: ; } switch (pwmp->config->channels[1].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC2P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC2E; default: ; } switch (pwmp->config->channels[2].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC3P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC3E; default: ; } switch (pwmp->config->channels[3].mode & PWM_OUTPUT_MASK) { case PWM_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC4P; case PWM_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC4E; default: ; } #if STM32_PWM_USE_ADVANCED #if STM32_PWM_USE_TIM1 && !STM32_PWM_USE_TIM8 if (&PWMD1 == pwmp) { #endif #if !STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { #endif #if STM32_PWM_USE_TIM1 && STM32_PWM_USE_TIM8 if ((&PWMD1 == pwmp) || (&PWMD8 == pwmp)) { #endif switch (pwmp->config->channels[0].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC1NP; case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC1NE; default: ; } switch (pwmp->config->channels[1].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC2NP; case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC2NE; default: ; } switch (pwmp->config->channels[2].mode & PWM_COMPLEMENTARY_OUTPUT_MASK) { case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW: ccer |= STM32_TIM_CCER_CC3NP; case PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH: ccer |= STM32_TIM_CCER_CC3NE; default: ; } } #endif /* STM32_PWM_USE_ADVANCED*/ pwmp->tim->CCER = ccer; pwmp->tim->EGR = STM32_TIM_EGR_UG; /* Update event. */ pwmp->tim->SR = 0; /* Clear pending IRQs. */ pwmp->tim->DIER = (pwmp->config->callback == NULL ? 0 : STM32_TIM_DIER_UIE) | (pwmp->config->dier & ~STM32_TIM_DIER_IRQ_MASK); #if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 #if STM32_PWM_USE_ADVANCED pwmp->tim->BDTR = pwmp->config->bdtr | STM32_TIM_BDTR_MOE; #else pwmp->tim->BDTR = STM32_TIM_BDTR_MOE; #endif #endif /* ATTENTION!!! */ /* THE FOLLOWING CODE IS MODIFIED DUE TO SPECIAL EvvGC-PLUS REQUIREMENTS! */ /* Timer configured but not started yet.*/ pwmp->tim->CR1 = STM32_TIM_CR1_ARPE | STM32_TIM_CR1_URS; } /** * @brief Deactivates the PWM peripheral. * * @param[in] pwmp pointer to a @p PWMDriver object * * @notapi */ void pwm_lld_stop(PWMDriver *pwmp) { /* If in ready state then disables the PWM clock.*/ if (pwmp->state == PWM_READY) { pwmp->tim->CR1 = 0; /* Timer disabled. */ pwmp->tim->DIER = 0; /* All IRQs disabled. */ pwmp->tim->SR = 0; /* Clear eventual pending IRQs. */ #if STM32_PWM_USE_TIM1 || STM32_PWM_USE_TIM8 pwmp->tim->BDTR = 0; #endif #if STM32_PWM_USE_TIM1 if (&PWMD1 == pwmp) { nvicDisableVector(STM32_TIM1_UP_NUMBER); nvicDisableVector(STM32_TIM1_CC_NUMBER); rccDisableTIM1(FALSE); } #endif #if STM32_PWM_USE_TIM2 if (&PWMD2 == pwmp) { nvicDisableVector(STM32_TIM2_NUMBER); rccDisableTIM2(FALSE); } #endif #if STM32_PWM_USE_TIM3 if (&PWMD3 == pwmp) { nvicDisableVector(STM32_TIM3_NUMBER); rccDisableTIM3(FALSE); } #endif #if STM32_PWM_USE_TIM4 if (&PWMD4 == pwmp) { nvicDisableVector(STM32_TIM4_NUMBER); rccDisableTIM4(FALSE); } #endif #if STM32_PWM_USE_TIM5 if (&PWMD5 == pwmp) { nvicDisableVector(STM32_TIM5_NUMBER); rccDisableTIM5(FALSE); } #endif #if STM32_PWM_USE_TIM8 if (&PWMD8 == pwmp) { nvicDisableVector(STM32_TIM8_UP_NUMBER); nvicDisableVector(STM32_TIM8_CC_NUMBER); rccDisableTIM8(FALSE); } #endif #if STM32_PWM_USE_TIM9 if (&PWMD9 == pwmp) { nvicDisableVector(STM32_TIM9_NUMBER); rccDisableTIM9(FALSE); } #endif } } /** * @brief Enables a PWM channel. * @pre The PWM unit must have been activated using @p pwmStart(). * @post The channel is active using the specified configuration. * @note The function has effect at the next cycle start. * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1) * @param[in] width PWM pulse width as clock pulses number * * @notapi */ void pwm_lld_enable_channel(PWMDriver *pwmp, pwmchannel_t channel, pwmcnt_t width) { pwmp->tim->CCR[channel] = width; /* New duty cycle. */ /* If there is a callback defined for the channel then the associated interrupt must be enabled.*/ if (pwmp->config->channels[channel].callback != NULL) { uint32_t dier = pwmp->tim->DIER; /* If the IRQ is not already enabled care must be taken to clear it, it is probably already pending because the timer is running.*/ if ((dier & (2 << channel)) == 0) { pwmp->tim->DIER = dier | (2 << channel); pwmp->tim->SR = ~(2 << channel); } } } /** * @brief Disables a PWM channel. * @pre The PWM unit must have been activated using @p pwmStart(). * @post The channel is disabled and its output line returned to the * idle state. * @note The function has effect at the next cycle start. * * @param[in] pwmp pointer to a @p PWMDriver object * @param[in] channel PWM channel identifier (0...PWM_CHANNELS-1) * * @notapi */ void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) { pwmp->tim->CCR[channel] = 0; pwmp->tim->DIER &= ~(2 << channel); }
/** * @brief Configures and activates the I2C peripheral. * * @param[in] i2cp pointer to the @p I2CDriver object * * @notapi */ void i2c_lld_start(I2CDriver *i2cp) { I2C_TypeDef *dp = i2cp->i2c; /* If in stopped state then enables the I2C clocks.*/ if (i2cp->state == I2C_STOP) { #if TIVA_I2C_USE_I2C0 if (&I2CD1 == i2cp) { SYSCTL->RCGCI2C |= (1 << 0); nvicEnableVector(TIVA_I2C0_NUMBER, TIVA_I2C_I2C0_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C0 */ #if TIVA_I2C_USE_I2C1 if (&I2CD2 == i2cp) { SYSCTL->RCGCI2C |= (1 << 1); nvicEnableVector(TIVA_I2C1_NUMBER, TIVA_I2C_I2C1_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C1 */ #if TIVA_I2C_USE_I2C2 if (&I2CD3 == i2cp) { SYSCTL->RCGCI2C |= (1 << 2); nvicEnableVector(TIVA_I2C2_NUMBER, TIVA_I2C_I2C2_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C2 */ #if TIVA_I2C_USE_I2C3 if (&I2CD4 == i2cp) { SYSCTL->RCGCI2C |= (1 << 3); nvicEnableVector(TIVA_I2C3_NUMBER, TIVA_I2C_I2C3_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C3 */ #if TIVA_I2C_USE_I2C4 if (&I2CD5 == i2cp) { SYSCTL->RCGCI2C |= (1 << 4); nvicEnableVector(TIVA_I2C4_NUMBER, TIVA_I2C_I2C4_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C4 */ #if TIVA_I2C_USE_I2C5 if (&I2CD6 == i2cp) { SYSCTL->RCGCI2C |= (1 << 5); nvicEnableVector(TIVA_I2C5_NUMBER, TIVA_I2C_I2C5_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C5 */ #if TIVA_I2C_USE_I2C6 if (&I2CD7 == i2cp) { SYSCTL->RCGCI2C |= (1 << 6); nvicEnableVector(TIVA_I2C6_NUMBER, TIVA_I2C_I2C6_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C6 */ #if TIVA_I2C_USE_I2C7 if (&I2CD8 == i2cp) { SYSCTL->RCGCI2C |= (1 << 7); nvicEnableVector(TIVA_I2C7_NUMBER, TIVA_I2C_I2C7_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C7 */ #if TIVA_I2C_USE_I2C8 if (&I2CD9 == i2cp) { SYSCTL->RCGCI2C |= (1 << 8); nvicEnableVector(TIVA_I2C8_NUMBER, TIVA_I2C_I2C8_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C7 */ #if TIVA_I2C_USE_I2C9 if (&I2CD10 == i2cp) { SYSCTL->RCGCI2C |= (1 << 9); nvicEnableVector(TIVA_I2C9_NUMBER, TIVA_I2C_I2C9_IRQ_PRIORITY); } #endif /* TIVA_I2C_USE_I2C7 */ } dp->MCR = 0x10; dp->MTPR = MTPR_VALUE; }
/** * @brief Enables EXTI IRQ sources. * * @notapi */ void ext_lld_exti_irq_enable(void) { nvicEnableVector(EXTI0_IRQn, STM32_EXT_EXTI0_IRQ_PRIORITY); nvicEnableVector(EXTI1_IRQn, STM32_EXT_EXTI1_IRQ_PRIORITY); nvicEnableVector(EXTI2_IRQn, STM32_EXT_EXTI2_IRQ_PRIORITY); nvicEnableVector(EXTI3_IRQn, STM32_EXT_EXTI3_IRQ_PRIORITY); nvicEnableVector(EXTI4_IRQn, STM32_EXT_EXTI4_IRQ_PRIORITY); nvicEnableVector(EXTI9_5_IRQn, STM32_EXT_EXTI5_9_IRQ_PRIORITY); nvicEnableVector(EXTI15_10_IRQn, STM32_EXT_EXTI10_15_IRQ_PRIORITY); nvicEnableVector(PVD_IRQn, STM32_EXT_EXTI16_IRQ_PRIORITY); nvicEnableVector(RTC_Alarm_IRQn, STM32_EXT_EXTI17_IRQ_PRIORITY); nvicEnableVector(OTG_FS_WKUP_IRQn, STM32_EXT_EXTI18_IRQ_PRIORITY); nvicEnableVector(ETH_WKUP_IRQn, STM32_EXT_EXTI19_IRQ_PRIORITY); nvicEnableVector(OTG_HS_WKUP_IRQn, STM32_EXT_EXTI20_IRQ_PRIORITY); nvicEnableVector(TAMP_STAMP_IRQn, STM32_EXT_EXTI21_IRQ_PRIORITY); nvicEnableVector(RTC_WKUP_IRQn, STM32_EXT_EXTI22_IRQ_PRIORITY); }
/** Setup the USART for receive with DMA. * This function sets up the DMA controller and additional USART parameters for * DMA receive. The USART must already be configured for normal operation. * * \param s The USART DMA state structure. * \oaram usart The USART base address. * \param dma The DMA controller base address. * \param stream The DMA stream number to use. * \param channel The DMA channel to use. The stream and channel must * correspond to a USART RX channel. */ void usart_rx_dma_setup(usart_rx_dma_state* s, u32 usart, u32 dma, u8 stream, u8 channel) { s->dma = dma; s->usart = usart; s->stream = stream; s->channel = channel; /* Enable clock to DMA peripheral. */ if (dma == DMA1) RCC_AHB1ENR |= RCC_AHB1ENR_DMA1EN; else if (dma == DMA2) RCC_AHB1ENR |= RCC_AHB1ENR_DMA2EN; /* Enable RX DMA on the USART. */ usart_enable_rx_dma(usart); /* Make sure stream is disabled to start. */ DMA_SCR(dma, stream) &= ~DMA_SxCR_EN; /* RM0090 - 9.3.17 : Supposed to wait until enable bit reads '0' before we * write to registers. */ while (DMA_SCR(dma, stream) & DMA_SxCR_EN) ; /* RM0090 - 9.3.17 : Supposed to clear any interrupts in DMA status register * before we reconfigure registers. */ dma_clear_interrupt_flags(dma, stream, DMA_ISR_FLAGS); /* Configure the DMA controller. */ DMA_SCR(dma, stream) = 0; DMA_SCR(dma, stream) = /* Error interrupts. */ DMA_SxCR_DMEIE | DMA_SxCR_TEIE | /* Transfer complete interrupt. */ DMA_SxCR_TCIE | /* Enable circular buffer mode. */ DMA_SxCR_CIRC | DMA_SxCR_DIR_PERIPHERAL_TO_MEM | /* Increment the memory address after each transfer. */ DMA_SxCR_MINC | /* 8 bit transfers from USART peripheral. */ DMA_SxCR_PSIZE_8BIT | /* and to memory. */ DMA_SxCR_MSIZE_8BIT | /* Low priority. */ DMA_SxCR_PL_LOW | /* The channel selects which request line will trigger a transfer. * (see CD00225773.pdf Table 23). */ DMA_SxCR_CHSEL(channel); /* Transfer up to the length of the buffer. */ DMA_SNDTR(dma, stream) = USART_RX_BUFFER_LEN; /* DMA from the USART data register... */ DMA_SPAR(dma, stream) = &USART_DR(usart); /* ...to the RX buffer. */ DMA_SM0AR(dma, stream) = s->buff; /* Buffer is empty to begin with. */ s->rd = 0; s->rd_wraps = s->wr_wraps = 0; /* Enable DMA interrupts for this stream with the NVIC. */ if (dma == DMA1) nvicEnableVector(dma_irq_lookup[0][stream], CORTEX_PRIORITY_MASK(USART_DMA_ISR_PRIORITY)); else if (dma == DMA2) nvicEnableVector(dma_irq_lookup[1][stream], CORTEX_PRIORITY_MASK(USART_DMA_ISR_PRIORITY)); /* Enable the DMA channel. */ DMA_SCR(dma, stream) |= DMA_SxCR_EN; }
/** * @brief Configures and activates the USB peripheral. * @note Starting the OTG cell can be a slow operation carried out with * interrupts disabled, perform it before starting time-critical * operations. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void usb_lld_start(USBDriver *usbp) { stm32_otg_t *otgp = usbp->otg; if (usbp->state == USB_STOP) { /* Clock activation.*/ #if STM32_USB_USE_OTG1 if (&USBD1 == usbp) { /* OTG FS clock enable and reset.*/ rccEnableOTG_FS(FALSE); rccResetOTG_FS(); /* Enables IRQ vector.*/ nvicEnableVector(STM32_OTG1_NUMBER, STM32_USB_OTG1_IRQ_PRIORITY); } #endif #if STM32_USB_USE_OTG2 if (&USBD2 == usbp) { /* OTG HS clock enable and reset.*/ rccEnableOTG_HS(FALSE); rccResetOTG_HS(); /* Workaround for the problem described here: http://forum.chibios.org/phpbb/viewtopic.php?f=16&t=1798 */ rccDisableOTG_HSULPI(TRUE); /* Enables IRQ vector.*/ nvicEnableVector(STM32_OTG2_NUMBER, STM32_USB_OTG2_IRQ_PRIORITY); } #endif usbp->txpending = 0; /* - Forced device mode. - USB turn-around time = TRDT_VALUE. - Full Speed 1.1 PHY.*/ otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE) | GUSBCFG_PHYSEL; /* 48MHz 1.1 PHY.*/ otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11; /* PHY enabled.*/ otgp->PCGCCTL = 0; /* Internal FS PHY activation.*/ #if defined(BOARD_OTG_NOVBUSSENS) otgp->GCCFG = GCCFG_NOVBUSSENS | GCCFG_VBUSASEN | GCCFG_VBUSBSEN | GCCFG_PWRDWN; #else otgp->GCCFG = GCCFG_VBUSASEN | GCCFG_VBUSBSEN | GCCFG_PWRDWN; #endif /* Soft core reset.*/ otg_core_reset(usbp); /* Interrupts on TXFIFOs half empty.*/ otgp->GAHBCFG = 0; /* Endpoints re-initialization.*/ otg_disable_ep(usbp); /* Clear all pending Device Interrupts, only the USB Reset interrupt is required initially.*/ otgp->DIEPMSK = 0; otgp->DOEPMSK = 0; otgp->DAINTMSK = 0; if (usbp->config->sof_cb == NULL) otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM | GINTMSK_ESUSPM |*/; else otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM | GINTMSK_ESUSPM */ | GINTMSK_SOFM; otgp->GINTSTS = 0xFFFFFFFF; /* Clears all pending IRQs, if any. */ #if defined(_CHIBIOS_RT_) /* Creates the data pump thread. Note, it is created only once.*/ if (usbp->tr == NULL) { usbp->tr = chThdCreateI(usbp->wa_pump, sizeof usbp->wa_pump, STM32_USB_OTG_THREAD_PRIO, usb_lld_pump, usbp); chThdStartI(usbp->tr); chSchRescheduleS(); } #endif /* Global interrupts enable.*/ otgp->GAHBCFG |= GAHBCFG_GINTMSK; } }
/** * @brief Low level serial driver initialization. * * @notapi */ void sd_lld_init(void) { #if STM32_SERIAL_USE_USART1 sdObjectInit(&SD1); iqObjectInit(&SD1.iqueue, sd_in_buf1, sizeof sd_in_buf1, NULL, &SD1); oqObjectInit(&SD1.oqueue, sd_out_buf1, sizeof sd_out_buf1, notify1, &SD1); SD1.usart = USART1; SD1.clock = STM32_USART1CLK; #if defined(STM32_USART1_NUMBER) nvicEnableVector(STM32_USART1_NUMBER, STM32_SERIAL_USART1_PRIORITY); #endif #endif #if STM32_SERIAL_USE_USART2 sdObjectInit(&SD2); iqObjectInit(&SD2.iqueue, sd_in_buf2, sizeof sd_in_buf2, NULL, &SD2); oqObjectInit(&SD2.oqueue, sd_out_buf2, sizeof sd_out_buf2, notify2, &SD2); SD2.usart = USART2; SD2.clock = STM32_USART2CLK; #if defined(STM32_USART2_NUMBER) nvicEnableVector(STM32_USART2_NUMBER, STM32_SERIAL_USART2_PRIORITY); #endif #endif #if STM32_SERIAL_USE_USART3 sdObjectInit(&SD3); iqObjectInit(&SD3.iqueue, sd_in_buf3, sizeof sd_in_buf3, NULL, &SD3); oqObjectInit(&SD3.oqueue, sd_out_buf3, sizeof sd_out_buf3, notify3, &SD3); SD3.usart = USART3; SD3.clock = STM32_USART3CLK; #if defined(STM32_USART3_NUMBER) nvicEnableVector(STM32_USART3_NUMBER, STM32_SERIAL_USART3_PRIORITY); #endif #endif #if STM32_SERIAL_USE_UART4 sdObjectInit(&SD4); iqObjectInit(&SD4.iqueue, sd_in_buf4, sizeof sd_in_buf4, NULL, &SD4); oqObjectInit(&SD4.oqueue, sd_out_buf4, sizeof sd_out_buf4, notify4, &SD4); SD4.usart = UART4; SD4.clock = STM32_UART4CLK; #if defined(STM32_UART4_NUMBER) nvicEnableVector(STM32_UART4_NUMBER, STM32_SERIAL_UART4_PRIORITY); #endif #endif #if STM32_SERIAL_USE_UART5 sdObjectInit(&SD5); iqObjectInit(&SD5.iqueue, sd_in_buf5, sizeof sd_in_buf5, NULL, &SD5); oqObjectInit(&SD5.oqueue, sd_out_buf5, sizeof sd_out_buf5, notify5, &SD5); SD5.usart = UART5; SD5.clock = STM32_UART5CLK; #if defined(STM32_UART5_NUMBER) nvicEnableVector(STM32_UART5_NUMBER, STM32_SERIAL_UART5_PRIORITY); #endif #endif #if STM32_SERIAL_USE_USART6 sdObjectInit(&SD6); iqObjectInit(&SD6.iqueue, sd_in_buf6, sizeof sd_in_buf6, NULL, &SD6); oqObjectInit(&SD6.oqueue, sd_out_buf6, sizeof sd_out_buf6, notify6, &SD6); SD6.usart = USART6; SD6.clock = STM32_USART6CLK; #if defined(STM32_USART6_NUMBER) nvicEnableVector(STM32_USART6_NUMBER, STM32_SERIAL_USART6_PRIORITY); #endif #endif #if STM32_SERIAL_USE_UART7 sdObjectInit(&SD7); iqObjectInit(&SD7.iqueue, sd_in_buf7, sizeof sd_in_buf7, NULL, &SD7); oqObjectInit(&SD7.oqueue, sd_out_buf7, sizeof sd_out_buf7, notify7, &SD7); SD7.usart = UART7; SD7.clock = STM32_UART7CLK; #if defined(STM32_UART7_NUMBER) nvicEnableVector(STM32_UART7_NUMBER, STM32_SERIAL_UART7_PRIORITY); #endif #endif #if STM32_SERIAL_USE_UART8 sdObjectInit(&SD8); iqObjectInit(&SD8.iqueue, sd_in_buf8, sizeof sd_in_buf8, NULL, &SD8); oqObjectInit(&SD8.oqueue, sd_out_buf8, sizeof sd_out_buf8, notify8, &SD8); SD8.usart = UART8; SD8.clock = STM32_UART8CLK; #if defined(STM32_UART8_NUMBER) nvicEnableVector(STM32_UART8_NUMBER, STM32_SERIAL_UART8_PRIORITY); #endif #endif #if STM32_SERIAL_USE_LPUART1 sdObjectInit(&LPSD1); iqObjectInit(&LPSD1.iqueue, sd_in_buflp1, sizeof sd_in_buflp1, NULL, &LPSD1); oqObjectInit(&LPSD1.oqueue, sd_out_buflp1, sizeof sd_out_buflp1, notifylp1, &LPSD1); LPSD1.usart = LPUART1; LPSD1.clock = STM32_LPUART1CLK; #if defined(STM32_LPUART1_NUMBER) nvicEnableVector(STM32_LPUART1_NUMBER, STM32_SERIAL_LPUART1_PRIORITY); #endif #endif #if STM32_SERIAL_USE_USART3 || STM32_SERIAL_USE_UART4 || \ STM32_SERIAL_USE_UART5 || STM32_SERIAL_USE_USART6 || \ STM32_SERIAL_USE_UART7 || STM32_SERIAL_USE_UART8 #if defined(STM32_USART3_8_HANDLER) nvicEnableVector(STM32_USART3_8_NUMBER, STM32_SERIAL_USART3_8_PRIORITY); #endif #endif }
/** * @brief Configures and activates the GPT peripheral. * * @param[in] gptp pointer to the @p GPTDriver object * * @notapi */ void gpt_lld_start(GPTDriver *gptp) { uint16_t psc; if (gptp->state == GPT_STOP) { /* Clock activation.*/ #if STM32_GPT_USE_TIM1 if (&GPTD1 == gptp) { rccEnableTIM1(FALSE); rccResetTIM1(); #if !defined(STM32_TIM1_SUPPRESS_ISR) nvicEnableVector(STM32_TIM1_UP_NUMBER, STM32_GPT_TIM1_IRQ_PRIORITY); #endif #if defined(STM32_TIM1CLK) gptp->clock = STM32_TIM1CLK; #else gptp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_GPT_USE_TIM2 if (&GPTD2 == gptp) { rccEnableTIM2(FALSE); rccResetTIM2(); #if !defined(STM32_TIM2_SUPPRESS_ISR) nvicEnableVector(STM32_TIM2_NUMBER, STM32_GPT_TIM2_IRQ_PRIORITY); #endif #if defined(STM32_TIM2CLK) gptp->clock = STM32_TIM2CLK; #else gptp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_GPT_USE_TIM3 if (&GPTD3 == gptp) { rccEnableTIM3(FALSE); rccResetTIM3(); #if !defined(STM32_TIM3_SUPPRESS_ISR) nvicEnableVector(STM32_TIM3_NUMBER, STM32_GPT_TIM3_IRQ_PRIORITY); #endif #if defined(STM32_TIM3CLK) gptp->clock = STM32_TIM3CLK; #else gptp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_GPT_USE_TIM4 if (&GPTD4 == gptp) { rccEnableTIM4(FALSE); rccResetTIM4(); #if !defined(STM32_TIM4_SUPPRESS_ISR) nvicEnableVector(STM32_TIM4_NUMBER, STM32_GPT_TIM4_IRQ_PRIORITY); #endif #if defined(STM32_TIM4CLK) gptp->clock = STM32_TIM4CLK; #else gptp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_GPT_USE_TIM5 if (&GPTD5 == gptp) { rccEnableTIM5(FALSE); rccResetTIM5(); #if !defined(STM32_TIM5_SUPPRESS_ISR) nvicEnableVector(STM32_TIM5_NUMBER, STM32_GPT_TIM5_IRQ_PRIORITY); #endif #if defined(STM32_TIM5CLK) gptp->clock = STM32_TIM5CLK; #else gptp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_GPT_USE_TIM6 if (&GPTD6 == gptp) { rccEnableTIM6(FALSE); rccResetTIM6(); #if !defined(STM32_TIM6_SUPPRESS_ISR) nvicEnableVector(STM32_TIM6_NUMBER, STM32_GPT_TIM6_IRQ_PRIORITY); #endif #if defined(STM32_TIM6CLK) gptp->clock = STM32_TIM6CLK; #else gptp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_GPT_USE_TIM7 if (&GPTD7 == gptp) { rccEnableTIM7(FALSE); rccResetTIM7(); #if !defined(STM32_TIM7_SUPPRESS_ISR) nvicEnableVector(STM32_TIM7_NUMBER, STM32_GPT_TIM7_IRQ_PRIORITY); #endif #if defined(STM32_TIM7CLK) gptp->clock = STM32_TIM7CLK; #else gptp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_GPT_USE_TIM8 if (&GPTD8 == gptp) { rccEnableTIM8(FALSE); rccResetTIM8(); #if !defined(STM32_TIM8_SUPPRESS_ISR) nvicEnableVector(STM32_TIM8_UP_NUMBER, STM32_GPT_TIM8_IRQ_PRIORITY); #endif #if defined(STM32_TIM8CLK) gptp->clock = STM32_TIM8CLK; #else gptp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_GPT_USE_TIM9 if (&GPTD9 == gptp) { rccEnableTIM9(FALSE); rccResetTIM9(); #if !defined(STM32_TIM9_SUPPRESS_ISR) nvicEnableVector(STM32_TIM9_NUMBER, STM32_GPT_TIM9_IRQ_PRIORITY); #endif #if defined(STM32_TIM9CLK) gptp->clock = STM32_TIM9CLK; #else gptp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_GPT_USE_TIM11 if (&GPTD11 == gptp) { rccEnableTIM11(FALSE); rccResetTIM11(); #if !defined(STM32_TIM11_SUPPRESS_ISR) nvicEnableVector(STM32_TIM11_NUMBER, STM32_GPT_TIM11_IRQ_PRIORITY); #endif #if defined(STM32_TIM11CLK) gptp->clock = STM32_TIM11CLK; #else gptp->clock = STM32_TIMCLK2; #endif } #endif #if STM32_GPT_USE_TIM12 if (&GPTD12 == gptp) { rccEnableTIM12(FALSE); rccResetTIM12(); #if !defined(STM32_TIM12_SUPPRESS_ISR) nvicEnableVector(STM32_TIM12_NUMBER, STM32_GPT_TIM12_IRQ_PRIORITY); #endif #if defined(STM32_TIM12CLK) gptp->clock = STM32_TIM12CLK; #else gptp->clock = STM32_TIMCLK1; #endif } #endif #if STM32_GPT_USE_TIM14 if (&GPTD14 == gptp) { rccEnableTIM14(FALSE); rccResetTIM14(); #if !defined(STM32_TIM14_SUPPRESS_ISR) nvicEnableVector(STM32_TIM14_NUMBER, STM32_GPT_TIM14_IRQ_PRIORITY); #endif #if defined(STM32_TIM14CLK) gptp->clock = STM32_TIM14CLK; #else gptp->clock = STM32_TIMCLK1; #endif } #endif } /* Prescaler value calculation.*/ psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1); osalDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock, "invalid frequency"); /* Timer configuration.*/ gptp->tim->CR1 = 0; /* Initially stopped. */ gptp->tim->CR2 = gptp->config->cr2; gptp->tim->PSC = psc; /* Prescaler value. */ gptp->tim->SR = 0; /* Clear pending IRQs. */ gptp->tim->DIER = gptp->config->dier & /* DMA-related DIER bits. */ ~STM32_TIM_DIER_IRQ_MASK; }
/** * @brief Configures and activates the USB peripheral. * @note Starting the OTG cell can be a slow operation carried out with * interrupts disabled, perform it before starting time-critical * operations. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void usb_lld_start(USBDriver *usbp) { stm32_otg_t *otgp = usbp->otg; if (usbp->state == USB_STOP) { /* Clock activation.*/ #if STM32_USB_USE_OTG1 if (&USBD1 == usbp) { /* OTG FS clock enable and reset.*/ rccEnableOTG_FS(FALSE); rccResetOTG_FS(); /* Enables IRQ vector.*/ nvicEnableVector(STM32_OTG1_NUMBER, CORTEX_PRIORITY_MASK(STM32_USB_OTG1_IRQ_PRIORITY)); } #endif #if STM32_USB_USE_OTG2 if (&USBD2 == usbp) { /* OTG HS clock enable and reset.*/ rccEnableOTG_HS(FALSE); rccResetOTG_HS(); /* Enables IRQ vector.*/ nvicEnableVector(STM32_OTG2_NUMBER, CORTEX_PRIORITY_MASK(STM32_USB_OTG2_IRQ_PRIORITY)); } #endif /* Creates the data pump threads in a suspended state. Note, it is created only once, the first time @p usbStart() is invoked.*/ usbp->txpending = 0; if (usbp->thd_ptr == NULL) usbp->thd_ptr = usbp->thd_wait = chThdCreateI(usbp->wa_pump, sizeof usbp->wa_pump, STM32_USB_OTG_THREAD_PRIO, usb_lld_pump, usbp); /* - Forced device mode. - USB turn-around time = TRDT_VALUE. - Full Speed 1.1 PHY.*/ otgp->GUSBCFG = GUSBCFG_FDMOD | GUSBCFG_TRDT(TRDT_VALUE) | GUSBCFG_PHYSEL; /* 48MHz 1.1 PHY.*/ otgp->DCFG = 0x02200000 | DCFG_DSPD_FS11; /* PHY enabled.*/ otgp->PCGCCTL = 0; /* Internal FS PHY activation.*/ otgp->GCCFG = GCCFG_VBUSASEN | GCCFG_VBUSBSEN | GCCFG_PWRDWN; /* Soft core reset.*/ otg_core_reset(usbp); /* Interrupts on TXFIFOs half empty.*/ otgp->GAHBCFG = 0; /* Endpoints re-initialization.*/ otg_disable_ep(usbp); /* Clear all pending Device Interrupts, only the USB Reset interrupt is required initially.*/ otgp->DIEPMSK = 0; otgp->DOEPMSK = 0; otgp->DAINTMSK = 0; if (usbp->config->sof_cb == NULL) otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM | GINTMSK_ESUSPM |*/; else otgp->GINTMSK = GINTMSK_ENUMDNEM | GINTMSK_USBRSTM /*| GINTMSK_USBSUSPM | GINTMSK_ESUSPM */ | GINTMSK_SOFM; otgp->GINTSTS = 0xFFFFFFFF; /* Clears all pending IRQs, if any. */ /* Global interrupts enable.*/ otgp->GAHBCFG |= GAHBCFG_GINTMSK; } }
/** * @brief Enables EXTI IRQ sources. * * @notapi */ void ext_lld_exti_irq_enable(void) { nvicEnableVector(EXTI0_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI0_IRQ_PRIORITY)); nvicEnableVector(EXTI1_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI1_IRQ_PRIORITY)); nvicEnableVector(EXTI2_TS_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI2_IRQ_PRIORITY)); nvicEnableVector(EXTI3_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI3_IRQ_PRIORITY)); nvicEnableVector(EXTI4_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI4_IRQ_PRIORITY)); nvicEnableVector(EXTI9_5_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI5_9_IRQ_PRIORITY)); nvicEnableVector(EXTI15_10_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI10_15_IRQ_PRIORITY)); nvicEnableVector(PVD_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI16_IRQ_PRIORITY)); nvicEnableVector(RTC_Alarm_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI17_IRQ_PRIORITY)); nvicEnableVector(USBWakeUp_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI18_IRQ_PRIORITY)); nvicEnableVector(TAMPER_STAMP_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI19_IRQ_PRIORITY)); nvicEnableVector(COMP1_2_3_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI20_23_IRQ_PRIORITY)); nvicEnableVector(COMP4_5_6_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI30_32_IRQ_PRIORITY)); nvicEnableVector(COMP7_IRQn, CORTEX_PRIORITY_MASK(STM32_EXT_EXTI33_IRQ_PRIORITY)); }
/** * @brief Configures and activates the GPT peripheral. * * @param[in] gptp pointer to the @p GPTDriver object * * @notapi */ void gpt_lld_start(GPTDriver *gptp) { uint16_t psc; if (gptp->state == GPT_STOP) { /* Clock activation.*/ #if STM32_GPT_USE_TIM1 if (&GPTD1 == gptp) { rccEnableTIM1(FALSE); rccResetTIM1(); nvicEnableVector(STM32_TIM1_UP_NUMBER, CORTEX_PRIORITY_MASK(STM32_GPT_TIM1_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK2; } #endif #if STM32_GPT_USE_TIM2 if (&GPTD2 == gptp) { rccEnableTIM2(FALSE); rccResetTIM2(); nvicEnableVector(STM32_TIM2_NUMBER, CORTEX_PRIORITY_MASK(STM32_GPT_TIM2_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK1; } #endif #if STM32_GPT_USE_TIM3 if (&GPTD3 == gptp) { rccEnableTIM3(FALSE); rccResetTIM3(); nvicEnableVector(STM32_TIM3_NUMBER, CORTEX_PRIORITY_MASK(STM32_GPT_TIM3_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK1; } #endif #if STM32_GPT_USE_TIM4 if (&GPTD4 == gptp) { rccEnableTIM4(FALSE); rccResetTIM4(); nvicEnableVector(STM32_TIM4_NUMBER, CORTEX_PRIORITY_MASK(STM32_GPT_TIM4_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK1; } #endif #if STM32_GPT_USE_TIM5 if (&GPTD5 == gptp) { rccEnableTIM5(FALSE); rccResetTIM5(); nvicEnableVector(STM32_TIM5_NUMBER, CORTEX_PRIORITY_MASK(STM32_GPT_TIM5_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK1; } #endif #if STM32_GPT_USE_TIM8 if (&GPTD8 == gptp) { rccEnableTIM8(FALSE); rccResetTIM8(); nvicEnableVector(STM32_TIM8_UP_NUMBER, CORTEX_PRIORITY_MASK(STM32_GPT_TIM8_IRQ_PRIORITY)); gptp->clock = STM32_TIMCLK2; } #endif } /* Prescaler value calculation.*/ psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1); chDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock, "gpt_lld_start(), #1", "invalid frequency"); /* Timer configuration.*/ gptp->tim->CR1 = 0; /* Initially stopped. */ gptp->tim->CR2 = TIM_CR2_CCDS; /* DMA on UE (if any). */ gptp->tim->PSC = psc; /* Prescaler value. */ gptp->tim->DIER = 0; }
/** * @brief Configures and activates the UART peripheral. * * @param[in] uartp pointer to the @p UARTDriver object * * @notapi */ void uart_lld_start(UARTDriver *uartp) { uartp->dmamode = STM32_DMA_CR_DMEIE | STM32_DMA_CR_TEIE; if (uartp->state == UART_STOP) { #if STM32_UART_USE_USART1 if (&UARTD1 == uartp) { bool_t b; b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART1_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #1", "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART1_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #2", "stream already allocated"); rccEnableUSART1(FALSE); nvicEnableVector(STM32_USART1_NUMBER, CORTEX_PRIORITY_MASK(STM32_UART_USART1_IRQ_PRIORITY)); uartp->dmamode |= STM32_DMA_CR_CHSEL(USART1_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART1_DMA_PRIORITY); } #endif #if STM32_UART_USE_USART2 if (&UARTD2 == uartp) { bool_t b; b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART2_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #3", "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART2_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #4", "stream already allocated"); rccEnableUSART2(FALSE); nvicEnableVector(STM32_USART2_NUMBER, CORTEX_PRIORITY_MASK(STM32_UART_USART2_IRQ_PRIORITY)); uartp->dmamode |= STM32_DMA_CR_CHSEL(USART2_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART2_DMA_PRIORITY); } #endif #if STM32_UART_USE_USART3 if (&UARTD3 == uartp) { bool_t b; b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART3_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART3_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated"); rccEnableUSART3(FALSE); nvicEnableVector(STM32_USART3_NUMBER, CORTEX_PRIORITY_MASK(STM32_UART_USART3_IRQ_PRIORITY)); uartp->dmamode |= STM32_DMA_CR_CHSEL(USART3_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART3_DMA_PRIORITY); } #endif #if STM32_UART_USE_USART6 if (&UARTD6 == uartp) { bool_t b; b = dmaStreamAllocate(uartp->dmarx, STM32_UART_USART6_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_rx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #5", "stream already allocated"); b = dmaStreamAllocate(uartp->dmatx, STM32_UART_USART6_IRQ_PRIORITY, (stm32_dmaisr_t)uart_lld_serve_tx_end_irq, (void *)uartp); chDbgAssert(!b, "uart_lld_start(), #6", "stream already allocated"); rccEnableUSART6(FALSE); nvicEnableVector(STM32_USART6_NUMBER, CORTEX_PRIORITY_MASK(STM32_UART_USART6_IRQ_PRIORITY)); uartp->dmamode |= STM32_DMA_CR_CHSEL(USART6_RX_DMA_CHANNEL) | STM32_DMA_CR_PL(STM32_UART_USART6_DMA_PRIORITY); } #endif /* Static DMA setup, the transfer size depends on the USART settings, it is 16 bits if M=1 and PCE=0 else it is 8 bits.*/ if ((uartp->config->cr1 & (USART_CR1_M | USART_CR1_PCE)) == USART_CR1_M) uartp->dmamode |= STM32_DMA_CR_PSIZE_HWORD | STM32_DMA_CR_MSIZE_HWORD; dmaStreamSetPeripheral(uartp->dmarx, &uartp->usart->DR); dmaStreamSetPeripheral(uartp->dmatx, &uartp->usart->DR); uartp->rxbuf = 0; } uartp->rxstate = UART_RX_IDLE; uartp->txstate = UART_TX_IDLE; usart_start(uartp); }
/** * @brief Enables EXTI IRQ sources. * * @notapi */ void ext_lld_exti_irq_enable(void) { nvicEnableVector(EXTI0_IRQn, STM32_EXT_EXTI0_IRQ_PRIORITY); nvicEnableVector(EXTI1_IRQn, STM32_EXT_EXTI1_IRQ_PRIORITY); nvicEnableVector(EXTI2_IRQn, STM32_EXT_EXTI2_IRQ_PRIORITY); nvicEnableVector(EXTI3_IRQn, STM32_EXT_EXTI3_IRQ_PRIORITY); nvicEnableVector(EXTI4_IRQn, STM32_EXT_EXTI4_IRQ_PRIORITY); nvicEnableVector(EXTI9_5_IRQn, STM32_EXT_EXTI5_9_IRQ_PRIORITY); nvicEnableVector(EXTI15_10_IRQn, STM32_EXT_EXTI10_15_IRQ_PRIORITY); nvicEnableVector(PVD_IRQn, STM32_EXT_EXTI16_IRQ_PRIORITY); nvicEnableVector(RTC_Alarm_IRQn, STM32_EXT_EXTI17_IRQ_PRIORITY); #if defined(STM32F10X_CL) /* EXTI vectors specific to STM32F1xx Connectivity Line.*/ nvicEnableVector(OTG_FS_WKUP_IRQn, STM32_EXT_EXTI18_IRQ_PRIORITY); nvicEnableVector(ETH_WKUP_IRQn, STM32_EXT_EXTI19_IRQ_PRIORITY); #elif defined(STM32F10X_MD_VL) || defined(STM32F10X_HD_VL) /* EXTI vectors specific to STM32F1xx Value Line.*/ #else /* EXTI vectors specific to STM32F1xx except Connectivity Line.*/ nvicEnableVector(USBWakeUp_IRQn, STM32_EXT_EXTI18_IRQ_PRIORITY); #endif }