// Hello World - Echo Test von S.F. webseite, usb.c file vom 27.2. 19:05 #include #include "stm32f0xx.h" //[ALEX] #include "usb.h" // The current clock frequency //uint32_t SystemCoreClock=8000000; // Counts milliseconds //volatile uint32_t systick_count=0; // Interrupt handler [ALEX] -> in stm32f0xx_it.c //void SysTick_Handler(void) //{ // systick_count++; //} // Delay some milliseconds void delay_ms(int ms) { //[ALEX] uint32_t start=systick_count; uint32_t start=HAL_GetTick(); while (HAL_GetTick()-startCR2, RCC_CR2_HSI48ON); while (!READ_BIT(RCC->CR2, RCC_CR2_HSI48RDY)); // switch SYSCLK to HSI48 MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_HSI48); while (!READ_BIT(RCC->CFGR, RCC_CFGR_SWS_HSI48)); // Configure the USB clock source MODIFY_REG(RCC->CFGR3, RCC_CFGR3_USBSW, RCC_CFGR3_USBSW_HSI48); SystemCoreClock = 48000000; // Initialize system timer SysTick_Config(SystemCoreClock/1000); //[ALEX] SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN); while (!READ_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN)); //[ALEX] SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN); while (!READ_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN)); //[ALEX] remap pins for USB SYSCFG->CFGR1 |= (SYSCFG_CFGR1_PA11_PA12_RMP); // Setup Clock Recovery System CRS to sync with USB SOF // enable CRS SET_BIT(RCC->APB1ENR, RCC_APB1ENR_CRSEN); while (!READ_BIT(RCC->APB1ENR, RCC_APB1ENR_CRSEN)); // reset CRS RCC->APB1RSTR |= (RCC_APB1RSTR_CRSRST); RCC->APB1RSTR &= ~(RCC_APB1RSTR_CRSRST); CRS->CFGR = CRS_CFGR_SYNCDIV_0 | // prescaler: no divider CRS_CFGR_SYNCSRC_1 | // source: USB SOF CRS_CFGR_SYNCPOL | // polarity: falling (47999U << CRS_CFGR_RELOAD_Pos) | // reload value (34 << CRS_CFGR_FELIM_Pos); // error limit value // reload value = f_{target} / f_{sync} - 1 // reload value = 48e6/1e3 - 1 = 47999 // error limit value: from cubeMx code generator // Adjust HSI48 oscillator smooth trimming MODIFY_REG(CRS->CR, CRS_CR_TRIM, (32 << CRS_CR_TRIM_Pos)); // trim value: from cubeMx code genererator // START AUTOMATIC SYNCHRONIZATION SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN); // enable automatic trimming & frequency error counter } void init_io() { // Enable USB SET_BIT(RCC->APB1ENR, RCC_APB1ENR_USBEN); // Enable Port A and C //[ALEX] SET_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPAEN + RCC_APB2ENR_IOPCEN); // PA5 = Output (LED on Nucleo-64 board) //[ALEX] MODIFY_REG(GPIOA->CRL, GPIO_CRL_CNF5 + GPIO_CRL_MODE5, GPIO_CRL_MODE5_0); // PC13 = Output (LED on Blue-Pill board) //[ALEX] MODIFY_REG(GPIOC->CRH, GPIO_CRH_CNF13 + GPIO_CRH_MODE13, GPIO_CRH_MODE13_0); } // Alternative: Redirect standard output to the USB port, e.g. from puts() or printf() int _write(int file, char *ptr, int len) { for (int i=0; iCFGR1 |= (SYSCFG_CFGR1_PA11_PA12_RMP); init_io(); UsbSetup(); SET_BIT(USB->BCDR, USB_BCDR_DPPU); // enable pullup USB while (1) { // LED On //[ALEX]WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS5); //[ALEX]WRITE_REG(GPIOC->BSRR, GPIO_BSRR_BR13); delay_ms(100); UsbStrOut("Hello World!\n"); // Alternative: puts("Hello World!"); // Send echo of received characters back while (UsbRxAvail()) { char c=UsbGetChar(); UsbCharOut(c); } // LED Off //[ALEX]WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BR5); //[ALEX]WRITE_REG(GPIOC->BSRR, GPIO_BSRR_BS13); delay_ms(900); } }