diff options
author | root <root@lab2.panaceas.james.local> | 2014-11-02 10:14:39 +0000 |
---|---|---|
committer | root <root@lab2.panaceas.james.local> | 2014-11-02 10:14:39 +0000 |
commit | 1dc7d758f96dd2b9bd7b03f01ca032d68b696cf0 (patch) | |
tree | 1a70fddfcc79c54c863912a3b8b8cecc594f21ae /libopencm3/lib/stm32/f4 | |
download | stm32_usb_kvm-1dc7d758f96dd2b9bd7b03f01ca032d68b696cf0.tar.gz stm32_usb_kvm-1dc7d758f96dd2b9bd7b03f01ca032d68b696cf0.tar.bz2 stm32_usb_kvm-1dc7d758f96dd2b9bd7b03f01ca032d68b696cf0.zip |
fish
Diffstat (limited to 'libopencm3/lib/stm32/f4')
-rw-r--r-- | libopencm3/lib/stm32/f4/Makefile | 59 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/adc.c | 437 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/crc.c | 33 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/crypto.c | 66 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/dac.c | 31 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/dma.c | 31 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/flash.c | 53 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/fmc.c | 99 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/gpio.c | 31 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/hash.c | 31 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/i2c.c | 31 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/iwdg.c | 31 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/libopencm3_stm32f4.ld | 106 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/pwr.c | 46 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/rcc.c | 539 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/rtc.c | 97 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/spi.c | 31 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/stm32f405x6.ld | 33 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/timer.c | 38 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/usart.c | 31 | ||||
-rw-r--r-- | libopencm3/lib/stm32/f4/vector_chipset.c | 27 |
21 files changed, 1881 insertions, 0 deletions
diff --git a/libopencm3/lib/stm32/f4/Makefile b/libopencm3/lib/stm32/f4/Makefile new file mode 100644 index 0000000..475d917 --- /dev/null +++ b/libopencm3/lib/stm32/f4/Makefile @@ -0,0 +1,59 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> +## Copyright (C) 2013 Alexandru Gagniuc <mr.nuke.me@gmail.com> +## +## This library is free software: you can redistribute it and/or modify +## it under the terms of the GNU Lesser General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## This library 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 Lesser General Public License for more details. +## +## You should have received a copy of the GNU Lesser General Public License +## along with this library. If not, see <http://www.gnu.org/licenses/>. +## + +LIBNAME = libopencm3_stm32f4 +SRCLIBDIR ?= ../.. + +FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16 +PREFIX ?= arm-none-eabi + +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g \ + -Wall -Wextra -Wimplicit-function-declaration \ + -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \ + -Wundef -Wshadow \ + -I../../../include -fno-common \ + -mcpu=cortex-m4 -mthumb $(FP_FLAGS) \ + -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F4 +# ARFLAGS = rcsv +ARFLAGS = rcs + +OBJS = adc.o adc_common_v1.o can.o gpio.o pwr.o rcc.o rtc.o crypto.o + +OBJS += crc_common_all.o dac_common_all.o dma_common_f24.o \ + gpio_common_all.o gpio_common_f0234.o i2c_common_all.o \ + iwdg_common_all.o pwr_common_all.o rtc_common_l1f024.o \ + spi_common_all.o spi_common_l1f124.o timer_common_all.o \ + timer_common_f234.o timer_common_f24.o usart_common_all.o \ + usart_common_f124.o flash_common_f234.o flash_common_f24.o \ + hash_common_f24.o crypto_common_f24.o exti_common_all.o \ + rcc_common_all.o + +OBJS += usb.o usb_standard.o usb_control.o usb_fx07_common.o \ + usb_f107.o usb_f207.o usb_msc.o + +OBJS += mac.o phy.o mac_stm32fxx7.o phy_ksz8051mll.o fmc.o + +VPATH += ../../usb:../:../../cm3:../common +VPATH += ../../ethernet + +include ../../Makefile.include diff --git a/libopencm3/lib/stm32/f4/adc.c b/libopencm3/lib/stm32/f4/adc.c new file mode 100644 index 0000000..fba88de --- /dev/null +++ b/libopencm3/lib/stm32/f4/adc.c @@ -0,0 +1,437 @@ +/** @defgroup adc_file ADC + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx Analog to Digital Converters</b> + +@author @htmlonly © @endhtmlonly 2012 +Ken Sarkies <ksarkies@internode.on.net> + +@date 30 August 2012 + +This library supports the A/D Converter Control System in the STM32 series +of ARM Cortex Microcontrollers by ST Microelectronics. + +Devices can have up to three A/D converters each with their own set of +registers. However all the A/D converters share a common clock which is +prescaled from the APB2 clock by default by a minimum factor of 2 to a maximum +of 8. The ADC resolution can be set to 12, 10, 8 or 6 bits. + +Each A/D converter has up to 19 channels: +@li On ADC1 the analog channels 16 is internally connected to the temperature +sensor, channel 17 to V<sub>REFINT</sub>, and channel 18 to V<sub>BATT</sub>. +@li On ADC2 and ADC3 the analog channels 16 - 18 are not used. + +The conversions can occur as a one-off conversion whereby the process stops +once conversion is complete. The conversions can also be continuous wherein a +new conversion starts immediately the previous conversion has ended. + +Conversion can occur as a single channel conversion or a scan of a group of +channels in either continuous or one-off mode. If more than one channel is +converted in a scan group, DMA must be used to transfer the data as there is +only one result register available. An interrupt can be set to occur at the end +of conversion, which occurs after all channels have been scanned. + +A discontinuous mode allows a subgroup of group of a channels to be converted +in bursts of a given length. + +Injected conversions allow a second group of channels to be converted +separately from the regular group. An interrupt can be set to occur at the end +of conversion, which occurs after all channels have been scanned. + +@section adc_f4_api_ex Basic ADC Handling API. + +Example 1: Simple single channel conversion polled. Enable the peripheral clock +and ADC, reset ADC and set the prescaler divider. Set multiple mode to +independent. + +@code +gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO1); +rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN); +adc_set_clk_prescale(RCC_CFGR_ADCPRE_BY2); +adc_disable_scan_mode(ADC1); +adc_set_single_conversion_mode(ADC1); +adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC); +uint8_t channels[] = ADC_CHANNEL0; +adc_set_regular_sequence(ADC1, 1, channels); +adc_set_multi_mode(ADC_CCR_MULTI_INDEPENDENT); +adc_power_on(ADC1); +adc_start_conversion_regular(ADC1); +while (! adc_eoc(ADC1)); +reg16 = adc_read_regular(ADC1); +@endcode + +LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2012 Ken Sarkies <ksarkies@internode.on.net> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/adc.h> + +/**@{*/ + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for a Single Channel + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] channel Unsigned int8. ADC Channel integer 0..18 or from @ref +adc_channel +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg + * NOTE Common with f1, f2 and f37x +*/ + +void adc_set_sample_time(uint32_t adc, uint8_t channel, uint8_t time) +{ + uint32_t reg32; + + if (channel < 10) { + reg32 = ADC_SMPR2(adc); + reg32 &= ~(0x7 << (channel * 3)); + reg32 |= (time << (channel * 3)); + ADC_SMPR2(adc) = reg32; + } else { + reg32 = ADC_SMPR1(adc); + reg32 &= ~(0x7 << ((channel - 10) * 3)); + reg32 |= (time << ((channel - 10) * 3)); + ADC_SMPR1(adc) = reg32; + } +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set the Sample Time for All Channels + +The sampling time can be selected in ADC clock cycles from 1.5 to 239.5, same +for all channels. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg + * NOTE Common with f1, f2 and f37x +*/ + +void adc_set_sample_time_on_all_channels(uint32_t adc, uint8_t time) +{ + uint8_t i; + uint32_t reg32 = 0; + + for (i = 0; i <= 9; i++) { + reg32 |= (time << (i * 3)); + } + ADC_SMPR2(adc) = reg32; + + for (i = 10; i <= 17; i++) { + reg32 |= (time << ((i - 10) * 3)); + } + ADC_SMPR1(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Power On + +If the ADC is in power-down mode then it is powered up. The application needs +to wait a time of about 3 microseconds for stabilization before using the ADC. +If the ADC is already on this function call will have no effect. + * NOTE Common with L1 and F2 + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_power_on(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_ADON; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Clock Prescale + +The ADC clock taken from the APB2 clock can be scaled down by 2, 4, 6 or 8. + +@param[in] prescale Unsigned int32. Prescale value for ADC Clock @ref +adc_ccr_adcpre +*/ + +void adc_set_clk_prescale(uint32_t prescale) +{ + uint32_t reg32 = ((ADC_CCR & ~ADC_CCR_ADCPRE_MASK) | prescale); + ADC_CCR = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Dual/Triple Mode + +The multiple mode uses ADC1 as master, ADC2 and optionally ADC3 in a slave +arrangement. This setting is applied to ADC1 only. + +The various modes possible are described in the reference manual. + +@param[in] mode Unsigned int32. Multiple mode selection from @ref adc_multi_mode +*/ + +void adc_set_multi_mode(uint32_t mode) +{ + ADC_CCR |= mode; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Regular Channels + +This enables an external trigger for set of defined regular channels, and sets +the polarity of the trigger event: rising or falling edge or both. Note that if +the trigger polarity is zero, triggering is disabled. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int32. Trigger identifier @ref adc_trigger_regular +@param[in] polarity Unsigned int32. Trigger polarity @ref +adc_trigger_polarity_regular +*/ + +void adc_enable_external_trigger_regular(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_CR2(adc); + + reg32 &= ~(ADC_CR2_EXTSEL_MASK | ADC_CR2_EXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CR2(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Regular Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_external_trigger_regular(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EXTEN_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an External Trigger for Injected Channels + +This enables an external trigger for set of defined injected channels, and sets +the polarity of the trigger event: rising or falling edge or both. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_injected +@param[in] polarity Unsigned int32. Trigger polarity @ref +adc_trigger_polarity_injected +*/ + +void adc_enable_external_trigger_injected(uint32_t adc, uint32_t trigger, + uint32_t polarity) +{ + uint32_t reg32 = ADC_CR2(adc); + + reg32 &= ~(ADC_CR2_JEXTSEL_MASK | ADC_CR2_JEXTEN_MASK); + reg32 |= (trigger | polarity); + ADC_CR2(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable an External Trigger for Injected Channels + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_external_trigger_injected(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_JEXTEN_MASK; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set Resolution + +ADC Resolution can be reduced from 12 bits to 10, 8 or 6 bits for a +corresponding reduction in conversion time (resolution + 3 ADC clock cycles). + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@param[in] resolution Unsigned int32. Resolution value @ref adc_cr1_res +*/ + +void adc_set_resolution(uint32_t adc, uint32_t resolution) +{ + uint32_t reg32 = ADC_CR1(adc); + + reg32 &= ~ADC_CR1_RES_MASK; + reg32 |= resolution; + ADC_CR1(adc) = reg32; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable the Overrun Interrupt + +The overrun interrupt is generated when data is not read from a result register +before the next conversion is written. If DMA is enabled, all transfers are +terminated and any conversion sequence is aborted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_overrun_interrupt(uint32_t adc) +{ + ADC_CR1(adc) |= ADC_CR1_OVRIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable the Overrun Interrupt + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_overrun_interrupt(uint32_t adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_OVRIE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the Overrun Flag + +The overrun flag is set when data is not read from a result register before the +next conversion is written. If DMA is enabled, all transfers are terminated and +any conversion sequence is aborted. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns Unsigned int32 conversion result. +*/ + +bool adc_get_overrun_flag(uint32_t adc) +{ + return ADC_SR(adc) & ADC_SR_OVR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Clear Overrun Flags + +The overrun flag is cleared. Note that if an overrun occurs, DMA is terminated. +The flag must be cleared and the DMA stream and ADC reinitialised to resume +conversions (see the reference manual). + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns Unsigned int32 conversion result. +*/ + +void adc_clear_overrun_flag(uint32_t adc) +{ +/* need to write zero to clear this */ + ADC_SR(adc) &= ~ADC_SR_OVR; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable an EOC for Each Conversion + +The EOC is set after each conversion in a sequence rather than at the end of the +sequence. Overrun detection is enabled only if DMA is enabled. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_eoc_after_each(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_EOCS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable the EOC for Each Conversion + +The EOC is set at the end of each sequence rather than after each conversion in +the sequence. Overrun detection is enabled always. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_eoc_after_group(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EOCS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set DMA to Continue + +This must be set to allow DMA to continue to operate after the last conversion +in the DMA sequence. This allows DMA to be used in continuous circular mode. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_dma_continue(uint32_t adc) +{ + ADC_CR2(adc) |= ADC_CR2_DDS; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Set DMA to Terminate + +This must be set to allow DMA to terminate after the last conversion in the DMA +sequence. This can avoid overrun errors. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_set_dma_terminate(uint32_t adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_DDS; +} +/*---------------------------------------------------------------------------*/ +/** @brief ADC Read the Analog Watchdog Flag + +This flag is set when the converted voltage crosses the high or low thresholds. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +@returns bool. AWD flag. +*/ + +bool adc_awd(uint32_t adc) +{ + return ADC_SR(adc) & ADC_SR_AWD; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Enable The Temperature Sensor + +This enables both the sensor and the reference voltage measurements on channels +16 and 17. These are only available on ADC1 channel 16 and 17 respectively. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_enable_temperature_sensor() +{ + ADC_CCR |= ADC_CCR_TSVREFE; +} + +/*---------------------------------------------------------------------------*/ +/** @brief ADC Disable The Temperature Sensor + +Disabling this will reduce power consumption from the sensor and the reference +voltage measurements. + +@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base +*/ + +void adc_disable_temperature_sensor() +{ + ADC_CCR &= ~ADC_CCR_TSVREFE; +} + +/*---------------------------------------------------------------------------*/ + +/**@}*/ + diff --git a/libopencm3/lib/stm32/f4/crc.c b/libopencm3/lib/stm32/f4/crc.c new file mode 100644 index 0000000..6bc9456 --- /dev/null +++ b/libopencm3/lib/stm32/f4/crc.c @@ -0,0 +1,33 @@ +/** @defgroup crc_file CRC + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx CRC</b> + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/crc.h> + + diff --git a/libopencm3/lib/stm32/f4/crypto.c b/libopencm3/lib/stm32/f4/crypto.c new file mode 100644 index 0000000..651f365 --- /dev/null +++ b/libopencm3/lib/stm32/f4/crypto.c @@ -0,0 +1,66 @@ +/** @defgroup crypto_file CRYPTO + * + * @ingroup STM32F4xx + * + * @brief <b>libopencm3 STM32F4xx CRYPTO</b> + * + * @version 1.0.0 + * + * @date 18 Jun 2013 + * + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/crypto.h> + +/**@{*/ + +/*---------------------------------------------------------------------------*/ + +/** @brief Set the MAC algorithm + */ +void crypto_set_mac_algorithm(enum crypto_mode_mac mode) +{ + crypto_set_algorithm((enum crypto_mode) mode); +} + +/** + * @brief Swap context + * + *@param[in] buf uint32_t Memory space for swap (16 items length) + */ +void crypto_context_swap(uint32_t *buf) +{ + int i; + /* Apply exact order of ? */ + for (i = 0; i < 8; i++) { + uint32_t save = *buf; + *buf++ = CRYP_CSGCMCCMR(i); + CRYP_CSGCMCCMR(i) = save; + }; + + for (i = 0; i < 8; i++) { + uint32_t save = *buf; + *buf++ = CRYP_CSGCMR(i); + CRYP_CSGCMCCMR(i) = save; + }; +} + +/**@}*/ diff --git a/libopencm3/lib/stm32/f4/dac.c b/libopencm3/lib/stm32/f4/dac.c new file mode 100644 index 0000000..c5397b6 --- /dev/null +++ b/libopencm3/lib/stm32/f4/dac.c @@ -0,0 +1,31 @@ +/** @defgroup dac_file DAC + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx DAC</b> + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/dac.h> diff --git a/libopencm3/lib/stm32/f4/dma.c b/libopencm3/lib/stm32/f4/dma.c new file mode 100644 index 0000000..6616621 --- /dev/null +++ b/libopencm3/lib/stm32/f4/dma.c @@ -0,0 +1,31 @@ +/** @defgroup dma_file DMA + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx DMA</b> + +@version 1.0.0 + +@date 30 November 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/dma.h> diff --git a/libopencm3/lib/stm32/f4/flash.c b/libopencm3/lib/stm32/f4/flash.c new file mode 100644 index 0000000..5353605 --- /dev/null +++ b/libopencm3/lib/stm32/f4/flash.c @@ -0,0 +1,53 @@ +/** @defgroup flash_file FLASH + * + * @ingroup STM32F4xx + * + * @brief <b>libopencm3 STM32F4xx FLASH</b> + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2010 + * Thomas Otto <tommi@viadmin.org> + * @author @htmlonly © @endhtmlonly 2010 + * Mark Butler <mbutler@physics.otago.ac.nz> + * + * @date 14 January 2014 + * + * This library supports the FLASH memory controller in the STM32F4 + * series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * For the STM32F4xx, accessing FLASH memory is described briefly in + * section 2.3.3 of the STM32F4xx Reference Manual. + * For detailed programming information see: + * PM0081 programming manual: STM32F10xxx Flash programming + * September 2011, Doc ID 018520 Rev 1 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> + * Copyright (C) 2010 Mark Butler <mbutler@physics.otago.ac.nz> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/**@{*/ + +#include <libopencm3/stm32/flash.h> + +/**@}*/ + diff --git a/libopencm3/lib/stm32/f4/fmc.c b/libopencm3/lib/stm32/f4/fmc.c new file mode 100644 index 0000000..0de8a4a --- /dev/null +++ b/libopencm3/lib/stm32/f4/fmc.c @@ -0,0 +1,99 @@ +/* + * + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Utility functions for the SDRAM component of the FMC */ + +#include <stdint.h> +#include <libopencm3/stm32/fsmc.h> + +/* + * Install various timing values into the correct place in the + * SDRAM Timing Control Register format. + * + * Note that the register is 'zero' based to save bits so 1 cycle + * is stored as '0'. This command takes actual cycles and adjusts + * by subtracting 1. + */ +uint32_t +sdram_timing(struct sdram_timing *t) { + uint32_t result; + + result = 0; + result |= ((t->trcd - 1) & 0xf) * FMC_SDTR_TRCD_SHIFT; + result |= ((t->trp - 1) & 0xf) * FMC_SDTR_TRP_SHIFT; + result |= ((t->twr - 1) & 0xf) * FMC_SDTR_TWR_SHIFT; + result |= ((t->trc - 1) & 0xf) * FMC_SDTR_TRC_SHIFT; + result |= ((t->tras - 1) & 0xf) * FMC_SDTR_TRAS_SHIFT; + result |= ((t->txsr - 1) & 0xf) * FMC_SDTR_TXSR_SHIFT; + result |= ((t->tmrd - 1) & 0xf) * FMC_SDTR_TMRD_SHIFT; + return result; +} + +/* + * Send a command to the SDRAM controller, wait until it is not + * busy before sending. This allows you to chain sending commands + * and the code will pause as needed between them. + */ +void +sdram_command(enum fmc_sdram_bank bank, + enum fmc_sdram_command cmd, int autorefresh, int modereg) { + uint32_t tmp_reg = 0; + + switch (bank) { + case SDRAM_BANK1: + tmp_reg = FMC_SDCMR_CTB1; + break; + case SDRAM_BANK2: + tmp_reg = FMC_SDCMR_CTB2; + break; + case SDRAM_BOTH_BANKS: + tmp_reg = FMC_SDCMR_CTB1 | FMC_SDCMR_CTB2; + break; + } + tmp_reg |= autorefresh * FMC_SDCMR_NRFS_SHIFT; + tmp_reg |= modereg * FMC_SDCMR_MRD_SHIFT; + switch (cmd) { + case SDRAM_CLK_CONF: + tmp_reg |= FMC_SDCMR_MODE_CLOCK_CONFIG_ENA; + break; + case SDRAM_AUTO_REFRESH: + tmp_reg |= FMC_SDCMR_MODE_AUTO_REFRESH; + break; + case SDRAM_LOAD_MODE: + tmp_reg |= FMC_SDCMR_MODE_LOAD_MODE_REGISTER; + break; + case SDRAM_PALL: + tmp_reg |= FMC_SDCMR_MODE_PALL; + break; + case SDRAM_SELF_REFRESH: + tmp_reg |= FMC_SDCMR_MODE_SELF_REFRESH; + break; + case SDRAM_POWER_DOWN: + tmp_reg |= FMC_SDCMR_MODE_POWER_DOWN; + break; + case SDRAM_NORMAL: + default: + break; + } + + /* Wait for the next chance to talk to the controller */ + while (FMC_SDSR & FMC_SDSR_BUSY) ; + + /* Send the next command */ + FMC_SDCMR = tmp_reg; +} diff --git a/libopencm3/lib/stm32/f4/gpio.c b/libopencm3/lib/stm32/f4/gpio.c new file mode 100644 index 0000000..ea59ae7 --- /dev/null +++ b/libopencm3/lib/stm32/f4/gpio.c @@ -0,0 +1,31 @@ +/** @defgroup gpio_file GPIO + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx General Purpose I/O</b> + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/gpio.h> diff --git a/libopencm3/lib/stm32/f4/hash.c b/libopencm3/lib/stm32/f4/hash.c new file mode 100644 index 0000000..cd791bf --- /dev/null +++ b/libopencm3/lib/stm32/f4/hash.c @@ -0,0 +1,31 @@ +/** @defgroup hash_file HASH + * + * @ingroup STM32F4xx + * + * @brief <b>libopencm3 STM32F4xx Hash Processor</b> + * + * @version 1.0.0 + * + * @date 13 January 2014 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/hash.h> diff --git a/libopencm3/lib/stm32/f4/i2c.c b/libopencm3/lib/stm32/f4/i2c.c new file mode 100644 index 0000000..67df9b1 --- /dev/null +++ b/libopencm3/lib/stm32/f4/i2c.c @@ -0,0 +1,31 @@ +/** @defgroup i2c_file I2C + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx I2C</b> + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/i2c.h> diff --git a/libopencm3/lib/stm32/f4/iwdg.c b/libopencm3/lib/stm32/f4/iwdg.c new file mode 100644 index 0000000..3985657 --- /dev/null +++ b/libopencm3/lib/stm32/f4/iwdg.c @@ -0,0 +1,31 @@ +/** @defgroup iwdg_file IWDG + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx Independent Watchdog Timer</b> + +@version 1.0.0 + +@date 18 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/iwdg.h> diff --git a/libopencm3/lib/stm32/f4/libopencm3_stm32f4.ld b/libopencm3/lib/stm32/f4/libopencm3_stm32f4.ld new file mode 100644 index 0000000..3fc2ccb --- /dev/null +++ b/libopencm3/lib/stm32/f4/libopencm3_stm32f4.ld @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Generic linker script for STM32 targets using libopencm3. */ + +/* Memory regions must be defined in the ld script which includes this one. */ + +/* Enforce emmition of the vector table. */ +EXTERN (vector_table) + +/* Define the entry point of the output file. */ +ENTRY(reset_handler) + +/* Define sections. */ +SECTIONS +{ + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + . = ALIGN(4); + *(.rodata*) /* Read-only data */ + . = ALIGN(4); + } >rom + + /* C++ Static constructors/destructors, also used for __attribute__ + * ((constructor)) and the likes */ + .preinit_array : { + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + } >rom + .init_array : { + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + } >rom + .fini_array : { + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + } >rom + + /* + * Another section used by C++ stuff, appears when using newlib with + * 64bit (long long) printf support + */ + .ARM.extab : { + *(.ARM.extab*) + } >rom + .ARM.exidx : { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } >rom + + . = ALIGN(4); + _etext = .; + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + . = ALIGN(4); + _edata = .; + } >ram AT >rom + _data_loadaddr = LOADADDR(.data); + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + . = ALIGN(4); + _ebss = .; + } >ram + + /* + * The .eh_frame section appears to be used for C++ exception handling. + * You may need to fix this if you're using C++. + */ + /DISCARD/ : { *(.eh_frame) } + + . = ALIGN(4); + end = .; +} + +PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram)); + diff --git a/libopencm3/lib/stm32/f4/pwr.c b/libopencm3/lib/stm32/f4/pwr.c new file mode 100644 index 0000000..9b9e579 --- /dev/null +++ b/libopencm3/lib/stm32/f4/pwr.c @@ -0,0 +1,46 @@ +/** @defgroup pwr_file PWR + * + * @ingroup STM32F4xx + * + * @brief <b>libopencm3 STM32F4xx Power Control</b> + * + * @version 1.0.0 + * + * @author @htmlonly © @endhtmlonly 2011 Stephen Caudle <scaudle@doceme.com> + * + * @date 4 March 2013 + * + * This library supports the power control system for the + * STM32F4 series of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/pwr.h> + +void pwr_set_vos_scale(vos_scale_t scale) +{ + if (scale == SCALE1) { + PWR_CR |= PWR_CR_VOS; + } else if (scale == SCALE2) { + PWR_CR &= PWR_CR_VOS; + } +} diff --git a/libopencm3/lib/stm32/f4/rcc.c b/libopencm3/lib/stm32/f4/rcc.c new file mode 100644 index 0000000..d862691 --- /dev/null +++ b/libopencm3/lib/stm32/f4/rcc.c @@ -0,0 +1,539 @@ +/** @defgroup rcc_file RCC + * + * @ingroup STM32F4xx + * + * @section rcc_f4_api_ex Reset and Clock Control API. + * + * @brief <b>libopencm3 STM32F4xx Reset and Clock Control</b> + * + * @author @htmlonly © @endhtmlonly 2013 Frantisek Burian <BuFran at seznam.cz> + * + * @date 18 Jun 2013 + * + * This library supports the Reset and Clock Control System in the STM32 series + * of ARM Cortex Microcontrollers by ST Microelectronics. + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde <memeruiz at gmail dot com> + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * Copyright (C) 2010 Thomas Otto <tommi@viadmin.org> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/cm3/assert.h> +#include <libopencm3/stm32/rcc.h> +#include <libopencm3/stm32/pwr.h> +#include <libopencm3/stm32/flash.h> + +/**@{*/ + +/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset. */ +uint32_t rcc_ppre1_frequency = 16000000; +uint32_t rcc_ppre2_frequency = 16000000; + +const clock_scale_t hse_8mhz_3v3[CLOCK_3V3_END] = { + { /* 48MHz */ + .pllm = 8, + .plln = 96, + .pllp = 2, + .pllq = 2, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | + FLASH_ACR_LATENCY_3WS, + .apb1_frequency = 12000000, + .apb2_frequency = 24000000, + }, + { /* 120MHz */ + .pllm = 8, + .plln = 240, + .pllp = 2, + .pllq = 5, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | + FLASH_ACR_LATENCY_3WS, + .apb1_frequency = 30000000, + .apb2_frequency = 60000000, + }, + { /* 168MHz */ + .pllm = 8, + .plln = 336, + .pllp = 2, + .pllq = 7, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | + FLASH_ACR_LATENCY_5WS, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, +}; + +const clock_scale_t hse_12mhz_3v3[CLOCK_3V3_END] = { + { /* 48MHz */ + .pllm = 12, + .plln = 96, + .pllp = 2, + .pllq = 2, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | + FLASH_ACR_LATENCY_3WS, + .apb1_frequency = 12000000, + .apb2_frequency = 24000000, + }, + { /* 120MHz */ + .pllm = 12, + .plln = 240, + .pllp = 2, + .pllq = 5, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | + FLASH_ACR_LATENCY_3WS, + .apb1_frequency = 30000000, + .apb2_frequency = 60000000, + }, + { /* 168MHz */ + .pllm = 12, + .plln = 336, + .pllp = 2, + .pllq = 7, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | + FLASH_ACR_LATENCY_5WS, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, +}; + +const clock_scale_t hse_16mhz_3v3[CLOCK_3V3_END] = { + { /* 48MHz */ + .pllm = 16, + .plln = 96, + .pllp = 2, + .pllq = 2, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | + FLASH_ACR_LATENCY_3WS, + .apb1_frequency = 12000000, + .apb2_frequency = 24000000, + }, + { /* 120MHz */ + .pllm = 16, + .plln = 240, + .pllp = 2, + .pllq = 5, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .power_save = 1, + .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | + FLASH_ACR_LATENCY_3WS, + .apb1_frequency = 30000000, + .apb2_frequency = 60000000, + }, + { /* 168MHz */ + .pllm = 16, + .plln = 336, + .pllp = 2, + .pllq = 7, + .hpre = RCC_CFGR_HPRE_DIV_NONE, + .ppre1 = RCC_CFGR_PPRE_DIV_4, + .ppre2 = RCC_CFGR_PPRE_DIV_2, + .flash_config = FLASH_ACR_ICE | FLASH_ACR_DCE | + FLASH_ACR_LATENCY_5WS, + .apb1_frequency = 42000000, + .apb2_frequency = 84000000, + }, +}; + +void rcc_osc_ready_int_clear(enum rcc_osc osc) +{ + switch (osc) { + case PLL: + RCC_CIR |= RCC_CIR_PLLRDYC; + break; + case HSE: + RCC_CIR |= RCC_CIR_HSERDYC; + break; + case HSI: + RCC_CIR |= RCC_CIR_HSIRDYC; + break; + case LSE: + RCC_CIR |= RCC_CIR_LSERDYC; + break; + case LSI: + RCC_CIR |= RCC_CIR_LSIRDYC; + break; + } +} + +void rcc_osc_ready_int_enable(enum rcc_osc osc) +{ + switch (osc) { + case PLL: + RCC_CIR |= RCC_CIR_PLLRDYIE; + break; + case HSE: + RCC_CIR |= RCC_CIR_HSERDYIE; + break; + case HSI: + RCC_CIR |= RCC_CIR_HSIRDYIE; + break; + case LSE: + RCC_CIR |= RCC_CIR_LSERDYIE; + break; + case LSI: + RCC_CIR |= RCC_CIR_LSIRDYIE; + break; + } +} + +void rcc_osc_ready_int_disable(enum rcc_osc osc) +{ + switch (osc) { + case PLL: + RCC_CIR &= ~RCC_CIR_PLLRDYIE; + break; + case HSE: + RCC_CIR &= ~RCC_CIR_HSERDYIE; + break; + case HSI: + RCC_CIR &= ~RCC_CIR_HSIRDYIE; + break; + case LSE: + RCC_CIR &= ~RCC_CIR_LSERDYIE; + break; + case LSI: + RCC_CIR &= ~RCC_CIR_LSIRDYIE; + break; + } +} + +int rcc_osc_ready_int_flag(enum rcc_osc osc) +{ + switch (osc) { + case PLL: + return ((RCC_CIR & RCC_CIR_PLLRDYF) != 0); + break; + case HSE: + return ((RCC_CIR & RCC_CIR_HSERDYF) != 0); + break; + case HSI: + return ((RCC_CIR & RCC_CIR_HSIRDYF) != 0); + break; + case LSE: + return ((RCC_CIR & RCC_CIR_LSERDYF) != 0); + break; + case LSI: + return ((RCC_CIR & RCC_CIR_LSIRDYF) != 0); + break; + } + + cm3_assert_not_reached(); +} + +void rcc_css_int_clear(void) +{ + RCC_CIR |= RCC_CIR_CSSC; +} + +int rcc_css_int_flag(void) +{ + return ((RCC_CIR & RCC_CIR_CSSF) != 0); +} + +void rcc_wait_for_osc_ready(enum rcc_osc osc) +{ + switch (osc) { + case PLL: + while ((RCC_CR & RCC_CR_PLLRDY) == 0); + break; + case HSE: + while ((RCC_CR & RCC_CR_HSERDY) == 0); + break; + case HSI: + while ((RCC_CR & RCC_CR_HSIRDY) == 0); + break; + case LSE: + while ((RCC_BDCR & RCC_BDCR_LSERDY) == 0); + break; + case LSI: + while ((RCC_CSR & RCC_CSR_LSIRDY) == 0); + break; + } +} + +void rcc_wait_for_sysclk_status(enum rcc_osc osc) +{ + switch (osc) { + case PLL: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_PLL); + break; + case HSE: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_HSE); + break; + case HSI: + while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SWS_HSI); + break; + default: + /* Shouldn't be reached. */ + break; + } +} + +void rcc_osc_on(enum rcc_osc osc) +{ + switch (osc) { + case PLL: + RCC_CR |= RCC_CR_PLLON; + break; + case HSE: + RCC_CR |= RCC_CR_HSEON; + break; + case HSI: + RCC_CR |= RCC_CR_HSION; + break; + case LSE: + RCC_BDCR |= RCC_BDCR_LSEON; + break; + case LSI: + RCC_CSR |= RCC_CSR_LSION; + break; + } +} + +void rcc_osc_off(enum rcc_osc osc) +{ + switch (osc) { + case PLL: + RCC_CR &= ~RCC_CR_PLLON; + break; + case HSE: + RCC_CR &= ~RCC_CR_HSEON; + break; + case HSI: + RCC_CR &= ~RCC_CR_HSION; + break; + case LSE: + RCC_BDCR &= ~RCC_BDCR_LSEON; + break; + case LSI: + RCC_CSR &= ~RCC_CSR_LSION; + break; + } +} + +void rcc_css_enable(void) +{ + RCC_CR |= RCC_CR_CSSON; +} + +void rcc_css_disable(void) +{ + RCC_CR &= ~RCC_CR_CSSON; +} + +void rcc_osc_bypass_enable(enum rcc_osc osc) +{ + switch (osc) { + case HSE: + RCC_CR |= RCC_CR_HSEBYP; + break; + case LSE: + RCC_BDCR |= RCC_BDCR_LSEBYP; + break; + case PLL: + case HSI: + case LSI: + /* Do nothing, only HSE/LSE allowed here. */ + break; + } +} + +void rcc_osc_bypass_disable(enum rcc_osc osc) +{ + switch (osc) { + case HSE: + RCC_CR &= ~RCC_CR_HSEBYP; + break; + case LSE: + RCC_BDCR &= ~RCC_BDCR_LSEBYP; + break; + case PLL: + case HSI: + case LSI: + /* Do nothing, only HSE/LSE allowed here. */ + break; + } +} + + + +void rcc_set_sysclk_source(uint32_t clk) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | clk); +} + +void rcc_set_pll_source(uint32_t pllsrc) +{ + uint32_t reg32; + + reg32 = RCC_PLLCFGR; + reg32 &= ~(1 << 22); + RCC_PLLCFGR = (reg32 | (pllsrc << 22)); +} + +void rcc_set_ppre2(uint32_t ppre2) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 13) | (1 << 14) | (1 << 15)); + RCC_CFGR = (reg32 | (ppre2 << 13)); +} + +void rcc_set_ppre1(uint32_t ppre1) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 10) | (1 << 11) | (1 << 12)); + RCC_CFGR = (reg32 | (ppre1 << 10)); +} + +void rcc_set_hpre(uint32_t hpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)); + RCC_CFGR = (reg32 | (hpre << 4)); +} + +void rcc_set_rtcpre(uint32_t rtcpre) +{ + uint32_t reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 16) | (1 << 17) | (1 << 18) | (1 << 19) | (1 << 20)); + RCC_CFGR = (reg32 | (rtcpre << 16)); +} + +void rcc_set_main_pll_hsi(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq) +{ + RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) | + (plln << RCC_PLLCFGR_PLLN_SHIFT) | + (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) | + (pllq << RCC_PLLCFGR_PLLQ_SHIFT); +} + +void rcc_set_main_pll_hse(uint32_t pllm, uint32_t plln, uint32_t pllp, + uint32_t pllq) +{ + RCC_PLLCFGR = (pllm << RCC_PLLCFGR_PLLM_SHIFT) | + (plln << RCC_PLLCFGR_PLLN_SHIFT) | + (((pllp >> 1) - 1) << RCC_PLLCFGR_PLLP_SHIFT) | + RCC_PLLCFGR_PLLSRC | + (pllq << RCC_PLLCFGR_PLLQ_SHIFT); +} + +uint32_t rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return (RCC_CFGR & 0x000c) >> 2; +} + +void rcc_clock_setup_hse_3v3(const clock_scale_t *clock) +{ + /* Enable internal high-speed oscillator. */ + rcc_osc_on(HSI); + rcc_wait_for_osc_ready(HSI); + + /* Select HSI as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_HSI); + + /* Enable external high-speed oscillator 8MHz. */ + rcc_osc_on(HSE); + rcc_wait_for_osc_ready(HSE); + + /* Enable/disable high performance mode */ + if (!clock->power_save) { + pwr_set_vos_scale(SCALE1); + } else { + pwr_set_vos_scale(SCALE2); + } + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(clock->hpre); + rcc_set_ppre1(clock->ppre1); + rcc_set_ppre2(clock->ppre2); + + rcc_set_main_pll_hse(clock->pllm, clock->plln, + clock->pllp, clock->pllq); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Configure flash settings. */ + flash_set_ws(clock->flash_config); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_PLL); + + /* Wait for PLL clock to be selected. */ + rcc_wait_for_sysclk_status(PLL); + + /* Set the peripheral clock frequencies used. */ + rcc_ppre1_frequency = clock->apb1_frequency; + rcc_ppre2_frequency = clock->apb2_frequency; + + /* Disable internal high-speed oscillator. */ + rcc_osc_off(HSI); +} + + + +/**@}*/ diff --git a/libopencm3/lib/stm32/f4/rtc.c b/libopencm3/lib/stm32/f4/rtc.c new file mode 100644 index 0000000..f08ac2b --- /dev/null +++ b/libopencm3/lib/stm32/f4/rtc.c @@ -0,0 +1,97 @@ +/** @defgroup rtc_file RTC + * + * @ingroup STM32F4xx + * + * @brief <b>libopencm3 STM32F4xx RTC</b> + * + * @version 1.0.0 + * + * @date 4 March 2013 + * + * LGPL License Terms @ref lgpl_license + */ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/exti.h> +#include <libopencm3/cm3/nvic.h> +#include <libopencm3/stm32/rtc.h> + + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the wakeup timer + @warning You must unlock the registers before using this function + +*/ +void rtc_enable_wakeup_timer(void) +{ + RTC_CR |= RTC_CR_WUTE | (RTC_CR_OSEL_WAKEUP << RTC_CR_OSEL_SHIFT); + rtc_enable_wakeup_timer_interrupt(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the wakeup timer + @warning You must unlock the registers before using this function + +*/ +void rtc_disable_wakeup_timer(void) +{ + RTC_CR &= ~RTC_CR_WUTE; + rtc_disable_wakeup_timer_interrupt(); +} + +/*---------------------------------------------------------------------------*/ +/** @brief Enable the wakeup timer interrupt + @warning You must unlock the registers before using this function + +*/ +void rtc_enable_wakeup_timer_interrupt(void) +{ + /* FTFM: + * To enable the RTC Wakeup interrupt, the following sequence is + * required: + * 1. Configure and enable the EXTI Line 22 in interrupt mode and + * select the rising edge sensitivity. + */ + exti_enable_request(EXTI22); + exti_set_trigger(EXTI22, EXTI_TRIGGER_RISING); + + /* 2. Configure and enable the RTC_WKUP IRQ channel in the NVIC. */ + nvic_enable_irq(NVIC_RTC_WKUP_IRQ); + nvic_set_priority(NVIC_RTC_WKUP_IRQ, 1); + + /* 3. Configure the RTC to generate the RTC wakeup timer event. */ + RTC_CR |= RTC_CR_WUTIE; /* Enable the interrupt */ +} + +/*---------------------------------------------------------------------------*/ +/** @brief Disable the wakeup timer interrupt + @warning You must unlock the registers before using this function + +*/ +void rtc_disable_wakeup_timer_interrupt(void) +{ + /* 1. Disable EXTI Line 22 */ + exti_disable_request(EXTI22); + + /* 2. Disable RTC_WKUP IRQ channel in the NVIC. */ + nvic_disable_irq(NVIC_RTC_WKUP_IRQ); + + /* 3. Disable RTC wakeup timer event. */ + RTC_CR &= ~RTC_CR_WUTIE; +} diff --git a/libopencm3/lib/stm32/f4/spi.c b/libopencm3/lib/stm32/f4/spi.c new file mode 100644 index 0000000..c8a6b41 --- /dev/null +++ b/libopencm3/lib/stm32/f4/spi.c @@ -0,0 +1,31 @@ +/** @defgroup spi_file SPI + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx SPI</b> + +@version 1.0.0 + +@date 15 October 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/spi.h> diff --git a/libopencm3/lib/stm32/f4/stm32f405x6.ld b/libopencm3/lib/stm32/f4/stm32f405x6.ld new file mode 100644 index 0000000..a8733f3 --- /dev/null +++ b/libopencm3/lib/stm32/f4/stm32f405x6.ld @@ -0,0 +1,33 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de> + * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com> + * Copyright (C) 2013 Sergey Krukowski <softsr@yahoo.de> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +/* Linker script for the STM32F405RGT6 chip (1024K flash, 128K RAM). */ + +/* Define memory regions. */ +MEMORY +{ + rom (rx) : ORIGIN = 0x08000000, LENGTH = 1024K + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K +} + +/* Include the common ld script. */ +INCLUDE libopencm3_stm32f4.ld + diff --git a/libopencm3/lib/stm32/f4/timer.c b/libopencm3/lib/stm32/f4/timer.c new file mode 100644 index 0000000..72ecd8d --- /dev/null +++ b/libopencm3/lib/stm32/f4/timer.c @@ -0,0 +1,38 @@ +/* This file is used for documentation purposes. It does not need +to be compiled. All source code is in the common area. +If there is any device specific code required it can be included here, +in which case this file must be added to the compile list. */ + +/** @defgroup timer_file Timers + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx Timers</b> + +@version 1.0.0 + +@date 18 August 2012 + +*/ + +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman <evbuilder@users.sourceforge.org> + * Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/timer.h> diff --git a/libopencm3/lib/stm32/f4/usart.c b/libopencm3/lib/stm32/f4/usart.c new file mode 100644 index 0000000..06254c9 --- /dev/null +++ b/libopencm3/lib/stm32/f4/usart.c @@ -0,0 +1,31 @@ +/** @defgroup usart_file USART + +@ingroup STM32F4xx + +@brief <b>libopencm3 STM32F4xx USART</b> + +@version 1.0.0 + +@date 30 August 2012 + +LGPL License Terms @ref lgpl_license +*/ + +/* + * This file is part of the libopencm3 project. + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/stm32/usart.h> diff --git a/libopencm3/lib/stm32/f4/vector_chipset.c b/libopencm3/lib/stm32/f4/vector_chipset.c new file mode 100644 index 0000000..145be05 --- /dev/null +++ b/libopencm3/lib/stm32/f4/vector_chipset.c @@ -0,0 +1,27 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net> + * Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com> + * + * This library is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This library 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <libopencm3/cm3/scb.h> + +static void pre_main(void) +{ + /* Enable access to Floating-Point coprocessor. */ + SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11); +} |