From 36cff03af1b4ad08c72ccc21bbd3903113ef423a Mon Sep 17 00:00:00 2001 From: Stephen Caudle Date: Thu, 27 Oct 2011 23:34:52 -0400 Subject: Add RCC and FLASH support for STM32F2 --- lib/stm32f2/flash.c | 250 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 lib/stm32f2/flash.c (limited to 'lib/stm32f2/flash.c') diff --git a/lib/stm32f2/flash.c b/lib/stm32f2/flash.c new file mode 100644 index 0000000..e9bc73e --- /dev/null +++ b/lib/stm32f2/flash.c @@ -0,0 +1,250 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * Copyright (C) 2010 Mark Butler + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +static inline void flash_set_program_size(u32 psize) +{ + FLASH_CR &= ~(((1 << 0) | (1 << 1)) << 8); + FLASH_CR |= psize; +} + +void flash_data_cache_enable(void) +{ + FLASH_ACR |= FLASH_DCE; +} + +void flash_dcache_disable(void) +{ + FLASH_ACR &= ~FLASH_DCE; +} + +void flash_icache_enable(void) +{ + FLASH_ACR |= FLASH_ICE; +} + +void flash_icache_disable(void) +{ + FLASH_ACR &= ~FLASH_ICE; +} + +void flash_prefetch_enable(void) +{ + FLASH_ACR |= FLASH_PRFTEN; +} + +void flash_prefetch_disable(void) +{ + FLASH_ACR &= ~FLASH_PRFTEN; +} + +void flash_dcache_reset(void) +{ + FLASH_ACR |= FLASH_DCRST; +} + +void flash_icache_reset(void) +{ + FLASH_ACR |= FLASH_ICRST; +} + +void flash_set_ws(u32 ws) +{ + u32 reg32; + + reg32 = FLASH_ACR; + reg32 &= ~((1 << 0) | (1 << 1) | (1 << 2)); + reg32 |= ws; + FLASH_ACR = reg32; +} + +void flash_unlock(void) +{ + /* Authorize the FPEC access. */ + FLASH_KEYR = FLASH_KEY1; + FLASH_KEYR = FLASH_KEY2; +} + +void flash_lock(void) +{ + FLASH_CR |= FLASH_LOCK; +} + +void flash_clear_pgserr_flag(void) +{ + FLASH_SR |= FLASH_PGSERR; +} + +void flash_clear_pgperr_flag(void) +{ + FLASH_SR |= FLASH_PGPERR; +} + +void flash_clear_pgaerr_flag(void) +{ + FLASH_SR |= FLASH_PGAERR; +} + +void flash_clear_eop_flag(void) +{ + FLASH_SR |= FLASH_EOP; +} + +void flash_clear_wrperr_flag(void) +{ + FLASH_SR |= FLASH_WRPERR; +} + +void flash_clear_bsy_flag(void) +{ + FLASH_SR &= ~FLASH_BSY; +} + +void flash_clear_status_flags(void) +{ + flash_clear_pgserr_flag(); + flash_clear_pgperr_flag(); + flash_clear_pgaerr_flag(); + flash_clear_eop_flag(); + flash_clear_wrperr_flag(); + flash_clear_bsy_flag(); +} + +void flash_unlock_option_bytes(void) +{ + FLASH_OPTKEYR = FLASH_OPTKEY1; + FLASH_OPTKEYR = FLASH_OPTKEY2; +} + +void flash_lock_option_bytes(void) +{ + FLASH_OPTCR |= FLASH_OPTLOCK; +} + +void flash_wait_for_last_operation(void) +{ + while ((FLASH_SR & FLASH_BSY) == FLASH_BSY) + ; +} + +void flash_program_double_word(u32 address, u64 data, u32 program_size) +{ + /* Ensure that all flash operations are complete. */ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + /* Enable writes to flash. */ + FLASH_CR |= FLASH_PG; + + /* Program the first half of the word. */ + MMIO64(address) = data; + + /* Wait for the write to complete. */ + flash_wait_for_last_operation(); + + /* Disable writes to flash. */ + FLASH_CR &= ~FLASH_PG; +} + +void flash_program_word(u32 address, u32 data, u32 program_size) +{ + /* Ensure that all flash operations are complete. */ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + /* Enable writes to flash. */ + FLASH_CR |= FLASH_PG; + + /* Program the first half of the word. */ + MMIO32(address) = data; + + /* Wait for the write to complete. */ + flash_wait_for_last_operation(); + + /* Disable writes to flash. */ + FLASH_CR &= ~FLASH_PG; +} + +void flash_program_half_word(u32 address, u16 data, u32 program_size) +{ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + FLASH_CR |= FLASH_PG; + + MMIO16(address) = data; + + flash_wait_for_last_operation(); + + FLASH_CR &= ~FLASH_PG; /* Disable the PG bit. */ +} + +void flash_program_byte(u32 address, u8 data, u32 program_size) +{ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + FLASH_CR |= FLASH_PG; + + MMIO8(address) = data; + + flash_wait_for_last_operation(); + + FLASH_CR &= ~FLASH_PG; /* Disable the PG bit. */ +} + +void flash_erase_sector(u32 sector, u32 program_size) +{ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + FLASH_CR &= ~(((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) << 3); + FLASH_CR |= sector; + FLASH_CR |= FLASH_STRT; + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_SER; + FLASH_CR &= ~(((1 << 0) | (1 << 1) | (1 << 2) | (1 << 3)) << 3); +} + +void flash_erase_all_sectors(u32 program_size) +{ + flash_wait_for_last_operation(); + flash_set_program_size(program_size); + + FLASH_CR |= FLASH_MER; /* Enable mass erase. */ + FLASH_CR |= FLASH_STRT; /* Trigger the erase. */ + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_MER; /* Disable mass erase. */ +} + +void flash_program_option_bytes(u32 data) +{ + flash_wait_for_last_operation(); + + if (FLASH_OPTCR & FLASH_OPTLOCK) + flash_unlock_option_bytes(); + + FLASH_OPTCR = data & ~0x3; + FLASH_OPTCR |= FLASH_OPTSTRT; /* Enable option byte programming. */ + flash_wait_for_last_operation(); +} -- cgit v1.2.3