/* Portbelegungen und Konfiguration: */ #include "StdTypes.h" #include "STM32F103all.h" #include "startup.h" #include "config.h" /* Portbelegungen und Konfiguration: ================================= Diese Konfiguration ist für den STM32F103C8T6, also im LQFP-48 Gehäuse. Zu jedem Pin gibt es im zugehörigen GPIOx_CRL und .._CRH vier Bits, die das generelle Verhalten des Pins steuern. Man kann damit festlegen, ob das Pin ein GPIO oder Alternativfunktion sein soll. Aber um welche Alternativfunktion es sich handelt, muß in den AFIO Registern festgelegt werden. Bei Mehrfachbelegungen muß zudem auch in den betreffenden Peripheriecores und der Taktversorgung (RCC_..) ggf. noch was eingestellt werden. Das Ganze ist also etwas kompliziert und ohne Lektüre des RM008 nicht zu machen. */ /* Die Varianten der Pinfunktionen */ /* merke: bei Alternativ-Out wähle ALTF... und bei Alternetiv-In wähle IN */ #define noPin 4 /* für nicht vorhandene Pins */ #define ANALOG 0 /* analoger Eingang (oder Ausgang?) */ #define OUT_10 1 /* out, 10 MHz */ #define OUT_2 2 /* out, 2 MHz */ #define OUT_50 3 /* out, 50 MHz */ #define IN 4 /* digitaler Eingang */ #define OUT_10_OD 5 /* out, 10 MHz, OpenDrain */ #define OUT_2_OD 6 /* out, 2 MHz, OpenDrain */ #define OUT_50_OD 7 /* out, 50 MHz, OpenDrain */ #define IN_PUPD 8 /* digitaler Eingang, Pullup/down je nach GPIOx_ODR */ #define ALTF_10 9 /* Alternativ-Funktion, 10 MHz */ #define ALTF_2 10 /* Alternativ-Funktion, 2 MHz */ #define ALTF_50 11 /* Alternativ-Funktion, 50 MHz */ #define verboten 12 /* nicht benutzen! */ #define ALTF_10_OD 13 /* Alternativ-Funktion, 10 MHz, OpenDrain */ #define ALTF_2_OD 14 /* Alternativ-Funktion, 2 MHz, OpenDrain */ #define ALTF_50_OD 15 /* Alternativ-Funktion, 50 MHz, OpenDrain */ /***************** ab hier wird es anwendungs-spezifisch **********************/ /* ab Reset sind alle Register auf 4 = noPin = dig. Eingang */ /* Port A: */ #define wf_PA0 ANALOG /* an Vcc/2+JP3, usart2cts,adc,tim2,wkup*/ #define wf_PA1 IN_PUPD /* an JP3, usart2rts,adc,tim2*/ #define wf_PA2 ALTF_50 /* STlink-TX, usart2tx,adc,tim2*/ #define wf_PA3 IN /* STlink-RX usart2rx,adc,tim2*/ #define wf_PA4 IN_PUPD /* an JP2, spi1nss,usart2ck,adc*/ #define wf_PA5 IN /* T_JTCK auch an PB13, spi1sck,adc*/ #define wf_PA6 IN_PUPD /* an JP2, spi1miso,adc,tim3,*/ #define wf_PA7 IN_PUPD /* an JP2, spi1mosi,adc,tim3*/ #define wf_PA8 ALTF_50 /* MCO an JP2, usart1ck,tim1,mco*/ #define wf_PA9 ALTF_50 /* TX an XPRG, usart1tx,tim1*/ #define wf_PA10 IN /* RX an XPRG, usart1rx,tim1*/ #define wf_PA11 ALTF_50 /* USB-, usart1cts,canrx,tim1,usbdm*/ #define wf_PA12 ALTF_50 /* USB+, usart1rts,cantx,tim1,usbdp*/ #define wf_PA13 IN /* jtms,swdio*/ #define wf_PA14 IN /* jtck,swclk*/ #define wf_PA15 IN_PUPD /* an JP3, jtdi*/ /* Port B: */ #define wf_PB0 IN_PUPD /* adc,tim3*/ #define wf_PB1 IN_PUPD /* an JP2, adc,tim3*/ #define wf_PB2 IN /* BOOT1 */ #define wf_PB3 IN_PUPD /* an JP3, jtdo*/ #define wf_PB4 OUT_50 /* an JP3 und ggf. CS vom LCD, jntrst*/ #define wf_PB5 OUT_50 /* an JP3 und ggf. A0 vom LCD, i2c1smbai*/ #define wf_PB6 IN /* i2c1scl,tim4*/ #define wf_PB7 IN /* i2c1sda,tim4*/ #define wf_PB8 OUT_50 /* an JP3 und ggf. Clock vom LCD, tim4*/ #define wf_PB9 OUT_50 /* an JP3 und ggf. Data vom LCD, tim4*/ #define wf_PB10 ALTF_50 /* TX3 an JP2, i2c2scl,usart3tx*/ #define wf_PB11 IN /* RX3 an JP2, i2c2sda,usart3rx*/ #define wf_PB12 IN /* spi2nss,i2c2smbai,usart3ck,tim1*/ #define wf_PB13 OUT_50 /* T_JTCK auch an PA5, spi2sck,usart3cts,tim1*/ #define wf_PB14 IN /* spi2miso,usart3rts,tim1*/ #define wf_PB15 OUT_50 /* Test, an JP2, spi2mosi,tim1*/ /* Port C: */ #define wf_PC0 noPin /* */ #define wf_PC1 noPin /* */ #define wf_PC2 noPin /* */ #define wf_PC3 noPin /* */ #define wf_PC4 noPin /* */ #define wf_PC5 noPin /* */ #define wf_PC6 noPin /* */ #define wf_PC7 noPin /* */ #define wf_PC8 noPin /* */ #define wf_PC9 noPin /* */ #define wf_PC10 noPin /* */ #define wf_PC11 noPin /* */ #define wf_PC12 noPin /* */ #define wf_PC13 IN /* an JP3, rtc, tamper */ #define wf_PC14 IN /* 32kHz Osz */ #define wf_PC15 IN /* 32kHz Osz */ /* Port D: */ #define wf_PD0 IN /* Osc_In ab Reset */ #define wf_PD1 IN /* Osc_Out ab Reset */ #define wf_PD2 noPin /* */ #define wf_PD3 noPin /* */ #define wf_PD4 noPin /* */ #define wf_PD5 noPin /* */ #define wf_PD6 noPin /* */ #define wf_PD7 noPin /* */ #define wf_PD8 noPin /* */ #define wf_PD9 noPin /* */ #define wf_PD10 noPin /* */ #define wf_PD11 noPin /* */ #define wf_PD12 noPin /* */ #define wf_PD13 noPin /* */ #define wf_PD14 noPin /* */ #define wf_PD15 noPin /* */ /* Port E: */ #define wf_PE0 noPin /* */ #define wf_PE1 noPin /* */ #define wf_PE2 noPin /* */ #define wf_PE3 noPin /* */ #define wf_PE4 noPin /* */ #define wf_PE5 noPin /* */ #define wf_PE6 noPin /* */ #define wf_PE7 noPin /* */ #define wf_PE8 noPin /* */ #define wf_PE9 noPin /* */ #define wf_PE10 noPin /* */ #define wf_PE11 noPin /* */ #define wf_PE12 noPin /* */ #define wf_PE13 noPin /* */ #define wf_PE14 noPin /* */ #define wf_PE15 noPin /* */ /* Port F: */ #define wf_PF0 noPin /* */ #define wf_PF1 noPin /* */ #define wf_PF2 noPin /* */ #define wf_PF3 noPin /* */ #define wf_PF4 noPin /* */ #define wf_PF5 noPin /* */ #define wf_PF6 noPin /* */ #define wf_PF7 noPin /* */ #define wf_PF8 noPin /* */ #define wf_PF9 noPin /* */ #define wf_PF10 noPin /* */ #define wf_PF11 noPin /* */ #define wf_PF12 noPin /* */ #define wf_PF13 noPin /* */ #define wf_PF14 noPin /* */ #define wf_PF15 noPin /* */ /* Port G: */ #define wf_PG0 noPin /* */ #define wf_PG1 noPin /* */ #define wf_PG2 noPin /* */ #define wf_PG3 noPin /* */ #define wf_PG4 noPin /* */ #define wf_PG5 noPin /* */ #define wf_PG6 noPin /* */ #define wf_PG7 noPin /* */ #define wf_PG8 noPin /* */ #define wf_PG9 noPin /* */ #define wf_PG10 noPin /* */ #define wf_PG11 noPin /* */ #define wf_PG12 noPin /* */ #define wf_PG13 noPin /* */ #define wf_PG14 noPin /* */ #define wf_PG15 noPin /* */ /**************** Remap-setup ******************/ /* zu ändern je nach Projekt */ #define SPI1_REMAP 0 /* PA4,5,6,7 --> PA15,3,4,5 */ #define I2C1_REMAP 0 /* PB6,7 --> PB8,9 */ #define USART1_REMAP 0 /* PA9,10 --> PB6,7 */ #define USART2_REMAP 0 /* PA0,1,2,3,4 --> PD3,4,5,6,7 */ #define USART3_REMAP0_3 0 /* 0 = PB10,11,12,13,14 */ /* 1 = PC10,11,12,PB13,14 */ /* 2 = not used */ /* 3 = PD8,9,10,11,12 */ #define TIM1_REMAP0_3 3 /* 0 = PA12,8,9,10,11,PB12,13,14,15 */ /* 1 = PA12,8,9,10,11,6,7,PB0,1 */ /* 2 = not used */ /* 3 = PE7,9,11,13,14,15,8,10,12 */ #define TIM2_REMAP0_3 0 /* 0 = PA0,1,2,3 */ /* 1 = PA15,PB3,PA2,PA3 */ /* 2 = PA0,PA1,PB10,PB11 */ /* 3 = PA15,PB3,PB10,PB11*/ #define TIM3_REMAP0_3 0 /* 0 = PA6,7,PB0,1 */ /* 1 = not used */ /* 2 = PB4,5,0,1 */ /* 3 = PC6,7,8,9 */ #define TIM4_REMAP 0 /* PB6,7,8,9 --> PD12,13,14,15 */ #define CAN1_REMAP0_3 0 /* 0 = PA11,12 */ /* 1 = not used */ /* 2 = PB8,9 */ /* 3 = PD0,1 */ #define PD01_REMAP 1 /* PD0,1 --> OSC_IN, OSC_OUT */ #define TIM5CH4_REMAP 0 /* TIM5_CH4: PA3 --> LSI internal Clock */ #define ADC1_ETRGINJ_REMAP 0 /* */ #define ADC1_ETRGREG_REMAP 0 /* */ #define ADC2_ETRGINJ_REMAP 0 /* */ #define ADC3_ETRGREG_REMAP 0 /* */ #define SWJ_CFG0_7 0 /* 000: Full SWJ (JTAG-DP + SW-DP): Reset State 001: Full SWJ (JTAG-DP + SW-DP) but without NJTRST 010: JTAG-DP Disabled and SW-DP Enabled 100: JTAG-DP Disabled and SW-DP Disabled Other combinations: no effect */ /************* Power- bzw. Takt-Konfiguration ***************/ /* AHB */ #define en_DMA1 (0<<0) /* DMA 1 Clock */ #define en_DMA2 (0<<1) /* DMA 2 Clock */ #define en_SRAM (1<<2) /* SRAM während Schlafmodus */ /* 3 nix */ #define en_FLASH (1<<4) /* Flash Interface */ /* 5 nix */ #define en_CRC (0<<6) /* CRC-32 (ethernet) Calculator */ /* 7 nix */ #define en_FSMC (0<<8) /* externer Speichercontroller */ /* 9 nix */ #define en_SDIO (0<<10) /* SD-karten-Interface */ /***** APB1 ************/ /* 31..30 nix */ #define en1_DAC 0 /* 29 */ #define en1_PWR 1 /* 28 Power Interface */ #define en1_BKP 1 /* 27 Backup Interface */ /* 26 nix */ #define en1_CAN 0 /* 25 */ /* 24 nix */ #define en1_USB 1 /* 23 */ #define en1_I2C2 0 /* 22 */ #define en1_I2C1 0 /* 21 */ #define en1_UART5 0 /* 20 */ #define en1_UART4 0 /* 19 konkurriert mit SDIO */ #define en1_USART3 1 /* 18 */ #define en1_USART2 1 /* 17 */ /* 16 nix */ #define en1_SPI3 0 /* 15 */ #define en1_SPI2 0 /* 14 */ /* 13..12 nix */ #define en1_WWD 0 /* 11 Watchdog */ /* 10..6 nix */ #define en1_TIM7 0 /* 5 */ #define en1_TIM6 0 /* 4 */ #define en1_TIM5 0 /* 3 */ #define en1_TIM4 0 /* 2 */ #define en1_TIM3 0 /* 1 */ #define en1_TIM2 0 /* 0 */ /***** APB2 *****/ /* 31..16 nix */ #define en2_ADC3 0 /* 15 */ #define en2_USART1 1 /* 14 */ #define en2_TIM8 0 /* 13 konkurriert mit SDIO */ #define en2_SPI1 0 /* 12 */ #define en2_TIM1 0 /* 11 */ #define en2_ADC2 0 /* 10 */ #define en2_ADC1 0 /* 9 */ #define en2_IOPG 0 /* 8 Port G */ #define en2_IOPF 0 /* 7 Port F */ #define en2_IOPE 0 /* 6 Port E */ #define en2_IOPD 1 /* 5 Port D */ #define en2_IOPC 1 /* 4 Port C */ #define en2_IOPB 1 /* 3 Port B */ #define en2_IOPA 1 /* 2 Port A */ /* 1 nix */ #define en2_AFIO 1 /* 0 Alternative Portbelegungen */ /********************* ab hier gibt es nichts mehr zu ändern *****************/ #define wf_AFIO_MAPR (SPI1_REMAP)| \ (I2C1_REMAP<<1)| \ (USART1_REMAP<<2)| \ (USART2_REMAP<<3)| \ (USART3_REMAP0_3<<4)| \ (TIM1_REMAP0_3<<6)| \ (TIM2_REMAP0_3<8)| \ (TIM3_REMAP0_3<10)| \ (TIM4_REMAP<<12)| \ (CAN1_REMAP0_3<<13)| \ (PD01_REMAP<<15)| \ (TIM5CH4_REMAP<<16)| \ (ADC1_ETRGINJ_REMAP<<17)| \ (ADC1_ETRGREG_REMAP<<18)| \ (ADC2_ETRGINJ_REMAP<<19)| \ (ADC3_ETRGREG_REMAP<<20)| \ (SWJ_CFG0_7<<24) #define wf_GPIOA_CRL (wf_PA0 | (wf_PA1<<4) | (wf_PA2<<8) | (wf_PA3<<12) | (wf_PA4<<16) | (wf_PA5<<20) | (wf_PA6<<24) | (((unsigned)wf_PA7)<<28)) #define wf_GPIOA_CRH (wf_PA8 | (wf_PA9<<4) | (wf_PA10<<8) | (wf_PA11<<12) | (wf_PA12<<16) | (wf_PA13<<20) | (wf_PA14<<24) | (((unsigned)wf_PA15)<<28)) #define wf_GPIOB_CRL (wf_PB0 | (wf_PB1<<4) | (wf_PB2<<8) | (wf_PB3<<12) | (wf_PB4<<16) | (wf_PB5<<20) | (wf_PB6<<24) | (((unsigned)wf_PB7)<<28)) #define wf_GPIOB_CRH (wf_PB8 | (wf_PB9<<4) | (wf_PB10<<8) | (wf_PB11<<12) | (wf_PB12<<16) | (wf_PB13<<20) | (wf_PB14<<24) | (((unsigned)wf_PB15)<<28)) #define wf_GPIOC_CRL (wf_PC0 | (wf_PC1<<4) | (wf_PC2<<8) | (wf_PC3<<12) | (wf_PC4<<16) | (wf_PC5<<20) | (wf_PC6<<24) | (((unsigned)wf_PC7)<<28)) #define wf_GPIOC_CRH (wf_PC8 | (wf_PC9<<4) | (wf_PC10<<8) | (wf_PC11<<12) | (wf_PC12<<16) | (wf_PC13<<20) | (wf_PC14<<24) | (((unsigned)wf_PC15)<<28)) #define wf_GPIOD_CRL (wf_PD0 | (wf_PD1<<4) | (wf_PD2<<8) | (wf_PD3<<12) | (wf_PD4<<16) | (wf_PD5<<20) | (wf_PD6<<24) | (((unsigned)wf_PD7)<<28)) #define wf_GPIOD_CRH (wf_PD8 | (wf_PD9<<4) | (wf_PD10<<8) | (wf_PD11<<12) | (wf_PD12<<16) | (wf_PD13<<20) | (wf_PD14<<24) | (((unsigned)wf_PD15)<<28)) #define wf_GPIOE_CRL (wf_PE0 | (wf_PE1<<4) | (wf_PE2<<8) | (wf_PE3<<12) | (wf_PE4<<16) | (wf_PE5<<20) | (wf_PE6<<24) | (((unsigned)wf_PE7)<<28)) #define wf_GPIOE_CRH (wf_PE8 | (wf_PE9<<4) | (wf_PE10<<8) | (wf_PE11<<12) | (wf_PE12<<16) | (wf_PE13<<20) | (wf_PE14<<24) | (((unsigned)wf_PE15)<<28)) #define wf_GPIOF_CRL (wf_PF0 | (wf_PF1<<4) | (wf_PF2<<8) | (wf_PF3<<12) | (wf_PF4<<16) | (wf_PF5<<20) | (wf_PF6<<24) | (((unsigned)wf_PF7)<<28)) #define wf_GPIOF_CRH (wf_PF8 | (wf_PF9<<4) | (wf_PF10<<8) | (wf_PF11<<12) | (wf_PF12<<16) | (wf_PF13<<20) | (wf_PF14<<24) | (((unsigned)wf_PF15)<<28)) #define wf_GPIOG_CRL (wf_PG0 | (wf_PG1<<4) | (wf_PG2<<8) | (wf_PG3<<12) | (wf_PG4<<16) | (wf_PG5<<20) | (wf_PG6<<24) | (((unsigned)wf_PG7)<<28)) #define wf_GPIOG_CRH (wf_PG8 | (wf_PG9<<4) | (wf_PG10<<8) | (wf_PG11<<12) | (wf_PG12<<16) | (wf_PG13<<20) | (wf_PG14<<24) | (((unsigned)wf_PG15)<<28)) #define wf_AHBENR (en_SDIO | en_FSMC | en_CRC | en_FLASH | en_SRAM | en_DMA2 | en_DMA1) #define wf_APB1ENR (en1_TIM2<<0) | \ (en1_TIM3<<1) | \ (en1_TIM4<<2) | \ (en1_TIM5<<3) | \ (en1_TIM6<<4) | \ (en1_TIM7<<5) | \ (en1_WWD<<11) | \ (en1_SPI2<<14) | \ (en1_SPI3<<15) | \ (en1_USART2<<17)| \ (en1_USART3<<18)| \ (en1_UART4<<19) | \ (en1_UART5<<20) | \ (en1_I2C1<<21) | \ (en1_I2C2<<22) | \ (en1_USB<<23) | \ (en1_CAN<<25) | \ (en1_BKP<<27) | \ (en1_PWR<<28) | \ (en1_DAC<<29) #define wf_APB2ENR (en2_AFIO) | \ (en2_IOPA<<2) | \ (en2_IOPB<<3) | \ (en2_IOPC<<4) | \ (en2_IOPD<<5) | \ (en2_IOPE<<6) | \ (en2_IOPF<<7) | \ (en2_IOPG<<8) | \ (en2_ADC1<<9) | \ (en2_ADC2<<10) | \ (en2_TIM1<<11) | \ (en2_SPI1<<12) | \ (en2_TIM8<<13) | \ (en2_USART1<<14) | \ (en2_ADC3<<15) /* Sonstiges: Der Quarz für HSE ist 8.000 MHz Der Quarz für LSE ist 32.768 kHz Die CPU läuft mit 72 MHz Die Peripherie läuft mit 36 MHz (beide Stränge APB1 und APB2) */ void sysconfig (void) { long L; RCC_CIR = 0; /* alle RCC-Interrupts ausschalten */ RCC_APB1RSTR = 0; /* evtl. Reset's beseitigen */ RCC_APB2RSTR = 0; FLASH_ACR = (1<<4) | /* Flash-Prefetch-Buffer einschalten */ (0<<3) | /* half cycle access enable */ 2; /* 2 Waitstates ab 48 MHz */ RCC_CFGR = (5<<24); /* MCO=HSI, sonst nix.. erstmal */ RCC_AHBENR = wf_AHBENR; /* AHB enables */ RCC_APB1ENR = wf_APB1ENR; /* APB1 enables */ RCC_APB2ENR = wf_APB2ENR; /* APB2 enables */ /* Pin-Funktionen aufsetzen */ GPIOA_CRL = wf_GPIOA_CRL; GPIOA_CRH = wf_GPIOA_CRH; GPIOB_CRL = wf_GPIOB_CRL; GPIOB_CRH = wf_GPIOB_CRH; GPIOC_CRL = wf_GPIOC_CRL; GPIOC_CRH = wf_GPIOC_CRH; /* Diese Ports werden bei der 48 Pin Variante nicht wirklich benötigt GPIOD_CRL = wf_GPIOD_CRL; GPIOD_CRH = wf_GPIOD_CRH; GPIOE_CRL = wf_GPIOE_CRL; GPIOE_CRH = wf_GPIOE_CRH; GPIOF_CRL = wf_GPIOF_CRL; GPIOF_CRH = wf_GPIOF_CRH; GPIOG_CRL = wf_GPIOG_CRL; GPIOG_CRH = wf_GPIOG_CRH; */ /* Pin-Remap */ AFIO_MAPR = wf_AFIO_MAPR; /* Takterzeugung aufsetzen. nach einem Hardware-Reset sind folgende Bits gesetzt: in RCC_CR = HSIRDY, HSION, HSITRIM = 8 in RCC_AHBENR = FLITFEN, SRAMEN in RCC_CSR = PORRSTF, PINRSTF Vorsicht: nach irgendwelchen Software-Resets muß das nicht so sein! */ RCC_CR = (8<<2)|1; /* Umschalten auf HSI = interne 8 MHz */ while ((RCC_CR & 2)==0); /* warten auf HSIRDY (wird von Hardware gesetzt) */ /* so, jetzt ist RCC im Urzustand wie nach einem Hardware-Reset */ RCC_CR |= (1<<16); /* externen 8 MHz Oszillator HSE einschalten */ L = 10000; while (L) { --L; if (RCC_CR & (1<<17)) goto _hse_rdy; } /* wenn ext. Oszi ready */ _hse_rdy: if (L) /* wenn wir nicht vergeblich auf HSE gewartet haben.. */ { FLASH_ACR = (1<<4)|2; /* Prefetch-Buffer + 2 Waits bei 72 MHz */ RCC_CFGR = (7<<24)| /* MCO=1/2PLL */ (0<<22)| /* UsbClk=PLL/1.5 */ (7<<18)| /* PLL = 9*HSE (9*8MHz=72MHz) */ (1<<16)| /* PllSource=HSE */ (3<<14)| /* AdcTakt=PCLK2/8 */ (4<<11)| /* APB2=Hclk/2=36MHz */ (4<<8); /* APB1=Hclk/2=36MHz */ RCC_CR |= (1<<24); /* PLL einschalten */ while ((RCC_CR & (1<<25))==0); /* warten auf PLLRDY */ RCC_CFGR = (RCC_CFGR & 0xFFFFFFFC)|2; /* PLL als Taktquelle wählen */ do { L = RCC_CFGR & (3<<2);} while (L!= (2<<2)); /* warten bis PLL=Taktquelle */ } /* Backup-Domain enables: sind nach Reset erstmal schreibgeschützt. Entsperren mit PWR->CR (1<<8) auf hi */ if ((RCC_BDCR & 2)==0) /* wenn 32kHz Oszi nicht ready ist */ { PWR_CR |= (1<<8); RCC_BDCR = (1<<16)|(1<<15)|1; /* RTC Reset, enable, 32kHz on */ RCC_BDCR = (1<<15)|(1<<8)|1; /* RTC enable, LSE als Quelle, 32kHz on */ } }