static inline void lpc_usb_close_device(CORE* core) { int i; //disable interrupts NVIC_DisableIRQ(USB_IRQn); irq_unregister(USB_IRQn); #if (USB_SOFT_CONNECT) //disable pullap LPC_USB->DEVCMDSTAT &= ~USB_DEVCMDSTAT_DCON; #endif //close all endpoints for (i = 0; i < USB_EP_COUNT_MAX; ++i) { if (core->usb.out[i] != NULL) lpc_usb_close_ep(core, i); if (core->usb.in[i] != NULL) lpc_usb_close_ep(core, USB_EP_IN | i); } //Mask all interrupts LPC_USB->INTEN = 0; //disable device LPC_USB->DEVCMDSTAT &= ~USB_DEVCMDSTAT_DEV_EN; //power down //turn clock off LPC_SYSCON->SYSAHBCLKCTRL &= ~((1 << SYSCON_SYSAHBCLKCTRL_USB_POS) | (1 << SYSCON_SYSAHBCLKCTRL_USBRAM_POS)); //power down LPC_SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_USBPAD_PD; #if (USB_DEDICATED_PLL) LPC_SYSCON->PDRUNCFG |= SYSCON_PDRUNCFG_USBPLL_PD; #endif //disable pins lpc_pin_request_inside(core, HAL_REQ(HAL_PIN, IPC_CLOSE), VBUS, 0, 0); #if (USB_SOFT_CONNECT) lpc_pin_request_inside(core, HAL_REQ(HAL_PIN, IPC_CLOSE), SCONNECT, 0, 0); #endif }
void ipc_read(IPC* ipc) { for (;;) { error(ERROR_OK); if (rb_is_empty(&__GLOBAL->process->ipcs)) svc_call(SVC_IPC_WAIT, ANY_HANDLE, ANY_CMD, ANY_HANDLE); ipc_peek(__GLOBAL->process->ipcs.tail, ipc); if (ipc->cmd == HAL_REQ(HAL_SYSTEM, IPC_PING)) ipc_write(ipc); else break; } }
void lpc_usb_open_device(CORE* core, HANDLE device) { int i; core->usb.device = device; lpc_pin_request_inside(core, HAL_REQ(HAL_PIN, IPC_OPEN), VBUS, PIO0_3_VBUS, 0); #if (USB_SOFT_CONNECT) lpc_pin_request_inside(core, HAL_REQ(HAL_PIN, IPC_OPEN), SCONNECT, PIO0_6_USB_CONNECT, 0); #endif //enable clock, power up //power on. USBPLL must be turned on even in case of SYS PLL used. Why? LPC_SYSCON->PDRUNCFG &= ~(SYSCON_PDRUNCFG_USBPLL_PD | SYSCON_PDRUNCFG_USBPAD_PD); #if (USB_DEDICATED_PLL) int i; //enable and lock PLL LPC_SYSCON->USBPLLCTRL = ((USBPLL_M - 1) << SYSCON_USBPLLCTRL_MSEL_POS) | ((32 - __builtin_clz(USBPLL_P)) << SYSCON_USBPLLCTRL_PSEL_POS); LPC_SYSCON->USBPLLCLKSEL = SYSCON_USBPLLCLKSEL_SYSOSC; LPC_SYSCON->USBPLLCLKUEN = 0; LPC_SYSCON->USBPLLCLKUEN = SYSCON_SYSPLLCLKUEN_ENA; //wait for PLL lock for (i = 0; i < PLL_LOCK_TIMEOUT; ++i) { if (LPC_SYSCON->USBPLLSTAT & SYSCON_USBPLLSTAT_LOCK) break; } LPC_SYSCON->USBCLKSEL = SYSCON_USBCLKSEL_PLL; #else LPC_SYSCON->USBCLKSEL = SYSCON_USBCLKSEL_MAIN; #endif //switch to clock source LPC_SYSCON->USBCLKUEN = 0; LPC_SYSCON->USBCLKUEN = SYSCON_USBCLKUEN_ENA; //turn clock on LPC_SYSCON->SYSAHBCLKCTRL |= (1 << SYSCON_SYSAHBCLKCTRL_USB_POS) | (1 << SYSCON_SYSAHBCLKCTRL_USBRAM_POS); //clear any spurious pending interrupts LPC_USB->DEVCMDSTAT = USB_DEVCMDSTAT_DCON_C | USB_DEVCMDSTAT_DSUS_C | USB_DEVCMDSTAT_DRES_C | USB_DEVCMDSTAT_SETUP; LPC_USB->INTSTAT = USB_INTSTAT_EP0OUT | USB_INTSTAT_EP0IN | USB_INTSTAT_EP1OUT | USB_INTSTAT_EP1IN | USB_INTSTAT_EP2OUT | USB_INTSTAT_EP2IN | USB_INTSTAT_EP3OUT | USB_INTSTAT_EP3IN | USB_INTSTAT_EP4OUT | USB_INTSTAT_EP4IN | USB_INTSTAT_FRAME_INT | USB_INTSTAT_DEV_INT; #if (USB_DEBUG_ERRORS) LPC_USB->INFO &= ~USB_INFO_ERR_CODE_MASK; #endif //setup buffer descriptor table LPC_USB->EPLISTSTART = USB_RAM_BASE & ~0xff; LPC_USB->DATABUFSTART = USB_BUF_BASE & ~0x3fffff; //clear descriptor table data for (i = 0; i < USB_HW_EP_COUNT; ++i) { *USB_EP_LISTSTS(i, 0) = *USB_EP_LISTSTS(i, 1) = 0; *USB_EP_LISTSTS(i | USB_EP_IN, 0) = *USB_EP_LISTSTS(i | USB_EP_IN, 1) = 0; } //SETUP buffer offset is not incremented *USB_EP_LISTSTS(0, 1) = USB_EP_LISTST_OFFSET_SET(USB_SETUP_BUF_BASE); //enable interrupts irq_register(USB_IRQn, lpc_usb_on_isr, core); NVIC_EnableIRQ(USB_IRQn); NVIC_SetPriority(USB_IRQn, 1); //Unmask common interrupts LPC_USB->INTEN = USB_INTSTAT_DEV_INT; #if (USB_SOFT_CONNECT) //pullap LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_DCON; #endif }
ETH_CONN_TYPE tcpip_get_conn_state(HANDLE tcpip) { return (ETH_CONN_TYPE)get_handle(tcpip, HAL_REQ(HAL_TCPIP, TCPIP_GET_CONN_STATE), 0, 0, 0); }
void tcpip_close(HANDLE tcpip) { ack(tcpip, HAL_REQ(HAL_TCPIP, IPC_CLOSE), 0, 0, 0); }
bool tcpip_open(HANDLE tcpip, HANDLE eth, unsigned int eth_handle, ETH_CONN_TYPE conn_type) { return get_handle(tcpip, HAL_REQ(HAL_TCPIP, IPC_OPEN), eth_handle, eth, conn_type) != INVALID_HANDLE; }
unsigned int gpio_get_mask(unsigned int port, unsigned int mask) { return get_exo(HAL_REQ(HAL_GPIO, IPC_GPIO_GET_MASK), port, mask, 0); }
bool gpio_get_pin(unsigned int pin) { return get_exo(HAL_REQ(HAL_GPIO, IPC_GPIO_GET_PIN), pin, 0, 0); }
void rndis_set_host_mac(HANDLE usbd, unsigned int iface, const MAC* mac) { ack(usbd, HAL_REQ(HAL_USBD_IFACE, RNDIS_SET_HOST_MAC), iface, mac->u32.hi, mac->u32.lo); }
void rndis_set_vendor_id(HANDLE usbd, unsigned int iface, uint8_t a, uint8_t b, uint8_t c) { ack(usbd, HAL_REQ(HAL_USBD_IFACE, RNDIS_SET_VENDOR_ID), iface, (a << 16) | (b << 8) | c, 0); }
void rndis_set_link(HANDLE usbd, unsigned int iface, ETH_CONN_TYPE conn) { ack(usbd, HAL_REQ(HAL_USBD_IFACE, RNDIS_SET_LINK), iface, (unsigned int)conn, 0); }
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; }
unsigned int power_get_clock(POWER_CLOCK_TYPE clock_type) { return get(object_get(SYS_OBJ_CORE), HAL_REQ(HAL_POWER, POWER_GET_CLOCK), clock_type, 0, 0); }
void power_set_mode(POWER_MODE mode) { ack(object_get(SYS_OBJ_CORE), HAL_REQ(HAL_POWER, POWER_SET_MODE), mode, 0, 0); }
unsigned int power_get_clock(POWER_CLOCK_TYPE clock_type) { return get_exo(HAL_REQ(HAL_POWER, POWER_GET_CLOCK), clock_type, 0, 0); }