static inline void stm32_otg_close_device(EXO* exo) { int i; //Mask global interrupts OTG_FS_GENERAL->INTMSK &= ~OTG_FS_GENERAL_INTMSK_OTGM; //disable interrupts NVIC_DisableIRQ(OTG_FS_IRQn); kirq_unregister(KERNEL_HANDLE, OTG_FS_IRQn); //close all endpoints for (i = 0; i < USB_EP_COUNT_MAX; ++i) { if (exo->usb.out[i] != NULL) stm32_otg_close_ep(exo, i); if (exo->usb.in[i] != NULL) stm32_otg_close_ep(exo, USB_EP_IN | i); } exo->usb.device = INVALID_HANDLE; //power down #if defined(STM32F10X_CL) //disable clock RCC->AHBENR &= ~RCC_AHBENR_OTGFSEN; //F100, F101, F103 #elif defined(STM32F1) RCC->APB1ENR &= ~RCC_APB1ENR_USBEN; #endif //disable pins stm32_pin_request_inside(exo, HAL_REQ(HAL_PIN, IPC_CLOSE), A9, 0, 0); stm32_pin_request_inside(exo, HAL_REQ(HAL_PIN, IPC_CLOSE), A10, 0, 0); }
static inline void stm32_adc_open_channel(CORE* core, STM32_ADC_CHANNEL channel) { //enable pin #ifdef STM32F1 if (channel < STM32_ADC_REGULAR_CHANNELS_COUNT) stm32_pin_request_inside(core, HAL_REQ(HAL_PIN, STM32_GPIO_ENABLE_PIN), ADC_PINS[channel], stm32_pin_MODE_INPUT_ANALOG, false); else ADC1->CR2 |= ADC_CR2_TSVREFE; #elif defined STM32L0 switch (channel) { case STM32_ADC_TEMP: ADC->CCR |= ADC_CCR_VLCDEN; ADC->CCR |= ADC_CCR_TSEN; break; case STM32_ADC_VREF: ADC->CCR |= ADC_CCR_VREFEN; break; case STM32_ADC_VLCD: ADC->CCR |= ADC_CCR_VLCDEN; break; default: stm32_pin_request_inside(core, HAL_REQ(HAL_PIN, STM32_GPIO_ENABLE_PIN), ADC_PINS[channel], STM32_GPIO_MODE_ANALOG, AF0); } #endif }
static inline void stm32_adc_close_channel(CORE* core, STM32_ADC_CHANNEL channel) { //disable pin if (channel < STM32_ADC_REGULAR_CHANNELS_COUNT) stm32_pin_request_inside(core, HAL_REQ(HAL_PIN, STM32_GPIO_DISABLE_PIN), ADC_PINS[channel], 0, 0); else #ifdef STM32F1 if (core->adc.channels[STM32_ADC_TEMP].samplerate == STM32_ADC_CHANNEL_INVALID_SAMPLERATE && core->adc.channels[STM32_ADC_VREF].samplerate == STM32_ADC_CHANNEL_INVALID_SAMPLERATE ) ADC1->CR2 &= ~ADC_CR2_TSVREFE; #elif defined STM32L0 switch (channel) { case STM32_ADC_TEMP: ADC->CCR &= ~ADC_CCR_TSEN; break; case STM32_ADC_VREF: ADC->CCR &= ~ADC_CCR_VREFEN; break; case STM32_ADC_VLCD: ADC->CCR &= ~ADC_CCR_VLCDEN; break; default: break; } #endif }
void stm32_otg_open_device(EXO* exo, HANDLE device) { int trdt; exo->usb.device = device; //enable GPIO stm32_pin_request_inside(exo, HAL_REQ(HAL_PIN, IPC_OPEN), A9, STM32_GPIO_MODE_INPUT_FLOAT, false); stm32_pin_request_inside(exo, HAL_REQ(HAL_PIN, IPC_OPEN), A10, STM32_GPIO_MODE_INPUT_PULL, true); //enable clock, setup prescaller switch (GET_CORE_CLOCK) { case 72000000: RCC->CFGR &= ~(1 << 22); break; case 48000000: RCC->CFGR |= 1 << 22; break; default: kerror(ERROR_NOT_SUPPORTED); return; } #if defined(STM32F10X_CL) //enable clock RCC->AHBENR |= RCC_AHBENR_OTGFSEN; //F100, F101, F103 #elif defined(STM32F1) RCC->APB1ENR |= RCC_APB1ENR_USBEN; #endif OTG_FS_GENERAL->CCFG = OTG_FS_GENERAL_CCFG_PWRDWN; //reset core while ((OTG_FS_GENERAL->RSTCTL & OTG_FS_GENERAL_RSTCTL_AHBIDL) == 0) {} OTG_FS_GENERAL->RSTCTL |= OTG_FS_GENERAL_RSTCTL_CSRST; while (OTG_FS_GENERAL->RSTCTL & OTG_FS_GENERAL_RSTCTL_CSRST) {}; __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); //disable HNP/SRP OTG_FS_GENERAL->OTGCTL = 0; //refer to programming manual: 1. Setup AHB OTG_FS_GENERAL->AHBCFG = (OTG_FS_GENERAL_AHBCFG_GINT) | (OTG_FS_GENERAL_AHBCFG_TXFELVL); trdt = GET_CORE_CLOCK == 72000000 ? 9 : 5; //2. Setup USB turn-around time OTG_FS_GENERAL->USBCFG = OTG_FS_GENERAL_USBCFG_FDMOD | (trdt << OTG_FS_GENERAL_USBCFG_TRDT_POS) | OTG_FS_GENERAL_USBCFG_PHYSEL | (17 << OTG_FS_GENERAL_USBCFG_TOCAL_POS); //Device init: 1. OTG_FS_DEVICE->CFG = OTG_FS_DEVICE_CFG_DSPD_FS; //2. OTG_FS_GENERAL->INTMSK = OTG_FS_GENERAL_INTMSK_USBSUSPM | OTG_FS_GENERAL_INTMSK_ENUMDNEM | OTG_FS_GENERAL_INTMSK_IEPM | OTG_FS_GENERAL_INTMSK_RXFLVLM; //3. OTG_FS_GENERAL->CCFG |= OTG_FS_GENERAL_CCFG_VBUSBSEN; //disable endpoint interrupts, except IN XFRC OTG_FS_DEVICE->IEPMSK = OTG_FS_DEVICE_IEPMSK_XFRCM; OTG_FS_DEVICE->OEPMSK = 0; OTG_FS_DEVICE->CTL = OTG_FS_DEVICE_CTL_POPRGDNE; //Setup data FIFO OTG_FS_GENERAL->RXFSIZ = ((STM32_USB_MPS / 4) + 1) * 2 + 10 + 1; //enable interrupts kirq_register(KERNEL_HANDLE, OTG_FS_IRQn, usb_on_isr, exo); NVIC_EnableIRQ(OTG_FS_IRQn); NVIC_SetPriority(OTG_FS_IRQn, 13); //Unmask global interrupts OTG_FS_GENERAL->INTMSK |= OTG_FS_GENERAL_INTMSK_OTGM; }