/* ********************************************************************** *name: IE_stm32.c *author: Samuel Igwe *date: 08/04/2013 *description: Igbo Embedded stm32.c source ********************************************************************** */ #include "IE_stm32.h" #include "IE_tclib.h" /* ********************************************************************** *external reference to stm32_ivt ********************************************************************** */ #define STM32_RAM_BASE_ADDRESS 0x20000000 extern int stm32_ivt; extern int stm32_ivt_end; /* ********************************************************************** *uart buffer and control ********************************************************************** */ #define STM32_UART_BUF_SIZE 64 struct STR_STM32_UART { char sbUartBuf[STM32_UART_BUF_SIZE + 1]; int wdMutex; int wdBufCnt; int wdDmaFlag; }strUart; /* ********************************************************************** *8Mhz * 9 = 72Mhz. 100 clock rate (10mS) desired ********************************************************************** */ #define STM32_TIMER_TICK_RATE_PER_SEC 100 struct STR_STM32_SYSTICK { /*timer module*/ volatile unsigned int dwMsTick; volatile unsigned int dwSeconds; volatile unsigned int dwMsTotal; /*a means to hook into the timer routine*/ void (*ptrFunc)(void); }strSystick; /* ********************************************************************** *functions private to this module ********************************************************************** */ void stm32_init(void); void stm32_rcc_cr_init(void); void stm32_gpio_init(void); void stm32_uart_init(void); void stm32_nvic_init(void); void stm32_timer_init(void); void stm32_nvic_fault_isr(void); void stm32_nvic_unknown_isr(void); void stm32_nvic_systick_isr(void); void stm32_uart_dequeue_buffer(void); /* ********************************************************************** *description: core init *inputs: none *note: ascii cart generator: digital form * http://www.network-science.de/ascii/ ********************************************************************** */ void stm32_init(void) { char *ptrBanner[] = {\ "+-++-++-++-+ +-++-++-++-++-++-++-++-+ +-++-++-++-++-++-++-++-++-+",\ "|I||g||b||o| |E||m||b||e||d||d||e||d| |C||o||r||t||e||x||-||m||3|",\ "+-++-++-++-+ +-++-++-++-++-++-++-++-+ +-++-++-++-++-++-++-++-++-+"}; unsigned char ptrNewline[] = {13,10,0}; int wdCount, wdTemp; /* ********************************************************************** *initialization should start with: *reset control clock registers *general purpose input output registers *universal asynchronous receiver transmitter registers *nested vectored interrupt controller registers ********************************************************************** */ stm32_rcc_cr_init(); stm32_gpio_init(); stm32_uart_init(); stm32_timer_init(); stm32_nvic_init(); /* ********************************************************************** *write banner ********************************************************************** */ for(wdCount=0; wdCount < 3; wdCount++) { wdTemp = tclib_strlen(ptrNewline); stm32_uart_puts(ptrNewline, wdTemp); wdTemp = tclib_strlen((unsigned char *)ptrBanner[wdCount]); stm32_uart_puts((unsigned char *)ptrBanner[wdCount], wdTemp); } wdTemp = tclib_strlen(ptrNewline); stm32_uart_puts(ptrNewline, wdTemp); } /* ********************************************************************** *description: delay wdUs ticks *input: unsigned int wdUs = number of uS ticks to delay for *note: use timer2. its tied to a 36Mhz reference (PCLK1) ********************************************************************** */ void stm32_timer_uS_delay(unsigned int wdUs) { volatile unsigned int wdTemp, wdPr; if(wdUs > 1000000) wdUs = 1000000; /*adjust preload counter if greater than 1000*/ if(wdUs > 1000) { wdUs /= 1000; wdPr = 36000; } else wdPr = 36; /* ********************************************************************** *clear status *clear interrupt enable reg *clear control reg 2 *then *setup prescaler value *setup autoreload (for count up) *clear the status register' UIF bit *then set control reg 1 OPM + CEN *finally *loop on status register checking UIF ********************************************************************** */ (*PTR_STM32_TIM2_CR1) = 0; (*PTR_STM32_TIM2_SR) = 0; (*PTR_STM32_TIM2_DIER)= 0; (*PTR_STM32_TIM2_CR2) = 0; (*PTR_STM32_TIM2_PSC) = wdPr; (*PTR_STM32_TIM2_ARR) = wdUs; (*PTR_STM32_TIM2_SR) = STM32_TIM_SR_UIF; wdTemp = STM32_TIM_CR1_OPM; wdTemp |= STM32_TIM_CR1_CEN; (*PTR_STM32_TIM2_CR1) = wdTemp; do { wdTemp = (*PTR_STM32_TIM2_SR); wdTemp &= STM32_TIM_SR_UIF; }while(wdTemp != STM32_TIM_SR_UIF); } /* ********************************************************************** *description: unhook timer services *input: void (*ptrFunc)(void) = pointer to function to call ********************************************************************** */ void stm32_systick_unhook_services(void(*ptrFunc)(void)) { if(strSystick.ptrFunc == ptrFunc) strSystick.ptrFunc = NULL; } /* ********************************************************************** *description: hook timer services *input: void (*ptrFunc)(void) = pointer to function to call ********************************************************************** */ void stm32_systick_hook_services(void (*ptrFunc)(void)) { if(strSystick.ptrFunc == NULL) strSystick.ptrFunc = ptrFunc; } /* ********************************************************************** *description: get seconds *output: int wdSeconds ********************************************************************** */ int stm32_systick_get_seconds(void) { return strSystick.dwSeconds; } /* ********************************************************************** *description: get millisecond tick *output: int wdMsTick value ********************************************************************** */ int stm32_systick_get_mS_tick(void) { return strSystick.dwMsTick; } /* ********************************************************************** *description: nvic un-install isr routine *inputs: unsigned int wdIrqNum = irq number (0 - 255) *note: handlers are just regular C functions. this routine * un-installes handlers for vectors above 16! ********************************************************************** */ void stm32_nvic_uninstall_isr(unsigned int wdIrqNum) { volatile unsigned int wdByteIdx, wdBitIdx, *ptrTemp; if(wdIrqNum > 255) return; /*install generic handler into table*/ ptrTemp = (volatile unsigned int *)&stm32_ivt; ptrTemp += 16; /*get passed system tables*/ *(ptrTemp + wdIrqNum) = ((unsigned int)(stm32_nvic_unknown_isr) | 0x1); /*enable the particular bit*/ wdByteIdx = (wdIrqNum / 32); wdBitIdx = (wdIrqNum % 32); ptrTemp = PTR_STM32_NVIC_INTCE_BASE; ptrTemp += wdByteIdx; (*ptrTemp)= (1 << wdBitIdx); } /* ********************************************************************** *description: nvic install isr routine *inputs: unsigned int wdIrqNum = irq number (0 - 255) * unsigned int wdIsrAddr= address of handler *note: handlers are just regular C functions. this routine * installs handlers for vectors above 16! ********************************************************************** */ void stm32_nvic_install_isr(unsigned int wdIrqNum,\ unsigned int wdIsrAddr) { volatile unsigned int wdByteIdx, wdBitIdx, *ptrTemp, wdTemp; if(wdIrqNum > 255) return; /*install handler into table*/ ptrTemp = (volatile unsigned int *)&stm32_ivt; ptrTemp += 16; /*get passed system tables*/ *(ptrTemp + wdIrqNum) = (unsigned int)(wdIsrAddr |0x1); /*set the priority low (high number) so as not to conflict with systick*/ wdByteIdx = (wdIrqNum / 4); wdBitIdx = (wdIrqNum % 4); wdTemp = (wdIrqNum >> 4); /*build prio from irqnum*/ if(wdTemp == 0) wdTemp++; ptrTemp = PTR_STM32_NVIC_INTP_BASE; ptrTemp += wdByteIdx; (*ptrTemp)= ((wdTemp << 4) << (wdBitIdx << 8)); /*bits [7:4] of prio*/ /*enable the particular bit*/ wdByteIdx = (wdIrqNum / 32); wdBitIdx = (wdIrqNum % 32); ptrTemp = PTR_STM32_NVIC_INTSE_BASE; ptrTemp += wdByteIdx; (*ptrTemp)= (1 << wdBitIdx); } /* ********************************************************************** *description: nvic fault isr handler *note: handlers are just regular C functions ********************************************************************** */ void stm32_nvic_fault_isr(void) { volatile unsigned int wdTemp; /*determine which interrupt led me here*/ wdTemp = (*PTR_STM32_NVIC_INTCS); wdTemp &= STM32_NVIC_INTCS_VECTACTIVE_MASK; wdTemp >>= STM32_NVIC_INTCS_VECTACTIVE_OFFSET; /*call stm32_uart_dequeue_buffer() twice to run dma and release semaphore*/ stm32_uart_dequeue_buffer(); stm32_uart_dequeue_buffer(); tclib_printf("nvic: vector= %d\n", wdTemp); wdTemp = (*PTR_STM32_NVIC_SHCSR); tclib_printf("nvic: shcsr = %x\t", wdTemp); wdTemp = (*PTR_STM32_NVIC_BFAR); tclib_printf("nvic: bfar = %x\t", wdTemp); /*call stm32_uart_dequeue_buffer() twice to run dma and release semaphore*/ stm32_uart_dequeue_buffer(); stm32_uart_dequeue_buffer(); while(1) ; } /* ********************************************************************** *description: nvic unknown isr handler *note: handlers are just regular C functions ********************************************************************** */ void stm32_nvic_unknown_isr(void) { volatile unsigned int wdIrqNum; /*determine which interrupt led me here*/ wdIrqNum = (*PTR_STM32_NVIC_INTCS); wdIrqNum &= STM32_NVIC_INTCS_VECTACTIVE_MASK; wdIrqNum >>= STM32_NVIC_INTCS_VECTACTIVE_OFFSET; if(wdIrqNum < 16) tclib_printf("nvic_irq_vector %d\n", wdIrqNum); else tclib_printf("nvic_irq %d\n", (wdIrqNum - 16)); } /* ********************************************************************** *description: nvic systick isr handler *note: handlers are just regular C functions * flash LED1 after a second ********************************************************************** */ void stm32_nvic_systick_isr(void) { volatile unsigned int wdTemp, wdPin; strSystick.dwMsTotal++; strSystick.dwMsTick++; if(strSystick.dwMsTick == STM32_TIMER_TICK_RATE_PER_SEC) { strSystick.dwMsTick = 0; strSystick.dwSeconds++; /*flash LED1 once a second*/ wdPin = STM32_GPIO_PIN_LED1; wdTemp = (*PTR_STM32_GPIO_B_ODR); wdTemp &= (1 << wdPin); wdTemp ^= (1 << wdPin); (*PTR_STM32_GPIO_B_ODR) = wdTemp; } /*call user function is requested*/ if(strSystick.ptrFunc != NULL) strSystick.ptrFunc(); /*dequeue uart buffer*/ stm32_uart_dequeue_buffer(); } /* ********************************************************************** *description: uart dequeue routine *notes: should be called from the systick handler. this is how * it is supposed to work * check if dma is in progress (wdDmaFlag) * if so check if dma completed * if so * clear wdDmaFlag * clear ISR flag * release semaphore * else * return * else * check if wdBufCnt > 0 * if so atttempt to acquire semaphore once * if failure exit * else * start dma * set wdDmaFlag to active * clear wdBufCnt * *DO NOT EXECUTE A "while" or "do-while" IN THIS ROUTINE ********************************************************************** */ void stm32_uart_dequeue_buffer(void) { volatile unsigned int wdTemp; if(strUart.wdDmaFlag == TRUE) { wdTemp = (*PTR_STM32_DMA1_ISR); wdTemp &= STM32_DMA_ISR_TCIF_MASK; if(wdTemp == 0) return; (*PTR_STM32_DMA1_ISR) = STM32_DMA_IFCR_CTCIF_MASK; (*PTR_STM32_DMA1_CCR4) = 0; strUart.wdDmaFlag = FALSE; tclib_release_semaphore((unsigned int *)&strUart.wdMutex); return; } else { if(strUart.wdBufCnt == 0) return; wdTemp = tclib_acquire_semaphore((unsigned int *)&strUart.wdMutex); if(wdTemp == 0) return; (*PTR_STM32_DMA1_CNDTR4)= strUart.wdBufCnt; (*PTR_STM32_DMA1_CPAR4) = (unsigned int)(PTR_STM32_UART1_DR); (*PTR_STM32_DMA1_CMAR4) = (unsigned int)&strUart.sbUartBuf; (*PTR_STM32_DMA1_ISR) = STM32_DMA_IFCR_CTCIF_MASK; wdTemp = STM32_DMA_CCR_MSIZE_8; wdTemp |= STM32_DMA_CCR_PSIZE_8; wdTemp |= STM32_DMA_CCR_MINC; wdTemp |= STM32_DMA_CCR_DIR_FROM_MEMORY; wdTemp |= STM32_DMA_CCR_EN; (*PTR_STM32_DMA1_CCR4) = wdTemp; strUart.wdDmaFlag = TRUE; strUart.wdBufCnt = 0; } } /* ********************************************************************** *description: uart queue routine *inputs: char *ptrBuffer = pointer to memory * int wdBytelen = byte length *notes: this is the generic uart i/o routine. heres how it is * supposed to work: * stm32_uart_puts() will be used to transmit both chars * and strings of characters * * while(bytelen != 0) * acquire semaphore * copy characters into buffer ********************************************************************** */ void stm32_uart_puts(unsigned char *ptrBuffer, int wdBytelen) { volatile unsigned int wdTemp, wdXferCnt; unsigned char *ptrTemp; while(wdBytelen != 0) { /*wait until space frees up*/ do { wdTemp = (STM32_UART_BUF_SIZE - strUart.wdBufCnt); }while(wdTemp == 0); /*get semaphore*/ do { wdTemp = tclib_acquire_semaphore((unsigned int *)&strUart.wdMutex); }while(wdTemp == 0); /*determine maximum number of characters i can queue up*/ if(wdBytelen > STM32_UART_BUF_SIZE) wdXferCnt = STM32_UART_BUF_SIZE; else wdXferCnt = wdBytelen; /*determine how much space is left in the uart buffer*/ wdTemp = STM32_UART_BUF_SIZE - strUart.wdBufCnt; if(wdXferCnt > wdTemp) wdXferCnt = wdTemp; /*memcpy the data over*/ ptrTemp = (unsigned char *)(strUart.sbUartBuf + strUart.wdBufCnt); tclib_memcpy((unsigned char *)ptrTemp, ptrBuffer, wdXferCnt); /*adjust strUart index and wdBytelen*/ strUart.wdBufCnt += wdXferCnt; wdBytelen -= wdXferCnt; ptrBuffer += wdXferCnt; /*release semaphore*/ tclib_release_semaphore((unsigned int *)&strUart.wdMutex); } } /* ********************************************************************** *description: free running timer to be used to time/guage progress *input: void *note: use timer3. its tied to a 36Mhz reference (PCLK1) ********************************************************************** */ void stm32_timer_init(void) { volatile unsigned int wdTemp; /* ********************************************************************** *clear control reg 2 *then *setup prescaler value *setup autoreload (for count up) *then set control reg 1 OPM + CEN ********************************************************************** */ (*PTR_STM32_TIM3_CR1) = 0; (*PTR_STM32_TIM3_DIER)= 0; (*PTR_STM32_TIM3_CR2) = 0; (*PTR_STM32_TIM3_PSC) = 36; (*PTR_STM32_TIM3_ARR) = 0xffffffff; wdTemp = STM32_TIM_CR1_DIR_UP; wdTemp |= STM32_TIM_CR1_CEN; (*PTR_STM32_TIM3_CR1) = wdTemp; } /* ********************************************************************** *description: nvic initialization function *note: setup the systick clock and handler and the interrupts * for usb (low and high priority) ********************************************************************** */ void stm32_nvic_init(void) { volatile unsigned int wdTemp, *ptrTemp, wdCount; tclib_memset((unsigned char *)&strSystick, 0, sizeof(strSystick)); /* ********************************************************************** *install handlers for all vector positions *skip positions 0 = thread stack and 1 = reset address *dont hardcode size of table - determine it with stm32_ivt and _end ********************************************************************** */ ptrTemp = (volatile unsigned int *)&stm32_ivt; wdTemp = (&stm32_ivt_end - &stm32_ivt); for(wdCount=2; wdCount<wdTemp; wdCount++) { if(wdCount <= 6) ptrTemp[wdCount] = ((unsigned int)(stm32_nvic_fault_isr)\ | 0x1); else { if(wdCount == 15) ptrTemp[wdCount] = ((unsigned int)(stm32_nvic_systick_isr)\ | 0x1); else ptrTemp[wdCount] = ((unsigned int)(stm32_nvic_unknown_isr)\ | 0x1); } } /* ********************************************************************** *setup exception and interrupt priorities. CRUCIAL because of a bug in *my code I discovered (because of leaving priorities set to the *default) that caused a branch into the usb isr to PREVENT premption *by the systick handler which was holding a mutex. deadlock ... * *zero out sytem handler priority registers. give them all max priority * *set all external interrupt priorities to 0x8 ********************************************************************** */ (*PTR_STM32_NVIC_SHPR_1) = 0; (*PTR_STM32_NVIC_SHPR_2) = 0; (*PTR_STM32_NVIC_SHPR_3) = 0; ptrTemp = PTR_STM32_NVIC_INTP_BASE; wdTemp = (&stm32_ivt_end - &stm32_ivt); wdTemp -= 16; /*subtract exceptions table*/ if((wdTemp & 0x3) != 0) /*really (wdTemp % 4)*/ wdTemp += 4; /*for non integer multiples*/ wdTemp >>= 2; /*there are 4 prio in one reg*/ for(wdCount=0; wdCount<= wdTemp; wdCount++) ptrTemp[wdCount] = 0x88888888; /*only bits [7:4] are used but*/ /* ********************************************************************** *the internal rc clock and external crystal clock are both 8Mhz. Setup *the pll to generate the maximum clock rate for the cortex-m3 - that *is 72Mhz. the systick reload register will be configured to generate *an interrupt 100 times a second ********************************************************************** */ (*PTR_STM32_NVIC_SYSTRV) = 720000; /* ********************************************************************** *set 8 byte stack alignment and context restoration *set the interrupt vector table *set and enable the systick interrupt ********************************************************************** */ wdTemp = STM32_NVIC_CCR_STKALIGN_QWORD; wdTemp |= STM32_NVIC_CCR_DIV_0_TRP; (*PTR_STM32_NVIC_CCR) = wdTemp; wdTemp = (unsigned int )&stm32_ivt; wdTemp -= STM32_RAM_BASE_ADDRESS; wdTemp |= STM32_NVIC_VTOR_TBLBASE_RAM; (*PTR_STM32_NVIC_VTOR) = wdTemp; wdTemp = STM32_NVIC_STCSR_CLKSOURCE_CORE; wdTemp |= STM32_NVIC_STCSR_TICKINT; wdTemp |= STM32_NVIC_STCSR_ENABLE; (*PTR_STM32_NVIC_SYSTCSR) = wdTemp; /* ********************************************************************** *now enable interrupts *enable interrupt set enable for the first 16 vectors ********************************************************************** */ asm("dsb"); wdTemp = 1 << 2; /*nmi*/ wdTemp |= 1 << 3; /*hard*/ wdTemp |= 1 << 4; /*mmu*/ wdTemp |= 1 << 5; /*bus*/ wdTemp |= 1 << 6; /*usage*/ wdTemp |= 1 << 15; /*systick*/ (*PTR_STM32_NVIC_INTSE_BASE) = wdTemp; asm("cpsie i"); } /* ********************************************************************** *description: setup uart for 115200 * setup * baud rate register * control reg1 * control reg2 * control reg3 ********************************************************************** */ void stm32_uart_init(void) { volatile unsigned int wdTemp; (*PTR_STM32_UART1_BRR) = 0x271; wdTemp = STM32_UART_CR1_UE; wdTemp |= STM32_UART_CR1_RE; wdTemp |= STM32_UART_CR1_TE; (*PTR_STM32_UART1_CR1) = wdTemp; (*PTR_STM32_UART1_CR2) = 0; wdTemp = STM32_UART_CR3_EIE; wdTemp |= STM32_UART_CR3_DMAT; (*PTR_STM32_UART1_CR3) = wdTemp; /*initialize strUart*/ tclib_memset((unsigned char *)&strUart, 0, sizeof(strUart)); } /* ********************************************************************** *description: setup general purpose I/O pins * uart * led * switches ********************************************************************** */ void stm32_gpio_init(void) { volatile unsigned int wdTemp, wdMask; wdTemp = STM32_GPIO_PIN_UART_TX - 8; wdMask = ((STM32_GPIO_CNF_OUT_ALT_OPEN_DRAIN << 2) | STM32_GPIO_MODE_OUTPUT_2MHZ)\ << (wdTemp << 2); wdTemp = STM32_GPIO_PIN_UART_RX - 8; wdMask |= ((STM32_GPIO_CNF_IN_FLOATING << 2) | STM32_GPIO_MODE_INPUT_MODE)\ << (wdTemp << 2); (*PTR_STM32_GPIO_A_CRH) = wdMask; wdTemp = STM32_GPIO_PIN_LED1 - 8; wdMask = ((STM32_GPIO_CNF_OUT_GEN_PUSH_PULL << 2) | STM32_GPIO_MODE_OUTPUT_2MHZ)\ << (wdTemp << 2); wdTemp = STM32_GPIO_PIN_LED2 - 8; wdMask |= ((STM32_GPIO_CNF_OUT_GEN_PUSH_PULL << 2) | STM32_GPIO_MODE_OUTPUT_2MHZ)\ << (wdTemp << 2); (*PTR_STM32_GPIO_B_CRH) = wdMask; wdTemp = STM32_GPIO_PIN_SW1; wdMask = ((STM32_GPIO_CNF_IN_PULL_UP_DOWN << 2) | STM32_GPIO_MODE_INPUT_MODE)\ << (wdTemp << 2); wdTemp = STM32_GPIO_PIN_SW2; wdMask |= ((STM32_GPIO_CNF_IN_PULL_UP_DOWN << 2) | STM32_GPIO_MODE_INPUT_MODE)\ << (wdTemp << 2); (*PTR_STM32_GPIO_C_CRL) = wdMask; (*PTR_STM32_GPIO_B_BRR) = (1 << STM32_GPIO_PIN_LED1 | 1 << STM32_GPIO_PIN_LED2); } /* ********************************************************************** *description: setup reset clock register and enable peripherals *note: reset then enable peripherals I need. note that this * routine should be called before any core peripherals * are enabled ********************************************************************** */ void stm32_rcc_cr_init(void) { volatile unsigned int wdTemp; /* ********************************************************************** *enable the various clocks and set pll and divider values ********************************************************************** */ wdTemp = STM32_RCC_CFGR_SW_PLL << STM32_RCC_CFGR_SW_OFFSET; wdTemp |= STM32_RCC_CFGR_HPRE_NODIV << STM32_RCC_CFGR_HPRE_OFFSET; wdTemp |= STM32_RCC_CFGR_PPRE1_2 << STM32_RCC_CFGR_PPRE1_OFFSET; wdTemp |= STM32_RCC_CFGR_PPRE2_NODIV << STM32_RCC_CFGR_PPRE2_OFFSET; wdTemp |= STM32_RCC_CFGR_PLLSRC; wdTemp |= (9 - STM32_RCC_CFGR_PLLMUL_ADJUSTMENT) << STM32_RCC_CFGR_PLLMUL_OFFSET; wdTemp |= STM32_RCC_CFGR_MCO_HSE; (*PTR_STM32_RCC_CFGR) = wdTemp; wdTemp = STM32_RCC_CR_HSEON; wdTemp |= STM32_RCC_CR_CSSON; wdTemp |= STM32_RCC_CR_PLLON; (*PTR_STM32_RCC_CR) = wdTemp; /* ********************************************************************** *wait for the pll and high speed external clock to be ready ... ********************************************************************** */ do { wdTemp = (*PTR_STM32_RCC_CR); wdTemp &= (STM32_RCC_CR_PLLRDY | STM32_RCC_CR_HSERDY); }while(wdTemp != (STM32_RCC_CR_PLLRDY | STM32_RCC_CR_HSERDY)); /* ********************************************************************** *reset the peripherals *then zero out the peripherals ********************************************************************** */ wdTemp = STM32_RCC_APB2RSTR_UART1RST; wdTemp |= STM32_RCC_APB2RSTR_IOPDRST; wdTemp |= STM32_RCC_APB2RSTR_IOPCRST; wdTemp |= STM32_RCC_APB2RSTR_IOPBRST; wdTemp |= STM32_RCC_APB2RSTR_IOPARST; wdTemp |= STM32_RCC_APB2RSTR_AFIORST; (*PTR_STM32_RCC_APB2RSTR) = wdTemp; wdTemp = STM32_RCC_APB1RSTR_PWRRST; wdTemp |= STM32_RCC_APB1RSTR_USBRST; wdTemp |= STM32_RCC_APB1RSTR_TIM5RST; wdTemp |= STM32_RCC_APB1RSTR_TIM4RST; wdTemp |= STM32_RCC_APB1RSTR_TIM3RST; wdTemp |= STM32_RCC_APB1RSTR_TIM2RST; (*PTR_STM32_RCC_APB1RSTR) = wdTemp; (*PTR_STM32_RCC_APB2RSTR) = 0; (*PTR_STM32_RCC_APB1RSTR) = 0; /* ********************************************************************** *enable the peripherals ********************************************************************** */ wdTemp = STM32_RCC_AHBENR_CRCEN; wdTemp |= STM32_RCC_AHBENR_SRAMEN; wdTemp |= STM32_RCC_AHBENR_DMA2EN; wdTemp |= STM32_RCC_AHBENR_DMA1EN; (*PTR_STM32_RCC_AHBENR) = wdTemp; wdTemp = STM32_RCC_APB2ENR_UART1EN; wdTemp |= STM32_RCC_APB2ENR_IOPDEN; wdTemp |= STM32_RCC_APB2ENR_IOPCEN; wdTemp |= STM32_RCC_APB2ENR_IOPBEN; wdTemp |= STM32_RCC_APB2ENR_IOPAEN; wdTemp |= STM32_RCC_APB2ENR_AFIOEN; (*PTR_STM32_RCC_APB2ENR) = wdTemp; wdTemp = STM32_RCC_APB1ENR_PWREN; wdTemp |= STM32_RCC_APB1ENR_USBEN; wdTemp |= STM32_RCC_APB1ENR_TIM5EN; wdTemp |= STM32_RCC_APB1ENR_TIM4EN; wdTemp |= STM32_RCC_APB1ENR_TIM3EN; wdTemp |= STM32_RCC_APB1ENR_TIM2EN; (*PTR_STM32_RCC_APB1ENR) = wdTemp; wdTemp = STM32_RCC_BDCR_RTCEN; wdTemp |= STM32_RCC_BDCR_RTCSEL_LSE << STM32_RCC_BDCR_RTCSEL_OFFSET; wdTemp |= STM32_RCC_BDCR_LSEON; (*PTR_STM32_RCC_BDCR) = wdTemp; }
Monday, August 5, 2013
IE_stm32.c
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment