forked from fcayci/stm32f1-bare-metal
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 7469fa4
Showing
8 changed files
with
608 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
*.o | ||
*.bin | ||
*.elf | ||
*.hex | ||
*.lst |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# stm32f1-bare-metal | ||
|
||
Bare-metal programming for a STM32F1-based board. (Cortex-M3) | ||
|
||
Tested on EasyMx Pro v7 board with STM32F107 chip. | ||
|
||
# Install | ||
* Toolchain - [GNU ARM Toolchain](https://developer.arm.com/open-source/gnu-toolchain/gnu-rm/downloads) | ||
* (Windows only) - [MinGW and MSYS ](http://www.mingw.org/) | ||
* Programmer - [STLink](https://github.com/texane/stlink) | ||
|
||
# Compile | ||
* Browse into any of the project directory `cd systick` and run `make` to compile. | ||
``` | ||
Cleaning... | ||
Building systick.c | ||
text data bss dec hex filename | ||
384 0 0 384 180 systick.elf | ||
Successfully finished... | ||
``` | ||
|
||
# Program | ||
* Run `make burn` to program the chip. | ||
``` | ||
... | ||
... | ||
Flash written and verified! jolly good! | ||
``` | ||
|
||
## Projects | ||
* systick - SysTick Timer example | ||
* clock - An example to bump the clock up to 72 Mhz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
/* | ||
* clock.c | ||
* | ||
* Description: | ||
* Clock example to set the MCU speed to 72 MHz | ||
* GPIOD Pin1 is the blinking LED | ||
* | ||
* Author: Furkan Cayci | ||
* | ||
* Project Setup: | ||
* EasyMX Pro V7 board | ||
* Cortex-M3 arch | ||
* STM32F107 chip | ||
*/ | ||
|
||
/************************************************* | ||
* Definitions | ||
*************************************************/ | ||
// Define some types for readibility | ||
#define int32_t int | ||
#define int16_t short | ||
#define int8_t char | ||
#define uint32_t unsigned int | ||
#define uint16_t unsigned short | ||
#define uint8_t unsigned char | ||
|
||
#define HSE_Value ((uint32_t) 25000000) /* Value of the External oscillator in Hz */ | ||
#define HSI_Value ((uint32_t) 8000000) /* Value of the Internal oscillator in Hz*/ | ||
|
||
// Define the base addresses for peripherals | ||
#define PERIPH_BASE ((uint32_t) 0x40000000) | ||
#define SRAM_BASE ((uint32_t) 0x20000000) | ||
|
||
#define APB1PERIPH_BASE PERIPH_BASE | ||
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000) | ||
#define AHBPERIPH_BASE (PERIPH_BASE + 0x20000) | ||
|
||
#define GPIOD_BASE (APB2PERIPH_BASE + 0x1400) // GPIOD base address is 0x40011400 | ||
#define RCC_BASE (AHBPERIPH_BASE + 0x1000) // RCC base address is 0x40021000 | ||
#define FLASH_BASE (AHBPERIPH_BASE + 0x2000) // FLASH base address is 0x40022000 | ||
|
||
#define STACKINIT 0x20008000 | ||
#define DELAY 7200000 | ||
|
||
#define GPIOD ((GPIO_type *) GPIOD_BASE) | ||
#define RCC ((RCC_type *) RCC_BASE) | ||
#define FLASH ((FLASH_type *) FLASH_BASE) | ||
|
||
/* | ||
* Register Addresses | ||
*/ | ||
typedef struct | ||
{ | ||
uint32_t CRL; /* GPIO port configuration register low, Address offset: 0x00 */ | ||
uint32_t CRH; /* GPIO port configuration register high, Address offset: 0x04 */ | ||
uint32_t IDR; /* GPIO port input data register, Address offset: 0x08 */ | ||
uint32_t ODR; /* GPIO port output data register, Address offset: 0x0C */ | ||
uint32_t BSRR; /* GPIO port bit set/reset register, Address offset: 0x10 */ | ||
uint32_t BRR; /* GPIO port bit reset register, Address offset: 0x14 */ | ||
uint32_t LCKR; /* GPIO port configuration lock register, Address offset: 0x18 */ | ||
} GPIO_type; | ||
|
||
typedef struct | ||
{ | ||
uint32_t CR; /* RCC clock control register, Address offset: 0x00 */ | ||
uint32_t CFGR; /* RCC clock configuration register, Address offset: 0x04 */ | ||
uint32_t CIR; /* RCC clock interrupt register, Address offset: 0x08 */ | ||
uint32_t APB2RSTR; /* RCC APB2 peripheral reset register, Address offset: 0x0C */ | ||
uint32_t APB1RSTR; /* RCC APB1 peripheral reset register, Address offset: 0x10 */ | ||
uint32_t AHBENR; /* RCC AHB peripheral clock enable register, Address offset: 0x14 */ | ||
uint32_t APB2ENR; /* RCC APB2 peripheral clock enable register, Address offset: 0x18 */ | ||
uint32_t APB1ENR; /* RCC APB1 peripheral clock enable register, Address offset: 0x1C */ | ||
uint32_t BDCR; /* RCC backup domain control register, Address offset: 0x20 */ | ||
uint32_t CSR; /* RCC control/status register, Address offset: 0x24 */ | ||
uint32_t AHBRSTR; /* RCC AHB peripheral clock reset register, Address offset: 0x28 */ | ||
uint32_t CFGR2; /* RCC clock configuration register2, Address offset: 0x2C */ | ||
} RCC_type; | ||
|
||
typedef struct | ||
{ | ||
uint32_t ACR; | ||
uint32_t KEYR; | ||
uint32_t OPTKEYR; | ||
uint32_t SR; | ||
uint32_t CR; | ||
uint32_t AR; | ||
uint32_t RESERVED; | ||
uint32_t OBR; | ||
uint32_t WRPR; | ||
} FLASH_type; | ||
|
||
// Function declarations. Add your functions here | ||
void nmi_handler(void); | ||
void set_system_clock_to_25Mhz(void); | ||
void set_system_clock_to_72Mhz(void); | ||
int32_t main(void); | ||
void delay(volatile uint32_t s); | ||
|
||
/************************************************* | ||
* Vector Table | ||
*************************************************/ | ||
// Attribute puts table in .vector section | ||
// which is the beginning of .text section in the linker script | ||
// Add other vectors in order here | ||
// Vector table can be found on page 197 in RM0008 | ||
uint32_t (* const vector_table[]) | ||
__attribute__ ((section(".vectors"))) = { | ||
((uint32_t *) STACKINIT), /* 0x00 Stack Pointer */ | ||
((uint32_t *) main), /* 0x04 Reset */ | ||
0, /* 0x08 NMI */ | ||
0, /* 0x0C Hardfault */ | ||
}; | ||
|
||
/* | ||
* By default 8 MHz internal clock is used (HSI) | ||
* Set up as 25 MHz | ||
* | ||
* 25 MHz External clock is selected as the source clock (HSE) | ||
*/ | ||
void set_system_clock_to_25Mhz(void) | ||
{ | ||
// Enable HSE | ||
RCC->CR |= (1 << 16); | ||
// Wait untill HSE settles down | ||
while (!(RCC->CR & (1 << 17))); | ||
// Choose HSE as the system clock | ||
RCC->CFGR |= (1 << 0); | ||
} | ||
|
||
/* | ||
* By default 8 MHz internal clock is used (HSI) | ||
* Set up as 72 MHz | ||
* | ||
* HSE -> PreDiv2 -> Pll2Mul -> PreDiv1 -> PllMul -> System Clock | ||
* Set Prediv1Src = PLL2, Set PllSrc as Prediv1 | ||
* | ||
* 25 MHz External clock is selected as the source clock (HSE) | ||
* It is divided by 5 with PreDiv2, then muliplied by 8 with Pll2Mul | ||
* Then it is divided by 5 with PreDiv1, then multiplied by 9 with PllMul | ||
* Then choose Pll as the clock source | ||
* | ||
* 25Mhz / 5 * 8 / 5 * 9 = 72 MHz | ||
*/ | ||
void set_system_clock_to_72Mhz(void) | ||
{ | ||
// Necessary wait states for Flash for high speeds | ||
FLASH->ACR = 0x12; | ||
// Enable HSE | ||
RCC->CR |= (1 << 16); | ||
// Wait untill HSE settles down | ||
while (!(RCC->CR & (1 << 17))); | ||
// Set PREDIV2 division factor to 5 | ||
RCC->CFGR2 |= (0b0100 << 4); | ||
// Set PLL2 multiplication factor to 8 | ||
RCC->CFGR2 |= (0b0110 << 8); | ||
// Enable PLL2 | ||
RCC->CR |= (1 << 26); | ||
// Wait untill PLL2 settles down | ||
while (!(RCC->CR & (1 << 27))); | ||
// Set PLL2 as PREDIV1 clock source | ||
RCC->CFGR2 |= (1 << 16); | ||
// Set PREDIV1 division factor to 5 | ||
RCC->CFGR2 |= (0b0100 << 0); | ||
// Select Prediv1 as PLL source | ||
RCC->CFGR |= (1 << 16); | ||
// Set PLL1 multiplication factor to 9 | ||
RCC->CFGR |= (0b0111 << 18); | ||
// Set APB1 to 36MHz | ||
RCC->CFGR |= 1 << 10; | ||
// Enable PLL | ||
RCC->CR |= (1 << 24); | ||
// Wait untill PLL settles down | ||
while (!(RCC->CR & (1 << 25))); | ||
// Finally, choose PLL as the system clock | ||
RCC->CFGR |= (0b10 << 0); | ||
} | ||
|
||
/************************************************* | ||
* Main code starts from here | ||
*************************************************/ | ||
int32_t main(void) | ||
{ | ||
// Set clock to 72 MHz | ||
set_system_clock_to_72Mhz(); | ||
|
||
// Set Bit 5 to enable GPIOD clock | ||
RCC->APB2ENR |= (1 << 5); | ||
|
||
// Set GPIOD Pin1 output | ||
GPIOD->CRL &= ~(0xF << 4); | ||
GPIOD->CRL |= (0x2 << 4); | ||
|
||
// Set GPIOD Pin1 | ||
GPIOD->ODR |= (1 << 1); | ||
|
||
while(1){ | ||
delay(DELAY); | ||
GPIOD->ODR ^= (1 << 1); | ||
} | ||
|
||
// Should never reach here | ||
return 0; | ||
} | ||
|
||
void delay(volatile uint32_t s) | ||
{ | ||
for(s; s>0; s--); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
TARGET = clock | ||
SRCS = clock.c | ||
|
||
OBJS = $(addsuffix .o, $(basename $(SRCS))) | ||
INCLUDES = -I. | ||
|
||
LINKER_SCRIPT = stm32.ld | ||
|
||
CFLAGS += -mcpu=cortex-m3 -mthumb # Processor setup | ||
CFLAGS += -O0 # Optimization is off | ||
CFLAGS += -g3 # Generate debug information | ||
CFLAGS += -fno-common -Wall | ||
CFLAGS += -ffunction-sections -fdata-sections -Wl,--gc-sections | ||
|
||
LDFLAGS += -nostartfiles -T$(LINKER_SCRIPT) | ||
|
||
CROSS_COMPILE = arm-none-eabi- | ||
CC = $(CROSS_COMPILE)gcc | ||
LD = $(CROSS_COMPILE)ld | ||
OBJDUMP = $(CROSS_COMPILE)objdump | ||
OBJCOPY = $(CROSS_COMPILE)objcopy | ||
SIZE = $(CROSS_COMPILE)size | ||
|
||
all: clean $(SRCS) build size | ||
@echo "Successfully finished..." | ||
|
||
build: $(TARGET).elf $(TARGET).hex $(TARGET).bin $(TARGET).lst | ||
|
||
$(TARGET).elf: $(OBJS) | ||
@$(CC) $(LDFLAGS) $(OBJS) -o $@ | ||
|
||
%.o: %.c | ||
@echo "Building" $< | ||
@$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ | ||
|
||
%.o: %.s | ||
@echo "Building" $< | ||
@$(CC) $(CFLAGS) -c $< -o $@ | ||
|
||
%.hex: %.elf | ||
@$(OBJCOPY) -O ihex $< $@ | ||
|
||
%.bin: %.elf | ||
@$(OBJCOPY) -O binary $< $@ | ||
|
||
%.lst: %.elf | ||
@$(OBJDUMP) -x -S $(TARGET).elf > $@ | ||
|
||
size: $(TARGET).elf | ||
@$(SIZE) $(TARGET).elf | ||
|
||
burn: | ||
@st-flash write $(TARGET).bin 0x8000000 | ||
|
||
clean: | ||
@echo "Cleaning..." | ||
@rm -f $(TARGET).elf | ||
@rm -f $(TARGET).bin | ||
@rm -f $(TARGET).map | ||
@rm -f $(TARGET).hex | ||
@rm -f $(TARGET).lst | ||
@rm -f $(TARGET).o | ||
|
||
.PHONY: all build size clean burn |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
MEMORY { | ||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K | ||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K | ||
} | ||
|
||
SECTIONS { | ||
. = 0x08000000; /* From 0x08000000 */ | ||
.text : | ||
{ | ||
*(.vectors) /* Vector table */ | ||
*(.text) /* Program code */ | ||
*(.rodata) /* Read only data */ | ||
} >rom | ||
|
||
. = 0x20000000; /* From 0x20000000 */ | ||
.data : | ||
{ | ||
*(.data) /* Data memory */ | ||
} >ram AT > rom | ||
|
||
.bss : | ||
{ | ||
*(.bss) /* Zero-filled run time allocate data memory */ | ||
} >ram AT > rom | ||
} |
Oops, something went wrong.