From b3a710b0bcc8e765b32cc255dc5047323933d22e Mon Sep 17 00:00:00 2001 From: Stephen Caudle Date: Fri, 28 Oct 2011 15:44:29 -0400 Subject: Rename stm32 lib folders to be consistent with include --- lib/stm32/f1/Makefile | 61 +++ lib/stm32/f1/adc.c | 375 +++++++++++++++ lib/stm32/f1/can.c | 303 ++++++++++++ lib/stm32/f1/dma.c | 543 ++++++++++++++++++++++ lib/stm32/f1/ethernet.c | 53 +++ lib/stm32/f1/exti.c | 145 ++++++ lib/stm32/f1/flash.c | 189 ++++++++ lib/stm32/f1/gpio.c | 118 +++++ lib/stm32/f1/libopencm3_stm32f1.ld | 63 +++ lib/stm32/f1/rcc.c | 677 +++++++++++++++++++++++++++ lib/stm32/f1/rtc.c | 282 ++++++++++++ lib/stm32/f1/scb.c | 30 ++ lib/stm32/f1/timer.c | 914 +++++++++++++++++++++++++++++++++++++ lib/stm32/f1/vector.c | 296 ++++++++++++ lib/stm32/f2/Makefile | 59 +++ lib/stm32/f2/exti.c | 146 ++++++ lib/stm32/f2/flash.c | 250 ++++++++++ lib/stm32/f2/gpio.c | 139 ++++++ lib/stm32/f2/libopencm3_stm32f2.ld | 63 +++ lib/stm32/f2/rcc.c | 412 +++++++++++++++++ lib/stm32/f2/vector.c | 336 ++++++++++++++ lib/stm32/i2c.c | 93 ++++ lib/stm32/nvic.c | 106 +++++ lib/stm32/spi.c | 298 ++++++++++++ lib/stm32/systick.c | 64 +++ lib/stm32/usart.c | 128 ++++++ lib/stm32_common/i2c.c | 93 ---- lib/stm32_common/nvic.c | 106 ----- lib/stm32_common/spi.c | 298 ------------ lib/stm32_common/systick.c | 64 --- lib/stm32_common/usart.c | 128 ------ lib/stm32f1/Makefile | 61 --- lib/stm32f1/adc.c | 375 --------------- lib/stm32f1/can.c | 303 ------------ lib/stm32f1/dma.c | 543 ---------------------- lib/stm32f1/ethernet.c | 53 --- lib/stm32f1/exti.c | 145 ------ lib/stm32f1/flash.c | 189 -------- lib/stm32f1/gpio.c | 118 ----- lib/stm32f1/libopencm3_stm32f1.ld | 63 --- lib/stm32f1/rcc.c | 677 --------------------------- lib/stm32f1/rtc.c | 282 ------------ lib/stm32f1/scb.c | 30 -- lib/stm32f1/timer.c | 914 ------------------------------------- lib/stm32f1/vector.c | 296 ------------ lib/stm32f2/Makefile | 59 --- lib/stm32f2/exti.c | 146 ------ lib/stm32f2/flash.c | 250 ---------- lib/stm32f2/gpio.c | 139 ------ lib/stm32f2/libopencm3_stm32f2.ld | 63 --- lib/stm32f2/rcc.c | 412 ----------------- lib/stm32f2/vector.c | 336 -------------- 52 files changed, 6143 insertions(+), 6143 deletions(-) create mode 100644 lib/stm32/f1/Makefile create mode 100644 lib/stm32/f1/adc.c create mode 100644 lib/stm32/f1/can.c create mode 100644 lib/stm32/f1/dma.c create mode 100644 lib/stm32/f1/ethernet.c create mode 100644 lib/stm32/f1/exti.c create mode 100644 lib/stm32/f1/flash.c create mode 100644 lib/stm32/f1/gpio.c create mode 100644 lib/stm32/f1/libopencm3_stm32f1.ld create mode 100644 lib/stm32/f1/rcc.c create mode 100644 lib/stm32/f1/rtc.c create mode 100644 lib/stm32/f1/scb.c create mode 100644 lib/stm32/f1/timer.c create mode 100644 lib/stm32/f1/vector.c create mode 100644 lib/stm32/f2/Makefile create mode 100644 lib/stm32/f2/exti.c create mode 100644 lib/stm32/f2/flash.c create mode 100644 lib/stm32/f2/gpio.c create mode 100644 lib/stm32/f2/libopencm3_stm32f2.ld create mode 100644 lib/stm32/f2/rcc.c create mode 100644 lib/stm32/f2/vector.c create mode 100644 lib/stm32/i2c.c create mode 100644 lib/stm32/nvic.c create mode 100644 lib/stm32/spi.c create mode 100644 lib/stm32/systick.c create mode 100644 lib/stm32/usart.c delete mode 100644 lib/stm32_common/i2c.c delete mode 100644 lib/stm32_common/nvic.c delete mode 100644 lib/stm32_common/spi.c delete mode 100644 lib/stm32_common/systick.c delete mode 100644 lib/stm32_common/usart.c delete mode 100644 lib/stm32f1/Makefile delete mode 100644 lib/stm32f1/adc.c delete mode 100644 lib/stm32f1/can.c delete mode 100644 lib/stm32f1/dma.c delete mode 100644 lib/stm32f1/ethernet.c delete mode 100644 lib/stm32f1/exti.c delete mode 100644 lib/stm32f1/flash.c delete mode 100644 lib/stm32f1/gpio.c delete mode 100644 lib/stm32f1/libopencm3_stm32f1.ld delete mode 100644 lib/stm32f1/rcc.c delete mode 100644 lib/stm32f1/rtc.c delete mode 100644 lib/stm32f1/scb.c delete mode 100644 lib/stm32f1/timer.c delete mode 100644 lib/stm32f1/vector.c delete mode 100644 lib/stm32f2/Makefile delete mode 100644 lib/stm32f2/exti.c delete mode 100644 lib/stm32f2/flash.c delete mode 100644 lib/stm32f2/gpio.c delete mode 100644 lib/stm32f2/libopencm3_stm32f2.ld delete mode 100644 lib/stm32f2/rcc.c delete mode 100644 lib/stm32f2/vector.c diff --git a/lib/stm32/f1/Makefile b/lib/stm32/f1/Makefile new file mode 100644 index 0000000..bd9fca2 --- /dev/null +++ b/lib/stm32/f1/Makefile @@ -0,0 +1,61 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 . +## + +LIBNAME = libopencm3_stm32f1 + +PREFIX ?= arm-none-eabi +#PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \ + -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F1 +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = vector.o rcc.o gpio.o usart.o adc.o spi.o flash.o nvic.o \ + rtc.o i2c.o dma.o systick.o exti.o scb.o ethernet.o \ + usb_f103.o usb.o usb_control.o usb_standard.o can.o \ + timer.o usb_f107.o + +VPATH += ../usb:../stm32_common + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +endif + +all: $(LIBNAME).a + +$(LIBNAME).a: $(OBJS) + @printf " AR $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(AR) $(ARFLAGS) $@ $^ + +%.o: %.c + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS) -o $@ -c $< + +clean: + @printf " CLEAN lib/stm32f1\n" + $(Q)rm -f *.o *.d + $(Q)rm -f $(LIBNAME).a + +.PHONY: clean + +-include $(OBJS:.o=.d) + diff --git a/lib/stm32/f1/adc.c b/lib/stm32/f1/adc.c new file mode 100644 index 0000000..31e4cbf --- /dev/null +++ b/lib/stm32/f1/adc.c @@ -0,0 +1,375 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Edward Cheeseman + * + * 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 . + */ + +/* + * Basic ADC handling API. + * + * Examples: + * rcc_peripheral_enable_clock(&RCC_APB2ENR, ADC1EN); + * rcc_peripheral_disable_clock(&RCC_APB2ENR, ADC1EN); + * rcc_peripheral_reset(&RCC_APB2RSTR, ADC1RST); + * rcc_peripheral_clear_reset(&RCC_APB2RSTR, ADC1RST); + * + * rcc_set_adc_clk(ADC_PRE_PLCK2_DIV2); + * adc_set_mode(ADC1, TODO); + * reg16 = adc_read(ADC1, ADC_CH_0); + */ + +#include + +void rcc_set_adc_clk(u32 prescaler) +{ + /* TODO */ + + /* FIXME: QUICK HACK to prevent compiler warnings. */ + prescaler = prescaler; +} + +void adc_set_mode(u32 block, /* TODO */ u8 mode) +{ + /* TODO */ + + /* FIXME: QUICK HACK to prevent compiler warnings. */ + block = block; + mode = mode; +} + +void adc_read(u32 block, u32 channel) +{ + /* TODO */ + + /* FIXME: QUICK HACK to prevent compiler warnings. */ + block = block; + channel = channel; +} + +void adc_enable_analog_watchdog_regular(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_AWDEN; +} + +void adc_disable_analog_watchdog_regular(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_AWDEN; +} + +void adc_enable_analog_watchdog_injected(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_JAWDEN; +} + +void adc_disable_analog_watchdog_injected(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JAWDEN; +} + +void adc_enable_discontinous_mode_regular(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_DISCEN; +} + +void adc_disable_discontinous_mode_regular(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_DISCEN; +} + +void adc_enable_discontinous_mode_injected(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_JDISCEN; +} + +void adc_disable_discontinous_mode_injected(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JDISCEN; +} + +void adc_enable_automatic_injected_group_conversion(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_JAUTO; +} + +void adc_disable_automatic_injected_group_conversion(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JAUTO; +} + +void adc_enable_analog_watchdog_on_all_channels(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_AWDSGL; +} + +void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel) +{ + u32 reg32; + + reg32 = (ADC_CR1(adc) & 0xffffffe0); /* Clear bits [4:0]. */ + if (channel < 18) + reg32 |= channel; + ADC_CR1(adc) = reg32; + ADC_CR1(adc) &= ~ADC_CR1_AWDSGL; +} + +void adc_enable_scan_mode(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_SCAN; +} + +void adc_disable_scan_mode(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_SCAN; +} + +void adc_enable_jeoc_interrupt(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_JEOCIE; +} + +void adc_disable_jeoc_interrupt(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_JEOCIE; +} + +void adc_enable_awd_interrupt(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_AWDIE; +} + +void adc_disable_awd_interrupt(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_AWDIE; +} + +void adc_enable_eoc_interrupt(u32 adc) +{ + ADC_CR1(adc) |= ADC_CR1_EOCIE; +} + +void adc_disable_eoc_interrupt(u32 adc) +{ + ADC_CR1(adc) &= ~ADC_CR1_EOCIE; +} + +void adc_enable_temperature_sensor(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_TSVREFE; +} + +void adc_disable_temperature_sensor(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_TSVREFE; +} + +void adc_start_conversion_regular(u32 adc) +{ + /* start conversion on regular channels */ + ADC_CR2(adc) |= ADC_CR2_SWSTART; + + /* wait til the ADC starts the conversion */ + while (ADC_CR2(adc) & ADC_CR2_SWSTART); +} + +void adc_start_conversion_injected(u32 adc) +{ + /* start conversion on injected channels */ + ADC_CR2(adc) |= ADC_CR2_JSWSTART; + + /* wait til the ADC starts the conversion */ + while (ADC_CR2(adc) & ADC_CR2_JSWSTART); +} + +void adc_enable_external_trigger_regular(u32 adc, u8 trigger) +{ + u32 reg32; + + reg32 = (ADC_CR2(adc) & 0xfff1ffff); /* Clear bits [19:17]. */ + if (trigger < 8) + reg32 |= (trigger << ADC_CR2_EXTSEL_LSB); + ADC_CR2(adc) = reg32; + ADC_CR2(adc) |= ADC_CR2_EXTTRIG; +} + +void adc_disable_external_trigger_regular(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_EXTTRIG; +} + +void adc_enable_external_trigger_injected(u32 adc, u8 trigger) +{ + u32 reg32; + + reg32 = (ADC_CR2(adc) & 0xffff8fff); /* Clear bits [12:14]. */ + if (trigger < 8) + reg32 |= (trigger << ADC_CR2_JEXTSEL_LSB); + ADC_CR2(adc) = reg32; + ADC_CR2(adc) |= ADC_CR2_JEXTTRIG; +} + +void adc_disable_external_trigger_injected(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_JEXTTRIG; +} + +void adc_set_left_aligned(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_ALIGN; +} + +void adc_set_right_aligned(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_ALIGN; +} + +void adc_enable_dma(u32 adc) +{ + if ((adc == ADC1) | (adc==ADC3)) + ADC_CR2(adc) |= ADC_CR2_DMA; +} + +void adc_disable_dma(u32 adc) +{ + if ((adc == ADC1) | (adc==ADC3)) + ADC_CR2(adc) &= ~ADC_CR2_DMA; +} + +void adc_reset_calibration(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_RSTCAL; + while (ADC_CR2(adc) & ADC_CR2_RSTCAL); +} + +void adc_calibration(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_CAL; + while (ADC_CR2(adc) & ADC_CR2_CAL); +} + +void adc_set_continous_conversion_mode(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_CONT; +} + +void adc_set_single_conversion_mode(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_CONT; +} + +void adc_on(u32 adc) +{ + ADC_CR2(adc) |= ADC_CR2_ADON; +} + +void adc_off(u32 adc) +{ + ADC_CR2(adc) &= ~ADC_CR2_ADON; +} + +void adc_set_conversion_time(u32 adc, u8 channel, u8 time) +{ + u32 reg32; + + if (channel < 10) { + reg32 = ADC_SMPR2(adc); + reg32 &= ~(0b111 << (channel * 3)); + reg32 |= (time << (channel * 3)); + ADC_SMPR2(adc) = reg32; + } + else { + reg32 = ADC_SMPR1(adc); + reg32 &= ~(0b111 << ((channel-10) * 3)); + reg32 |= (time << ((channel-10) * 3)); + ADC_SMPR1(adc) = reg32; + } +} + +void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) +{ + u32 reg32 = 0; + u8 i; + + 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; +} + +void adc_set_watchdog_high_threshold(u32 adc, u16 threshold) +{ + u32 reg32 = 0; + + reg32 = (u32)threshold; + reg32 &= ~0xfffff000; /* clear all bits above 11 */ + ADC_HTR(adc) = reg32; +} + +void adc_set_watchdog_low_threshold(u32 adc, u16 threshold) +{ + u32 reg32 = 0; + + reg32 = (u32)threshold; + reg32 &= ~0xfffff000; /* clear all bits above 11 */ + ADC_LTR(adc) = reg32; +} + +void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]) +{ + u32 reg32_1 = 0; + u32 reg32_2 = 0; + u32 reg32_3 = 0; + u8 i = 0; + + /* maximum sequence length is 16 channels */ + if (length > 16) + return; + + for (i=1; i<=length; i++) { + if (i <= 6) + reg32_3 |= (channel[i-1] << ((i-1) * 5)); + if ((i > 6) & (i <= 12)) + reg32_2 |= (channel[i-1] << ((i-6-1) * 5)); + if ((i > 12) & (i <= 16)) + reg32_1 |= (channel[i-1] << ((i-12-1) * 5)); + } + reg32_1 |= ((length -1) << ADC_SQR1_L_LSB); + + ADC_SQR1(adc) = reg32_1; + ADC_SQR2(adc) = reg32_2; + ADC_SQR3(adc) = reg32_3; +} + +void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]) +{ + u32 reg32 = 0; + u8 i = 0; + + /* maximum sequence length is 4 channels */ + if (length > 4) + return; + + for (i = 1; i <= length; i++) { + reg32 |= (channel[i-1] << ((i-1) * 5)); + } + reg32 |= ((length-1) << ADC_JSQR_JL_LSB); + + ADC_JSQR(adc) = reg32; +} diff --git a/lib/stm32/f1/can.c b/lib/stm32/f1/can.c new file mode 100644 index 0000000..8c5d7ec --- /dev/null +++ b/lib/stm32/f1/can.c @@ -0,0 +1,303 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * + * 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 +#include + +void can_reset(u32 canport) +{ + if (canport == CAN1) { + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN1RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN1RST); + } else { + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN2RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN2RST); + } +} + +int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart, + bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp) +{ + u32 wait_ack = 0x00000000; + u32 can_msr_inak_timeout = 0x0000FFFF; + int ret = 0; + + /* Exit from sleep mode. */ + CAN_MCR(canport) &= ~CAN_MCR_SLEEP; + + /* Request initialization "enter". */ + CAN_MCR(canport) |= CAN_MCR_INRQ; + + /* Wait for acknowledge. */ + while ((wait_ack != can_msr_inak_timeout) && + ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)) { + wait_ack++; + } + + /* Check the acknowledge. */ + if ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK) + return 1; + + /* Set the automatic bus-off management. */ + if (ttcm) + CAN_MCR(canport) |= CAN_MCR_TTCM; + else + CAN_MCR(canport) &= ~CAN_MCR_TTCM; + + if (abom) + CAN_MCR(canport) |= CAN_MCR_ABOM; + else + CAN_MCR(canport) &= ~CAN_MCR_ABOM; + + if (awum) + CAN_MCR(canport) |= CAN_MCR_AWUM; + else + CAN_MCR(canport) &= ~CAN_MCR_AWUM; + + if (nart) + CAN_MCR(canport) |= CAN_MCR_NART; + else + CAN_MCR(canport) &= ~CAN_MCR_NART; + + if (rflm) + CAN_MCR(canport) |= CAN_MCR_RFLM; + else + CAN_MCR(canport) &= ~CAN_MCR_RFLM; + + if (txfp) + CAN_MCR(canport) |= CAN_MCR_TXFP; + else + CAN_MCR(canport) &= ~CAN_MCR_TXFP; + + /* Set bit timings. */ + CAN_BTR(canport) = sjw | ts2 | ts1 | + (u32)(CAN_BTR_BRP_MASK & (brp - 1)); + + /* Request initialization "leave". */ + CAN_MCR(canport) &= ~CAN_MCR_INRQ; + + /* Wait for acknowledge. */ + wait_ack = 0x00000000; + while ((wait_ack != can_msr_inak_timeout) && + ((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK)) { + wait_ack++; + } + + if ((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK) + ret = 1; + + return ret; +} + +void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode, + u32 fr1, u32 fr2, u32 fifo, bool enable) +{ + u32 filter_select_bit = 0x00000001 << nr; + + /* Request initialization "enter". */ + CAN_FMR(canport) |= CAN_FMR_FINIT; + + /* Deactivate the filter. */ + CAN_FA1R(canport) &= ~filter_select_bit; + + if (scale_32bit) { + /* Set 32-bit scale for the filter. */ + CAN_FS1R(canport) |= filter_select_bit; + } else { + /* Set 16-bit scale for the filter. */ + CAN_FS1R(canport) &= ~filter_select_bit; + } + + if (id_list_mode) { + /* Set filter mode to ID list mode. */ + CAN_FM1R(canport) |= filter_select_bit; + } else { + /* Set filter mode to id/mask mode. */ + CAN_FM1R(canport) &= ~filter_select_bit; + } + + /* Set the first filter register. */ + CAN_FiR1(canport, nr) = fr1; + + /* Set the second filter register. */ + CAN_FiR2(canport, nr) = fr2; + + /* Select FIFO0 or FIFO1 as filter assignement. */ + if (fifo) + CAN_FFA1R(canport) |= filter_select_bit; /* FIFO1 */ + else + CAN_FFA1R(canport) &= ~filter_select_bit; /* FIFO0 */ + + if (enable) + CAN_FA1R(canport) |= filter_select_bit; /* Activate filter. */ + + /* Request initialization "leave". */ + CAN_FMR(canport) &= ~CAN_FMR_FINIT; +} + +void can_filter_id_mask_16bit_init(u32 canport, u32 nr, u16 id1, u16 mask1, + u16 id2, u16 mask2, u32 fifo, bool enable) +{ + can_filter_init(canport, nr, false, false, + ((u32)id1 << 16) | (u32)mask1, + ((u32)id2 << 16) | (u32)mask2, fifo, enable); +} + +void can_filter_id_mask_32bit_init(u32 canport, u32 nr, u32 id, u32 mask, + u32 fifo, bool enable) +{ + can_filter_init(canport, nr, true, false, id, mask, fifo, enable); +} + +void can_filter_id_list_16bit_init(u32 canport, u32 nr, u16 id1, u16 id2, + u16 id3, u16 id4, u32 fifo, bool enable) +{ + can_filter_init(canport, nr, false, true, + ((u32)id1 << 16) | (u32)id2, + ((u32)id3 << 16) | (u32)id4, fifo, enable); +} + +void can_filter_id_list_32bit_init(u32 canport, u32 nr, u32 id1, u32 id2, + u32 fifo, bool enable) +{ + can_filter_init(canport, nr, true, true, id1, id2, fifo, enable); +} + +void can_enable_irq(u32 canport, u32 irq) +{ + CAN_IER(canport) |= irq; +} + +void can_disable_irq(u32 canport, u32 irq) +{ + CAN_IER(canport) &= ~irq; +} + +int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data) +{ + int ret = 0, i; + u32 mailbox = 0; + + if ((CAN_TSR(canport) & CAN_TSR_TME0) == CAN_TSR_TME0) { + ret = 0; + mailbox = CAN_MBOX0; + } else if ((CAN_TSR(canport) & CAN_TSR_TME1) == CAN_TSR_TME1) { + ret = 1; + mailbox = CAN_MBOX1; + } else if ((CAN_TSR(canport) & CAN_TSR_TME2) == CAN_TSR_TME2) { + ret = 2; + mailbox = CAN_MBOX2; + } else { + ret = -1; + } + + /* Check if we have an empty mailbox. */ + if (ret == -1) + return ret; + + /* Clear stale register bits */ + CAN_TIxR(canport, mailbox) = 0; + if (ext) { + /* Set extended ID. */ + CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_EXID_SHIFT; + /* Set extended ID indicator bit. */ + CAN_TIxR(canport, mailbox) |= CAN_TIxR_IDE; + } else { + /* Set standard ID. */ + CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_STID_SHIFT; + } + + /* Set/clear remote transmission request bit. */ + if (rtr) + CAN_TIxR(canport, mailbox) |= CAN_TIxR_RTR; /* Set */ + + /* Set the DLC. */ + CAN_TDTxR(canport, mailbox) &= 0xFFFFFFFF0; + CAN_TDTxR(canport, mailbox) |= length & CAN_TDTxR_DLC_MASK; + + /* Set the data. */ + CAN_TDLxR(canport, mailbox) = 0; + CAN_TDHxR(canport, mailbox) = 0; + for (i = 0; (i < 4) && (i < length); i++) + CAN_TDLxR(canport, mailbox) |= (u32)data[i] << (8 * i); + for (i = 4; (i < 8) && (i < length); i++) + CAN_TDHxR(canport, mailbox) |= (u32)data[i] << (8 * (i - 4)); + + /* Request transmission. */ + CAN_TIxR(canport, mailbox) |= CAN_TIxR_TXRQ; + + return ret; +} + +void can_fifo_release(u32 canport, u8 fifo) +{ + if (fifo == 0) + CAN_RF0R(canport) |= CAN_RF1R_RFOM1; + else + CAN_RF1R(canport) |= CAN_RF1R_RFOM1; +} + +void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext, + bool *rtr, u32 *fmi, u8 *length, u8 *data) +{ + u32 fifo_id = 0; + int i; + + if (fifo == 0) + fifo_id = CAN_FIFO0; + else + fifo_id = CAN_FIFO1; + + /* Get type of CAN ID and CAN ID. */ + if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_IDE) { + *ext = true; + /* Get extended CAN ID. */ + *id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_EXID_MASK) >> + CAN_RIxR_EXID_SHIFT); + } else { + *ext = false; + /* Get standard CAN ID. */ + *id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_STID_MASK) >> + CAN_RIxR_STID_SHIFT); + } + + /* Get request transmit flag. */ + if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_RTR) + *rtr = true; + else + *rtr = false; + + /* Get filter match ID. */ + *fmi = ((CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_FMI_MASK) > + CAN_RDTxR_FMI_SHIFT); + + /* Get data length. */ + *length = CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_DLC_MASK; + + /* Get data. */ + for (i = 0; (i < 4) && (i < *length); i++) + data[i] = (CAN_RDLxR(canport, fifo_id) >> (8 * i)) & 0xFF; + + for (i = 4; (i < 8) && (i < *length); i++) + data[i] = (CAN_RDHxR(canport, fifo_id) >> (8 * (i - 4))) & 0xFF; + + /* Release the FIFO. */ + if (release) + can_fifo_release(CAN1, 0); +} diff --git a/lib/stm32/f1/dma.c b/lib/stm32/f1/dma.c new file mode 100644 index 0000000..4f0af6f --- /dev/null +++ b/lib/stm32/f1/dma.c @@ -0,0 +1,543 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * 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 + +void dma_enable_mem2mem_mode(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) |= DMA_CCR1_MEM2MEM; + DMA_CCR1(dma) &= ~DMA_CCR1_CIRC; + case 2: + DMA_CCR2(dma) |= DMA_CCR2_MEM2MEM; + DMA_CCR2(dma) &= ~DMA_CCR2_CIRC; + case 3: + DMA_CCR3(dma) |= DMA_CCR3_MEM2MEM; + DMA_CCR3(dma) &= ~DMA_CCR3_CIRC; + case 4: + DMA_CCR4(dma) |= DMA_CCR4_MEM2MEM; + DMA_CCR4(dma) &= ~DMA_CCR4_CIRC; + case 5: + DMA_CCR5(dma) |= DMA_CCR5_MEM2MEM; + DMA_CCR5(dma) &= ~DMA_CCR5_CIRC; + case 6: + if (dma == DMA1) { + DMA_CCR6(dma) |= DMA_CCR6_MEM2MEM; + DMA_CCR6(dma) &= ~DMA_CCR6_CIRC; + } + case 7: + if (dma == DMA1) { + DMA_CCR7(dma) |= DMA_CCR7_MEM2MEM; + DMA_CCR7(dma) &= ~DMA_CCR7_CIRC; + } + } +} + + + + +void dma_set_priority(u32 dma, u8 channel, u8 prio) +{ + /* parameter check */ + if (prio > 3) + return; + + switch (channel) + { + case 1: + DMA_CCR1(dma) &= ~(0x3 << DMA_CCR1_PL_LSB); + DMA_CCR1(dma) |= (prio << DMA_CCR1_PL_LSB); + case 2: + DMA_CCR2(dma) &= ~(0x3 << DMA_CCR2_PL_LSB); + DMA_CCR2(dma) |= (prio << DMA_CCR2_PL_LSB); + case 3: + DMA_CCR3(dma) &= ~(0x3 << DMA_CCR3_PL_LSB); + DMA_CCR3(dma) |= (prio << DMA_CCR3_PL_LSB); + case 4: + DMA_CCR4(dma) &= ~(0x3 << DMA_CCR4_PL_LSB); + DMA_CCR4(dma) |= (prio << DMA_CCR4_PL_LSB); + case 5: + DMA_CCR5(dma) &= ~(0x3 << DMA_CCR5_PL_LSB); + DMA_CCR5(dma) |= (prio << DMA_CCR5_PL_LSB); + case 6: + if (dma == DMA1) { + DMA_CCR6(dma) &= ~(0x3 << DMA_CCR6_PL_LSB); + DMA_CCR6(dma) |= (prio << DMA_CCR6_PL_LSB); + } + case 7: + if (dma == DMA1) { + DMA_CCR7(dma) &= ~(0x3 << DMA_CCR7_PL_LSB); + DMA_CCR7(dma) |= (prio << DMA_CCR7_PL_LSB); + } + } +} + +void dma_set_memory_size(u32 dma, u8 channel, u8 mem_size) +{ + /* parameter check */ + if (mem_size > 2) + return; + + switch (channel) + { + case 1: + DMA_CCR1(dma) &= ~(0x3 << DMA_CCR1_MSIZE_LSB); + DMA_CCR1(dma) |= (mem_size << DMA_CCR1_MSIZE_LSB); + case 2: + DMA_CCR2(dma) &= ~(0x3 << DMA_CCR2_MSIZE_LSB); + DMA_CCR2(dma) |= (mem_size << DMA_CCR2_MSIZE_LSB); + case 3: + DMA_CCR3(dma) &= ~(0x3 << DMA_CCR3_MSIZE_LSB); + DMA_CCR3(dma) |= (mem_size << DMA_CCR3_MSIZE_LSB); + case 4: + DMA_CCR4(dma) &= ~(0x3 << DMA_CCR4_MSIZE_LSB); + DMA_CCR4(dma) |= (mem_size << DMA_CCR4_MSIZE_LSB); + case 5: + DMA_CCR5(dma) &= ~(0x3 << DMA_CCR5_MSIZE_LSB); + DMA_CCR5(dma) |= (mem_size << DMA_CCR5_MSIZE_LSB); + case 6: + if (dma == DMA1) { + DMA_CCR6(dma) &= ~(0x3 << DMA_CCR6_MSIZE_LSB); + DMA_CCR6(dma) |= (mem_size << DMA_CCR6_MSIZE_LSB); + } + case 7: + if (dma == DMA1) { + DMA_CCR7(dma) &= ~(0x3 << DMA_CCR7_MSIZE_LSB); + DMA_CCR7(dma) |= (mem_size << DMA_CCR7_MSIZE_LSB); + } + } +} + + + +void dma_set_peripheral_size(u32 dma, u8 channel, u8 peripheral_size) +{ + /* parameter check */ + if (peripheral_size > 2) + return; + + switch (channel) + { + case 1: + DMA_CCR1(dma) &= ~(0x3 << DMA_CCR1_PSIZE_LSB); + DMA_CCR1(dma) |= (peripheral_size << DMA_CCR1_PSIZE_LSB); + case 2: + DMA_CCR2(dma) &= ~(0x3 << DMA_CCR2_PSIZE_LSB); + DMA_CCR2(dma) |= (peripheral_size << DMA_CCR2_PSIZE_LSB); + case 3: + DMA_CCR3(dma) &= ~(0x3 << DMA_CCR3_PSIZE_LSB); + DMA_CCR3(dma) |= (peripheral_size << DMA_CCR3_PSIZE_LSB); + case 4: + DMA_CCR4(dma) &= ~(0x3 << DMA_CCR4_PSIZE_LSB); + DMA_CCR4(dma) |= (peripheral_size << DMA_CCR4_PSIZE_LSB); + case 5: + DMA_CCR5(dma) &= ~(0x3 << DMA_CCR5_PSIZE_LSB); + DMA_CCR5(dma) |= (peripheral_size << DMA_CCR5_PSIZE_LSB); + case 6: + if (dma == DMA1) { + DMA_CCR6(dma) &= ~(0x3 << DMA_CCR6_PSIZE_LSB); + DMA_CCR6(dma) |= (peripheral_size << DMA_CCR6_PSIZE_LSB); + } + case 7: + if (dma == DMA1) { + DMA_CCR7(dma) &= ~(0x3 << DMA_CCR7_PSIZE_LSB); + DMA_CCR7(dma) |= (peripheral_size << DMA_CCR7_PSIZE_LSB); + } + } +} + + +void dma_enable_memory_increment_mode(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) |= DMA_CCR1_MINC; + case 2: + DMA_CCR2(dma) |= DMA_CCR2_MINC; + case 3: + DMA_CCR3(dma) |= DMA_CCR3_MINC; + case 4: + DMA_CCR4(dma) |= DMA_CCR4_MINC; + case 5: + DMA_CCR5(dma) |= DMA_CCR5_MINC; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) |= DMA_CCR6_MINC; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) |= DMA_CCR7_MINC; + } +} + +void dma_enable_peripheral_increment_mode(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) |= DMA_CCR1_PINC; + case 2: + DMA_CCR2(dma) |= DMA_CCR2_PINC; + case 3: + DMA_CCR3(dma) |= DMA_CCR3_PINC; + case 4: + DMA_CCR4(dma) |= DMA_CCR4_PINC; + case 5: + DMA_CCR5(dma) |= DMA_CCR5_PINC; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) |= DMA_CCR6_PINC; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) |= DMA_CCR7_PINC; + } +} + +void dma_enable_circular_mode(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) |= DMA_CCR1_CIRC; + DMA_CCR1(dma) &= ~DMA_CCR1_MEM2MEM; + case 2: + DMA_CCR2(dma) |= DMA_CCR2_CIRC; + DMA_CCR2(dma) &= ~DMA_CCR2_MEM2MEM; + case 3: + DMA_CCR3(dma) |= DMA_CCR3_CIRC; + DMA_CCR3(dma) &= ~DMA_CCR3_MEM2MEM; + case 4: + DMA_CCR4(dma) |= DMA_CCR4_CIRC; + DMA_CCR4(dma) &= ~DMA_CCR4_MEM2MEM; + case 5: + DMA_CCR5(dma) |= DMA_CCR5_CIRC; + DMA_CCR5(dma) &= ~DMA_CCR5_MEM2MEM; + case 6: + if (dma == DMA1) { + DMA_CCR6(dma) |= DMA_CCR6_CIRC; + DMA_CCR6(dma) &= ~DMA_CCR6_MEM2MEM; + } + case 7: + if (dma == DMA1) { + DMA_CCR7(dma) |= DMA_CCR7_CIRC; + DMA_CCR7(dma) &= ~DMA_CCR7_MEM2MEM; + } + } +} + +void dma_set_read_from_peripheral(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) &= ~DMA_CCR1_DIR; + case 2: + DMA_CCR2(dma) &= ~DMA_CCR2_DIR; + case 3: + DMA_CCR3(dma) &= ~DMA_CCR3_DIR; + case 4: + DMA_CCR4(dma) &= ~DMA_CCR4_DIR; + case 5: + DMA_CCR5(dma) &= ~DMA_CCR5_DIR; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) &= ~DMA_CCR6_DIR; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) &= ~DMA_CCR7_DIR; + } +} + +void dma_set_read_from_memory(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) |= DMA_CCR1_DIR; + case 2: + DMA_CCR2(dma) |= DMA_CCR2_DIR; + case 3: + DMA_CCR3(dma) |= DMA_CCR3_DIR; + case 4: + DMA_CCR4(dma) |= DMA_CCR4_DIR; + case 5: + DMA_CCR5(dma) |= DMA_CCR5_DIR; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) |= DMA_CCR6_DIR; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) |= DMA_CCR7_DIR; + } +} + +void dma_enable_transfer_error_interrupt(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) |= DMA_CCR1_TEIE; + case 2: + DMA_CCR2(dma) |= DMA_CCR2_TEIE; + case 3: + DMA_CCR3(dma) |= DMA_CCR3_TEIE; + case 4: + DMA_CCR4(dma) |= DMA_CCR4_TEIE; + case 5: + DMA_CCR5(dma) |= DMA_CCR5_TEIE; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) |= DMA_CCR6_TEIE; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) |= DMA_CCR7_TEIE; + } +} + +void dma_disable_transfer_error_interrupt(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) &= ~DMA_CCR1_TEIE; + case 2: + DMA_CCR2(dma) &= ~DMA_CCR2_TEIE; + case 3: + DMA_CCR3(dma) &= ~DMA_CCR3_TEIE; + case 4: + DMA_CCR4(dma) &= ~DMA_CCR4_TEIE; + case 5: + DMA_CCR5(dma) &= ~DMA_CCR5_TEIE; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) &= ~DMA_CCR6_TEIE; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) &= ~DMA_CCR7_TEIE; + } +} + +void dma_enable_half_transfer_interrupt(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) |= DMA_CCR1_HTIE; + case 2: + DMA_CCR2(dma) |= DMA_CCR2_HTIE; + case 3: + DMA_CCR3(dma) |= DMA_CCR3_HTIE; + case 4: + DMA_CCR4(dma) |= DMA_CCR4_HTIE; + case 5: + DMA_CCR5(dma) |= DMA_CCR5_HTIE; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) |= DMA_CCR6_HTIE; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) |= DMA_CCR7_HTIE; + } +} + +void dma_disable_half_transfer_interrupt(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) &= ~DMA_CCR1_HTIE; + case 2: + DMA_CCR2(dma) &= ~DMA_CCR2_HTIE; + case 3: + DMA_CCR3(dma) &= ~DMA_CCR3_HTIE; + case 4: + DMA_CCR4(dma) &= ~DMA_CCR4_HTIE; + case 5: + DMA_CCR5(dma) &= ~DMA_CCR5_HTIE; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) &= ~DMA_CCR6_HTIE; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) &= ~DMA_CCR7_HTIE; + } +} + +void dma_enable_transfer_complete_interrupt(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) |= DMA_CCR1_TCIE; + case 2: + DMA_CCR2(dma) |= DMA_CCR2_TCIE; + case 3: + DMA_CCR3(dma) |= DMA_CCR3_TCIE; + case 4: + DMA_CCR4(dma) |= DMA_CCR4_TCIE; + case 5: + DMA_CCR5(dma) |= DMA_CCR5_TCIE; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) |= DMA_CCR6_TCIE; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) |= DMA_CCR7_TCIE; + } +} + +void dma_disable_transfer_complete_interrupt(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) &= ~DMA_CCR1_TCIE; + case 2: + DMA_CCR2(dma) &= ~DMA_CCR2_TCIE; + case 3: + DMA_CCR3(dma) &= ~DMA_CCR3_TCIE; + case 4: + DMA_CCR4(dma) &= ~DMA_CCR4_TCIE; + case 5: + DMA_CCR5(dma) &= ~DMA_CCR5_TCIE; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) &= ~DMA_CCR6_TCIE; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) &= ~DMA_CCR7_TCIE; + } +} + +void dma_enable_channel(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) |= DMA_CCR1_EN; + case 2: + DMA_CCR2(dma) |= DMA_CCR2_EN; + case 3: + DMA_CCR3(dma) |= DMA_CCR3_EN; + case 4: + DMA_CCR4(dma) |= DMA_CCR4_EN; + case 5: + DMA_CCR5(dma) |= DMA_CCR5_EN; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) |= DMA_CCR6_EN; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) |= DMA_CCR7_EN; + } +} + +void dma_disable_channel(u32 dma, u8 channel) +{ + switch (channel) + { + case 1: + DMA_CCR1(dma) &= ~DMA_CCR1_EN; + case 2: + DMA_CCR2(dma) &= ~DMA_CCR2_EN; + case 3: + DMA_CCR3(dma) &= ~DMA_CCR3_EN; + case 4: + DMA_CCR4(dma) &= ~DMA_CCR4_EN; + case 5: + DMA_CCR5(dma) &= ~DMA_CCR5_EN; + case 6: + if (dma == DMA1) + DMA_CCR6(dma) &= ~DMA_CCR6_EN; + case 7: + if (dma == DMA1) + DMA_CCR7(dma) &= ~DMA_CCR7_EN; + } +} + +void dma_set_peripheral_address(u32 dma, u8 channel, u32 address) +{ + switch (channel) + { + case 1: + DMA_CPAR1(dma) = (u32)address; + case 2: + DMA_CPAR2(dma) = (u32)address; + case 3: + DMA_CPAR3(dma) = (u32)address; + case 4: + DMA_CPAR4(dma) = (u32)address; + case 5: + DMA_CPAR5(dma) = (u32)address; + case 6: + if (dma == DMA1) + DMA_CPAR6(dma) = (u32)address; + case 7: + if (dma == DMA1) + DMA_CPAR7(dma) = (u32)address; + } +} + +void dma_set_memory_address(u32 dma, u8 channel, u32 address) +{ + switch (channel) + { + case 1: + DMA_CMAR1(dma) = (u32)address; + case 2: + DMA_CMAR2(dma) = (u32)address; + case 3: + DMA_CMAR3(dma) = (u32)address; + case 4: + DMA_CMAR4(dma) = (u32)address; + case 5: + DMA_CMAR5(dma) = (u32)address; + case 6: + if (dma == DMA1) + DMA_CMAR6(dma) = (u32)address; + case 7: + if (dma == DMA1) + DMA_CMAR7(dma) = (u32)address; + } +} + +void dma_set_number_of_data(u32 dma, u8 channel, u16 number) +{ + switch (channel) + { + case 1: + DMA_CNDTR1(dma) = number; + case 2: + DMA_CNDTR2(dma) = number; + case 3: + DMA_CNDTR3(dma) = number; + case 4: + DMA_CNDTR4(dma) = number; + case 5: + DMA_CNDTR5(dma) = number; + case 6: + if (dma == DMA1) + DMA_CNDTR6(dma) = number; + case 7: + if (dma == DMA1) + DMA_CNDTR7(dma) = number; + } +} diff --git a/lib/stm32/f1/ethernet.c b/lib/stm32/f1/ethernet.c new file mode 100644 index 0000000..fc65ec2 --- /dev/null +++ b/lib/stm32/f1/ethernet.c @@ -0,0 +1,53 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * 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 + +void eth_smi_write(u8 phy, u8 reg, u16 data) +{ + /* Set PHY and register addresses for write access. */ + ETH_MACMIIAR &= ~(ETH_MACMIIAR_MR | ETH_MACMIIAR_PA); + ETH_MACMIIAR |= (phy << 11) | (reg << 6) | ETH_MACMIIAR_MW; + + /* Set register value. */ + ETH_MACMIIDR = data; + + /* Begin transaction. */ + ETH_MACMIIAR |= ETH_MACMIIAR_MB; + + /* Wait for not busy. */ + while (ETH_MACMIIAR & ETH_MACMIIAR_MB); +} + +u16 eth_smi_read(u8 phy, u8 reg) +{ + /* Set PHY and register addresses for write access. */ + ETH_MACMIIAR &= ~(ETH_MACMIIAR_MR | ETH_MACMIIAR_PA | + ETH_MACMIIAR_MW); + ETH_MACMIIAR |= (phy << 11) | (reg << 6); + + /* Begin transaction. */ + ETH_MACMIIAR |= ETH_MACMIIAR_MB; + + /* Wait for not busy. */ + while (ETH_MACMIIAR & ETH_MACMIIAR_MB); + + /* Set register value. */ + return (u16)(ETH_MACMIIDR); +} diff --git a/lib/stm32/f1/exti.c b/lib/stm32/f1/exti.c new file mode 100644 index 0000000..e4e9748 --- /dev/null +++ b/lib/stm32/f1/exti.c @@ -0,0 +1,145 @@ +/* + * This file is part of the libopencm3 project. + * + * 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 +#include + +void exti_set_trigger(u32 extis, exti_trigger_type trig) +{ + switch (trig) { + case EXTI_TRIGGER_RISING: + EXTI_RTSR |= extis; + EXTI_FTSR &= ~extis; + break; + case EXTI_TRIGGER_FALLING: + EXTI_RTSR &= ~extis; + EXTI_FTSR |= extis; + break; + case EXTI_TRIGGER_BOTH: + EXTI_RTSR |= extis; + EXTI_FTSR |= extis; + break; + } +} + +void exti_enable_request(u32 extis) +{ + /* Enable interrupts. */ + EXTI_IMR |= extis; + + /* Enable events. */ + EXTI_EMR |= extis; +} + +void exti_disable_request(u32 extis) +{ + /* Disable interrupts. */ + EXTI_IMR &= ~extis; + + /* Disable events. */ + EXTI_EMR &= ~extis; +} + +/* + * Reset the interrupt request by writing a 1 to the corresponding + * pending bit register. + */ +void exti_reset_request(u32 extis) +{ + EXTI_PR |= extis; +} + +/* + * Remap an external interrupt line to the corresponding pin on the + * specified GPIO port. + * + * TODO: This could be rewritten in fewer lines of code. + */ +void exti_select_source(u32 exti, u32 gpioport) +{ + u8 shift, bits; + + shift = bits = 0; + + switch (exti) { + case EXTI0: + case EXTI4: + case EXTI8: + case EXTI12: + shift = 0; + break; + case EXTI1: + case EXTI5: + case EXTI9: + case EXTI13: + shift = 4; + break; + case EXTI2: + case EXTI6: + case EXTI10: + case EXTI14: + shift = 8; + break; + case EXTI3: + case EXTI7: + case EXTI11: + case EXTI15: + shift = 12; + break; + } + + switch (gpioport) { + case GPIOA: + bits = 0xf; + break; + case GPIOB: + bits = 0xe; + break; + case GPIOC: + bits = 0xd; + break; + case GPIOD: + bits = 0xc; + break; + case GPIOE: + bits = 0xb; + break; + case GPIOF: + bits = 0xa; + break; + case GPIOG: + bits = 0x9; + break; + } + + /* Ensure that only valid EXTI lines are used. */ + if (exti < EXTI4) { + AFIO_EXTICR1 &= ~(0x000F << shift); + AFIO_EXTICR1 |= (~bits << shift); + } else if (exti < EXTI8) { + AFIO_EXTICR2 &= ~(0x000F << shift); + AFIO_EXTICR2 |= (~bits << shift); + } else if (exti < EXTI12) { + AFIO_EXTICR3 &= ~(0x000F << shift); + AFIO_EXTICR3 |= (~bits << shift); + } else if (exti < EXTI16) { + AFIO_EXTICR4 &= ~(0x000F << shift); + AFIO_EXTICR4 |= (~bits << shift); + } +} diff --git a/lib/stm32/f1/flash.c b/lib/stm32/f1/flash.c new file mode 100644 index 0000000..b8b3d52 --- /dev/null +++ b/lib/stm32/f1/flash.c @@ -0,0 +1,189 @@ +/* + * 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 + +void flash_prefetch_buffer_enable(void) +{ + FLASH_ACR |= FLASH_PRFTBE; +} + +void flash_prefetch_buffer_disable(void) +{ + FLASH_ACR &= ~FLASH_PRFTBE; +} + +void flash_halfcycle_enable(void) +{ + FLASH_ACR |= FLASH_HLFCYA; +} + +void flash_halfcycle_disable(void) +{ + FLASH_ACR &= ~FLASH_HLFCYA; +} + +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_pgerr_flag(void) +{ + FLASH_SR |= FLASH_PGERR; +} + +void flash_clear_eop_flag(void) +{ + FLASH_SR |= FLASH_EOP; +} + +void flash_clear_wrprterr_flag(void) +{ + FLASH_SR |= FLASH_WRPRTERR; +} + +void flash_clear_bsy_flag(void) +{ + FLASH_SR &= ~FLASH_BSY; +} + +void flash_clear_status_flags(void) +{ + flash_clear_pgerr_flag(); + flash_clear_eop_flag(); + flash_clear_wrprterr_flag(); + flash_clear_bsy_flag(); +} + +void flash_unlock_option_bytes(void) +{ + FLASH_OPTKEYR = FLASH_KEY1; + FLASH_OPTKEYR = FLASH_KEY2; +} + +void flash_wait_for_last_operation(void) +{ + while ((FLASH_SR & FLASH_BSY) == FLASH_BSY) + ; +} + +void flash_program_word(u32 address, u32 data) +{ + /* Ensure that all flash operations are complete. */ + flash_wait_for_last_operation(); + + /* Enable writes to flash. */ + FLASH_CR |= FLASH_PG; + + /* Program the first half of the word. */ + (*(volatile u16 *)address) = (u16)data; + + /* Wait for the write to complete. */ + flash_wait_for_last_operation(); + + /* Program the second half of the word. */ + (*(volatile u16 *)(address + 2)) = data >> 16; + + /* 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) +{ + flash_wait_for_last_operation(); + + FLASH_CR |= FLASH_PG; + + (*(volatile u16 *)address) = data; + + flash_wait_for_last_operation(); + + FLASH_CR &= ~FLASH_PG; /* Disable the PG bit. */ +} + +void flash_erase_page(u32 page_address) +{ + flash_wait_for_last_operation(); + + FLASH_CR |= FLASH_PER; + FLASH_AR = page_address; + FLASH_CR |= FLASH_STRT; + + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_PER; +} + +void flash_erase_all_pages(void) +{ + flash_wait_for_last_operation(); + + 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_erase_option_bytes(void) +{ + flash_wait_for_last_operation(); + + if ((FLASH_CR & FLASH_OPTWRE) == 0) + flash_unlock_option_bytes(); + + FLASH_CR |= FLASH_OPTER; /* Enable option byte erase. */ + FLASH_CR |= FLASH_STRT; + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_OPTER; /* Disable option byte erase. */ +} + +void flash_program_option_bytes(u32 address, u16 data) +{ + flash_wait_for_last_operation(); + + if ((FLASH_CR & FLASH_OPTWRE) == 0) + flash_unlock_option_bytes(); + + FLASH_CR |= FLASH_OPTPG; /* Enable option byte programming. */ + (*(volatile u16 *)address) = data; + flash_wait_for_last_operation(); + FLASH_CR &= ~FLASH_OPTPG; /* Disable option byte programming. */ +} diff --git a/lib/stm32/f1/gpio.c b/lib/stm32/f1/gpio.c new file mode 100644 index 0000000..f1ea12c --- /dev/null +++ b/lib/stm32/f1/gpio.c @@ -0,0 +1,118 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * 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 . + */ + +/* + * Basic GPIO handling API. + * + * Examples: + * gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, + * GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); + * gpio_set(GPIOB, GPIO4); + * gpio_clear(GPIOG, GPIO2 | GPIO9); + * gpio_get(GPIOC, GPIO1); + * gpio_toggle(GPIOA, GPIO7 | GPIO8); + * reg16 = gpio_port_read(GPIOD); + * gpio_port_write(GPIOF, 0xc8fe); + * + * TODO: + * - GPIO remapping support + */ + +#include + +void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios) +{ + u16 i, offset = 0; + u32 crl = 0, crh = 0, tmp32 = 0; + + /* + * We want to set the config only for the pins mentioned in gpios, + * but keeping the others, so read out the actual config first. + */ + crl = GPIO_CRL(gpioport); + crh = GPIO_CRH(gpioport); + + /* Iterate over all bits, use i as the bitnumber. */ + for (i = 0; i < 16; i++) { + /* Only set the config if the bit is set in gpios. */ + if (!((1 << i) & gpios)) + continue; + + /* Calculate bit offset. */ + offset = (i < 8) ? (i * 4) : ((i - 8) * 4); + + /* Use tmp32 to either modify crl or crh. */ + tmp32 = (i < 8) ? crl : crh; + + /* Modify bits are needed. */ + tmp32 &= ~(0b1111 << offset); /* Clear the bits first. */ + tmp32 |= (mode << offset) | (cnf << (offset + 2)); + + /* Write tmp32 into crl or crh, leave the other unchanged. */ + crl = (i < 8) ? tmp32 : crl; + crh = (i >= 8) ? tmp32 : crh; + } + + GPIO_CRL(gpioport) = crl; + GPIO_CRH(gpioport) = crh; +} + +void gpio_set(u32 gpioport, u16 gpios) +{ + GPIO_BSRR(gpioport) = gpios; +} + +void gpio_clear(u32 gpioport, u16 gpios) +{ + GPIO_BRR(gpioport) = gpios; +} + +u16 gpio_get(u32 gpioport, u16 gpios) +{ + return gpio_port_read(gpioport) & gpios; +} + +void gpio_toggle(u32 gpioport, u16 gpios) +{ + GPIO_ODR(gpioport) ^= gpios; +} + +u16 gpio_port_read(u32 gpioport) +{ + return (u16)GPIO_IDR(gpioport); +} + +void gpio_port_write(u32 gpioport, u16 data) +{ + GPIO_ODR(gpioport) = data; +} + +void gpio_port_config_lock(u32 gpioport, u16 gpios) +{ + u32 reg32; + + /* Special "Lock Key Writing Sequence", see datasheet. */ + GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ + GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */ + GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ + reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */ + reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */ + + /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */ +} diff --git a/lib/stm32/f1/libopencm3_stm32f1.ld b/lib/stm32/f1/libopencm3_stm32f1.ld new file mode 100644 index 0000000..fda7d02 --- /dev/null +++ b/lib/stm32/f1/libopencm3_stm32f1.ld @@ -0,0 +1,63 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * 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 . + */ + +/* 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 sections. */ +SECTIONS +{ + . = ORIGIN(rom); + + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + *(.rodata*) /* Read-only data */ + _etext = .; + } >rom + + . = ORIGIN(ram); + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + _edata = .; + } >ram AT >rom + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + _ebss = .; + } >ram AT >rom + + /* + * 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) } + + end = .; +} + +PROVIDE(_stack = 0x20000800); + diff --git a/lib/stm32/f1/rcc.c b/lib/stm32/f1/rcc.c new file mode 100644 index 0000000..689cabb --- /dev/null +++ b/lib/stm32/f1/rcc.c @@ -0,0 +1,677 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * + * 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 +#include + +/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset */ +u32 rcc_ppre1_frequency = 8000000; +u32 rcc_ppre2_frequency = 8000000; + +void rcc_osc_ready_int_clear(osc_t 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(osc_t 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(osc_t 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(osc_t 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; + } + + /* Shouldn't be reached. */ + return -1; +} + +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(osc_t 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_osc_on(osc_t 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(osc_t 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(osc_t 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(osc_t 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_peripheral_enable_clock(volatile u32 *reg, u32 en) +{ + *reg |= en; +} + +void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en) +{ + *reg &= ~en; +} + +void rcc_peripheral_reset(volatile u32 *reg, u32 reset) +{ + *reg |= reset; +} + +void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset) +{ + *reg &= ~clear_reset; +} + +void rcc_set_sysclk_source(u32 clk) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | clk); +} + +void rcc_set_pll_multiplication_factor(u32 mul) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 21) | (1 << 20) | (1 << 19) | (1 << 18)); + RCC_CFGR = (reg32 | (mul << 18)); +} + +void rcc_set_pll_source(u32 pllsrc) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(1 << 16); + RCC_CFGR = (reg32 | (pllsrc << 16)); +} + +void rcc_set_pllxtpre(u32 pllxtpre) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(1 << 17); + RCC_CFGR = (reg32 | (pllxtpre << 17)); +} + +void rcc_set_adcpre(u32 adcpre) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 14) | (1 << 15)); + RCC_CFGR = (reg32 | (adcpre << 14)); +} + +void rcc_set_ppre2(u32 ppre2) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 11) | (1 << 12) | (1 << 13)); + RCC_CFGR = (reg32 | (ppre2 << 11)); +} + +void rcc_set_ppre1(u32 ppre1) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 8) | (1 << 9) | (1 << 10)); + RCC_CFGR = (reg32 | (ppre1 << 8)); +} + +void rcc_set_hpre(u32 hpre) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)); + RCC_CFGR = (reg32 | (hpre << 4)); +} + +void rcc_set_usbpre(u32 usbpre) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~(1 << 22); + RCC_CFGR = (reg32 | (usbpre << 22)); +} + +u32 rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return ((RCC_CFGR & 0x000c) >> 2); +} + +/* + * These functions are setting up the whole clock system for the most common + * input clock and output clock configurations. + */ +void rcc_clock_setup_in_hsi_out_64mhz(void) +{ + /* 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_SYSCLKSEL_HSICLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 64MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 8MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 32MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 64MHz Max. 72MHz */ + + /* + * Sysclk is running with 64MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_2WS); + + /* + * Set the PLL multiplication factor to 16. + * 8MHz (internal) * 16 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 64MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL16); + + /* Select HSI/2 as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ppre1_frequency = 32000000; + rcc_ppre2_frequency = 64000000; +} + +void rcc_clock_setup_in_hsi_out_48mhz(void) +{ + /* 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_SYSCLKSEL_HSICLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 48MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 6MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 24MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 48MHz Max. 72MHz */ + rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_CLK_NODIV); /* Set. 48MHz Max. 48MHz */ + + /* + * Sysclk runs with 48MHz -> 1 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_1WS); + + /* + * Set the PLL multiplication factor to 12. + * 8MHz (internal) * 12 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 48MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL12); + + /* Select HSI/2 as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ppre1_frequency = 24000000; + rcc_ppre2_frequency = 48000000; +} + +void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) +{ + /* 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_SYSCLKSEL_HSICLK); + + /* Enable external high-speed oscillator 8MHz. */ + rcc_osc_on(HSE); + rcc_wait_for_osc_ready(HSE); + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 24MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_NODIV); /* Set. 24MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 24MHz Max. 72MHz */ + + /* + * Sysclk runs with 24MHz -> 0 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_0WS); + + /* + * Set the PLL multiplication factor to 3. + * 8MHz (external) * 3 (multiplier) = 24MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL3); + + /* Select HSE as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); + + /* + * External frequency undivided before entering PLL + * (only valid/needed for HSE). + */ + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ppre1_frequency = 24000000; + rcc_ppre2_frequency = 24000000; +} +void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) +{ + /* 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_SYSCLKSEL_HSICLK); + + /* Enable external high-speed oscillator 8MHz. */ + rcc_osc_on(HSE); + rcc_wait_for_osc_ready(HSE); + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 9MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + + /* + * Sysclk runs with 72MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_2WS); + + /* + * Set the PLL multiplication factor to 9. + * 8MHz (external) * 9 (multiplier) = 72MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9); + + /* Select HSE as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); + + /* + * External frequency undivided before entering PLL + * (only valid/needed for HSE). + */ + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ppre1_frequency = 36000000; + rcc_ppre2_frequency = 72000000; +} + +void rcc_clock_setup_in_hse_12mhz_out_72mhz(void) +{ + /* 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_SYSCLKSEL_HSICLK); + + /* Enable external high-speed oscillator 16MHz. */ + rcc_osc_on(HSE); + rcc_wait_for_osc_ready(HSE); + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + + /* + * Sysclk runs with 72MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_2WS); + + /* + * Set the PLL multiplication factor to 9. + * 12MHz (external) * 6 (multiplier) / 1 (PLLXTPRE_HSE_CLK) = 72MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL6); + + /* Select HSI as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); + + /* + * Divide external frequency by 2 before entering PLL + * (only valid/needed for HSE). + */ + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ppre1_frequency = 36000000; + rcc_ppre2_frequency = 72000000; +} + +void rcc_clock_setup_in_hse_16mhz_out_72mhz(void) +{ + /* 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_SYSCLKSEL_HSICLK); + + /* Enable external high-speed oscillator 16MHz. */ + rcc_osc_on(HSE); + rcc_wait_for_osc_ready(HSE); + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ + + /* + * Sysclk runs with 72MHz -> 2 waitstates. + * 0WS from 0-24MHz + * 1WS from 24-48MHz + * 2WS from 48-72MHz + */ + flash_set_ws(FLASH_LATENCY_2WS); + + /* + * Set the PLL multiplication factor to 9. + * 16MHz (external) * 9 (multiplier) / 2 (PLLXTPRE_HSE_CLK_DIV2) = 72MHz + */ + rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9); + + /* Select HSI as PLL source. */ + rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); + + /* + * Divide external frequency by 2 before entering PLL + * (only valid/needed for HSE). + */ + rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* Select PLL as SYSCLK source. */ + rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); + + /* Set the peripheral clock frequencies used */ + rcc_ppre1_frequency = 36000000; + rcc_ppre2_frequency = 72000000; +} + +void rcc_backupdomain_reset(void) +{ + /* Set the backup domain software reset. */ + RCC_BDCR |= RCC_BDCR_BDRST; + + /* Clear the backup domain software reset. */ + RCC_BDCR &= ~RCC_BDCR_BDRST; +} diff --git a/lib/stm32/f1/rtc.c b/lib/stm32/f1/rtc.c new file mode 100644 index 0000000..c187be9 --- /dev/null +++ b/lib/stm32/f1/rtc.c @@ -0,0 +1,282 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Uwe Hermann + * Copyright (C) 2010 Lord James + * + * 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 +#include +#include + +void rtc_awake_from_off(osc_t clock_source) +{ + u32 reg32; + + /* Enable power and backup interface clocks. */ + RCC_APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); + + /* Enable access to the backup registers and the RTC. */ + PWR_CR |= PWR_CR_DBP; + + /* + * Reset the backup domain, clears everything RTC related. + * If not wanted use the rtc_awake_from_standby() function. + */ + rcc_backupdomain_reset(); + + switch (clock_source) { + case LSE: + /* Turn the LSE on and wait while it stabilises. */ + RCC_BDCR |= RCC_BDCR_LSEON; + while ((reg32 = (RCC_BDCR & RCC_BDCR_LSERDY)) == 0); + + /* Choose LSE as the RTC clock source. */ + RCC_BDCR &= ~((1 << 8) | (1 << 9)); + RCC_BDCR |= (1 << 8); + break; + case LSI: + /* Turn the LSI on and wait while it stabilises. */ + RCC_CSR |= RCC_CSR_LSION; + while ((reg32 = (RCC_CSR & RCC_CSR_LSIRDY)) == 0); + + /* Choose LSI as the RTC clock source. */ + RCC_BDCR &= ~((1 << 8) | (1 << 9)); + RCC_BDCR |= (1 << 9); + break; + case HSE: + /* Turn the HSE on and wait while it stabilises. */ + RCC_CR |= RCC_CR_HSEON; + while ((reg32 = (RCC_CR & RCC_CR_HSERDY)) == 0); + + /* Choose HSE as the RTC clock source. */ + RCC_BDCR &= ~((1 << 8) | (1 << 9)); + RCC_BDCR |= (1 << 9) | (1 << 8); + break; + case PLL: + case HSI: + /* Unusable clock source, here to prevent warnings. */ + /* Turn off clock sources to RTC. */ + RCC_BDCR &= ~((1 << 8) | (1 << 9)); + break; + } + + /* Enable the RTC. */ + RCC_BDCR |= RCC_BDCR_RTCEN; + + /* Wait for the RSF bit in RTC_CRL to be set by hardware. */ + RTC_CRL &= ~RTC_CRL_RSF; + while ((reg32 = (RTC_CRL & RTC_CRL_RSF)) == 0); + + /* Wait for the last write operation to finish. */ + /* TODO: Necessary? */ + while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); +} + +void rtc_enter_config_mode(void) +{ + u32 reg32; + + /* Wait until the RTOFF bit is 1 (no RTC register writes ongoing). */ + while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); + + /* Enter configuration mode. */ + RTC_CRL |= RTC_CRL_CNF; +} + +void rtc_exit_config_mode(void) +{ + /* u32 reg32; */ + + /* Exit configuration mode. */ + RTC_CRL &= ~RTC_CRL_CNF; + + /* Wait until the RTOFF bit is 1 (our RTC register write finished). */ + /* while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); */ + /* TODO: Unnecessary since we poll the bit on config entry(?) */ +} + +void rtc_set_alarm_time(u32 alarm_time) +{ + rtc_enter_config_mode(); + RTC_ALRL = (alarm_time & 0x0000ffff); + RTC_ALRH = (alarm_time & 0xffff0000) >> 16; + rtc_exit_config_mode(); +} + +void rtc_enable_alarm(void) +{ + rtc_enter_config_mode(); + RTC_CRH |= RTC_CRH_ALRIE; + rtc_exit_config_mode(); +} + +void rtc_disable_alarm(void) +{ + rtc_enter_config_mode(); + RTC_CRH &= ~RTC_CRH_ALRIE; + rtc_exit_config_mode(); +} + +void rtc_set_prescale_val(u32 prescale_val) +{ + rtc_enter_config_mode(); + RTC_PRLL = prescale_val & 0x0000ffff; /* PRL[15:0] */ + RTC_PRLH = (prescale_val & 0x000f0000) >> 16; /* PRL[19:16] */ + rtc_exit_config_mode(); +} + +u32 rtc_get_counter_val(void) +{ + return (RTC_CNTH << 16) | RTC_CNTL; +} + +u32 rtc_get_prescale_div_val(void) +{ + return (RTC_DIVH << 16) | RTC_DIVL; +} + +u32 rtc_get_alarm_val(void) +{ + return (RTC_ALRH << 16) | RTC_ALRL; +} + +void rtc_set_counter_val(u32 counter_val) +{ + rtc_enter_config_mode(); + RTC_CNTH = (counter_val & 0xffff0000) >> 16; /* CNT[31:16] */ + RTC_CNTL = counter_val & 0x0000ffff; /* CNT[15:0] */ + rtc_exit_config_mode(); +} + +void rtc_interrupt_enable(rtcflag_t flag_val) +{ + rtc_enter_config_mode(); + + /* Set the correct interrupt enable. */ + switch(flag_val) { + case RTC_SEC: + RTC_CRH |= RTC_CRH_SECIE; + break; + case RTC_ALR: + RTC_CRH |= RTC_CRH_ALRIE; + break; + case RTC_OW: + RTC_CRH |= RTC_CRH_OWIE; + break; + } + + rtc_exit_config_mode(); +} + +void rtc_interrupt_disable(rtcflag_t flag_val) +{ + rtc_enter_config_mode(); + + /* Disable the correct interrupt enable. */ + switch(flag_val) { + case RTC_SEC: + RTC_CRH &= ~RTC_CRH_SECIE; + break; + case RTC_ALR: + RTC_CRH &= ~RTC_CRH_ALRIE; + break; + case RTC_OW: + RTC_CRH &= ~RTC_CRH_OWIE; + break; + } + + rtc_exit_config_mode(); +} + +void rtc_clear_flag(rtcflag_t flag_val) +{ + /* Configuration mode not needed. */ + + /* Clear the correct flag. */ + switch(flag_val) { + case RTC_SEC: + RTC_CRL &= ~RTC_CRL_SECF; + break; + case RTC_ALR: + RTC_CRL &= ~RTC_CRL_ALRF; + break; + case RTC_OW: + RTC_CRL &= ~RTC_CRL_OWF; + break; + } +} + +u32 rtc_check_flag(rtcflag_t flag_val) +{ + u32 reg32; + + /* Read correct flag. */ + switch(flag_val) { + case RTC_SEC: + reg32 = RTC_CRL & RTC_CRL_SECF; + break; + case RTC_ALR: + reg32 = RTC_CRL & RTC_CRL_ALRF; + break; + case RTC_OW: + reg32 = RTC_CRL & RTC_CRL_OWF; + break; + default: + reg32 = 0; + break; + } + + return reg32; +} + +void rtc_awake_from_standby(void) +{ + u32 reg32; + + /* Enable power and backup interface clocks. */ + RCC_APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); + + /* Enable access to the backup registers and the RTC. */ + PWR_CR |= PWR_CR_DBP; + + /* Wait for the RSF bit in RTC_CRL to be set by hardware. */ + RTC_CRL &= ~RTC_CRL_RSF; + while ((reg32 = (RTC_CRL & RTC_CRL_RSF)) == 0); + + /* Wait for the last write operation to finish. */ + /* TODO: Necessary? */ + while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); +} + +void rtc_auto_awake(osc_t clock_source, u32 prescale_val) +{ + u32 reg32; + + /* Enable power and backup interface clocks. */ + RCC_APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); + + /* Enable access to the backup registers and the RTC. */ + /* TODO: Not sure if this is necessary to just read the flag. */ + PWR_CR |= PWR_CR_DBP; + + if ((reg32 = RCC_BDCR & RCC_BDCR_RTCEN) != 0) { + rtc_awake_from_standby(); + } else { + rtc_awake_from_off(clock_source); + rtc_set_prescale_val(prescale_val); + } +} diff --git a/lib/stm32/f1/scb.c b/lib/stm32/f1/scb.c new file mode 100644 index 0000000..54c5776 --- /dev/null +++ b/lib/stm32/f1/scb.c @@ -0,0 +1,30 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Gareth McMullin + * + * 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 + +void scb_reset_core(void) +{ + SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_VECTRESET; +} + +void scb_reset_system(void) +{ + SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ; +} diff --git a/lib/stm32/f1/timer.c b/lib/stm32/f1/timer.c new file mode 100644 index 0000000..a61f67f --- /dev/null +++ b/lib/stm32/f1/timer.c @@ -0,0 +1,914 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Edward Cheeseman + * + * 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 . + */ + +/* + * Basic TIMER handling API. + * + * Examples: + * timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT_MUL_2, + * TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP); + */ + +#include +#include + +void timer_reset(u32 timer_peripheral) +{ + switch (timer_peripheral) { + case TIM1: + rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST); + rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST); + break; + case TIM2: + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST); + break; + case TIM3: + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST); + break; + case TIM4: + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST); + break; + case TIM5: + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST); + break; + case TIM6: + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST); + break; + case TIM7: + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST); + break; + case TIM8: + rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST); + rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST); + break; +/* These timers are not supported in libopencm3 yet */ +/* + case TIM9: + rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST); + rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST); + break; + case TIM10: + rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST); + rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST); + break; + case TIM11: + rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST); + rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST); + break; + case TIM12: + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST); + break; + case TIM13: + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST); + break; + case TIM14: + rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST); + rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST); + break; +*/ + } +} + +void timer_enable_irq(u32 timer_peripheral, u32 irq) +{ + TIM_DIER(timer_peripheral) |= irq; +} + +void timer_disable_irq(u32 timer_peripheral, u32 irq) +{ + TIM_DIER(timer_peripheral) &= ~irq; +} + +bool timer_get_flag(u32 timer_peripheral, u32 flag) +{ + if (((TIM_SR(timer_peripheral) & flag) != 0) && + ((TIM_DIER(timer_peripheral) & flag) != 0)) { + return true; + } + + return false; +} + +void timer_clear_flag(u32 timer_peripheral, u32 flag) +{ + TIM_SR(timer_peripheral) &= ~flag; +} + +void timer_set_mode(u32 timer_peripheral, u8 clock_div, + u8 alignment, u8 direction) +{ + u32 cr1; + + cr1 = TIM_CR1(timer_peripheral); + + cr1 &= ~(TIM_CR1_CKD_CK_INT_MASK | + TIM_CR1_CMS_MASK | + TIM_CR1_DIR_DOWN); + + cr1 |= clock_div | alignment | direction; + + TIM_CR1(timer_peripheral) = cr1; +} + +void timer_set_clock_division(u32 timer_peripheral, u32 clock_div) +{ + clock_div &= TIM_CR1_CKD_CK_INT_MASK; + TIM_CR1(timer_peripheral) &= ~TIM_CR1_CKD_CK_INT_MASK; + TIM_CR1(timer_peripheral) |= clock_div; +} + +void timer_enable_preload(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE; +} + +void timer_disable_preload(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE; +} + +void timer_set_alignment(u32 timer_peripheral, u32 alignment) +{ + alignment &= TIM_CR1_CMS_MASK; + TIM_CR1(timer_peripheral) &= ~TIM_CR1_CMS_MASK; + TIM_CR1(timer_peripheral) |= alignment; +} + +void timer_direction_up(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN; +} + +void timer_direction_down(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN; +} + +void timer_one_shot_mode(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_OPM; +} + +void timer_continuous_mode(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM; +} + +void timer_update_on_any(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS; +} + +void timer_update_on_overflow(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_URS; +} + +void timer_enable_update_event(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS; +} + +void timer_disable_update_event(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS; +} + +void timer_enable_counter(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) |= TIM_CR1_CEN; +} + +void timer_disable_counter(u32 timer_peripheral) +{ + TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN; +} + +void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs) +{ + TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK; +} + +void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs) +{ + TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK); +} + +void timer_set_ti1_ch123_xor(u32 timer_peripheral) +{ + TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S; +} + +void timer_set_ti1_ch1(u32 timer_peripheral) +{ + TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S; +} + +void timer_set_master_mode(u32 timer_peripheral, u32 mode) +{ + TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK; + TIM_CR2(timer_peripheral) |= mode; +} + +void timer_set_dma_on_compare_event(u32 timer_peripheral) +{ + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS; +} + +void timer_set_dma_on_update_event(u32 timer_peripheral) +{ + TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS; +} + +void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral) +{ + TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS; +} + +void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral) +{ + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS; +} + +void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral) +{ + TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC; +} + +void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral) +{ + TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; +} + +void timer_set_prescaler(u32 timer_peripheral, u32 value) +{ + TIM_PSC(timer_peripheral) = value; +} + +void timer_set_repetition_counter(u32 timer_peripheral, u32 value) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_RCR(timer_peripheral) = value; +} + +void timer_set_period(u32 timer_peripheral, u32 period) +{ + TIM_ARR(timer_peripheral) = period; +} + +void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1CE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2CE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3CE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4CE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as fast enable only applies to the whole channel. */ + break; + } +} + +void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1CE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2CE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3CE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4CE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as fast enable only applies to the whole channel. */ + break; + } +} + +void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1FE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2FE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3FE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4FE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as fast enable only applies to the whole channel. */ + break; + } +} + +void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1FE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2FE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3FE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4FE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, + enum tim_oc_mode oc_mode) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC1S_OUT; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1M_MASK; + switch (oc_mode) { + case TIM_OCM_FROZEN: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FROZEN; + break; + case TIM_OCM_ACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_ACTIVE; + break; + case TIM_OCM_INACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_INACTIVE; + break; + case TIM_OCM_TOGGLE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_TOGGLE; + break; + case TIM_OCM_FORCE_LOW: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_LOW; + break; + case TIM_OCM_FORCE_HIGH: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_HIGH; + break; + case TIM_OCM_PWM1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM1; + break; + case TIM_OCM_PWM2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM2; + break; + } + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC2S_OUT; + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2M_MASK; + switch (oc_mode) { + case TIM_OCM_FROZEN: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FROZEN; + break; + case TIM_OCM_ACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_ACTIVE; + break; + case TIM_OCM_INACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_INACTIVE; + break; + case TIM_OCM_TOGGLE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_TOGGLE; + break; + case TIM_OCM_FORCE_LOW: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_LOW; + break; + case TIM_OCM_FORCE_HIGH: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_HIGH; + break; + case TIM_OCM_PWM1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM1; + break; + case TIM_OCM_PWM2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM2; + break; + } + break; + case TIM_OC3: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC3S_OUT; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3M_MASK; + switch (oc_mode) { + case TIM_OCM_FROZEN: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FROZEN; + break; + case TIM_OCM_ACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC3M_ACTIVE; + break; + case TIM_OCM_INACTIVE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_INACTIVE; + break; + case TIM_OCM_TOGGLE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_TOGGLE; + break; + case TIM_OCM_FORCE_LOW: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_LOW; + break; + case TIM_OCM_FORCE_HIGH: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_HIGH; + break; + case TIM_OCM_PWM1: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM1; + break; + case TIM_OCM_PWM2: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM2; + break; + } + break; + case TIM_OC4: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK; + TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC4S_OUT; + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4M_MASK; + switch (oc_mode) { + case TIM_OCM_FROZEN: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FROZEN; + break; + case TIM_OCM_ACTIVE: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC4M_ACTIVE; + break; + case TIM_OCM_INACTIVE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_INACTIVE; + break; + case TIM_OCM_TOGGLE: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_TOGGLE; + break; + case TIM_OCM_FORCE_LOW: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_LOW; + break; + case TIM_OCM_FORCE_HIGH: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_HIGH; + break; + case TIM_OCM_PWM1: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM1; + break; + case TIM_OCM_PWM2: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM2; + break; + } + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1PE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2PE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3PE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4PE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1PE; + break; + case TIM_OC2: + TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2PE; + break; + case TIM_OC3: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3PE; + break; + case TIM_OC4: + TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4PE; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1P; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2P; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3P; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4P; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + /* Acting for TIM1 and TIM8 only from here onwards. */ + if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) + return; + + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NP; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NP; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NP; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } +} + +void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1P; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2P; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3P; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC4P; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + /* Acting for TIM1 and TIM8 only from here onwards. */ + if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) + return; + + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NP; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NP; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NP; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } +} + +void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1E; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2E; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3E; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC4E; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + /* Acting for TIM1 and TIM8 only from here onwards. */ + if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) + return; + + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NE; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NE; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NE; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } +} + +void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1E; + break; + case TIM_OC2: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2E; + break; + case TIM_OC3: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3E; + break; + case TIM_OC4: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4E; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to TIM1 and TIM8 only. */ + break; + } + + /* Acting for TIM1 and TIM8 only from here onwards. */ + if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) + return; + + switch (oc_id) { + case TIM_OC1N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NE; + break; + case TIM_OC2N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NE; + break; + case TIM_OC3N: + TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NE; + break; + case TIM_OC1: + case TIM_OC2: + case TIM_OC3: + case TIM_OC4: + /* Ignoring as this option was already set above. */ + break; + } +} + +void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + /* Acting for TIM1 and TIM8 only. */ + if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) + return; + + switch (oc_id) { + case TIM_OC1: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1; + break; + case TIM_OC1N: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1N; + break; + case TIM_OC2: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2; + break; + case TIM_OC2N: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2N; + break; + case TIM_OC3: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3; + break; + case TIM_OC3N: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3N; + break; + case TIM_OC4: + TIM_CR2(timer_peripheral) |= TIM_CR2_OIS4; + break; + } +} + +void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id) +{ + /* Acting for TIM1 and TIM8 only. */ + if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) + return; + + switch (oc_id) { + case TIM_OC1: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1; + break; + case TIM_OC1N: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1N; + break; + case TIM_OC2: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2; + break; + case TIM_OC2N: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2N; + break; + case TIM_OC3: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3; + break; + case TIM_OC3N: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3N; + break; + case TIM_OC4: + TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS4; + break; + } +} + +void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value) +{ + switch (oc_id) { + case TIM_OC1: + TIM_CCR1(timer_peripheral) = value; + break; + case TIM_OC2: + TIM_CCR2(timer_peripheral) = value; + break; + case TIM_OC3: + TIM_CCR3(timer_peripheral) = value; + break; + case TIM_OC4: + TIM_CCR4(timer_peripheral) = value; + break; + case TIM_OC1N: + case TIM_OC2N: + case TIM_OC3N: + /* Ignoring as this option applies to the whole channel. */ + break; + } +} + +void timer_enable_break_main_output(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE; +} + +void timer_disable_break_main_output(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE; +} + +void timer_enable_break_automatic_output(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE; +} + +void timer_disable_break_automatic_output(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE; +} + +void timer_set_break_polarity_high(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP; +} + +void timer_set_break_polarity_low(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP; +} + +void timer_enable_break(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE; +} + +void timer_disable_break(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE; +} + +void timer_set_enabled_off_state_in_run_mode(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR; +} + +void timer_set_disabled_off_state_in_run_mode(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR; +} + +void timer_set_enabled_off_state_in_idle_mode(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI; +} + +void timer_set_disabled_off_state_in_idle_mode(u32 timer_peripheral) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI; +} + +void timer_set_break_lock(u32 timer_peripheral, u32 lock) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) |= lock; +} + +void timer_set_deadtime(u32 timer_peripheral, u32 deadtime) +{ + if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) + TIM_BDTR(timer_peripheral) |= deadtime; +} + +void timer_generate_event(u32 timer_peripheral, u32 event) +{ + TIM_EGR(timer_peripheral) |= event; +} + +u32 timer_get_counter(u32 timer_peripheral) +{ + return TIM_CNT(timer_peripheral); +} diff --git a/lib/stm32/f1/vector.c b/lib/stm32/f1/vector.c new file mode 100644 index 0000000..39bd9a1 --- /dev/null +++ b/lib/stm32/f1/vector.c @@ -0,0 +1,296 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * + * 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 . + */ + +#define WEAK __attribute__ ((weak)) + +/* Symbols exported by linker script */ +extern unsigned _etext, _data, _edata, _ebss, _stack; + +void main(void); +void reset_handler(void); +void blocking_handler(void); +void null_handler(void); + +void WEAK nmi_handler(void); +void WEAK hard_fault_handler(void); +void WEAK mem_manage_handler(void); +void WEAK bus_fault_handler(void); +void WEAK usage_fault_handler(void); +void WEAK sv_call_handler(void); +void WEAK debug_monitor_handler(void); +void WEAK pend_sv_handler(void); +void WEAK sys_tick_handler(void); +void WEAK wwdg_isr(void); +void WEAK pvd_isr(void); +void WEAK tamper_isr(void); +void WEAK rtc_isr(void); +void WEAK flash_isr(void); +void WEAK rcc_isr(void); +void WEAK exti0_isr(void); +void WEAK exti1_isr(void); +void WEAK exti2_isr(void); +void WEAK exti3_isr(void); +void WEAK exti4_isr(void); +void WEAK dma1_channel1_isr(void); +void WEAK dma1_channel2_isr(void); +void WEAK dma1_channel3_isr(void); +void WEAK dma1_channel4_isr(void); +void WEAK dma1_channel5_isr(void); +void WEAK dma1_channel6_isr(void); +void WEAK dma1_channel7_isr(void); +void WEAK adc1_2_isr(void); +void WEAK usb_hp_can_tx_isr(void); +void WEAK usb_lp_can_rx0_isr(void); +void WEAK can_rx1_isr(void); +void WEAK can_sce_isr(void); +void WEAK exti9_5_isr(void); +void WEAK tim1_brk_isr(void); +void WEAK tim1_up_isr(void); +void WEAK tim1_trg_com_isr(void); +void WEAK tim1_cc_isr(void); +void WEAK tim2_isr(void); +void WEAK tim3_isr(void); +void WEAK tim4_isr(void); +void WEAK i2c1_ev_isr(void); +void WEAK i2c1_er_isr(void); +void WEAK i2c2_ev_isr(void); +void WEAK i2c2_er_isr(void); +void WEAK spi1_isr(void); +void WEAK spi2_isr(void); +void WEAK usart1_isr(void); +void WEAK usart2_isr(void); +void WEAK usart3_isr(void); +void WEAK exti15_10_isr(void); +void WEAK rtc_alarm_isr(void); +void WEAK usb_wakeup_isr(void); +void WEAK tim8_brk_isr(void); +void WEAK tim8_up_isr(void); +void WEAK tim8_trg_com_isr(void); +void WEAK tim8_cc_isr(void); +void WEAK adc3_isr(void); +void WEAK fsmc_isr(void); +void WEAK sdio_isr(void); +void WEAK tim5_isr(void); +void WEAK spi3_isr(void); +void WEAK usart4_isr(void); +void WEAK usart5_isr(void); +void WEAK tim6_isr(void); +void WEAK tim7_isr(void); +void WEAK dma2_channel1_isr(void); +void WEAK dma2_channel2_isr(void); +void WEAK dma2_channel3_isr(void); +void WEAK dma2_channel4_5_isr(void); +void WEAK dma2_channel5_isr(void); +void WEAK eth_isr(void); +void WEAK eth_wkup_isr(void); +void WEAK can2_tx_isr(void); +void WEAK can2_rx0_isr(void); +void WEAK can2_rx1_isr(void); +void WEAK can2_sce_isr(void); +void WEAK otg_fs_isr(void); + + +__attribute__ ((section(".vectors"))) +void (*const vector_table[]) (void) = { + (void*)&_stack, + reset_handler, + nmi_handler, + hard_fault_handler, + mem_manage_handler, + bus_fault_handler, + usage_fault_handler, + 0, 0, 0, 0, /* Reserved */ + sv_call_handler, + debug_monitor_handler, + 0, /* Reserved */ + pend_sv_handler, + sys_tick_handler, + wwdg_isr, + pvd_isr, + tamper_isr, + rtc_isr, + flash_isr, + rcc_isr, + exti0_isr, + exti1_isr, + exti2_isr, + exti3_isr, + exti4_isr, + dma1_channel1_isr, + dma1_channel2_isr, + dma1_channel3_isr, + dma1_channel4_isr, + dma1_channel5_isr, + dma1_channel6_isr, + dma1_channel7_isr, + adc1_2_isr, + usb_hp_can_tx_isr, + usb_lp_can_rx0_isr, + can_rx1_isr, + can_sce_isr, + exti9_5_isr, + tim1_brk_isr, + tim1_up_isr, + tim1_trg_com_isr, + tim1_cc_isr, + tim2_isr, + tim3_isr, + tim4_isr, + i2c1_ev_isr, + i2c1_er_isr, + i2c2_ev_isr, + i2c2_er_isr, + spi1_isr, + spi2_isr, + usart1_isr, + usart2_isr, + usart3_isr, + exti15_10_isr, + rtc_alarm_isr, + usb_wakeup_isr, + tim8_brk_isr, + tim8_up_isr, + tim8_trg_com_isr, + tim8_cc_isr, + adc3_isr, + fsmc_isr, + sdio_isr, + tim5_isr, + spi3_isr, + usart4_isr, + usart5_isr, + tim6_isr, + tim7_isr, + dma2_channel1_isr, + dma2_channel2_isr, + dma2_channel3_isr, + dma2_channel4_5_isr, + dma2_channel5_isr, + eth_isr, + eth_wkup_isr, + can2_tx_isr, + can2_rx0_isr, + can2_rx1_isr, + can2_sce_isr, + otg_fs_isr, +}; + +void reset_handler(void) +{ + volatile unsigned *src, *dest; + asm("MSR msp, %0" : : "r"(&_stack)); + + for (src = &_etext, dest = &_data; dest < &_edata; src++, dest++) + *dest = *src; + + while (dest < &_ebss) + *dest++ = 0; + + /* Call the application's entry point. */ + main(); +} + +void blocking_handler(void) +{ + while (1) ; +} + +void null_handler(void) +{ + /* Do nothing. */ +} + +#pragma weak nmi_handler = null_handler +#pragma weak hard_fault_handler = blocking_handler +#pragma weak mem_manage_handler = blocking_handler +#pragma weak bus_fault_handler = blocking_handler +#pragma weak usage_fault_handler = blocking_handler +#pragma weak sv_call_handler = null_handler +#pragma weak debug_monitor_handler = null_handler +#pragma weak pend_sv_handler = null_handler +#pragma weak sys_tick_handler = null_handler +#pragma weak wwdg_isr = null_handler +#pragma weak pvd_isr = null_handler +#pragma weak tamper_isr = null_handler +#pragma weak rtc_isr = null_handler +#pragma weak flash_isr = null_handler +#pragma weak rcc_isr = null_handler +#pragma weak exti0_isr = null_handler +#pragma weak exti1_isr = null_handler +#pragma weak exti2_isr = null_handler +#pragma weak exti3_isr = null_handler +#pragma weak exti4_isr = null_handler +#pragma weak dma1_channel1_isr = null_handler +#pragma weak dma1_channel2_isr = null_handler +#pragma weak dma1_channel3_isr = null_handler +#pragma weak dma1_channel4_isr = null_handler +#pragma weak dma1_channel5_isr = null_handler +#pragma weak dma1_channel6_isr = null_handler +#pragma weak dma1_channel7_isr = null_handler +#pragma weak adc1_2_isr = null_handler +#pragma weak usb_hp_can_tx_isr = null_handler +#pragma weak usb_lp_can_rx0_isr = null_handler +#pragma weak can_rx1_isr = null_handler +#pragma weak can_sce_isr = null_handler +#pragma weak exti9_5_isr = null_handler +#pragma weak tim1_brk_isr = null_handler +#pragma weak tim1_up_isr = null_handler +#pragma weak tim1_trg_com_isr = null_handler +#pragma weak tim1_cc_isr = null_handler +#pragma weak tim2_isr = null_handler +#pragma weak tim3_isr = null_handler +#pragma weak tim4_isr = null_handler +#pragma weak i2c1_ev_isr = null_handler +#pragma weak i2c1_er_isr = null_handler +#pragma weak i2c2_ev_isr = null_handler +#pragma weak i2c2_er_isr = null_handler +#pragma weak spi1_isr = null_handler +#pragma weak spi2_isr = null_handler +#pragma weak usart1_isr = null_handler +#pragma weak usart2_isr = null_handler +#pragma weak usart3_isr = null_handler +#pragma weak exti15_10_isr = null_handler +#pragma weak rtc_alarm_isr = null_handler +#pragma weak usb_wakeup_isr = null_handler +#pragma weak tim8_brk_isr = null_handler +#pragma weak tim8_up_isr = null_handler +#pragma weak tim8_trg_com_isr = null_handler +#pragma weak tim8_cc_isr = null_handler +#pragma weak adc3_isr = null_handler +#pragma weak fsmc_isr = null_handler +#pragma weak sdio_isr = null_handler +#pragma weak tim5_isr = null_handler +#pragma weak spi3_isr = null_handler +#pragma weak usart4_isr = null_handler +#pragma weak usart5_isr = null_handler +#pragma weak tim6_isr = null_handler +#pragma weak tim7_isr = null_handler +#pragma weak dma2_channel1_isr = null_handler +#pragma weak dma2_channel2_isr = null_handler +#pragma weak dma2_channel3_isr = null_handler +#pragma weak dma2_channel4_5_isr = null_handler +#pragma weak dma2_channel5_isr +#pragma weak eth_isr = null_handler +#pragma weak eth_wkup_isr = null_handler +#pragma weak can2_tx_isr = null_handler +#pragma weak can2_rx0_isr = null_handler +#pragma weak can2_rx1_isr = null_handler +#pragma weak can2_sce_isr = null_handler +#pragma weak otg_fs_isr = null_handler + diff --git a/lib/stm32/f2/Makefile b/lib/stm32/f2/Makefile new file mode 100644 index 0000000..496f4a5 --- /dev/null +++ b/lib/stm32/f2/Makefile @@ -0,0 +1,59 @@ +## +## This file is part of the libopencm3 project. +## +## Copyright (C) 2009 Uwe Hermann +## +## 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 . +## + +LIBNAME = libopencm3_stm32f2 + +PREFIX ?= arm-none-eabi +# PREFIX ?= arm-elf +CC = $(PREFIX)-gcc +AR = $(PREFIX)-ar +CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \ + -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ + -ffunction-sections -fdata-sections -MD -DSTM32F2 +# ARFLAGS = rcsv +ARFLAGS = rcs +OBJS = vector.o gpio.o systick.o i2c.o spi.o nvic.o usart.o exti.o rcc.o flash.o + +#VPATH += ../usb +VPATH += ../stm32_common + +# Be silent per default, but 'make V=1' will show all compiler calls. +ifneq ($(V),1) +Q := @ +endif + +all: $(LIBNAME).a + +$(LIBNAME).a: $(OBJS) + @printf " AR $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(AR) $(ARFLAGS) $@ $^ + +%.o: %.c + @printf " CC $(subst $(shell pwd)/,,$(@))\n" + $(Q)$(CC) $(CFLAGS) -o $@ -c $< + +clean: + @printf " CLEAN lib/stm32f2\n" + $(Q)rm -f *.o *.d + $(Q)rm -f $(LIBNAME).a + +.PHONY: clean + +-include $(OBJS:.o=.d) + diff --git a/lib/stm32/f2/exti.c b/lib/stm32/f2/exti.c new file mode 100644 index 0000000..1db9ad7 --- /dev/null +++ b/lib/stm32/f2/exti.c @@ -0,0 +1,146 @@ +/* + * This file is part of the libopencm3 project. + * + * 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 +#include +#include + +void exti_set_trigger(u32 extis, exti_trigger_type trig) +{ + switch (trig) { + case EXTI_TRIGGER_RISING: + EXTI_RTSR |= extis; + EXTI_FTSR &= ~extis; + break; + case EXTI_TRIGGER_FALLING: + EXTI_RTSR &= ~extis; + EXTI_FTSR |= extis; + break; + case EXTI_TRIGGER_BOTH: + EXTI_RTSR |= extis; + EXTI_FTSR |= extis; + break; + } +} + +void exti_enable_request(u32 extis) +{ + /* Enable interrupts. */ + EXTI_IMR |= extis; + + /* Enable events. */ + EXTI_EMR |= extis; +} + +void exti_disable_request(u32 extis) +{ + /* Disable interrupts. */ + EXTI_IMR &= ~extis; + + /* Disable events. */ + EXTI_EMR &= ~extis; +} + +/* + * Reset the interrupt request by writing a 1 to the corresponding + * pending bit register. + */ +void exti_reset_request(u32 extis) +{ + EXTI_PR = extis; +} + +/* + * Remap an external interrupt line to the corresponding pin on the + * specified GPIO port. + * + * TODO: This could be rewritten in fewer lines of code. + */ +void exti_select_source(u32 exti, u32 gpioport) +{ + u8 shift, bits; + + shift = bits = 0; + + switch (exti) { + case EXTI0: + case EXTI4: + case EXTI8: + case EXTI12: + shift = 0; + break; + case EXTI1: + case EXTI5: + case EXTI9: + case EXTI13: + shift = 4; + break; + case EXTI2: + case EXTI6: + case EXTI10: + case EXTI14: + shift = 8; + break; + case EXTI3: + case EXTI7: + case EXTI11: + case EXTI15: + shift = 12; + break; + } + + switch (gpioport) { + case GPIOA: + bits = 0xf; + break; + case GPIOB: + bits = 0xe; + break; + case GPIOC: + bits = 0xd; + break; + case GPIOD: + bits = 0xc; + break; + case GPIOE: + bits = 0xb; + break; + case GPIOF: + bits = 0xa; + break; + case GPIOG: + bits = 0x9; + break; + } + + /* Ensure that only valid EXTI lines are used. */ + if (exti < EXTI4) { + SYSCFG_EXTICR1 &= ~(0x000F << shift); + SYSCFG_EXTICR1 |= (~bits << shift); + } else if (exti < EXTI8) { + SYSCFG_EXTICR2 &= ~(0x000F << shift); + SYSCFG_EXTICR2 |= (~bits << shift); + } else if (exti < EXTI12) { + SYSCFG_EXTICR3 &= ~(0x000F << shift); + SYSCFG_EXTICR3 |= (~bits << shift); + } else if (exti < EXTI16) { + SYSCFG_EXTICR4 &= ~(0x000F << shift); + SYSCFG_EXTICR4 |= (~bits << shift); + } +} diff --git a/lib/stm32/f2/flash.c b/lib/stm32/f2/flash.c new file mode 100644 index 0000000..e9bc73e --- /dev/null +++ b/lib/stm32/f2/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(); +} diff --git a/lib/stm32/f2/gpio.c b/lib/stm32/f2/gpio.c new file mode 100644 index 0000000..6e1ef08 --- /dev/null +++ b/lib/stm32/f2/gpio.c @@ -0,0 +1,139 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2011 Fergus Noble + * + * 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 + +void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios) +{ + u16 i; + u32 moder, pupd; + + /* + * We want to set the config only for the pins mentioned in gpios, + * but keeping the others, so read out the actual config first. + */ + moder = GPIO_MODER(gpioport); + pupd = GPIO_PUPDR(gpioport); + + for (i = 0; i < 16; i++) { + if (!((1 << i) & gpios)) + continue; + + moder &= ~GPIO_MODE_MASK(i); + moder |= GPIO_MODE(i, mode); + pupd &= ~GPIO_PUPD_MASK(i); + pupd |= GPIO_PUPD(i, pull_up_down); + } + + /* Set mode and pull up/down control registers. */ + GPIO_MODER(gpioport) = moder; + GPIO_PUPDR(gpioport) = pupd; +} + +void gpio_set_output_options(u32 gpioport, u8 otype, u8 speed, u16 gpios) +{ + u16 i; + u32 ospeedr; + + if (otype == 0x1) + GPIO_OTYPER(gpioport) |= gpios; + else + GPIO_OTYPER(gpioport) &= ~gpios; + + ospeedr = GPIO_OSPEEDR(gpioport); + + for (i = 0; i < 16; i++) { + if (!((1 << i) & gpios)) + continue; + ospeedr &= ~GPIO_OSPEED_MASK(i); + ospeedr |= GPIO_OSPEED(i, speed); + } + + GPIO_OSPEEDR(gpioport) = ospeedr; +} + +void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios) +{ + u16 i; + u32 afrl, afrh; + + afrl = GPIO_AFRL(gpioport); + afrh = GPIO_AFRH(gpioport); + + for (i = 0; i < 8; i++) { + if (!((1 << i) & gpios)) + continue; + afrl &= GPIO_AFR_MASK(i); + afrl |= GPIO_AFR(i, alt_func_num); + } + + for (i = 8; i < 16; i++) { + if (!((1 << i) & gpios)) + continue; + afrl &= GPIO_AFR_MASK(i-8); + afrh |= GPIO_AFR(i-8, alt_func_num); + } + + GPIO_AFRL(gpioport) = afrl; + GPIO_AFRH(gpioport) = afrh; +} + +void gpio_set(u32 gpioport, u16 gpios) +{ + GPIO_BSRR(gpioport) = gpios; +} + +void gpio_clear(u32 gpioport, u16 gpios) +{ + GPIO_BSRR(gpioport) = gpios << 16; +} + +u16 gpio_get(u32 gpioport, u16 gpios) +{ + return gpio_port_read(gpioport) & gpios; +} + +void gpio_toggle(u32 gpioport, u16 gpios) +{ + GPIO_ODR(gpioport) = GPIO_IDR(gpioport) ^ gpios; +} + +u16 gpio_port_read(u32 gpioport) +{ + return (u16)GPIO_IDR(gpioport); +} + +void gpio_port_write(u32 gpioport, u16 data) +{ + GPIO_ODR(gpioport) = data; +} + +void gpio_port_config_lock(u32 gpioport, u16 gpios) +{ + u32 reg32; + + /* Special "Lock Key Writing Sequence", see datasheet. */ + GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ + GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */ + GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ + reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */ + reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */ + + /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */ +} diff --git a/lib/stm32/f2/libopencm3_stm32f2.ld b/lib/stm32/f2/libopencm3_stm32f2.ld new file mode 100644 index 0000000..fda7d02 --- /dev/null +++ b/lib/stm32/f2/libopencm3_stm32f2.ld @@ -0,0 +1,63 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * 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 . + */ + +/* 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 sections. */ +SECTIONS +{ + . = ORIGIN(rom); + + .text : { + *(.vectors) /* Vector table */ + *(.text*) /* Program code */ + *(.rodata*) /* Read-only data */ + _etext = .; + } >rom + + . = ORIGIN(ram); + + .data : { + _data = .; + *(.data*) /* Read-write initialized data */ + _edata = .; + } >ram AT >rom + + .bss : { + *(.bss*) /* Read-write zero initialized data */ + *(COMMON) + _ebss = .; + } >ram AT >rom + + /* + * 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) } + + end = .; +} + +PROVIDE(_stack = 0x20000800); + diff --git a/lib/stm32/f2/rcc.c b/lib/stm32/f2/rcc.c new file mode 100644 index 0000000..048f0ff --- /dev/null +++ b/lib/stm32/f2/rcc.c @@ -0,0 +1,412 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Federico Ruiz-Ugalde + * Copyright (C) 2009 Uwe Hermann + * Copyright (C) 2010 Thomas Otto + * + * 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 +#include + +/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset */ +u32 rcc_ppre1_frequency = 8000000; +u32 rcc_ppre2_frequency = 8000000; + +/* TODO: Create a table for these values */ +#define RCC_PLL_M 8 +#define RCC_PLL_N 336 +#define RCC_PLL_P 2 +#define RCC_PLL_Q 7 +#define RCC_PLLI2S_N 192 +#define RCC_PLLI2S_R 5 + +void rcc_osc_ready_int_clear(osc_t 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(osc_t 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(osc_t 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(osc_t 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; + } + + /* Shouldn't be reached. */ + return -1; +} + +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(osc_t 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(osc_t 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(osc_t 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(osc_t 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(osc_t 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(osc_t 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_peripheral_enable_clock(volatile u32 *reg, u32 en) +{ + *reg |= en; +} + +void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en) +{ + *reg &= ~en; +} + +void rcc_peripheral_reset(volatile u32 *reg, u32 reset) +{ + *reg |= reset; +} + +void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset) +{ + *reg &= ~clear_reset; +} + +void rcc_set_sysclk_source(u32 clk) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 1) | (1 << 0)); + RCC_CFGR = (reg32 | clk); +} + +void rcc_set_pll_source(u32 pllsrc) +{ + u32 reg32; + + reg32 = RCC_PLLCFGR; + reg32 &= ~(1 << 22); + RCC_PLLCFGR = (reg32 | (pllsrc << 22)); +} + +void rcc_set_ppre2(u32 ppre2) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 11) | (1 << 12) | (1 << 13)); + RCC_CFGR = (reg32 | (ppre2 << 11)); +} + +void rcc_set_ppre1(u32 ppre1) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 8) | (1 << 9) | (1 << 10)); + RCC_CFGR = (reg32 | (ppre1 << 8)); +} + +void rcc_set_hpre(u32 hpre) +{ + u32 reg32; + + reg32 = RCC_CFGR; + reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)); + RCC_CFGR = (reg32 | (hpre << 4)); +} + +void rcc_set_rtcpre(u32 rtcpre) +{ + u32 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(u32 pllm, u32 plln, u32 pllp, u32 pllq) +{ + RCC_PLLCFGR = pllm | + (plln << 6) | + (((pllp >> 1) - 1) << 16) | + (pllq << 24); +} + +void rcc_set_main_pll_hse(u32 pllm, u32 plln, u32 pllp, u32 pllq) +{ + RCC_PLLCFGR = pllm | + (plln << 6) | + (((pllp >> 1) - 1) << 16) | + RCC_PLLCFGR_PLLSRC | + (pllq << 24); +} + +u32 rcc_system_clock_source(void) +{ + /* Return the clock source which is used as system clock. */ + return ((RCC_CFGR & 0x000c) >> 2); +} + +void rcc_clock_setup_in_hse_8mhz_out_120mhz(void) +{ + /* 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); + rcc_set_sysclk_source(RCC_CFGR_SW_HSE); + + /* + * Set prescalers for AHB, ADC, ABP1, ABP2. + * Do this before touching the PLL (TODO: why?). + */ + rcc_set_hpre(RCC_CFGR_HPRE_DIV_NONE); /* Set. 120MHz Max. 120MHz */ + rcc_set_ppre1(RCC_CFGR_PPRE_DIV_4); /* Set. 30MHz Max. 30MHz */ + rcc_set_ppre2(RCC_CFGR_PPRE_DIV_2); /* Set. 60MHz Max. 60MHz */ + + rcc_set_main_pll_hse(RCC_PLL_M, RCC_PLL_N, RCC_PLL_P, RCC_PLL_Q); + + /* Enable PLL oscillator and wait for it to stabilize. */ + rcc_osc_on(PLL); + rcc_wait_for_osc_ready(PLL); + + /* + * @3.3V + * Sysclk runs with 120MHz -> 3 waitstates. + * 0WS from 0-30MHz + * 1WS from 30-60MHz + * 2WS from 60-90MHz + * 3WS from 90-120MHz + */ + flash_set_ws(FLASH_PRFTEN | FLASH_ICE | FLASH_DCE | FLASH_LATENCY_3WS); + + /* 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 = 30000000; + rcc_ppre2_frequency = 60000000; +} + +void rcc_backupdomain_reset(void) +{ + /* Set the backup domain software reset. */ + RCC_BDCR |= RCC_BDCR_BDRST; + + /* Clear the backup domain software reset. */ + RCC_BDCR &= ~RCC_BDCR_BDRST; +} diff --git a/lib/stm32/f2/vector.c b/lib/stm32/f2/vector.c new file mode 100644 index 0000000..d6f70f8 --- /dev/null +++ b/lib/stm32/f2/vector.c @@ -0,0 +1,336 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Piotr Esden-Tempski + * Copyright (C) 2011 Fergus Noble + * + * 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 . + */ + +#define WEAK __attribute__ ((weak)) + +/* Symbols exported by linker script */ +extern unsigned _etext, _data, _edata, _ebss, _stack; + +void main(void); +void reset_handler(void); +void blocking_handler(void); +void null_handler(void); + +void WEAK reset_handler(void); +void WEAK nmi_handler(void); +void WEAK hard_fault_handler(void); +void WEAK mem_manage_handler(void); +void WEAK bus_fault_handler(void); +void WEAK usage_fault_handler(void); +void WEAK sv_call_handler(void); +void WEAK debug_monitor_handler(void); +void WEAK pend_sv_handler(void); +void WEAK sys_tick_handler(void); +void WEAK wwdg_isr(void); +void WEAK pvd_isr(void); +void WEAK tamp_stamp_isr(void); +void WEAK rtc_wkup_isr(void); +void WEAK flash_isr(void); +void WEAK rcc_isr(void); +void WEAK exti0_isr(void); +void WEAK exti1_isr(void); +void WEAK exti2_isr(void); +void WEAK exti3_isr(void); +void WEAK exti4_isr(void); +void WEAK dma1_stream0_isr(void); +void WEAK dma1_stream1_isr(void); +void WEAK dma1_stream2_isr(void); +void WEAK dma1_stream3_isr(void); +void WEAK dma1_stream4_isr(void); +void WEAK dma1_stream5_isr(void); +void WEAK dma1_stream6_isr(void); +void WEAK adc_isr(void); +void WEAK can1_tx_isr(void); +void WEAK can1_rx0_isr(void); +void WEAK can1_rx1_isr(void); +void WEAK can1_sce_isr(void); +void WEAK exti9_5_isr(void); +void WEAK tim1_brk_tim9_isr(void); +void WEAK tim1_up_tim10_isr(void); +void WEAK tim1_trg_com_tim11_isr(void); +void WEAK tim1_cc_isr(void); +void WEAK tim2_isr(void); +void WEAK tim3_isr(void); +void WEAK tim4_isr(void); +void WEAK i2c1_ev_isr(void); +void WEAK i2c1_er_isr(void); +void WEAK i2c2_ev_isr(void); +void WEAK i2c2_er_isr(void); +void WEAK spi1_isr(void); +void WEAK spi2_isr(void); +void WEAK usart1_isr(void); +void WEAK usart2_isr(void); +void WEAK usart3_isr(void); +void WEAK exti15_10_isr(void); +void WEAK rtc_alarm_isr(void); +void WEAK usb_fs_wkup_isr(void); +void WEAK tim8_brk_tim12_isr(void); +void WEAK tim8_up_tim13_isr(void); +void WEAK tim8_trg_com_tim14_isr(void); +void WEAK tim8_cc_isr(void); +void WEAK dma1_stream7_isr(void); +void WEAK fsmc_isr(void); +void WEAK sdio_isr(void); +void WEAK tim5_isr(void); +void WEAK spi3_isr(void); +void WEAK usart4_isr(void); +void WEAK usart5_isr(void); +void WEAK tim6_dac_isr(void); +void WEAK tim7_isr(void); +void WEAK dma2_stream0_isr(void); +void WEAK dma2_stream1_isr(void); +void WEAK dma2_stream2_isr(void); +void WEAK dma2_stream3_isr(void); +void WEAK dma2_stream4_isr(void); +void WEAK eth_isr(void); +void WEAK eth_wkup_isr(void); +void WEAK can2_tx_isr(void); +void WEAK can2_rx0_isr(void); +void WEAK can2_rx1_isr(void); +void WEAK can2_sce_isr(void); +void WEAK otg_fs_isr(void); +void WEAK dma2_stream5_isr(void); +void WEAK dma2_stream6_isr(void); +void WEAK dma2_stream7_isr(void); +void WEAK usart6_isr(void); +void WEAK i2c3_ev_isr(void); +void WEAK i2c3_er_isr(void); +void WEAK otg_hs_ep1_out_isr(void); +void WEAK otg_hs_ep1_in_isr(void); +void WEAK otg_hs_wkup_isr(void); +void WEAK otg_hs_isr(void); +void WEAK dcmi_isr(void); +void WEAK cryp_isr(void); +void WEAK hash_rng_isr(void); + +__attribute__ ((section(".vectors"))) +void (*const vector_table[]) (void) = { + (void*)&_stack, + reset_handler, + nmi_handler, + hard_fault_handler, + mem_manage_handler, + bus_fault_handler, + usage_fault_handler, + 0, 0, 0, 0, /* Reserved */ + sv_call_handler, + debug_monitor_handler, + 0, /* Reserved */ + pend_sv_handler, + sys_tick_handler, + wwdg_isr, + pvd_isr, + tamp_stamp_isr, + rtc_wkup_isr, + flash_isr, + rcc_isr, + exti0_isr, + exti1_isr, + exti2_isr, + exti3_isr, + exti4_isr, + dma1_stream0_isr, + dma1_stream1_isr, + dma1_stream2_isr, + dma1_stream3_isr, + dma1_stream4_isr, + dma1_stream5_isr, + dma1_stream6_isr, + adc_isr, + can1_tx_isr, + can1_rx0_isr, + can1_rx1_isr, + can1_sce_isr, + exti9_5_isr, + tim1_brk_tim9_isr, + tim1_up_tim10_isr, + tim1_trg_com_tim11_isr, + tim1_cc_isr, + tim2_isr, + tim3_isr, + tim4_isr, + i2c1_ev_isr, + i2c1_er_isr, + i2c2_ev_isr, + i2c2_er_isr, + spi1_isr, + spi2_isr, + usart1_isr, + usart2_isr, + usart3_isr, + exti15_10_isr, + rtc_alarm_isr, + usb_fs_wkup_isr, + tim8_brk_tim12_isr, + tim8_up_tim13_isr, + tim8_trg_com_tim14_isr, + tim8_cc_isr, + dma1_stream7_isr, + fsmc_isr, + sdio_isr, + tim5_isr, + spi3_isr, + usart4_isr, + usart5_isr, + tim6_dac_isr, + tim7_isr, + dma2_stream0_isr, + dma2_stream1_isr, + dma2_stream2_isr, + dma2_stream3_isr, + dma2_stream4_isr, + eth_isr, + eth_wkup_isr, + can2_tx_isr, + can2_rx0_isr, + can2_rx1_isr, + can2_sce_isr, + otg_fs_isr, + dma2_stream5_isr, + dma2_stream6_isr, + dma2_stream7_isr, + usart6_isr, + i2c3_ev_isr, + i2c3_er_isr, + otg_hs_ep1_out_isr, + otg_hs_ep1_in_isr, + otg_hs_wkup_isr, + otg_hs_isr, + dcmi_isr, + cryp_isr, + hash_rng_isr, +}; + +void reset_handler(void) +{ + volatile unsigned *src, *dest; + asm("MSR msp, %0" : : "r"(&_stack)); + + for (src = &_etext, dest = &_data; dest < &_edata; src++, dest++) + *dest = *src; + + while (dest < &_ebss) + *dest++ = 0; + + /* Call the application's entry point. */ + main(); +} + +void blocking_handler(void) +{ + while (1) ; +} + +void null_handler(void) +{ + /* Do nothing. */ +} + +#pragma weak nmi_handler = null_handler +#pragma weak hard_fault_handler = blocking_handler +#pragma weak mem_manage_handler = blocking_handler +#pragma weak bus_fault_handler = blocking_handler +#pragma weak usage_fault_handler = blocking_handler +#pragma weak sv_call_handler = null_handler +#pragma weak debug_monitor_handler = null_handler +#pragma weak pend_sv_handler = null_handler +#pragma weak sys_tick_handler = null_handler +#pragma weak wwdg_isr = null_handler +#pragma weak pvd_isr = null_handler +#pragma weak tamp_stamp_isr = null_handler +#pragma weak rtc_wkup_isr = null_handler +#pragma weak flash_isr = null_handler +#pragma weak rcc_isr = null_handler +#pragma weak exti0_isr = null_handler +#pragma weak exti1_isr = null_handler +#pragma weak exti2_isr = null_handler +#pragma weak exti3_isr = null_handler +#pragma weak exti4_isr = null_handler +#pragma weak dma1_stream0_isr = null_handler +#pragma weak dma1_stream1_isr = null_handler +#pragma weak dma1_stream2_isr = null_handler +#pragma weak dma1_stream3_isr = null_handler +#pragma weak dma1_stream4_isr = null_handler +#pragma weak dma1_stream5_isr = null_handler +#pragma weak dma1_stream6_isr = null_handler +#pragma weak adc_isr = null_handler +#pragma weak can1_tx_isr = null_handler +#pragma weak can1_rx0_isr = null_handler +#pragma weak can1_rx1_isr = null_handler +#pragma weak can1_sce_isr = null_handler +#pragma weak exti9_5_isr = null_handler +#pragma weak tim1_brk_tim9_isr = null_handler +#pragma weak tim1_up_tim10_isr = null_handler +#pragma weak tim1_trg_com_tim11_isr = null_handler +#pragma weak tim1_cc_isr = null_handler +#pragma weak tim2_isr = null_handler +#pragma weak tim3_isr = null_handler +#pragma weak tim4_isr = null_handler +#pragma weak i2c1_ev_isr = null_handler +#pragma weak i2c1_er_isr = null_handler +#pragma weak i2c2_ev_isr = null_handler +#pragma weak i2c2_er_isr = null_handler +#pragma weak spi1_isr = null_handler +#pragma weak spi2_isr = null_handler +#pragma weak usart1_isr = null_handler +#pragma weak usart2_isr = null_handler +#pragma weak usart3_isr = null_handler +#pragma weak exti15_10_isr = null_handler +#pragma weak rtc_alarm_isr = null_handler +#pragma weak usb_fs_wkup_isr = null_handler +#pragma weak tim8_brk_tim12_isr = null_handler +#pragma weak tim8_up_tim13_isr = null_handler +#pragma weak tim8_trg_com_tim14_isr = null_handler +#pragma weak tim8_cc_isr = null_handler +#pragma weak dma1_stream7_isr = null_handler +#pragma weak fsmc_isr = null_handler +#pragma weak sdio_isr = null_handler +#pragma weak tim5_isr = null_handler +#pragma weak spi3_isr = null_handler +#pragma weak usart4_isr = null_handler +#pragma weak usart5_isr = null_handler +#pragma weak tim6_dac_isr = null_handler +#pragma weak tim7_isr = null_handler +#pragma weak dma2_stream0_isr = null_handler +#pragma weak dma2_stream1_isr = null_handler +#pragma weak dma2_stream2_isr = null_handler +#pragma weak dma2_stream3_isr = null_handler +#pragma weak dma2_stream4_isr = null_handler +#pragma weak eth_isr = null_handler +#pragma weak eth_wkup_isr = null_handler +#pragma weak can2_tx_isr = null_handler +#pragma weak can2_rx0_isr = null_handler +#pragma weak can2_rx1_isr = null_handler +#pragma weak can2_sce_isr = null_handler +#pragma weak otg_fs_isr = null_handler +#pragma weak dma2_stream5_isr = null_handler +#pragma weak dma2_stream6_isr = null_handler +#pragma weak dma2_stream7_isr = null_handler +#pragma weak usart6_isr = null_handler +#pragma weak i2c3_ev_isr = null_handler +#pragma weak i2c3_er_isr = null_handler +#pragma weak otg_hs_ep1_out_isr = null_handler +#pragma weak otg_hs_ep1_in_isr = null_handler +#pragma weak otg_hs_wkup_isr = null_handler +#pragma weak otg_hs_isr = null_handler +#pragma weak dcmi_isr = null_handler +#pragma weak cryp_isr = null_handler +#pragma weak hash_rng_isr = null_handler + diff --git a/lib/stm32/i2c.c b/lib/stm32/i2c.c new file mode 100644 index 0000000..e1a3b84 --- /dev/null +++ b/lib/stm32/i2c.c @@ -0,0 +1,93 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * 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 + +void i2c_peripheral_enable(u32 i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_PE; +} + +void i2c_peripheral_disable(u32 i2c) +{ + I2C_CR1(i2c) &= ~I2C_CR1_PE; +} + +void i2c_send_start(u32 i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_START; +} + +void i2c_send_stop(u32 i2c) +{ + I2C_CR1(i2c) |= I2C_CR1_STOP; +} + +void i2c_set_own_7bit_slave_address(u32 i2c, u8 slave) +{ + I2C_OAR1(i2c) = (u16)(slave << 1); + I2C_OAR1(i2c) &= ~I2C_OAR1_ADDMODE; + I2C_OAR1(i2c) |= (1 << 14); /* Datasheet: always keep 1 by software. */ +} + +void i2c_set_own_10bit_slave_address(u32 i2c, u16 slave) +{ + I2C_OAR1(i2c) = (u16)(I2C_OAR1_ADDMODE | slave); +} + +void i2c_set_fast_mode(u32 i2c) +{ + I2C_CCR(i2c) |= I2C_CCR_FS; +} + +void i2c_set_standard_mode(u32 i2c) +{ + I2C_CCR(i2c) &= ~I2C_CCR_FS; +} + +void i2c_set_clock_frequency(u32 i2c, u8 freq) +{ + u16 reg16; + reg16 = I2C_CR2(i2c) & 0xffc0; /* Clear bits [5:0]. */ + reg16 |= freq; + I2C_CR2(i2c) = reg16; +} + +void i2c_set_ccr(u32 i2c, u16 freq) +{ + u16 reg16; + reg16 = I2C_CCR(i2c) & 0xf000; /* Clear bits [11:0]. */ + reg16 |= freq; + I2C_CCR(i2c) = reg16; +} + +void i2c_set_trise(u32 i2c, u16 trise) +{ + I2C_TRISE(i2c) = trise; +} + +void i2c_send_7bit_address(u32 i2c, u8 slave, u8 readwrite) +{ + I2C_DR(i2c) = (u8)((slave << 1) | readwrite); +} + +void i2c_send_data(u32 i2c, u8 data) +{ + I2C_DR(i2c) = data; +} diff --git a/lib/stm32/nvic.c b/lib/stm32/nvic.c new file mode 100644 index 0000000..cf77cc3 --- /dev/null +++ b/lib/stm32/nvic.c @@ -0,0 +1,106 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * 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 + +void nvic_enable_irq(u8 irqn) +{ + if (irqn < 32) + NVIC_ISER(0) |= (1 << irqn); + if ((irqn >= 32) & (irqn < 64)) + NVIC_ISER(1) |= (1 << (irqn - 32)); + if ((irqn >= 64) & (irqn < 68)) + NVIC_ISER(2) |= (1 << (irqn - 64)); +} + +void nvic_disable_irq(u8 irqn) +{ + if (irqn < 32) + NVIC_ICER(0) |= (1 << irqn); + if ((irqn >= 32) & (irqn < 64)) + NVIC_ICER(1) |= (1 << (irqn - 32)); + if ((irqn >= 64) & (irqn < 68)) + NVIC_ICER(2) |= (1 << (irqn - 64)); +} + +u8 nvic_get_pending_irq(u8 irqn) +{ + if (irqn < 32) + return (NVIC_ISPR(0) & (1 << irqn)); + if ((irqn >= 32) & (irqn < 64)) + return (NVIC_ISPR(1) & (1 << (irqn - 32))); + if ((irqn >= 64) & (irqn < 68)) + return (NVIC_ISPR(2) & (1 << (irqn - 64))); + return 0; +} + +void nvic_set_pending_irq(u8 irqn) +{ + if (irqn < 32) + NVIC_ISPR(0) |= (1 << irqn); + if ((irqn >= 32) & (irqn < 64)) + NVIC_ISPR(1) |= (1 << (irqn - 32)); + if ((irqn >= 64) & (irqn < 68)) + NVIC_ISPR(2) |= (1 << (irqn - 64)); +} + +void nvic_clear_pending_irq(u8 irqn) +{ + if (irqn < 32) + NVIC_ICPR(0) |= (1 << irqn); + if ((irqn >= 32) & (irqn < 64)) + NVIC_ICPR(1) |= (1 << (irqn - 32)); + if ((irqn >= 64) & (irqn < 68)) + NVIC_ICPR(2) |= (1 << (irqn - 64)); +} + +u8 nvic_get_active_irq(u8 irqn) +{ + if (irqn < 32) + return (NVIC_IABR(0) & (1 << irqn)); + if ((irqn >= 32) & (irqn < 64)) + return (NVIC_IABR(1) & (1 << (irqn - 32))); + if ((irqn >= 64) & (irqn < 68)) + return (NVIC_IABR(2) & (1 << (irqn - 64))); + return 0; +} + +u8 nvic_get_irq_enabled(u8 irqn) +{ + if (irqn < 32) + return (NVIC_ISER(0) & (1 << irqn)); + if ((irqn >= 32) & (irqn < 64)) + return (NVIC_ISER(1) & (1 << (irqn - 32))); + if ((irqn >= 64) & (irqn < 68)) + return (NVIC_ISER(2) & (1 << (irqn - 64))); + return 0; +} + +void nvic_set_priority(u8 irqn, u8 priority) +{ + NVIC_IPR(irqn/4) |= (priority << ((irqn % 4) * 8)); +} + +void nvic_generate_software_interrupt(u8 irqn) +{ + if (irqn <= 239) + NVIC_STIR |= irqn; +} + + diff --git a/lib/stm32/spi.c b/lib/stm32/spi.c new file mode 100644 index 0000000..71bb846 --- /dev/null +++ b/lib/stm32/spi.c @@ -0,0 +1,298 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * 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 + +/* + * SPI and I2S code. + * + * Examples: + * spi_init_master(SPI1, 1000000, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, + * SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, + * SPI_CR1_LSBFIRST); + * spi_write(SPI1, 0x55); // 8-bit write + * spi_write(SPI1, 0xaa88); // 16-bit write + * reg8 = spi_read(SPI1); // 8-bit read + * reg16 = spi_read(SPI1); // 16-bit read + */ + +int spi_init_master(u32 spi, u32 br, u32 cpol, u32 cpha, u32 dff, u32 lsbfirst) +{ + u32 reg32 = 0; + + reg32 |= SPI_CR1_MSTR; /* Configure SPI as master. */ + + reg32 |= br; /* Set BAUD rate bits. */ + reg32 |= cpol; /* Set CPOL value. */ + reg32 |= cpha; /* Set CPHA value. */ + reg32 |= dff; /* Set data format (8 or 16 bits). */ + reg32 |= lsbfirst; /* Set frame format (LSB- or MSB-first). */ + + /* TODO: NSS pin handling. */ + + SPI_CR1(spi) = reg32; + + return 0; /* TODO */ +} + +/* TODO: Error handling? */ +void spi_enable(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_SPE; /* Enable SPI. */ +} + +/* TODO: Error handling? */ +void spi_disable(u32 spi) +{ + u32 reg32; + + /* TODO: Follow procedure from section 23.3.8 in the techref manual. */ + reg32 = SPI_CR1(spi); + reg32 &= ~(SPI_CR1_SPE); /* Disable SPI. */ + SPI_CR1(spi) = reg32; +} + +void spi_write(u32 spi, u16 data) +{ + /* Write data (8 or 16 bits, depending on DFF) into DR. */ + SPI_DR(spi) = data; +} + +void spi_send(u32 spi, u16 data) +{ + /* wait for transfer finished */ + while (!(SPI_SR(spi) & SPI_SR_TXE )); + + /* Write data (8 or 16 bits, depending on DFF) into DR. */ + SPI_DR(spi) = data; +} + +u16 spi_read(u32 spi) +{ + /* wait for transfer finished */ + while (!(SPI_SR(spi) & SPI_SR_RXNE )); + + /* Read the data (8 or 16 bits, depending on DFF bit) from DR. */ + return SPI_DR(spi); +} + +u16 spi_xfer(u32 spi, u16 data) +{ + spi_write(spi, data); + + /* wait for transfer finished */ + while (!(SPI_SR(spi) & SPI_SR_RXNE )); + + /* Read the data (8 or 16 bits, depending on DFF bit) from DR. */ + return SPI_DR(spi); +} + +void spi_set_bidirectional_mode(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_BIDIMODE; +} + +void spi_set_unidirectional_mode(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_BIDIMODE; +} + +void spi_set_bidirectional_receive_only_mode(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_BIDIMODE; + SPI_CR1(spi) &= ~SPI_CR1_BIDIOE; +} + +void spi_set_bidirectional_transmit_only_mode(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_BIDIMODE; + SPI_CR1(spi) |= SPI_CR1_BIDIOE; +} + +void spi_enable_crc(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_CRCEN; +} + +void spi_disable_crc(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_CRCEN; +} + +void spi_set_next_tx_from_buffer(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_CRCNEXT; +} + +void spi_set_next_tx_from_crc(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_CRCNEXT; +} + +void spi_set_dff_8bit(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_DFF; +} + +void spi_set_dff_16bit(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_DFF; +} + +void spi_set_full_duplex_mode(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_RXONLY; +} + +void spi_set_receive_only_mode(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_RXONLY; +} + +void spi_disable_software_slave_management(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_SSM; +} + +void spi_enable_software_slave_management(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_SSM; +} + +void spi_set_nss_high(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_SSI; +} + +void spi_set_nss_low(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_SSI; +} + +void spi_send_lsb_first(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_LSBFIRST; +} + +void spi_send_msb_first(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_LSBFIRST; +} + +void spi_set_baudrate_prescaler(u32 spi, u8 baudrate) +{ + u32 reg32; + + if (baudrate > 7) + return; + + reg32 = ( SPI_CR1(spi) & 0xffc7 ); /* clear bits [5:3] */ + reg32 |= (baudrate << 3); + SPI_CR1(spi) = reg32; +} + +void spi_set_master_mode(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_MSTR; +} + +void spi_set_slave_mode(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_MSTR; +} + +void spi_set_clock_polarity_1(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_CPOL; +} + +void spi_set_clock_polarity_0(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_CPOL; +} + +void spi_set_clock_phase_1(u32 spi) +{ + SPI_CR1(spi) |= SPI_CR1_CPHA; +} + +void spi_set_clock_phase_0(u32 spi) +{ + SPI_CR1(spi) &= ~SPI_CR1_CPHA; +} + +void spi_enable_tx_buffer_empty_interrupt(u32 spi) +{ + SPI_CR2(spi) |= SPI_CR2_TXEIE; +} + +void spi_disable_tx_buffer_empty_interrupt(u32 spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_TXEIE; +} + +void spi_enable_rx_buffer_not_empty_interrupt(u32 spi) +{ + SPI_CR2(spi) |= SPI_CR2_RXNEIE; +} + +void spi_disable_rx_buffer_not_empty_interrupt(u32 spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_RXNEIE; +} + +void spi_enable_error_interrupt(u32 spi) +{ + SPI_CR2(spi) |= SPI_CR2_ERRIE; +} + +void spi_disable_error_interrupt(u32 spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_ERRIE; +} + +void spi_enable_ss_output(u32 spi) +{ + SPI_CR2(spi) |= SPI_CR2_SSOE; +} + +void spi_disable_ss_output(u32 spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_SSOE; +} + +void spi_enable_tx_dma(u32 spi) +{ + SPI_CR2(spi) |= SPI_CR2_TXDMAEN; +} + +void spi_disable_tx_dma(u32 spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_TXDMAEN; +} + +void spi_enable_rx_dma(u32 spi) +{ + SPI_CR2(spi) |= SPI_CR2_RXDMAEN; +} + +void spi_disable_rx_dma(u32 spi) +{ + SPI_CR2(spi) &= ~SPI_CR2_RXDMAEN; +} diff --git a/lib/stm32/systick.c b/lib/stm32/systick.c new file mode 100644 index 0000000..882601d --- /dev/null +++ b/lib/stm32/systick.c @@ -0,0 +1,64 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2010 Thomas Otto + * + * 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 + +void systick_set_reload(u32 value) +{ + STK_LOAD = (value & 0x00FFFFFF); +} + +u32 systick_get_value(void) +{ + return STK_VAL; +} + +void systick_set_clocksource(u8 clocksource) +{ + if (clocksource < 2) + STK_CTRL |= (clocksource << STK_CTRL_CLKSOURCE_LSB); +} + +void systick_interrupt_enable(void) +{ + STK_CTRL |= STK_CTRL_TICKINT; +} + +void systick_interrupt_disable(void) +{ + STK_CTRL &= ~STK_CTRL_TICKINT; +} + +void systick_counter_enable(void) +{ + STK_CTRL |= STK_CTRL_ENABLE; +} + +void systick_counter_disable(void) +{ + STK_CTRL &= ~STK_CTRL_ENABLE; +} + +u8 systick_get_countflag(void) +{ + if (STK_CTRL & STK_CTRL_COUNTFLAG) + return 1; + else + return 0; +} diff --git a/lib/stm32/usart.c b/lib/stm32/usart.c new file mode 100644 index 0000000..116b159 --- /dev/null +++ b/lib/stm32/usart.c @@ -0,0 +1,128 @@ +/* + * This file is part of the libopencm3 project. + * + * Copyright (C) 2009 Uwe Hermann + * + * 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 + +void usart_set_baudrate(u32 usart, u32 baud, u32 clock) +{ + //u32 clock = rcc_ppre1_frequency; + + //if (usart == USART1) { + // clock = rcc_ppre2_frequency; + //} + + /* yes it is as simple as that. The reference manual is + * talking about factional calculation but it seems to be only + * marketting bable to sound awesome. It is nothing else but a + * simple divider to generate the correct baudrate. >_< If I + * am wrong feel free to correct me on that. :) (esden) + */ + USART_BRR(usart) = clock/baud; +} + +void usart_set_databits(u32 usart, u32 bits) +{ + if (bits == 8) + USART_CR1(usart) &= ~USART_CR1_M; /* 8 data bits */ + else + USART_CR1(usart) |= USART_CR1_M; /* 9 data bits */ +} + +void usart_set_stopbits(u32 usart, u32 stopbits) +{ + u32 reg32; + + reg32 = USART_CR2(usart); + reg32 = (reg32 & ~USART_CR2_STOPBITS_MASK) | stopbits; + USART_CR2(usart) = reg32; +} + +void usart_set_parity(u32 usart, u32 parity) +{ + u32 reg32; + + reg32 = USART_CR1(usart); + reg32 = (reg32 & ~USART_PARITY_MASK) | parity; + USART_CR1(usart) = reg32; +} + +void usart_set_mode(u32 usart, u32 mode) +{ + u32 reg32; + + reg32 = USART_CR1(usart); + reg32 = (reg32 & ~USART_MODE_MASK) | mode; + USART_CR1(usart) = reg32; +} + +void usart_set_flow_control(u32 usart, u32 flowcontrol) +{ + u32 reg32; + + reg32 = USART_CR3(usart); + reg32 = (reg32 & ~USART_FLOWCONTROL_MASK) | flowcontrol; + USART_CR3(usart) = reg32; +} + +void usart_enable(u32 usart) +{ + USART_CR1(usart) |= USART_CR1_UE; +} + +void usart_disable(u32 usart) +{ + USART_CR1(usart) &= ~USART_CR1_UE; +} + +void usart_send(u32 usart, u16 data) +{ + /* Send data. */ + USART_DR(usart) = (data & USART_DR_MASK); +} + +u16 usart_recv(u32 usart) +{ + /* Receive data. */ + return USART_DR(usart) & USART_DR_MASK; +} + +void usart_wait_send_ready(u32 usart) +{ + /* Wait until the data has been transferred into the shift register. */ + while ((USART_SR(usart) & USART_SR_TXE) == 0); +} + +void usart_wait_recv_ready(u32 usart) +{ + /* Wait until the data is ready to be received. */ + while ((USART_SR(usart) & USART_SR_RXNE) == 0); +} + +void usart_send_blocking(u32 usart, u16 data) +{ + usart_wait_send_ready(usart); + usart_send(usart, data); +} + +u16 usart_recv_blocking(u32 usart) +{ + usart_wait_recv_ready(usart); + + return usart_recv(usart); +} diff --git a/lib/stm32_common/i2c.c b/lib/stm32_common/i2c.c deleted file mode 100644 index e1a3b84..0000000 --- a/lib/stm32_common/i2c.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Thomas Otto - * - * 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 - -void i2c_peripheral_enable(u32 i2c) -{ - I2C_CR1(i2c) |= I2C_CR1_PE; -} - -void i2c_peripheral_disable(u32 i2c) -{ - I2C_CR1(i2c) &= ~I2C_CR1_PE; -} - -void i2c_send_start(u32 i2c) -{ - I2C_CR1(i2c) |= I2C_CR1_START; -} - -void i2c_send_stop(u32 i2c) -{ - I2C_CR1(i2c) |= I2C_CR1_STOP; -} - -void i2c_set_own_7bit_slave_address(u32 i2c, u8 slave) -{ - I2C_OAR1(i2c) = (u16)(slave << 1); - I2C_OAR1(i2c) &= ~I2C_OAR1_ADDMODE; - I2C_OAR1(i2c) |= (1 << 14); /* Datasheet: always keep 1 by software. */ -} - -void i2c_set_own_10bit_slave_address(u32 i2c, u16 slave) -{ - I2C_OAR1(i2c) = (u16)(I2C_OAR1_ADDMODE | slave); -} - -void i2c_set_fast_mode(u32 i2c) -{ - I2C_CCR(i2c) |= I2C_CCR_FS; -} - -void i2c_set_standard_mode(u32 i2c) -{ - I2C_CCR(i2c) &= ~I2C_CCR_FS; -} - -void i2c_set_clock_frequency(u32 i2c, u8 freq) -{ - u16 reg16; - reg16 = I2C_CR2(i2c) & 0xffc0; /* Clear bits [5:0]. */ - reg16 |= freq; - I2C_CR2(i2c) = reg16; -} - -void i2c_set_ccr(u32 i2c, u16 freq) -{ - u16 reg16; - reg16 = I2C_CCR(i2c) & 0xf000; /* Clear bits [11:0]. */ - reg16 |= freq; - I2C_CCR(i2c) = reg16; -} - -void i2c_set_trise(u32 i2c, u16 trise) -{ - I2C_TRISE(i2c) = trise; -} - -void i2c_send_7bit_address(u32 i2c, u8 slave, u8 readwrite) -{ - I2C_DR(i2c) = (u8)((slave << 1) | readwrite); -} - -void i2c_send_data(u32 i2c, u8 data) -{ - I2C_DR(i2c) = data; -} diff --git a/lib/stm32_common/nvic.c b/lib/stm32_common/nvic.c deleted file mode 100644 index cf77cc3..0000000 --- a/lib/stm32_common/nvic.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Thomas Otto - * - * 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 - -void nvic_enable_irq(u8 irqn) -{ - if (irqn < 32) - NVIC_ISER(0) |= (1 << irqn); - if ((irqn >= 32) & (irqn < 64)) - NVIC_ISER(1) |= (1 << (irqn - 32)); - if ((irqn >= 64) & (irqn < 68)) - NVIC_ISER(2) |= (1 << (irqn - 64)); -} - -void nvic_disable_irq(u8 irqn) -{ - if (irqn < 32) - NVIC_ICER(0) |= (1 << irqn); - if ((irqn >= 32) & (irqn < 64)) - NVIC_ICER(1) |= (1 << (irqn - 32)); - if ((irqn >= 64) & (irqn < 68)) - NVIC_ICER(2) |= (1 << (irqn - 64)); -} - -u8 nvic_get_pending_irq(u8 irqn) -{ - if (irqn < 32) - return (NVIC_ISPR(0) & (1 << irqn)); - if ((irqn >= 32) & (irqn < 64)) - return (NVIC_ISPR(1) & (1 << (irqn - 32))); - if ((irqn >= 64) & (irqn < 68)) - return (NVIC_ISPR(2) & (1 << (irqn - 64))); - return 0; -} - -void nvic_set_pending_irq(u8 irqn) -{ - if (irqn < 32) - NVIC_ISPR(0) |= (1 << irqn); - if ((irqn >= 32) & (irqn < 64)) - NVIC_ISPR(1) |= (1 << (irqn - 32)); - if ((irqn >= 64) & (irqn < 68)) - NVIC_ISPR(2) |= (1 << (irqn - 64)); -} - -void nvic_clear_pending_irq(u8 irqn) -{ - if (irqn < 32) - NVIC_ICPR(0) |= (1 << irqn); - if ((irqn >= 32) & (irqn < 64)) - NVIC_ICPR(1) |= (1 << (irqn - 32)); - if ((irqn >= 64) & (irqn < 68)) - NVIC_ICPR(2) |= (1 << (irqn - 64)); -} - -u8 nvic_get_active_irq(u8 irqn) -{ - if (irqn < 32) - return (NVIC_IABR(0) & (1 << irqn)); - if ((irqn >= 32) & (irqn < 64)) - return (NVIC_IABR(1) & (1 << (irqn - 32))); - if ((irqn >= 64) & (irqn < 68)) - return (NVIC_IABR(2) & (1 << (irqn - 64))); - return 0; -} - -u8 nvic_get_irq_enabled(u8 irqn) -{ - if (irqn < 32) - return (NVIC_ISER(0) & (1 << irqn)); - if ((irqn >= 32) & (irqn < 64)) - return (NVIC_ISER(1) & (1 << (irqn - 32))); - if ((irqn >= 64) & (irqn < 68)) - return (NVIC_ISER(2) & (1 << (irqn - 64))); - return 0; -} - -void nvic_set_priority(u8 irqn, u8 priority) -{ - NVIC_IPR(irqn/4) |= (priority << ((irqn % 4) * 8)); -} - -void nvic_generate_software_interrupt(u8 irqn) -{ - if (irqn <= 239) - NVIC_STIR |= irqn; -} - - diff --git a/lib/stm32_common/spi.c b/lib/stm32_common/spi.c deleted file mode 100644 index 71bb846..0000000 --- a/lib/stm32_common/spi.c +++ /dev/null @@ -1,298 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * - * 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 - -/* - * SPI and I2S code. - * - * Examples: - * spi_init_master(SPI1, 1000000, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, - * SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, - * SPI_CR1_LSBFIRST); - * spi_write(SPI1, 0x55); // 8-bit write - * spi_write(SPI1, 0xaa88); // 16-bit write - * reg8 = spi_read(SPI1); // 8-bit read - * reg16 = spi_read(SPI1); // 16-bit read - */ - -int spi_init_master(u32 spi, u32 br, u32 cpol, u32 cpha, u32 dff, u32 lsbfirst) -{ - u32 reg32 = 0; - - reg32 |= SPI_CR1_MSTR; /* Configure SPI as master. */ - - reg32 |= br; /* Set BAUD rate bits. */ - reg32 |= cpol; /* Set CPOL value. */ - reg32 |= cpha; /* Set CPHA value. */ - reg32 |= dff; /* Set data format (8 or 16 bits). */ - reg32 |= lsbfirst; /* Set frame format (LSB- or MSB-first). */ - - /* TODO: NSS pin handling. */ - - SPI_CR1(spi) = reg32; - - return 0; /* TODO */ -} - -/* TODO: Error handling? */ -void spi_enable(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_SPE; /* Enable SPI. */ -} - -/* TODO: Error handling? */ -void spi_disable(u32 spi) -{ - u32 reg32; - - /* TODO: Follow procedure from section 23.3.8 in the techref manual. */ - reg32 = SPI_CR1(spi); - reg32 &= ~(SPI_CR1_SPE); /* Disable SPI. */ - SPI_CR1(spi) = reg32; -} - -void spi_write(u32 spi, u16 data) -{ - /* Write data (8 or 16 bits, depending on DFF) into DR. */ - SPI_DR(spi) = data; -} - -void spi_send(u32 spi, u16 data) -{ - /* wait for transfer finished */ - while (!(SPI_SR(spi) & SPI_SR_TXE )); - - /* Write data (8 or 16 bits, depending on DFF) into DR. */ - SPI_DR(spi) = data; -} - -u16 spi_read(u32 spi) -{ - /* wait for transfer finished */ - while (!(SPI_SR(spi) & SPI_SR_RXNE )); - - /* Read the data (8 or 16 bits, depending on DFF bit) from DR. */ - return SPI_DR(spi); -} - -u16 spi_xfer(u32 spi, u16 data) -{ - spi_write(spi, data); - - /* wait for transfer finished */ - while (!(SPI_SR(spi) & SPI_SR_RXNE )); - - /* Read the data (8 or 16 bits, depending on DFF bit) from DR. */ - return SPI_DR(spi); -} - -void spi_set_bidirectional_mode(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_BIDIMODE; -} - -void spi_set_unidirectional_mode(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_BIDIMODE; -} - -void spi_set_bidirectional_receive_only_mode(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_BIDIMODE; - SPI_CR1(spi) &= ~SPI_CR1_BIDIOE; -} - -void spi_set_bidirectional_transmit_only_mode(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_BIDIMODE; - SPI_CR1(spi) |= SPI_CR1_BIDIOE; -} - -void spi_enable_crc(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_CRCEN; -} - -void spi_disable_crc(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_CRCEN; -} - -void spi_set_next_tx_from_buffer(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_CRCNEXT; -} - -void spi_set_next_tx_from_crc(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_CRCNEXT; -} - -void spi_set_dff_8bit(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_DFF; -} - -void spi_set_dff_16bit(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_DFF; -} - -void spi_set_full_duplex_mode(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_RXONLY; -} - -void spi_set_receive_only_mode(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_RXONLY; -} - -void spi_disable_software_slave_management(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_SSM; -} - -void spi_enable_software_slave_management(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_SSM; -} - -void spi_set_nss_high(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_SSI; -} - -void spi_set_nss_low(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_SSI; -} - -void spi_send_lsb_first(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_LSBFIRST; -} - -void spi_send_msb_first(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_LSBFIRST; -} - -void spi_set_baudrate_prescaler(u32 spi, u8 baudrate) -{ - u32 reg32; - - if (baudrate > 7) - return; - - reg32 = ( SPI_CR1(spi) & 0xffc7 ); /* clear bits [5:3] */ - reg32 |= (baudrate << 3); - SPI_CR1(spi) = reg32; -} - -void spi_set_master_mode(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_MSTR; -} - -void spi_set_slave_mode(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_MSTR; -} - -void spi_set_clock_polarity_1(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_CPOL; -} - -void spi_set_clock_polarity_0(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_CPOL; -} - -void spi_set_clock_phase_1(u32 spi) -{ - SPI_CR1(spi) |= SPI_CR1_CPHA; -} - -void spi_set_clock_phase_0(u32 spi) -{ - SPI_CR1(spi) &= ~SPI_CR1_CPHA; -} - -void spi_enable_tx_buffer_empty_interrupt(u32 spi) -{ - SPI_CR2(spi) |= SPI_CR2_TXEIE; -} - -void spi_disable_tx_buffer_empty_interrupt(u32 spi) -{ - SPI_CR2(spi) &= ~SPI_CR2_TXEIE; -} - -void spi_enable_rx_buffer_not_empty_interrupt(u32 spi) -{ - SPI_CR2(spi) |= SPI_CR2_RXNEIE; -} - -void spi_disable_rx_buffer_not_empty_interrupt(u32 spi) -{ - SPI_CR2(spi) &= ~SPI_CR2_RXNEIE; -} - -void spi_enable_error_interrupt(u32 spi) -{ - SPI_CR2(spi) |= SPI_CR2_ERRIE; -} - -void spi_disable_error_interrupt(u32 spi) -{ - SPI_CR2(spi) &= ~SPI_CR2_ERRIE; -} - -void spi_enable_ss_output(u32 spi) -{ - SPI_CR2(spi) |= SPI_CR2_SSOE; -} - -void spi_disable_ss_output(u32 spi) -{ - SPI_CR2(spi) &= ~SPI_CR2_SSOE; -} - -void spi_enable_tx_dma(u32 spi) -{ - SPI_CR2(spi) |= SPI_CR2_TXDMAEN; -} - -void spi_disable_tx_dma(u32 spi) -{ - SPI_CR2(spi) &= ~SPI_CR2_TXDMAEN; -} - -void spi_enable_rx_dma(u32 spi) -{ - SPI_CR2(spi) |= SPI_CR2_RXDMAEN; -} - -void spi_disable_rx_dma(u32 spi) -{ - SPI_CR2(spi) &= ~SPI_CR2_RXDMAEN; -} diff --git a/lib/stm32_common/systick.c b/lib/stm32_common/systick.c deleted file mode 100644 index 882601d..0000000 --- a/lib/stm32_common/systick.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Thomas Otto - * - * 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 - -void systick_set_reload(u32 value) -{ - STK_LOAD = (value & 0x00FFFFFF); -} - -u32 systick_get_value(void) -{ - return STK_VAL; -} - -void systick_set_clocksource(u8 clocksource) -{ - if (clocksource < 2) - STK_CTRL |= (clocksource << STK_CTRL_CLKSOURCE_LSB); -} - -void systick_interrupt_enable(void) -{ - STK_CTRL |= STK_CTRL_TICKINT; -} - -void systick_interrupt_disable(void) -{ - STK_CTRL &= ~STK_CTRL_TICKINT; -} - -void systick_counter_enable(void) -{ - STK_CTRL |= STK_CTRL_ENABLE; -} - -void systick_counter_disable(void) -{ - STK_CTRL &= ~STK_CTRL_ENABLE; -} - -u8 systick_get_countflag(void) -{ - if (STK_CTRL & STK_CTRL_COUNTFLAG) - return 1; - else - return 0; -} diff --git a/lib/stm32_common/usart.c b/lib/stm32_common/usart.c deleted file mode 100644 index 116b159..0000000 --- a/lib/stm32_common/usart.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * - * 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 - -void usart_set_baudrate(u32 usart, u32 baud, u32 clock) -{ - //u32 clock = rcc_ppre1_frequency; - - //if (usart == USART1) { - // clock = rcc_ppre2_frequency; - //} - - /* yes it is as simple as that. The reference manual is - * talking about factional calculation but it seems to be only - * marketting bable to sound awesome. It is nothing else but a - * simple divider to generate the correct baudrate. >_< If I - * am wrong feel free to correct me on that. :) (esden) - */ - USART_BRR(usart) = clock/baud; -} - -void usart_set_databits(u32 usart, u32 bits) -{ - if (bits == 8) - USART_CR1(usart) &= ~USART_CR1_M; /* 8 data bits */ - else - USART_CR1(usart) |= USART_CR1_M; /* 9 data bits */ -} - -void usart_set_stopbits(u32 usart, u32 stopbits) -{ - u32 reg32; - - reg32 = USART_CR2(usart); - reg32 = (reg32 & ~USART_CR2_STOPBITS_MASK) | stopbits; - USART_CR2(usart) = reg32; -} - -void usart_set_parity(u32 usart, u32 parity) -{ - u32 reg32; - - reg32 = USART_CR1(usart); - reg32 = (reg32 & ~USART_PARITY_MASK) | parity; - USART_CR1(usart) = reg32; -} - -void usart_set_mode(u32 usart, u32 mode) -{ - u32 reg32; - - reg32 = USART_CR1(usart); - reg32 = (reg32 & ~USART_MODE_MASK) | mode; - USART_CR1(usart) = reg32; -} - -void usart_set_flow_control(u32 usart, u32 flowcontrol) -{ - u32 reg32; - - reg32 = USART_CR3(usart); - reg32 = (reg32 & ~USART_FLOWCONTROL_MASK) | flowcontrol; - USART_CR3(usart) = reg32; -} - -void usart_enable(u32 usart) -{ - USART_CR1(usart) |= USART_CR1_UE; -} - -void usart_disable(u32 usart) -{ - USART_CR1(usart) &= ~USART_CR1_UE; -} - -void usart_send(u32 usart, u16 data) -{ - /* Send data. */ - USART_DR(usart) = (data & USART_DR_MASK); -} - -u16 usart_recv(u32 usart) -{ - /* Receive data. */ - return USART_DR(usart) & USART_DR_MASK; -} - -void usart_wait_send_ready(u32 usart) -{ - /* Wait until the data has been transferred into the shift register. */ - while ((USART_SR(usart) & USART_SR_TXE) == 0); -} - -void usart_wait_recv_ready(u32 usart) -{ - /* Wait until the data is ready to be received. */ - while ((USART_SR(usart) & USART_SR_RXNE) == 0); -} - -void usart_send_blocking(u32 usart, u16 data) -{ - usart_wait_send_ready(usart); - usart_send(usart, data); -} - -u16 usart_recv_blocking(u32 usart) -{ - usart_wait_recv_ready(usart); - - return usart_recv(usart); -} diff --git a/lib/stm32f1/Makefile b/lib/stm32f1/Makefile deleted file mode 100644 index bd9fca2..0000000 --- a/lib/stm32f1/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -## -## This file is part of the libopencm3 project. -## -## Copyright (C) 2009 Uwe Hermann -## -## 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 . -## - -LIBNAME = libopencm3_stm32f1 - -PREFIX ?= arm-none-eabi -#PREFIX ?= arm-elf -CC = $(PREFIX)-gcc -AR = $(PREFIX)-ar -CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \ - -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ - -ffunction-sections -fdata-sections -MD -DSTM32F1 -# ARFLAGS = rcsv -ARFLAGS = rcs -OBJS = vector.o rcc.o gpio.o usart.o adc.o spi.o flash.o nvic.o \ - rtc.o i2c.o dma.o systick.o exti.o scb.o ethernet.o \ - usb_f103.o usb.o usb_control.o usb_standard.o can.o \ - timer.o usb_f107.o - -VPATH += ../usb:../stm32_common - -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -endif - -all: $(LIBNAME).a - -$(LIBNAME).a: $(OBJS) - @printf " AR $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(AR) $(ARFLAGS) $@ $^ - -%.o: %.c - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -clean: - @printf " CLEAN lib/stm32f1\n" - $(Q)rm -f *.o *.d - $(Q)rm -f $(LIBNAME).a - -.PHONY: clean - --include $(OBJS:.o=.d) - diff --git a/lib/stm32f1/adc.c b/lib/stm32f1/adc.c deleted file mode 100644 index 31e4cbf..0000000 --- a/lib/stm32f1/adc.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Edward Cheeseman - * - * 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 . - */ - -/* - * Basic ADC handling API. - * - * Examples: - * rcc_peripheral_enable_clock(&RCC_APB2ENR, ADC1EN); - * rcc_peripheral_disable_clock(&RCC_APB2ENR, ADC1EN); - * rcc_peripheral_reset(&RCC_APB2RSTR, ADC1RST); - * rcc_peripheral_clear_reset(&RCC_APB2RSTR, ADC1RST); - * - * rcc_set_adc_clk(ADC_PRE_PLCK2_DIV2); - * adc_set_mode(ADC1, TODO); - * reg16 = adc_read(ADC1, ADC_CH_0); - */ - -#include - -void rcc_set_adc_clk(u32 prescaler) -{ - /* TODO */ - - /* FIXME: QUICK HACK to prevent compiler warnings. */ - prescaler = prescaler; -} - -void adc_set_mode(u32 block, /* TODO */ u8 mode) -{ - /* TODO */ - - /* FIXME: QUICK HACK to prevent compiler warnings. */ - block = block; - mode = mode; -} - -void adc_read(u32 block, u32 channel) -{ - /* TODO */ - - /* FIXME: QUICK HACK to prevent compiler warnings. */ - block = block; - channel = channel; -} - -void adc_enable_analog_watchdog_regular(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_AWDEN; -} - -void adc_disable_analog_watchdog_regular(u32 adc) -{ - ADC_CR1(adc) &= ~ADC_CR1_AWDEN; -} - -void adc_enable_analog_watchdog_injected(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_JAWDEN; -} - -void adc_disable_analog_watchdog_injected(u32 adc) -{ - ADC_CR1(adc) &= ~ADC_CR1_JAWDEN; -} - -void adc_enable_discontinous_mode_regular(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_DISCEN; -} - -void adc_disable_discontinous_mode_regular(u32 adc) -{ - ADC_CR1(adc) &= ~ADC_CR1_DISCEN; -} - -void adc_enable_discontinous_mode_injected(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_JDISCEN; -} - -void adc_disable_discontinous_mode_injected(u32 adc) -{ - ADC_CR1(adc) &= ~ADC_CR1_JDISCEN; -} - -void adc_enable_automatic_injected_group_conversion(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_JAUTO; -} - -void adc_disable_automatic_injected_group_conversion(u32 adc) -{ - ADC_CR1(adc) &= ~ADC_CR1_JAUTO; -} - -void adc_enable_analog_watchdog_on_all_channels(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_AWDSGL; -} - -void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel) -{ - u32 reg32; - - reg32 = (ADC_CR1(adc) & 0xffffffe0); /* Clear bits [4:0]. */ - if (channel < 18) - reg32 |= channel; - ADC_CR1(adc) = reg32; - ADC_CR1(adc) &= ~ADC_CR1_AWDSGL; -} - -void adc_enable_scan_mode(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_SCAN; -} - -void adc_disable_scan_mode(u32 adc) -{ - ADC_CR1(adc) &= ~ADC_CR1_SCAN; -} - -void adc_enable_jeoc_interrupt(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_JEOCIE; -} - -void adc_disable_jeoc_interrupt(u32 adc) -{ - ADC_CR1(adc) &= ~ADC_CR1_JEOCIE; -} - -void adc_enable_awd_interrupt(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_AWDIE; -} - -void adc_disable_awd_interrupt(u32 adc) -{ - ADC_CR1(adc) &= ~ADC_CR1_AWDIE; -} - -void adc_enable_eoc_interrupt(u32 adc) -{ - ADC_CR1(adc) |= ADC_CR1_EOCIE; -} - -void adc_disable_eoc_interrupt(u32 adc) -{ - ADC_CR1(adc) &= ~ADC_CR1_EOCIE; -} - -void adc_enable_temperature_sensor(u32 adc) -{ - ADC_CR2(adc) |= ADC_CR2_TSVREFE; -} - -void adc_disable_temperature_sensor(u32 adc) -{ - ADC_CR2(adc) &= ~ADC_CR2_TSVREFE; -} - -void adc_start_conversion_regular(u32 adc) -{ - /* start conversion on regular channels */ - ADC_CR2(adc) |= ADC_CR2_SWSTART; - - /* wait til the ADC starts the conversion */ - while (ADC_CR2(adc) & ADC_CR2_SWSTART); -} - -void adc_start_conversion_injected(u32 adc) -{ - /* start conversion on injected channels */ - ADC_CR2(adc) |= ADC_CR2_JSWSTART; - - /* wait til the ADC starts the conversion */ - while (ADC_CR2(adc) & ADC_CR2_JSWSTART); -} - -void adc_enable_external_trigger_regular(u32 adc, u8 trigger) -{ - u32 reg32; - - reg32 = (ADC_CR2(adc) & 0xfff1ffff); /* Clear bits [19:17]. */ - if (trigger < 8) - reg32 |= (trigger << ADC_CR2_EXTSEL_LSB); - ADC_CR2(adc) = reg32; - ADC_CR2(adc) |= ADC_CR2_EXTTRIG; -} - -void adc_disable_external_trigger_regular(u32 adc) -{ - ADC_CR2(adc) &= ~ADC_CR2_EXTTRIG; -} - -void adc_enable_external_trigger_injected(u32 adc, u8 trigger) -{ - u32 reg32; - - reg32 = (ADC_CR2(adc) & 0xffff8fff); /* Clear bits [12:14]. */ - if (trigger < 8) - reg32 |= (trigger << ADC_CR2_JEXTSEL_LSB); - ADC_CR2(adc) = reg32; - ADC_CR2(adc) |= ADC_CR2_JEXTTRIG; -} - -void adc_disable_external_trigger_injected(u32 adc) -{ - ADC_CR2(adc) &= ~ADC_CR2_JEXTTRIG; -} - -void adc_set_left_aligned(u32 adc) -{ - ADC_CR2(adc) |= ADC_CR2_ALIGN; -} - -void adc_set_right_aligned(u32 adc) -{ - ADC_CR2(adc) &= ~ADC_CR2_ALIGN; -} - -void adc_enable_dma(u32 adc) -{ - if ((adc == ADC1) | (adc==ADC3)) - ADC_CR2(adc) |= ADC_CR2_DMA; -} - -void adc_disable_dma(u32 adc) -{ - if ((adc == ADC1) | (adc==ADC3)) - ADC_CR2(adc) &= ~ADC_CR2_DMA; -} - -void adc_reset_calibration(u32 adc) -{ - ADC_CR2(adc) |= ADC_CR2_RSTCAL; - while (ADC_CR2(adc) & ADC_CR2_RSTCAL); -} - -void adc_calibration(u32 adc) -{ - ADC_CR2(adc) |= ADC_CR2_CAL; - while (ADC_CR2(adc) & ADC_CR2_CAL); -} - -void adc_set_continous_conversion_mode(u32 adc) -{ - ADC_CR2(adc) |= ADC_CR2_CONT; -} - -void adc_set_single_conversion_mode(u32 adc) -{ - ADC_CR2(adc) &= ~ADC_CR2_CONT; -} - -void adc_on(u32 adc) -{ - ADC_CR2(adc) |= ADC_CR2_ADON; -} - -void adc_off(u32 adc) -{ - ADC_CR2(adc) &= ~ADC_CR2_ADON; -} - -void adc_set_conversion_time(u32 adc, u8 channel, u8 time) -{ - u32 reg32; - - if (channel < 10) { - reg32 = ADC_SMPR2(adc); - reg32 &= ~(0b111 << (channel * 3)); - reg32 |= (time << (channel * 3)); - ADC_SMPR2(adc) = reg32; - } - else { - reg32 = ADC_SMPR1(adc); - reg32 &= ~(0b111 << ((channel-10) * 3)); - reg32 |= (time << ((channel-10) * 3)); - ADC_SMPR1(adc) = reg32; - } -} - -void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) -{ - u32 reg32 = 0; - u8 i; - - 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; -} - -void adc_set_watchdog_high_threshold(u32 adc, u16 threshold) -{ - u32 reg32 = 0; - - reg32 = (u32)threshold; - reg32 &= ~0xfffff000; /* clear all bits above 11 */ - ADC_HTR(adc) = reg32; -} - -void adc_set_watchdog_low_threshold(u32 adc, u16 threshold) -{ - u32 reg32 = 0; - - reg32 = (u32)threshold; - reg32 &= ~0xfffff000; /* clear all bits above 11 */ - ADC_LTR(adc) = reg32; -} - -void adc_set_regular_sequence(u32 adc, u8 length, u8 channel[]) -{ - u32 reg32_1 = 0; - u32 reg32_2 = 0; - u32 reg32_3 = 0; - u8 i = 0; - - /* maximum sequence length is 16 channels */ - if (length > 16) - return; - - for (i=1; i<=length; i++) { - if (i <= 6) - reg32_3 |= (channel[i-1] << ((i-1) * 5)); - if ((i > 6) & (i <= 12)) - reg32_2 |= (channel[i-1] << ((i-6-1) * 5)); - if ((i > 12) & (i <= 16)) - reg32_1 |= (channel[i-1] << ((i-12-1) * 5)); - } - reg32_1 |= ((length -1) << ADC_SQR1_L_LSB); - - ADC_SQR1(adc) = reg32_1; - ADC_SQR2(adc) = reg32_2; - ADC_SQR3(adc) = reg32_3; -} - -void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[]) -{ - u32 reg32 = 0; - u8 i = 0; - - /* maximum sequence length is 4 channels */ - if (length > 4) - return; - - for (i = 1; i <= length; i++) { - reg32 |= (channel[i-1] << ((i-1) * 5)); - } - reg32 |= ((length-1) << ADC_JSQR_JL_LSB); - - ADC_JSQR(adc) = reg32; -} diff --git a/lib/stm32f1/can.c b/lib/stm32f1/can.c deleted file mode 100644 index 8c5d7ec..0000000 --- a/lib/stm32f1/can.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski - * - * 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 -#include - -void can_reset(u32 canport) -{ - if (canport == CAN1) { - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN1RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN1RST); - } else { - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN2RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_CAN2RST); - } -} - -int can_init(u32 canport, bool ttcm, bool abom, bool awum, bool nart, - bool rflm, bool txfp, u32 sjw, u32 ts1, u32 ts2, u32 brp) -{ - u32 wait_ack = 0x00000000; - u32 can_msr_inak_timeout = 0x0000FFFF; - int ret = 0; - - /* Exit from sleep mode. */ - CAN_MCR(canport) &= ~CAN_MCR_SLEEP; - - /* Request initialization "enter". */ - CAN_MCR(canport) |= CAN_MCR_INRQ; - - /* Wait for acknowledge. */ - while ((wait_ack != can_msr_inak_timeout) && - ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK)) { - wait_ack++; - } - - /* Check the acknowledge. */ - if ((CAN_MSR(canport) & CAN_MSR_INAK) != CAN_MSR_INAK) - return 1; - - /* Set the automatic bus-off management. */ - if (ttcm) - CAN_MCR(canport) |= CAN_MCR_TTCM; - else - CAN_MCR(canport) &= ~CAN_MCR_TTCM; - - if (abom) - CAN_MCR(canport) |= CAN_MCR_ABOM; - else - CAN_MCR(canport) &= ~CAN_MCR_ABOM; - - if (awum) - CAN_MCR(canport) |= CAN_MCR_AWUM; - else - CAN_MCR(canport) &= ~CAN_MCR_AWUM; - - if (nart) - CAN_MCR(canport) |= CAN_MCR_NART; - else - CAN_MCR(canport) &= ~CAN_MCR_NART; - - if (rflm) - CAN_MCR(canport) |= CAN_MCR_RFLM; - else - CAN_MCR(canport) &= ~CAN_MCR_RFLM; - - if (txfp) - CAN_MCR(canport) |= CAN_MCR_TXFP; - else - CAN_MCR(canport) &= ~CAN_MCR_TXFP; - - /* Set bit timings. */ - CAN_BTR(canport) = sjw | ts2 | ts1 | - (u32)(CAN_BTR_BRP_MASK & (brp - 1)); - - /* Request initialization "leave". */ - CAN_MCR(canport) &= ~CAN_MCR_INRQ; - - /* Wait for acknowledge. */ - wait_ack = 0x00000000; - while ((wait_ack != can_msr_inak_timeout) && - ((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK)) { - wait_ack++; - } - - if ((CAN_MSR(canport) & CAN_MSR_INAK) == CAN_MSR_INAK) - ret = 1; - - return ret; -} - -void can_filter_init(u32 canport, u32 nr, bool scale_32bit, bool id_list_mode, - u32 fr1, u32 fr2, u32 fifo, bool enable) -{ - u32 filter_select_bit = 0x00000001 << nr; - - /* Request initialization "enter". */ - CAN_FMR(canport) |= CAN_FMR_FINIT; - - /* Deactivate the filter. */ - CAN_FA1R(canport) &= ~filter_select_bit; - - if (scale_32bit) { - /* Set 32-bit scale for the filter. */ - CAN_FS1R(canport) |= filter_select_bit; - } else { - /* Set 16-bit scale for the filter. */ - CAN_FS1R(canport) &= ~filter_select_bit; - } - - if (id_list_mode) { - /* Set filter mode to ID list mode. */ - CAN_FM1R(canport) |= filter_select_bit; - } else { - /* Set filter mode to id/mask mode. */ - CAN_FM1R(canport) &= ~filter_select_bit; - } - - /* Set the first filter register. */ - CAN_FiR1(canport, nr) = fr1; - - /* Set the second filter register. */ - CAN_FiR2(canport, nr) = fr2; - - /* Select FIFO0 or FIFO1 as filter assignement. */ - if (fifo) - CAN_FFA1R(canport) |= filter_select_bit; /* FIFO1 */ - else - CAN_FFA1R(canport) &= ~filter_select_bit; /* FIFO0 */ - - if (enable) - CAN_FA1R(canport) |= filter_select_bit; /* Activate filter. */ - - /* Request initialization "leave". */ - CAN_FMR(canport) &= ~CAN_FMR_FINIT; -} - -void can_filter_id_mask_16bit_init(u32 canport, u32 nr, u16 id1, u16 mask1, - u16 id2, u16 mask2, u32 fifo, bool enable) -{ - can_filter_init(canport, nr, false, false, - ((u32)id1 << 16) | (u32)mask1, - ((u32)id2 << 16) | (u32)mask2, fifo, enable); -} - -void can_filter_id_mask_32bit_init(u32 canport, u32 nr, u32 id, u32 mask, - u32 fifo, bool enable) -{ - can_filter_init(canport, nr, true, false, id, mask, fifo, enable); -} - -void can_filter_id_list_16bit_init(u32 canport, u32 nr, u16 id1, u16 id2, - u16 id3, u16 id4, u32 fifo, bool enable) -{ - can_filter_init(canport, nr, false, true, - ((u32)id1 << 16) | (u32)id2, - ((u32)id3 << 16) | (u32)id4, fifo, enable); -} - -void can_filter_id_list_32bit_init(u32 canport, u32 nr, u32 id1, u32 id2, - u32 fifo, bool enable) -{ - can_filter_init(canport, nr, true, true, id1, id2, fifo, enable); -} - -void can_enable_irq(u32 canport, u32 irq) -{ - CAN_IER(canport) |= irq; -} - -void can_disable_irq(u32 canport, u32 irq) -{ - CAN_IER(canport) &= ~irq; -} - -int can_transmit(u32 canport, u32 id, bool ext, bool rtr, u8 length, u8 *data) -{ - int ret = 0, i; - u32 mailbox = 0; - - if ((CAN_TSR(canport) & CAN_TSR_TME0) == CAN_TSR_TME0) { - ret = 0; - mailbox = CAN_MBOX0; - } else if ((CAN_TSR(canport) & CAN_TSR_TME1) == CAN_TSR_TME1) { - ret = 1; - mailbox = CAN_MBOX1; - } else if ((CAN_TSR(canport) & CAN_TSR_TME2) == CAN_TSR_TME2) { - ret = 2; - mailbox = CAN_MBOX2; - } else { - ret = -1; - } - - /* Check if we have an empty mailbox. */ - if (ret == -1) - return ret; - - /* Clear stale register bits */ - CAN_TIxR(canport, mailbox) = 0; - if (ext) { - /* Set extended ID. */ - CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_EXID_SHIFT; - /* Set extended ID indicator bit. */ - CAN_TIxR(canport, mailbox) |= CAN_TIxR_IDE; - } else { - /* Set standard ID. */ - CAN_TIxR(canport, mailbox) |= id << CAN_TIxR_STID_SHIFT; - } - - /* Set/clear remote transmission request bit. */ - if (rtr) - CAN_TIxR(canport, mailbox) |= CAN_TIxR_RTR; /* Set */ - - /* Set the DLC. */ - CAN_TDTxR(canport, mailbox) &= 0xFFFFFFFF0; - CAN_TDTxR(canport, mailbox) |= length & CAN_TDTxR_DLC_MASK; - - /* Set the data. */ - CAN_TDLxR(canport, mailbox) = 0; - CAN_TDHxR(canport, mailbox) = 0; - for (i = 0; (i < 4) && (i < length); i++) - CAN_TDLxR(canport, mailbox) |= (u32)data[i] << (8 * i); - for (i = 4; (i < 8) && (i < length); i++) - CAN_TDHxR(canport, mailbox) |= (u32)data[i] << (8 * (i - 4)); - - /* Request transmission. */ - CAN_TIxR(canport, mailbox) |= CAN_TIxR_TXRQ; - - return ret; -} - -void can_fifo_release(u32 canport, u8 fifo) -{ - if (fifo == 0) - CAN_RF0R(canport) |= CAN_RF1R_RFOM1; - else - CAN_RF1R(canport) |= CAN_RF1R_RFOM1; -} - -void can_receive(u32 canport, u8 fifo, bool release, u32 *id, bool *ext, - bool *rtr, u32 *fmi, u8 *length, u8 *data) -{ - u32 fifo_id = 0; - int i; - - if (fifo == 0) - fifo_id = CAN_FIFO0; - else - fifo_id = CAN_FIFO1; - - /* Get type of CAN ID and CAN ID. */ - if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_IDE) { - *ext = true; - /* Get extended CAN ID. */ - *id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_EXID_MASK) >> - CAN_RIxR_EXID_SHIFT); - } else { - *ext = false; - /* Get standard CAN ID. */ - *id = ((CAN_RIxR(canport, fifo_id) & CAN_RIxR_STID_MASK) >> - CAN_RIxR_STID_SHIFT); - } - - /* Get request transmit flag. */ - if (CAN_RIxR(canport, fifo_id) & CAN_RIxR_RTR) - *rtr = true; - else - *rtr = false; - - /* Get filter match ID. */ - *fmi = ((CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_FMI_MASK) > - CAN_RDTxR_FMI_SHIFT); - - /* Get data length. */ - *length = CAN_RDTxR(canport, fifo_id) & CAN_RDTxR_DLC_MASK; - - /* Get data. */ - for (i = 0; (i < 4) && (i < *length); i++) - data[i] = (CAN_RDLxR(canport, fifo_id) >> (8 * i)) & 0xFF; - - for (i = 4; (i < 8) && (i < *length); i++) - data[i] = (CAN_RDHxR(canport, fifo_id) >> (8 * (i - 4))) & 0xFF; - - /* Release the FIFO. */ - if (release) - can_fifo_release(CAN1, 0); -} diff --git a/lib/stm32f1/dma.c b/lib/stm32f1/dma.c deleted file mode 100644 index 4f0af6f..0000000 --- a/lib/stm32f1/dma.c +++ /dev/null @@ -1,543 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Thomas Otto - * - * 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 - -void dma_enable_mem2mem_mode(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) |= DMA_CCR1_MEM2MEM; - DMA_CCR1(dma) &= ~DMA_CCR1_CIRC; - case 2: - DMA_CCR2(dma) |= DMA_CCR2_MEM2MEM; - DMA_CCR2(dma) &= ~DMA_CCR2_CIRC; - case 3: - DMA_CCR3(dma) |= DMA_CCR3_MEM2MEM; - DMA_CCR3(dma) &= ~DMA_CCR3_CIRC; - case 4: - DMA_CCR4(dma) |= DMA_CCR4_MEM2MEM; - DMA_CCR4(dma) &= ~DMA_CCR4_CIRC; - case 5: - DMA_CCR5(dma) |= DMA_CCR5_MEM2MEM; - DMA_CCR5(dma) &= ~DMA_CCR5_CIRC; - case 6: - if (dma == DMA1) { - DMA_CCR6(dma) |= DMA_CCR6_MEM2MEM; - DMA_CCR6(dma) &= ~DMA_CCR6_CIRC; - } - case 7: - if (dma == DMA1) { - DMA_CCR7(dma) |= DMA_CCR7_MEM2MEM; - DMA_CCR7(dma) &= ~DMA_CCR7_CIRC; - } - } -} - - - - -void dma_set_priority(u32 dma, u8 channel, u8 prio) -{ - /* parameter check */ - if (prio > 3) - return; - - switch (channel) - { - case 1: - DMA_CCR1(dma) &= ~(0x3 << DMA_CCR1_PL_LSB); - DMA_CCR1(dma) |= (prio << DMA_CCR1_PL_LSB); - case 2: - DMA_CCR2(dma) &= ~(0x3 << DMA_CCR2_PL_LSB); - DMA_CCR2(dma) |= (prio << DMA_CCR2_PL_LSB); - case 3: - DMA_CCR3(dma) &= ~(0x3 << DMA_CCR3_PL_LSB); - DMA_CCR3(dma) |= (prio << DMA_CCR3_PL_LSB); - case 4: - DMA_CCR4(dma) &= ~(0x3 << DMA_CCR4_PL_LSB); - DMA_CCR4(dma) |= (prio << DMA_CCR4_PL_LSB); - case 5: - DMA_CCR5(dma) &= ~(0x3 << DMA_CCR5_PL_LSB); - DMA_CCR5(dma) |= (prio << DMA_CCR5_PL_LSB); - case 6: - if (dma == DMA1) { - DMA_CCR6(dma) &= ~(0x3 << DMA_CCR6_PL_LSB); - DMA_CCR6(dma) |= (prio << DMA_CCR6_PL_LSB); - } - case 7: - if (dma == DMA1) { - DMA_CCR7(dma) &= ~(0x3 << DMA_CCR7_PL_LSB); - DMA_CCR7(dma) |= (prio << DMA_CCR7_PL_LSB); - } - } -} - -void dma_set_memory_size(u32 dma, u8 channel, u8 mem_size) -{ - /* parameter check */ - if (mem_size > 2) - return; - - switch (channel) - { - case 1: - DMA_CCR1(dma) &= ~(0x3 << DMA_CCR1_MSIZE_LSB); - DMA_CCR1(dma) |= (mem_size << DMA_CCR1_MSIZE_LSB); - case 2: - DMA_CCR2(dma) &= ~(0x3 << DMA_CCR2_MSIZE_LSB); - DMA_CCR2(dma) |= (mem_size << DMA_CCR2_MSIZE_LSB); - case 3: - DMA_CCR3(dma) &= ~(0x3 << DMA_CCR3_MSIZE_LSB); - DMA_CCR3(dma) |= (mem_size << DMA_CCR3_MSIZE_LSB); - case 4: - DMA_CCR4(dma) &= ~(0x3 << DMA_CCR4_MSIZE_LSB); - DMA_CCR4(dma) |= (mem_size << DMA_CCR4_MSIZE_LSB); - case 5: - DMA_CCR5(dma) &= ~(0x3 << DMA_CCR5_MSIZE_LSB); - DMA_CCR5(dma) |= (mem_size << DMA_CCR5_MSIZE_LSB); - case 6: - if (dma == DMA1) { - DMA_CCR6(dma) &= ~(0x3 << DMA_CCR6_MSIZE_LSB); - DMA_CCR6(dma) |= (mem_size << DMA_CCR6_MSIZE_LSB); - } - case 7: - if (dma == DMA1) { - DMA_CCR7(dma) &= ~(0x3 << DMA_CCR7_MSIZE_LSB); - DMA_CCR7(dma) |= (mem_size << DMA_CCR7_MSIZE_LSB); - } - } -} - - - -void dma_set_peripheral_size(u32 dma, u8 channel, u8 peripheral_size) -{ - /* parameter check */ - if (peripheral_size > 2) - return; - - switch (channel) - { - case 1: - DMA_CCR1(dma) &= ~(0x3 << DMA_CCR1_PSIZE_LSB); - DMA_CCR1(dma) |= (peripheral_size << DMA_CCR1_PSIZE_LSB); - case 2: - DMA_CCR2(dma) &= ~(0x3 << DMA_CCR2_PSIZE_LSB); - DMA_CCR2(dma) |= (peripheral_size << DMA_CCR2_PSIZE_LSB); - case 3: - DMA_CCR3(dma) &= ~(0x3 << DMA_CCR3_PSIZE_LSB); - DMA_CCR3(dma) |= (peripheral_size << DMA_CCR3_PSIZE_LSB); - case 4: - DMA_CCR4(dma) &= ~(0x3 << DMA_CCR4_PSIZE_LSB); - DMA_CCR4(dma) |= (peripheral_size << DMA_CCR4_PSIZE_LSB); - case 5: - DMA_CCR5(dma) &= ~(0x3 << DMA_CCR5_PSIZE_LSB); - DMA_CCR5(dma) |= (peripheral_size << DMA_CCR5_PSIZE_LSB); - case 6: - if (dma == DMA1) { - DMA_CCR6(dma) &= ~(0x3 << DMA_CCR6_PSIZE_LSB); - DMA_CCR6(dma) |= (peripheral_size << DMA_CCR6_PSIZE_LSB); - } - case 7: - if (dma == DMA1) { - DMA_CCR7(dma) &= ~(0x3 << DMA_CCR7_PSIZE_LSB); - DMA_CCR7(dma) |= (peripheral_size << DMA_CCR7_PSIZE_LSB); - } - } -} - - -void dma_enable_memory_increment_mode(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) |= DMA_CCR1_MINC; - case 2: - DMA_CCR2(dma) |= DMA_CCR2_MINC; - case 3: - DMA_CCR3(dma) |= DMA_CCR3_MINC; - case 4: - DMA_CCR4(dma) |= DMA_CCR4_MINC; - case 5: - DMA_CCR5(dma) |= DMA_CCR5_MINC; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) |= DMA_CCR6_MINC; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) |= DMA_CCR7_MINC; - } -} - -void dma_enable_peripheral_increment_mode(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) |= DMA_CCR1_PINC; - case 2: - DMA_CCR2(dma) |= DMA_CCR2_PINC; - case 3: - DMA_CCR3(dma) |= DMA_CCR3_PINC; - case 4: - DMA_CCR4(dma) |= DMA_CCR4_PINC; - case 5: - DMA_CCR5(dma) |= DMA_CCR5_PINC; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) |= DMA_CCR6_PINC; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) |= DMA_CCR7_PINC; - } -} - -void dma_enable_circular_mode(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) |= DMA_CCR1_CIRC; - DMA_CCR1(dma) &= ~DMA_CCR1_MEM2MEM; - case 2: - DMA_CCR2(dma) |= DMA_CCR2_CIRC; - DMA_CCR2(dma) &= ~DMA_CCR2_MEM2MEM; - case 3: - DMA_CCR3(dma) |= DMA_CCR3_CIRC; - DMA_CCR3(dma) &= ~DMA_CCR3_MEM2MEM; - case 4: - DMA_CCR4(dma) |= DMA_CCR4_CIRC; - DMA_CCR4(dma) &= ~DMA_CCR4_MEM2MEM; - case 5: - DMA_CCR5(dma) |= DMA_CCR5_CIRC; - DMA_CCR5(dma) &= ~DMA_CCR5_MEM2MEM; - case 6: - if (dma == DMA1) { - DMA_CCR6(dma) |= DMA_CCR6_CIRC; - DMA_CCR6(dma) &= ~DMA_CCR6_MEM2MEM; - } - case 7: - if (dma == DMA1) { - DMA_CCR7(dma) |= DMA_CCR7_CIRC; - DMA_CCR7(dma) &= ~DMA_CCR7_MEM2MEM; - } - } -} - -void dma_set_read_from_peripheral(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) &= ~DMA_CCR1_DIR; - case 2: - DMA_CCR2(dma) &= ~DMA_CCR2_DIR; - case 3: - DMA_CCR3(dma) &= ~DMA_CCR3_DIR; - case 4: - DMA_CCR4(dma) &= ~DMA_CCR4_DIR; - case 5: - DMA_CCR5(dma) &= ~DMA_CCR5_DIR; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) &= ~DMA_CCR6_DIR; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) &= ~DMA_CCR7_DIR; - } -} - -void dma_set_read_from_memory(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) |= DMA_CCR1_DIR; - case 2: - DMA_CCR2(dma) |= DMA_CCR2_DIR; - case 3: - DMA_CCR3(dma) |= DMA_CCR3_DIR; - case 4: - DMA_CCR4(dma) |= DMA_CCR4_DIR; - case 5: - DMA_CCR5(dma) |= DMA_CCR5_DIR; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) |= DMA_CCR6_DIR; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) |= DMA_CCR7_DIR; - } -} - -void dma_enable_transfer_error_interrupt(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) |= DMA_CCR1_TEIE; - case 2: - DMA_CCR2(dma) |= DMA_CCR2_TEIE; - case 3: - DMA_CCR3(dma) |= DMA_CCR3_TEIE; - case 4: - DMA_CCR4(dma) |= DMA_CCR4_TEIE; - case 5: - DMA_CCR5(dma) |= DMA_CCR5_TEIE; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) |= DMA_CCR6_TEIE; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) |= DMA_CCR7_TEIE; - } -} - -void dma_disable_transfer_error_interrupt(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) &= ~DMA_CCR1_TEIE; - case 2: - DMA_CCR2(dma) &= ~DMA_CCR2_TEIE; - case 3: - DMA_CCR3(dma) &= ~DMA_CCR3_TEIE; - case 4: - DMA_CCR4(dma) &= ~DMA_CCR4_TEIE; - case 5: - DMA_CCR5(dma) &= ~DMA_CCR5_TEIE; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) &= ~DMA_CCR6_TEIE; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) &= ~DMA_CCR7_TEIE; - } -} - -void dma_enable_half_transfer_interrupt(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) |= DMA_CCR1_HTIE; - case 2: - DMA_CCR2(dma) |= DMA_CCR2_HTIE; - case 3: - DMA_CCR3(dma) |= DMA_CCR3_HTIE; - case 4: - DMA_CCR4(dma) |= DMA_CCR4_HTIE; - case 5: - DMA_CCR5(dma) |= DMA_CCR5_HTIE; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) |= DMA_CCR6_HTIE; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) |= DMA_CCR7_HTIE; - } -} - -void dma_disable_half_transfer_interrupt(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) &= ~DMA_CCR1_HTIE; - case 2: - DMA_CCR2(dma) &= ~DMA_CCR2_HTIE; - case 3: - DMA_CCR3(dma) &= ~DMA_CCR3_HTIE; - case 4: - DMA_CCR4(dma) &= ~DMA_CCR4_HTIE; - case 5: - DMA_CCR5(dma) &= ~DMA_CCR5_HTIE; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) &= ~DMA_CCR6_HTIE; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) &= ~DMA_CCR7_HTIE; - } -} - -void dma_enable_transfer_complete_interrupt(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) |= DMA_CCR1_TCIE; - case 2: - DMA_CCR2(dma) |= DMA_CCR2_TCIE; - case 3: - DMA_CCR3(dma) |= DMA_CCR3_TCIE; - case 4: - DMA_CCR4(dma) |= DMA_CCR4_TCIE; - case 5: - DMA_CCR5(dma) |= DMA_CCR5_TCIE; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) |= DMA_CCR6_TCIE; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) |= DMA_CCR7_TCIE; - } -} - -void dma_disable_transfer_complete_interrupt(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) &= ~DMA_CCR1_TCIE; - case 2: - DMA_CCR2(dma) &= ~DMA_CCR2_TCIE; - case 3: - DMA_CCR3(dma) &= ~DMA_CCR3_TCIE; - case 4: - DMA_CCR4(dma) &= ~DMA_CCR4_TCIE; - case 5: - DMA_CCR5(dma) &= ~DMA_CCR5_TCIE; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) &= ~DMA_CCR6_TCIE; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) &= ~DMA_CCR7_TCIE; - } -} - -void dma_enable_channel(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) |= DMA_CCR1_EN; - case 2: - DMA_CCR2(dma) |= DMA_CCR2_EN; - case 3: - DMA_CCR3(dma) |= DMA_CCR3_EN; - case 4: - DMA_CCR4(dma) |= DMA_CCR4_EN; - case 5: - DMA_CCR5(dma) |= DMA_CCR5_EN; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) |= DMA_CCR6_EN; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) |= DMA_CCR7_EN; - } -} - -void dma_disable_channel(u32 dma, u8 channel) -{ - switch (channel) - { - case 1: - DMA_CCR1(dma) &= ~DMA_CCR1_EN; - case 2: - DMA_CCR2(dma) &= ~DMA_CCR2_EN; - case 3: - DMA_CCR3(dma) &= ~DMA_CCR3_EN; - case 4: - DMA_CCR4(dma) &= ~DMA_CCR4_EN; - case 5: - DMA_CCR5(dma) &= ~DMA_CCR5_EN; - case 6: - if (dma == DMA1) - DMA_CCR6(dma) &= ~DMA_CCR6_EN; - case 7: - if (dma == DMA1) - DMA_CCR7(dma) &= ~DMA_CCR7_EN; - } -} - -void dma_set_peripheral_address(u32 dma, u8 channel, u32 address) -{ - switch (channel) - { - case 1: - DMA_CPAR1(dma) = (u32)address; - case 2: - DMA_CPAR2(dma) = (u32)address; - case 3: - DMA_CPAR3(dma) = (u32)address; - case 4: - DMA_CPAR4(dma) = (u32)address; - case 5: - DMA_CPAR5(dma) = (u32)address; - case 6: - if (dma == DMA1) - DMA_CPAR6(dma) = (u32)address; - case 7: - if (dma == DMA1) - DMA_CPAR7(dma) = (u32)address; - } -} - -void dma_set_memory_address(u32 dma, u8 channel, u32 address) -{ - switch (channel) - { - case 1: - DMA_CMAR1(dma) = (u32)address; - case 2: - DMA_CMAR2(dma) = (u32)address; - case 3: - DMA_CMAR3(dma) = (u32)address; - case 4: - DMA_CMAR4(dma) = (u32)address; - case 5: - DMA_CMAR5(dma) = (u32)address; - case 6: - if (dma == DMA1) - DMA_CMAR6(dma) = (u32)address; - case 7: - if (dma == DMA1) - DMA_CMAR7(dma) = (u32)address; - } -} - -void dma_set_number_of_data(u32 dma, u8 channel, u16 number) -{ - switch (channel) - { - case 1: - DMA_CNDTR1(dma) = number; - case 2: - DMA_CNDTR2(dma) = number; - case 3: - DMA_CNDTR3(dma) = number; - case 4: - DMA_CNDTR4(dma) = number; - case 5: - DMA_CNDTR5(dma) = number; - case 6: - if (dma == DMA1) - DMA_CNDTR6(dma) = number; - case 7: - if (dma == DMA1) - DMA_CNDTR7(dma) = number; - } -} diff --git a/lib/stm32f1/ethernet.c b/lib/stm32f1/ethernet.c deleted file mode 100644 index fc65ec2..0000000 --- a/lib/stm32f1/ethernet.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Gareth McMullin - * - * 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 - -void eth_smi_write(u8 phy, u8 reg, u16 data) -{ - /* Set PHY and register addresses for write access. */ - ETH_MACMIIAR &= ~(ETH_MACMIIAR_MR | ETH_MACMIIAR_PA); - ETH_MACMIIAR |= (phy << 11) | (reg << 6) | ETH_MACMIIAR_MW; - - /* Set register value. */ - ETH_MACMIIDR = data; - - /* Begin transaction. */ - ETH_MACMIIAR |= ETH_MACMIIAR_MB; - - /* Wait for not busy. */ - while (ETH_MACMIIAR & ETH_MACMIIAR_MB); -} - -u16 eth_smi_read(u8 phy, u8 reg) -{ - /* Set PHY and register addresses for write access. */ - ETH_MACMIIAR &= ~(ETH_MACMIIAR_MR | ETH_MACMIIAR_PA | - ETH_MACMIIAR_MW); - ETH_MACMIIAR |= (phy << 11) | (reg << 6); - - /* Begin transaction. */ - ETH_MACMIIAR |= ETH_MACMIIAR_MB; - - /* Wait for not busy. */ - while (ETH_MACMIIAR & ETH_MACMIIAR_MB); - - /* Set register value. */ - return (u16)(ETH_MACMIIDR); -} diff --git a/lib/stm32f1/exti.c b/lib/stm32f1/exti.c deleted file mode 100644 index e4e9748..0000000 --- a/lib/stm32f1/exti.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * 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 -#include - -void exti_set_trigger(u32 extis, exti_trigger_type trig) -{ - switch (trig) { - case EXTI_TRIGGER_RISING: - EXTI_RTSR |= extis; - EXTI_FTSR &= ~extis; - break; - case EXTI_TRIGGER_FALLING: - EXTI_RTSR &= ~extis; - EXTI_FTSR |= extis; - break; - case EXTI_TRIGGER_BOTH: - EXTI_RTSR |= extis; - EXTI_FTSR |= extis; - break; - } -} - -void exti_enable_request(u32 extis) -{ - /* Enable interrupts. */ - EXTI_IMR |= extis; - - /* Enable events. */ - EXTI_EMR |= extis; -} - -void exti_disable_request(u32 extis) -{ - /* Disable interrupts. */ - EXTI_IMR &= ~extis; - - /* Disable events. */ - EXTI_EMR &= ~extis; -} - -/* - * Reset the interrupt request by writing a 1 to the corresponding - * pending bit register. - */ -void exti_reset_request(u32 extis) -{ - EXTI_PR |= extis; -} - -/* - * Remap an external interrupt line to the corresponding pin on the - * specified GPIO port. - * - * TODO: This could be rewritten in fewer lines of code. - */ -void exti_select_source(u32 exti, u32 gpioport) -{ - u8 shift, bits; - - shift = bits = 0; - - switch (exti) { - case EXTI0: - case EXTI4: - case EXTI8: - case EXTI12: - shift = 0; - break; - case EXTI1: - case EXTI5: - case EXTI9: - case EXTI13: - shift = 4; - break; - case EXTI2: - case EXTI6: - case EXTI10: - case EXTI14: - shift = 8; - break; - case EXTI3: - case EXTI7: - case EXTI11: - case EXTI15: - shift = 12; - break; - } - - switch (gpioport) { - case GPIOA: - bits = 0xf; - break; - case GPIOB: - bits = 0xe; - break; - case GPIOC: - bits = 0xd; - break; - case GPIOD: - bits = 0xc; - break; - case GPIOE: - bits = 0xb; - break; - case GPIOF: - bits = 0xa; - break; - case GPIOG: - bits = 0x9; - break; - } - - /* Ensure that only valid EXTI lines are used. */ - if (exti < EXTI4) { - AFIO_EXTICR1 &= ~(0x000F << shift); - AFIO_EXTICR1 |= (~bits << shift); - } else if (exti < EXTI8) { - AFIO_EXTICR2 &= ~(0x000F << shift); - AFIO_EXTICR2 |= (~bits << shift); - } else if (exti < EXTI12) { - AFIO_EXTICR3 &= ~(0x000F << shift); - AFIO_EXTICR3 |= (~bits << shift); - } else if (exti < EXTI16) { - AFIO_EXTICR4 &= ~(0x000F << shift); - AFIO_EXTICR4 |= (~bits << shift); - } -} diff --git a/lib/stm32f1/flash.c b/lib/stm32f1/flash.c deleted file mode 100644 index b8b3d52..0000000 --- a/lib/stm32f1/flash.c +++ /dev/null @@ -1,189 +0,0 @@ -/* - * 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 - -void flash_prefetch_buffer_enable(void) -{ - FLASH_ACR |= FLASH_PRFTBE; -} - -void flash_prefetch_buffer_disable(void) -{ - FLASH_ACR &= ~FLASH_PRFTBE; -} - -void flash_halfcycle_enable(void) -{ - FLASH_ACR |= FLASH_HLFCYA; -} - -void flash_halfcycle_disable(void) -{ - FLASH_ACR &= ~FLASH_HLFCYA; -} - -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_pgerr_flag(void) -{ - FLASH_SR |= FLASH_PGERR; -} - -void flash_clear_eop_flag(void) -{ - FLASH_SR |= FLASH_EOP; -} - -void flash_clear_wrprterr_flag(void) -{ - FLASH_SR |= FLASH_WRPRTERR; -} - -void flash_clear_bsy_flag(void) -{ - FLASH_SR &= ~FLASH_BSY; -} - -void flash_clear_status_flags(void) -{ - flash_clear_pgerr_flag(); - flash_clear_eop_flag(); - flash_clear_wrprterr_flag(); - flash_clear_bsy_flag(); -} - -void flash_unlock_option_bytes(void) -{ - FLASH_OPTKEYR = FLASH_KEY1; - FLASH_OPTKEYR = FLASH_KEY2; -} - -void flash_wait_for_last_operation(void) -{ - while ((FLASH_SR & FLASH_BSY) == FLASH_BSY) - ; -} - -void flash_program_word(u32 address, u32 data) -{ - /* Ensure that all flash operations are complete. */ - flash_wait_for_last_operation(); - - /* Enable writes to flash. */ - FLASH_CR |= FLASH_PG; - - /* Program the first half of the word. */ - (*(volatile u16 *)address) = (u16)data; - - /* Wait for the write to complete. */ - flash_wait_for_last_operation(); - - /* Program the second half of the word. */ - (*(volatile u16 *)(address + 2)) = data >> 16; - - /* 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) -{ - flash_wait_for_last_operation(); - - FLASH_CR |= FLASH_PG; - - (*(volatile u16 *)address) = data; - - flash_wait_for_last_operation(); - - FLASH_CR &= ~FLASH_PG; /* Disable the PG bit. */ -} - -void flash_erase_page(u32 page_address) -{ - flash_wait_for_last_operation(); - - FLASH_CR |= FLASH_PER; - FLASH_AR = page_address; - FLASH_CR |= FLASH_STRT; - - flash_wait_for_last_operation(); - FLASH_CR &= ~FLASH_PER; -} - -void flash_erase_all_pages(void) -{ - flash_wait_for_last_operation(); - - 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_erase_option_bytes(void) -{ - flash_wait_for_last_operation(); - - if ((FLASH_CR & FLASH_OPTWRE) == 0) - flash_unlock_option_bytes(); - - FLASH_CR |= FLASH_OPTER; /* Enable option byte erase. */ - FLASH_CR |= FLASH_STRT; - flash_wait_for_last_operation(); - FLASH_CR &= ~FLASH_OPTER; /* Disable option byte erase. */ -} - -void flash_program_option_bytes(u32 address, u16 data) -{ - flash_wait_for_last_operation(); - - if ((FLASH_CR & FLASH_OPTWRE) == 0) - flash_unlock_option_bytes(); - - FLASH_CR |= FLASH_OPTPG; /* Enable option byte programming. */ - (*(volatile u16 *)address) = data; - flash_wait_for_last_operation(); - FLASH_CR &= ~FLASH_OPTPG; /* Disable option byte programming. */ -} diff --git a/lib/stm32f1/gpio.c b/lib/stm32f1/gpio.c deleted file mode 100644 index f1ea12c..0000000 --- a/lib/stm32f1/gpio.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * - * 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 . - */ - -/* - * Basic GPIO handling API. - * - * Examples: - * gpio_set_mode(GPIOC, GPIO_MODE_OUTPUT_2_MHZ, - * GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); - * gpio_set(GPIOB, GPIO4); - * gpio_clear(GPIOG, GPIO2 | GPIO9); - * gpio_get(GPIOC, GPIO1); - * gpio_toggle(GPIOA, GPIO7 | GPIO8); - * reg16 = gpio_port_read(GPIOD); - * gpio_port_write(GPIOF, 0xc8fe); - * - * TODO: - * - GPIO remapping support - */ - -#include - -void gpio_set_mode(u32 gpioport, u8 mode, u8 cnf, u16 gpios) -{ - u16 i, offset = 0; - u32 crl = 0, crh = 0, tmp32 = 0; - - /* - * We want to set the config only for the pins mentioned in gpios, - * but keeping the others, so read out the actual config first. - */ - crl = GPIO_CRL(gpioport); - crh = GPIO_CRH(gpioport); - - /* Iterate over all bits, use i as the bitnumber. */ - for (i = 0; i < 16; i++) { - /* Only set the config if the bit is set in gpios. */ - if (!((1 << i) & gpios)) - continue; - - /* Calculate bit offset. */ - offset = (i < 8) ? (i * 4) : ((i - 8) * 4); - - /* Use tmp32 to either modify crl or crh. */ - tmp32 = (i < 8) ? crl : crh; - - /* Modify bits are needed. */ - tmp32 &= ~(0b1111 << offset); /* Clear the bits first. */ - tmp32 |= (mode << offset) | (cnf << (offset + 2)); - - /* Write tmp32 into crl or crh, leave the other unchanged. */ - crl = (i < 8) ? tmp32 : crl; - crh = (i >= 8) ? tmp32 : crh; - } - - GPIO_CRL(gpioport) = crl; - GPIO_CRH(gpioport) = crh; -} - -void gpio_set(u32 gpioport, u16 gpios) -{ - GPIO_BSRR(gpioport) = gpios; -} - -void gpio_clear(u32 gpioport, u16 gpios) -{ - GPIO_BRR(gpioport) = gpios; -} - -u16 gpio_get(u32 gpioport, u16 gpios) -{ - return gpio_port_read(gpioport) & gpios; -} - -void gpio_toggle(u32 gpioport, u16 gpios) -{ - GPIO_ODR(gpioport) ^= gpios; -} - -u16 gpio_port_read(u32 gpioport) -{ - return (u16)GPIO_IDR(gpioport); -} - -void gpio_port_write(u32 gpioport, u16 data) -{ - GPIO_ODR(gpioport) = data; -} - -void gpio_port_config_lock(u32 gpioport, u16 gpios) -{ - u32 reg32; - - /* Special "Lock Key Writing Sequence", see datasheet. */ - GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ - GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */ - GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ - reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */ - reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */ - - /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */ -} diff --git a/lib/stm32f1/libopencm3_stm32f1.ld b/lib/stm32f1/libopencm3_stm32f1.ld deleted file mode 100644 index fda7d02..0000000 --- a/lib/stm32f1/libopencm3_stm32f1.ld +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * - * 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 . - */ - -/* 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 sections. */ -SECTIONS -{ - . = ORIGIN(rom); - - .text : { - *(.vectors) /* Vector table */ - *(.text*) /* Program code */ - *(.rodata*) /* Read-only data */ - _etext = .; - } >rom - - . = ORIGIN(ram); - - .data : { - _data = .; - *(.data*) /* Read-write initialized data */ - _edata = .; - } >ram AT >rom - - .bss : { - *(.bss*) /* Read-write zero initialized data */ - *(COMMON) - _ebss = .; - } >ram AT >rom - - /* - * 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) } - - end = .; -} - -PROVIDE(_stack = 0x20000800); - diff --git a/lib/stm32f1/rcc.c b/lib/stm32f1/rcc.c deleted file mode 100644 index 689cabb..0000000 --- a/lib/stm32f1/rcc.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Federico Ruiz-Ugalde - * Copyright (C) 2009 Uwe Hermann - * Copyright (C) 2010 Thomas Otto - * - * 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 -#include - -/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset */ -u32 rcc_ppre1_frequency = 8000000; -u32 rcc_ppre2_frequency = 8000000; - -void rcc_osc_ready_int_clear(osc_t 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(osc_t 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(osc_t 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(osc_t 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; - } - - /* Shouldn't be reached. */ - return -1; -} - -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(osc_t 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_osc_on(osc_t 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(osc_t 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(osc_t 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(osc_t 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_peripheral_enable_clock(volatile u32 *reg, u32 en) -{ - *reg |= en; -} - -void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en) -{ - *reg &= ~en; -} - -void rcc_peripheral_reset(volatile u32 *reg, u32 reset) -{ - *reg |= reset; -} - -void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset) -{ - *reg &= ~clear_reset; -} - -void rcc_set_sysclk_source(u32 clk) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 1) | (1 << 0)); - RCC_CFGR = (reg32 | clk); -} - -void rcc_set_pll_multiplication_factor(u32 mul) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 21) | (1 << 20) | (1 << 19) | (1 << 18)); - RCC_CFGR = (reg32 | (mul << 18)); -} - -void rcc_set_pll_source(u32 pllsrc) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~(1 << 16); - RCC_CFGR = (reg32 | (pllsrc << 16)); -} - -void rcc_set_pllxtpre(u32 pllxtpre) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~(1 << 17); - RCC_CFGR = (reg32 | (pllxtpre << 17)); -} - -void rcc_set_adcpre(u32 adcpre) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 14) | (1 << 15)); - RCC_CFGR = (reg32 | (adcpre << 14)); -} - -void rcc_set_ppre2(u32 ppre2) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 11) | (1 << 12) | (1 << 13)); - RCC_CFGR = (reg32 | (ppre2 << 11)); -} - -void rcc_set_ppre1(u32 ppre1) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 8) | (1 << 9) | (1 << 10)); - RCC_CFGR = (reg32 | (ppre1 << 8)); -} - -void rcc_set_hpre(u32 hpre) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)); - RCC_CFGR = (reg32 | (hpre << 4)); -} - -void rcc_set_usbpre(u32 usbpre) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~(1 << 22); - RCC_CFGR = (reg32 | (usbpre << 22)); -} - -u32 rcc_system_clock_source(void) -{ - /* Return the clock source which is used as system clock. */ - return ((RCC_CFGR & 0x000c) >> 2); -} - -/* - * These functions are setting up the whole clock system for the most common - * input clock and output clock configurations. - */ -void rcc_clock_setup_in_hsi_out_64mhz(void) -{ - /* 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_SYSCLKSEL_HSICLK); - - /* - * Set prescalers for AHB, ADC, ABP1, ABP2. - * Do this before touching the PLL (TODO: why?). - */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 64MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 8MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 32MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 64MHz Max. 72MHz */ - - /* - * Sysclk is running with 64MHz -> 2 waitstates. - * 0WS from 0-24MHz - * 1WS from 24-48MHz - * 2WS from 48-72MHz - */ - flash_set_ws(FLASH_LATENCY_2WS); - - /* - * Set the PLL multiplication factor to 16. - * 8MHz (internal) * 16 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 64MHz - */ - rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL16); - - /* Select HSI/2 as PLL source. */ - rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); - - /* Set the peripheral clock frequencies used */ - rcc_ppre1_frequency = 32000000; - rcc_ppre2_frequency = 64000000; -} - -void rcc_clock_setup_in_hsi_out_48mhz(void) -{ - /* 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_SYSCLKSEL_HSICLK); - - /* - * Set prescalers for AHB, ADC, ABP1, ABP2. - * Do this before touching the PLL (TODO: why?). - */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 48MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 6MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 24MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 48MHz Max. 72MHz */ - rcc_set_usbpre(RCC_CFGR_USBPRE_PLL_CLK_NODIV); /* Set. 48MHz Max. 48MHz */ - - /* - * Sysclk runs with 48MHz -> 1 waitstates. - * 0WS from 0-24MHz - * 1WS from 24-48MHz - * 2WS from 48-72MHz - */ - flash_set_ws(FLASH_LATENCY_1WS); - - /* - * Set the PLL multiplication factor to 12. - * 8MHz (internal) * 12 (multiplier) / 2 (PLLSRC_HSI_CLK_DIV2) = 48MHz - */ - rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL12); - - /* Select HSI/2 as PLL source. */ - rcc_set_pll_source(RCC_CFGR_PLLSRC_HSI_CLK_DIV2); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); - - /* Set the peripheral clock frequencies used */ - rcc_ppre1_frequency = 24000000; - rcc_ppre2_frequency = 48000000; -} - -void rcc_clock_setup_in_hse_8mhz_out_24mhz(void) -{ - /* 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_SYSCLKSEL_HSICLK); - - /* Enable external high-speed oscillator 8MHz. */ - rcc_osc_on(HSE); - rcc_wait_for_osc_ready(HSE); - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); - - /* - * Set prescalers for AHB, ADC, ABP1, ABP2. - * Do this before touching the PLL (TODO: why?). - */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 24MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2); /* Set. 12MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_NODIV); /* Set. 24MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 24MHz Max. 72MHz */ - - /* - * Sysclk runs with 24MHz -> 0 waitstates. - * 0WS from 0-24MHz - * 1WS from 24-48MHz - * 2WS from 48-72MHz - */ - flash_set_ws(FLASH_LATENCY_0WS); - - /* - * Set the PLL multiplication factor to 3. - * 8MHz (external) * 3 (multiplier) = 24MHz - */ - rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL3); - - /* Select HSE as PLL source. */ - rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); - - /* - * External frequency undivided before entering PLL - * (only valid/needed for HSE). - */ - rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); - - /* Set the peripheral clock frequencies used */ - rcc_ppre1_frequency = 24000000; - rcc_ppre2_frequency = 24000000; -} -void rcc_clock_setup_in_hse_8mhz_out_72mhz(void) -{ - /* 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_SYSCLKSEL_HSICLK); - - /* Enable external high-speed oscillator 8MHz. */ - rcc_osc_on(HSE); - rcc_wait_for_osc_ready(HSE); - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); - - /* - * Set prescalers for AHB, ADC, ABP1, ABP2. - * Do this before touching the PLL (TODO: why?). - */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV8); /* Set. 9MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - - /* - * Sysclk runs with 72MHz -> 2 waitstates. - * 0WS from 0-24MHz - * 1WS from 24-48MHz - * 2WS from 48-72MHz - */ - flash_set_ws(FLASH_LATENCY_2WS); - - /* - * Set the PLL multiplication factor to 9. - * 8MHz (external) * 9 (multiplier) = 72MHz - */ - rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9); - - /* Select HSE as PLL source. */ - rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); - - /* - * External frequency undivided before entering PLL - * (only valid/needed for HSE). - */ - rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); - - /* Set the peripheral clock frequencies used */ - rcc_ppre1_frequency = 36000000; - rcc_ppre2_frequency = 72000000; -} - -void rcc_clock_setup_in_hse_12mhz_out_72mhz(void) -{ - /* 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_SYSCLKSEL_HSICLK); - - /* Enable external high-speed oscillator 16MHz. */ - rcc_osc_on(HSE); - rcc_wait_for_osc_ready(HSE); - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); - - /* - * Set prescalers for AHB, ADC, ABP1, ABP2. - * Do this before touching the PLL (TODO: why?). - */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - - /* - * Sysclk runs with 72MHz -> 2 waitstates. - * 0WS from 0-24MHz - * 1WS from 24-48MHz - * 2WS from 48-72MHz - */ - flash_set_ws(FLASH_LATENCY_2WS); - - /* - * Set the PLL multiplication factor to 9. - * 12MHz (external) * 6 (multiplier) / 1 (PLLXTPRE_HSE_CLK) = 72MHz - */ - rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL6); - - /* Select HSI as PLL source. */ - rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); - - /* - * Divide external frequency by 2 before entering PLL - * (only valid/needed for HSE). - */ - rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); - - /* Set the peripheral clock frequencies used */ - rcc_ppre1_frequency = 36000000; - rcc_ppre2_frequency = 72000000; -} - -void rcc_clock_setup_in_hse_16mhz_out_72mhz(void) -{ - /* 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_SYSCLKSEL_HSICLK); - - /* Enable external high-speed oscillator 16MHz. */ - rcc_osc_on(HSE); - rcc_wait_for_osc_ready(HSE); - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_HSECLK); - - /* - * Set prescalers for AHB, ADC, ABP1, ABP2. - * Do this before touching the PLL (TODO: why?). - */ - rcc_set_hpre(RCC_CFGR_HPRE_SYSCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV6); /* Set. 12MHz Max. 14MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE1_HCLK_DIV2); /* Set. 36MHz Max. 36MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE2_HCLK_NODIV); /* Set. 72MHz Max. 72MHz */ - - /* - * Sysclk runs with 72MHz -> 2 waitstates. - * 0WS from 0-24MHz - * 1WS from 24-48MHz - * 2WS from 48-72MHz - */ - flash_set_ws(FLASH_LATENCY_2WS); - - /* - * Set the PLL multiplication factor to 9. - * 16MHz (external) * 9 (multiplier) / 2 (PLLXTPRE_HSE_CLK_DIV2) = 72MHz - */ - rcc_set_pll_multiplication_factor(RCC_CFGR_PLLMUL_PLL_CLK_MUL9); - - /* Select HSI as PLL source. */ - rcc_set_pll_source(RCC_CFGR_PLLSRC_HSE_CLK); - - /* - * Divide external frequency by 2 before entering PLL - * (only valid/needed for HSE). - */ - rcc_set_pllxtpre(RCC_CFGR_PLLXTPRE_HSE_CLK_DIV2); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* Select PLL as SYSCLK source. */ - rcc_set_sysclk_source(RCC_CFGR_SW_SYSCLKSEL_PLLCLK); - - /* Set the peripheral clock frequencies used */ - rcc_ppre1_frequency = 36000000; - rcc_ppre2_frequency = 72000000; -} - -void rcc_backupdomain_reset(void) -{ - /* Set the backup domain software reset. */ - RCC_BDCR |= RCC_BDCR_BDRST; - - /* Clear the backup domain software reset. */ - RCC_BDCR &= ~RCC_BDCR_BDRST; -} diff --git a/lib/stm32f1/rtc.c b/lib/stm32f1/rtc.c deleted file mode 100644 index c187be9..0000000 --- a/lib/stm32f1/rtc.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Uwe Hermann - * Copyright (C) 2010 Lord James - * - * 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 -#include -#include - -void rtc_awake_from_off(osc_t clock_source) -{ - u32 reg32; - - /* Enable power and backup interface clocks. */ - RCC_APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); - - /* Enable access to the backup registers and the RTC. */ - PWR_CR |= PWR_CR_DBP; - - /* - * Reset the backup domain, clears everything RTC related. - * If not wanted use the rtc_awake_from_standby() function. - */ - rcc_backupdomain_reset(); - - switch (clock_source) { - case LSE: - /* Turn the LSE on and wait while it stabilises. */ - RCC_BDCR |= RCC_BDCR_LSEON; - while ((reg32 = (RCC_BDCR & RCC_BDCR_LSERDY)) == 0); - - /* Choose LSE as the RTC clock source. */ - RCC_BDCR &= ~((1 << 8) | (1 << 9)); - RCC_BDCR |= (1 << 8); - break; - case LSI: - /* Turn the LSI on and wait while it stabilises. */ - RCC_CSR |= RCC_CSR_LSION; - while ((reg32 = (RCC_CSR & RCC_CSR_LSIRDY)) == 0); - - /* Choose LSI as the RTC clock source. */ - RCC_BDCR &= ~((1 << 8) | (1 << 9)); - RCC_BDCR |= (1 << 9); - break; - case HSE: - /* Turn the HSE on and wait while it stabilises. */ - RCC_CR |= RCC_CR_HSEON; - while ((reg32 = (RCC_CR & RCC_CR_HSERDY)) == 0); - - /* Choose HSE as the RTC clock source. */ - RCC_BDCR &= ~((1 << 8) | (1 << 9)); - RCC_BDCR |= (1 << 9) | (1 << 8); - break; - case PLL: - case HSI: - /* Unusable clock source, here to prevent warnings. */ - /* Turn off clock sources to RTC. */ - RCC_BDCR &= ~((1 << 8) | (1 << 9)); - break; - } - - /* Enable the RTC. */ - RCC_BDCR |= RCC_BDCR_RTCEN; - - /* Wait for the RSF bit in RTC_CRL to be set by hardware. */ - RTC_CRL &= ~RTC_CRL_RSF; - while ((reg32 = (RTC_CRL & RTC_CRL_RSF)) == 0); - - /* Wait for the last write operation to finish. */ - /* TODO: Necessary? */ - while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); -} - -void rtc_enter_config_mode(void) -{ - u32 reg32; - - /* Wait until the RTOFF bit is 1 (no RTC register writes ongoing). */ - while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); - - /* Enter configuration mode. */ - RTC_CRL |= RTC_CRL_CNF; -} - -void rtc_exit_config_mode(void) -{ - /* u32 reg32; */ - - /* Exit configuration mode. */ - RTC_CRL &= ~RTC_CRL_CNF; - - /* Wait until the RTOFF bit is 1 (our RTC register write finished). */ - /* while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); */ - /* TODO: Unnecessary since we poll the bit on config entry(?) */ -} - -void rtc_set_alarm_time(u32 alarm_time) -{ - rtc_enter_config_mode(); - RTC_ALRL = (alarm_time & 0x0000ffff); - RTC_ALRH = (alarm_time & 0xffff0000) >> 16; - rtc_exit_config_mode(); -} - -void rtc_enable_alarm(void) -{ - rtc_enter_config_mode(); - RTC_CRH |= RTC_CRH_ALRIE; - rtc_exit_config_mode(); -} - -void rtc_disable_alarm(void) -{ - rtc_enter_config_mode(); - RTC_CRH &= ~RTC_CRH_ALRIE; - rtc_exit_config_mode(); -} - -void rtc_set_prescale_val(u32 prescale_val) -{ - rtc_enter_config_mode(); - RTC_PRLL = prescale_val & 0x0000ffff; /* PRL[15:0] */ - RTC_PRLH = (prescale_val & 0x000f0000) >> 16; /* PRL[19:16] */ - rtc_exit_config_mode(); -} - -u32 rtc_get_counter_val(void) -{ - return (RTC_CNTH << 16) | RTC_CNTL; -} - -u32 rtc_get_prescale_div_val(void) -{ - return (RTC_DIVH << 16) | RTC_DIVL; -} - -u32 rtc_get_alarm_val(void) -{ - return (RTC_ALRH << 16) | RTC_ALRL; -} - -void rtc_set_counter_val(u32 counter_val) -{ - rtc_enter_config_mode(); - RTC_CNTH = (counter_val & 0xffff0000) >> 16; /* CNT[31:16] */ - RTC_CNTL = counter_val & 0x0000ffff; /* CNT[15:0] */ - rtc_exit_config_mode(); -} - -void rtc_interrupt_enable(rtcflag_t flag_val) -{ - rtc_enter_config_mode(); - - /* Set the correct interrupt enable. */ - switch(flag_val) { - case RTC_SEC: - RTC_CRH |= RTC_CRH_SECIE; - break; - case RTC_ALR: - RTC_CRH |= RTC_CRH_ALRIE; - break; - case RTC_OW: - RTC_CRH |= RTC_CRH_OWIE; - break; - } - - rtc_exit_config_mode(); -} - -void rtc_interrupt_disable(rtcflag_t flag_val) -{ - rtc_enter_config_mode(); - - /* Disable the correct interrupt enable. */ - switch(flag_val) { - case RTC_SEC: - RTC_CRH &= ~RTC_CRH_SECIE; - break; - case RTC_ALR: - RTC_CRH &= ~RTC_CRH_ALRIE; - break; - case RTC_OW: - RTC_CRH &= ~RTC_CRH_OWIE; - break; - } - - rtc_exit_config_mode(); -} - -void rtc_clear_flag(rtcflag_t flag_val) -{ - /* Configuration mode not needed. */ - - /* Clear the correct flag. */ - switch(flag_val) { - case RTC_SEC: - RTC_CRL &= ~RTC_CRL_SECF; - break; - case RTC_ALR: - RTC_CRL &= ~RTC_CRL_ALRF; - break; - case RTC_OW: - RTC_CRL &= ~RTC_CRL_OWF; - break; - } -} - -u32 rtc_check_flag(rtcflag_t flag_val) -{ - u32 reg32; - - /* Read correct flag. */ - switch(flag_val) { - case RTC_SEC: - reg32 = RTC_CRL & RTC_CRL_SECF; - break; - case RTC_ALR: - reg32 = RTC_CRL & RTC_CRL_ALRF; - break; - case RTC_OW: - reg32 = RTC_CRL & RTC_CRL_OWF; - break; - default: - reg32 = 0; - break; - } - - return reg32; -} - -void rtc_awake_from_standby(void) -{ - u32 reg32; - - /* Enable power and backup interface clocks. */ - RCC_APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); - - /* Enable access to the backup registers and the RTC. */ - PWR_CR |= PWR_CR_DBP; - - /* Wait for the RSF bit in RTC_CRL to be set by hardware. */ - RTC_CRL &= ~RTC_CRL_RSF; - while ((reg32 = (RTC_CRL & RTC_CRL_RSF)) == 0); - - /* Wait for the last write operation to finish. */ - /* TODO: Necessary? */ - while ((reg32 = (RTC_CRL & RTC_CRL_RTOFF)) == 0); -} - -void rtc_auto_awake(osc_t clock_source, u32 prescale_val) -{ - u32 reg32; - - /* Enable power and backup interface clocks. */ - RCC_APB1ENR |= (RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN); - - /* Enable access to the backup registers and the RTC. */ - /* TODO: Not sure if this is necessary to just read the flag. */ - PWR_CR |= PWR_CR_DBP; - - if ((reg32 = RCC_BDCR & RCC_BDCR_RTCEN) != 0) { - rtc_awake_from_standby(); - } else { - rtc_awake_from_off(clock_source); - rtc_set_prescale_val(prescale_val); - } -} diff --git a/lib/stm32f1/scb.c b/lib/stm32f1/scb.c deleted file mode 100644 index 54c5776..0000000 --- a/lib/stm32f1/scb.c +++ /dev/null @@ -1,30 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Gareth McMullin - * - * 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 - -void scb_reset_core(void) -{ - SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_VECTRESET; -} - -void scb_reset_system(void) -{ - SCB_AIRCR = SCB_AIRCR_VECTKEY | SCB_AIRCR_SYSRESETREQ; -} diff --git a/lib/stm32f1/timer.c b/lib/stm32f1/timer.c deleted file mode 100644 index a61f67f..0000000 --- a/lib/stm32f1/timer.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Edward Cheeseman - * - * 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 . - */ - -/* - * Basic TIMER handling API. - * - * Examples: - * timer_set_mode(TIM1, TIM_CR1_CKD_CK_INT_MUL_2, - * TIM_CR1_CMS_CENTRE_3, TIM_CR1_DIR_UP); - */ - -#include -#include - -void timer_reset(u32 timer_peripheral) -{ - switch (timer_peripheral) { - case TIM1: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM1RST); - break; - case TIM2: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM2RST); - break; - case TIM3: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM3RST); - break; - case TIM4: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM4RST); - break; - case TIM5: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM5RST); - break; - case TIM6: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM6RST); - break; - case TIM7: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM7RST); - break; - case TIM8: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM8RST); - break; -/* These timers are not supported in libopencm3 yet */ -/* - case TIM9: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM9RST); - break; - case TIM10: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM10RST); - break; - case TIM11: - rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST); - rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_TIM11RST); - break; - case TIM12: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM12RST); - break; - case TIM13: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM13RST); - break; - case TIM14: - rcc_peripheral_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST); - rcc_peripheral_clear_reset(&RCC_APB1RSTR, RCC_APB1RSTR_TIM14RST); - break; -*/ - } -} - -void timer_enable_irq(u32 timer_peripheral, u32 irq) -{ - TIM_DIER(timer_peripheral) |= irq; -} - -void timer_disable_irq(u32 timer_peripheral, u32 irq) -{ - TIM_DIER(timer_peripheral) &= ~irq; -} - -bool timer_get_flag(u32 timer_peripheral, u32 flag) -{ - if (((TIM_SR(timer_peripheral) & flag) != 0) && - ((TIM_DIER(timer_peripheral) & flag) != 0)) { - return true; - } - - return false; -} - -void timer_clear_flag(u32 timer_peripheral, u32 flag) -{ - TIM_SR(timer_peripheral) &= ~flag; -} - -void timer_set_mode(u32 timer_peripheral, u8 clock_div, - u8 alignment, u8 direction) -{ - u32 cr1; - - cr1 = TIM_CR1(timer_peripheral); - - cr1 &= ~(TIM_CR1_CKD_CK_INT_MASK | - TIM_CR1_CMS_MASK | - TIM_CR1_DIR_DOWN); - - cr1 |= clock_div | alignment | direction; - - TIM_CR1(timer_peripheral) = cr1; -} - -void timer_set_clock_division(u32 timer_peripheral, u32 clock_div) -{ - clock_div &= TIM_CR1_CKD_CK_INT_MASK; - TIM_CR1(timer_peripheral) &= ~TIM_CR1_CKD_CK_INT_MASK; - TIM_CR1(timer_peripheral) |= clock_div; -} - -void timer_enable_preload(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_ARPE; -} - -void timer_disable_preload(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_ARPE; -} - -void timer_set_alignment(u32 timer_peripheral, u32 alignment) -{ - alignment &= TIM_CR1_CMS_MASK; - TIM_CR1(timer_peripheral) &= ~TIM_CR1_CMS_MASK; - TIM_CR1(timer_peripheral) |= alignment; -} - -void timer_direction_up(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_DIR_DOWN; -} - -void timer_direction_down(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_DIR_DOWN; -} - -void timer_one_shot_mode(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_OPM; -} - -void timer_continuous_mode(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_OPM; -} - -void timer_update_on_any(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_URS; -} - -void timer_update_on_overflow(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_URS; -} - -void timer_enable_update_event(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_UDIS; -} - -void timer_disable_update_event(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_UDIS; -} - -void timer_enable_counter(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) |= TIM_CR1_CEN; -} - -void timer_disable_counter(u32 timer_peripheral) -{ - TIM_CR1(timer_peripheral) &= ~TIM_CR1_CEN; -} - -void timer_set_output_idle_state(u32 timer_peripheral, u32 outputs) -{ - TIM_CR2(timer_peripheral) |= outputs & TIM_CR2_OIS_MASK; -} - -void timer_reset_output_idle_state(u32 timer_peripheral, u32 outputs) -{ - TIM_CR2(timer_peripheral) &= ~(outputs & TIM_CR2_OIS_MASK); -} - -void timer_set_ti1_ch123_xor(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_TI1S; -} - -void timer_set_ti1_ch1(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_TI1S; -} - -void timer_set_master_mode(u32 timer_peripheral, u32 mode) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_MMS_MASK; - TIM_CR2(timer_peripheral) |= mode; -} - -void timer_set_dma_on_compare_event(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCDS; -} - -void timer_set_dma_on_update_event(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_CCDS; -} - -void timer_enable_compare_control_update_on_trigger(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_CCUS; -} - -void timer_disable_compare_control_update_on_trigger(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCUS; -} - -void timer_enable_preload_complementry_enable_bits(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) |= TIM_CR2_CCPC; -} - -void timer_disable_preload_complementry_enable_bits(u32 timer_peripheral) -{ - TIM_CR2(timer_peripheral) &= ~TIM_CR2_CCPC; -} - -void timer_set_prescaler(u32 timer_peripheral, u32 value) -{ - TIM_PSC(timer_peripheral) = value; -} - -void timer_set_repetition_counter(u32 timer_peripheral, u32 value) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_RCR(timer_peripheral) = value; -} - -void timer_set_period(u32 timer_peripheral, u32 period) -{ - TIM_ARR(timer_peripheral) = period; -} - -void timer_enable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1CE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2CE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3CE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4CE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ - break; - } -} - -void timer_disable_oc_clear(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1CE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2CE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3CE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4CE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ - break; - } -} - -void timer_set_oc_fast_mode(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1FE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2FE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3FE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4FE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as fast enable only applies to the whole channel. */ - break; - } -} - -void timer_set_oc_slow_mode(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1FE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2FE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3FE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4FE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_set_oc_mode(u32 timer_peripheral, enum tim_oc_id oc_id, - enum tim_oc_mode oc_mode) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC1S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC1S_OUT; - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1M_PWM2; - break; - } - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_CC2S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_CC2S_OUT; - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2M_PWM2; - break; - } - break; - case TIM_OC3: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC3S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC3S_OUT; - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC3M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3M_PWM2; - break; - } - break; - case TIM_OC4: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR2_CC4S_MASK; - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_CC4S_OUT; - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4M_MASK; - switch (oc_mode) { - case TIM_OCM_FROZEN: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FROZEN; - break; - case TIM_OCM_ACTIVE: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR2_OC4M_ACTIVE; - break; - case TIM_OCM_INACTIVE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_INACTIVE; - break; - case TIM_OCM_TOGGLE: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_TOGGLE; - break; - case TIM_OCM_FORCE_LOW: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_LOW; - break; - case TIM_OCM_FORCE_HIGH: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_FORCE_HIGH; - break; - case TIM_OCM_PWM1: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM1; - break; - case TIM_OCM_PWM2: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4M_PWM2; - break; - } - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_enable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC1PE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) |= TIM_CCMR1_OC2PE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC3PE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) |= TIM_CCMR2_OC4PE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_disable_oc_preload(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC1PE; - break; - case TIM_OC2: - TIM_CCMR1(timer_peripheral) &= ~TIM_CCMR1_OC2PE; - break; - case TIM_OC3: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC3PE; - break; - case TIM_OC4: - TIM_CCMR2(timer_peripheral) &= ~TIM_CCMR2_OC4PE; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_set_oc_polarity_high(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1P; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2P; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3P; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4P; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NP; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NP; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NP; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_set_oc_polarity_low(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1P; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2P; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3P; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC4P; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NP; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NP; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NP; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_enable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1E; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2E; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3E; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC4E; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC1NE; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC2NE; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) |= TIM_CCER_CC3NE; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_disable_oc_output(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1E; - break; - case TIM_OC2: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2E; - break; - case TIM_OC3: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3E; - break; - case TIM_OC4: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC4E; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to TIM1 and TIM8 only. */ - break; - } - - /* Acting for TIM1 and TIM8 only from here onwards. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC1NE; - break; - case TIM_OC2N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC2NE; - break; - case TIM_OC3N: - TIM_CCER(timer_peripheral) &= ~TIM_CCER_CC3NE; - break; - case TIM_OC1: - case TIM_OC2: - case TIM_OC3: - case TIM_OC4: - /* Ignoring as this option was already set above. */ - break; - } -} - -void timer_set_oc_idle_state_set(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - /* Acting for TIM1 and TIM8 only. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1; - break; - case TIM_OC1N: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS1N; - break; - case TIM_OC2: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2; - break; - case TIM_OC2N: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS2N; - break; - case TIM_OC3: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3; - break; - case TIM_OC3N: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS3N; - break; - case TIM_OC4: - TIM_CR2(timer_peripheral) |= TIM_CR2_OIS4; - break; - } -} - -void timer_set_oc_idle_state_unset(u32 timer_peripheral, enum tim_oc_id oc_id) -{ - /* Acting for TIM1 and TIM8 only. */ - if ((timer_peripheral != TIM1) && (timer_peripheral != TIM8)) - return; - - switch (oc_id) { - case TIM_OC1: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1; - break; - case TIM_OC1N: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS1N; - break; - case TIM_OC2: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2; - break; - case TIM_OC2N: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS2N; - break; - case TIM_OC3: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3; - break; - case TIM_OC3N: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS3N; - break; - case TIM_OC4: - TIM_CR2(timer_peripheral) &= ~TIM_CR2_OIS4; - break; - } -} - -void timer_set_oc_value(u32 timer_peripheral, enum tim_oc_id oc_id, u32 value) -{ - switch (oc_id) { - case TIM_OC1: - TIM_CCR1(timer_peripheral) = value; - break; - case TIM_OC2: - TIM_CCR2(timer_peripheral) = value; - break; - case TIM_OC3: - TIM_CCR3(timer_peripheral) = value; - break; - case TIM_OC4: - TIM_CCR4(timer_peripheral) = value; - break; - case TIM_OC1N: - case TIM_OC2N: - case TIM_OC3N: - /* Ignoring as this option applies to the whole channel. */ - break; - } -} - -void timer_enable_break_main_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_MOE; -} - -void timer_disable_break_main_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_MOE; -} - -void timer_enable_break_automatic_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_AOE; -} - -void timer_disable_break_automatic_output(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_AOE; -} - -void timer_set_break_polarity_high(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKP; -} - -void timer_set_break_polarity_low(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKP; -} - -void timer_enable_break(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_BKE; -} - -void timer_disable_break(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_BKE; -} - -void timer_set_enabled_off_state_in_run_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSR; -} - -void timer_set_disabled_off_state_in_run_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSR; -} - -void timer_set_enabled_off_state_in_idle_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= TIM_BDTR_OSSI; -} - -void timer_set_disabled_off_state_in_idle_mode(u32 timer_peripheral) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) &= ~TIM_BDTR_OSSI; -} - -void timer_set_break_lock(u32 timer_peripheral, u32 lock) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= lock; -} - -void timer_set_deadtime(u32 timer_peripheral, u32 deadtime) -{ - if ((timer_peripheral == TIM1) || (timer_peripheral == TIM8)) - TIM_BDTR(timer_peripheral) |= deadtime; -} - -void timer_generate_event(u32 timer_peripheral, u32 event) -{ - TIM_EGR(timer_peripheral) |= event; -} - -u32 timer_get_counter(u32 timer_peripheral) -{ - return TIM_CNT(timer_peripheral); -} diff --git a/lib/stm32f1/vector.c b/lib/stm32f1/vector.c deleted file mode 100644 index 39bd9a1..0000000 --- a/lib/stm32f1/vector.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski - * - * 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 . - */ - -#define WEAK __attribute__ ((weak)) - -/* Symbols exported by linker script */ -extern unsigned _etext, _data, _edata, _ebss, _stack; - -void main(void); -void reset_handler(void); -void blocking_handler(void); -void null_handler(void); - -void WEAK nmi_handler(void); -void WEAK hard_fault_handler(void); -void WEAK mem_manage_handler(void); -void WEAK bus_fault_handler(void); -void WEAK usage_fault_handler(void); -void WEAK sv_call_handler(void); -void WEAK debug_monitor_handler(void); -void WEAK pend_sv_handler(void); -void WEAK sys_tick_handler(void); -void WEAK wwdg_isr(void); -void WEAK pvd_isr(void); -void WEAK tamper_isr(void); -void WEAK rtc_isr(void); -void WEAK flash_isr(void); -void WEAK rcc_isr(void); -void WEAK exti0_isr(void); -void WEAK exti1_isr(void); -void WEAK exti2_isr(void); -void WEAK exti3_isr(void); -void WEAK exti4_isr(void); -void WEAK dma1_channel1_isr(void); -void WEAK dma1_channel2_isr(void); -void WEAK dma1_channel3_isr(void); -void WEAK dma1_channel4_isr(void); -void WEAK dma1_channel5_isr(void); -void WEAK dma1_channel6_isr(void); -void WEAK dma1_channel7_isr(void); -void WEAK adc1_2_isr(void); -void WEAK usb_hp_can_tx_isr(void); -void WEAK usb_lp_can_rx0_isr(void); -void WEAK can_rx1_isr(void); -void WEAK can_sce_isr(void); -void WEAK exti9_5_isr(void); -void WEAK tim1_brk_isr(void); -void WEAK tim1_up_isr(void); -void WEAK tim1_trg_com_isr(void); -void WEAK tim1_cc_isr(void); -void WEAK tim2_isr(void); -void WEAK tim3_isr(void); -void WEAK tim4_isr(void); -void WEAK i2c1_ev_isr(void); -void WEAK i2c1_er_isr(void); -void WEAK i2c2_ev_isr(void); -void WEAK i2c2_er_isr(void); -void WEAK spi1_isr(void); -void WEAK spi2_isr(void); -void WEAK usart1_isr(void); -void WEAK usart2_isr(void); -void WEAK usart3_isr(void); -void WEAK exti15_10_isr(void); -void WEAK rtc_alarm_isr(void); -void WEAK usb_wakeup_isr(void); -void WEAK tim8_brk_isr(void); -void WEAK tim8_up_isr(void); -void WEAK tim8_trg_com_isr(void); -void WEAK tim8_cc_isr(void); -void WEAK adc3_isr(void); -void WEAK fsmc_isr(void); -void WEAK sdio_isr(void); -void WEAK tim5_isr(void); -void WEAK spi3_isr(void); -void WEAK usart4_isr(void); -void WEAK usart5_isr(void); -void WEAK tim6_isr(void); -void WEAK tim7_isr(void); -void WEAK dma2_channel1_isr(void); -void WEAK dma2_channel2_isr(void); -void WEAK dma2_channel3_isr(void); -void WEAK dma2_channel4_5_isr(void); -void WEAK dma2_channel5_isr(void); -void WEAK eth_isr(void); -void WEAK eth_wkup_isr(void); -void WEAK can2_tx_isr(void); -void WEAK can2_rx0_isr(void); -void WEAK can2_rx1_isr(void); -void WEAK can2_sce_isr(void); -void WEAK otg_fs_isr(void); - - -__attribute__ ((section(".vectors"))) -void (*const vector_table[]) (void) = { - (void*)&_stack, - reset_handler, - nmi_handler, - hard_fault_handler, - mem_manage_handler, - bus_fault_handler, - usage_fault_handler, - 0, 0, 0, 0, /* Reserved */ - sv_call_handler, - debug_monitor_handler, - 0, /* Reserved */ - pend_sv_handler, - sys_tick_handler, - wwdg_isr, - pvd_isr, - tamper_isr, - rtc_isr, - flash_isr, - rcc_isr, - exti0_isr, - exti1_isr, - exti2_isr, - exti3_isr, - exti4_isr, - dma1_channel1_isr, - dma1_channel2_isr, - dma1_channel3_isr, - dma1_channel4_isr, - dma1_channel5_isr, - dma1_channel6_isr, - dma1_channel7_isr, - adc1_2_isr, - usb_hp_can_tx_isr, - usb_lp_can_rx0_isr, - can_rx1_isr, - can_sce_isr, - exti9_5_isr, - tim1_brk_isr, - tim1_up_isr, - tim1_trg_com_isr, - tim1_cc_isr, - tim2_isr, - tim3_isr, - tim4_isr, - i2c1_ev_isr, - i2c1_er_isr, - i2c2_ev_isr, - i2c2_er_isr, - spi1_isr, - spi2_isr, - usart1_isr, - usart2_isr, - usart3_isr, - exti15_10_isr, - rtc_alarm_isr, - usb_wakeup_isr, - tim8_brk_isr, - tim8_up_isr, - tim8_trg_com_isr, - tim8_cc_isr, - adc3_isr, - fsmc_isr, - sdio_isr, - tim5_isr, - spi3_isr, - usart4_isr, - usart5_isr, - tim6_isr, - tim7_isr, - dma2_channel1_isr, - dma2_channel2_isr, - dma2_channel3_isr, - dma2_channel4_5_isr, - dma2_channel5_isr, - eth_isr, - eth_wkup_isr, - can2_tx_isr, - can2_rx0_isr, - can2_rx1_isr, - can2_sce_isr, - otg_fs_isr, -}; - -void reset_handler(void) -{ - volatile unsigned *src, *dest; - asm("MSR msp, %0" : : "r"(&_stack)); - - for (src = &_etext, dest = &_data; dest < &_edata; src++, dest++) - *dest = *src; - - while (dest < &_ebss) - *dest++ = 0; - - /* Call the application's entry point. */ - main(); -} - -void blocking_handler(void) -{ - while (1) ; -} - -void null_handler(void) -{ - /* Do nothing. */ -} - -#pragma weak nmi_handler = null_handler -#pragma weak hard_fault_handler = blocking_handler -#pragma weak mem_manage_handler = blocking_handler -#pragma weak bus_fault_handler = blocking_handler -#pragma weak usage_fault_handler = blocking_handler -#pragma weak sv_call_handler = null_handler -#pragma weak debug_monitor_handler = null_handler -#pragma weak pend_sv_handler = null_handler -#pragma weak sys_tick_handler = null_handler -#pragma weak wwdg_isr = null_handler -#pragma weak pvd_isr = null_handler -#pragma weak tamper_isr = null_handler -#pragma weak rtc_isr = null_handler -#pragma weak flash_isr = null_handler -#pragma weak rcc_isr = null_handler -#pragma weak exti0_isr = null_handler -#pragma weak exti1_isr = null_handler -#pragma weak exti2_isr = null_handler -#pragma weak exti3_isr = null_handler -#pragma weak exti4_isr = null_handler -#pragma weak dma1_channel1_isr = null_handler -#pragma weak dma1_channel2_isr = null_handler -#pragma weak dma1_channel3_isr = null_handler -#pragma weak dma1_channel4_isr = null_handler -#pragma weak dma1_channel5_isr = null_handler -#pragma weak dma1_channel6_isr = null_handler -#pragma weak dma1_channel7_isr = null_handler -#pragma weak adc1_2_isr = null_handler -#pragma weak usb_hp_can_tx_isr = null_handler -#pragma weak usb_lp_can_rx0_isr = null_handler -#pragma weak can_rx1_isr = null_handler -#pragma weak can_sce_isr = null_handler -#pragma weak exti9_5_isr = null_handler -#pragma weak tim1_brk_isr = null_handler -#pragma weak tim1_up_isr = null_handler -#pragma weak tim1_trg_com_isr = null_handler -#pragma weak tim1_cc_isr = null_handler -#pragma weak tim2_isr = null_handler -#pragma weak tim3_isr = null_handler -#pragma weak tim4_isr = null_handler -#pragma weak i2c1_ev_isr = null_handler -#pragma weak i2c1_er_isr = null_handler -#pragma weak i2c2_ev_isr = null_handler -#pragma weak i2c2_er_isr = null_handler -#pragma weak spi1_isr = null_handler -#pragma weak spi2_isr = null_handler -#pragma weak usart1_isr = null_handler -#pragma weak usart2_isr = null_handler -#pragma weak usart3_isr = null_handler -#pragma weak exti15_10_isr = null_handler -#pragma weak rtc_alarm_isr = null_handler -#pragma weak usb_wakeup_isr = null_handler -#pragma weak tim8_brk_isr = null_handler -#pragma weak tim8_up_isr = null_handler -#pragma weak tim8_trg_com_isr = null_handler -#pragma weak tim8_cc_isr = null_handler -#pragma weak adc3_isr = null_handler -#pragma weak fsmc_isr = null_handler -#pragma weak sdio_isr = null_handler -#pragma weak tim5_isr = null_handler -#pragma weak spi3_isr = null_handler -#pragma weak usart4_isr = null_handler -#pragma weak usart5_isr = null_handler -#pragma weak tim6_isr = null_handler -#pragma weak tim7_isr = null_handler -#pragma weak dma2_channel1_isr = null_handler -#pragma weak dma2_channel2_isr = null_handler -#pragma weak dma2_channel3_isr = null_handler -#pragma weak dma2_channel4_5_isr = null_handler -#pragma weak dma2_channel5_isr -#pragma weak eth_isr = null_handler -#pragma weak eth_wkup_isr = null_handler -#pragma weak can2_tx_isr = null_handler -#pragma weak can2_rx0_isr = null_handler -#pragma weak can2_rx1_isr = null_handler -#pragma weak can2_sce_isr = null_handler -#pragma weak otg_fs_isr = null_handler - diff --git a/lib/stm32f2/Makefile b/lib/stm32f2/Makefile deleted file mode 100644 index 496f4a5..0000000 --- a/lib/stm32f2/Makefile +++ /dev/null @@ -1,59 +0,0 @@ -## -## This file is part of the libopencm3 project. -## -## Copyright (C) 2009 Uwe Hermann -## -## 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 . -## - -LIBNAME = libopencm3_stm32f2 - -PREFIX ?= arm-none-eabi -# PREFIX ?= arm-elf -CC = $(PREFIX)-gcc -AR = $(PREFIX)-ar -CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \ - -mcpu=cortex-m3 -mthumb -Wstrict-prototypes \ - -ffunction-sections -fdata-sections -MD -DSTM32F2 -# ARFLAGS = rcsv -ARFLAGS = rcs -OBJS = vector.o gpio.o systick.o i2c.o spi.o nvic.o usart.o exti.o rcc.o flash.o - -#VPATH += ../usb -VPATH += ../stm32_common - -# Be silent per default, but 'make V=1' will show all compiler calls. -ifneq ($(V),1) -Q := @ -endif - -all: $(LIBNAME).a - -$(LIBNAME).a: $(OBJS) - @printf " AR $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(AR) $(ARFLAGS) $@ $^ - -%.o: %.c - @printf " CC $(subst $(shell pwd)/,,$(@))\n" - $(Q)$(CC) $(CFLAGS) -o $@ -c $< - -clean: - @printf " CLEAN lib/stm32f2\n" - $(Q)rm -f *.o *.d - $(Q)rm -f $(LIBNAME).a - -.PHONY: clean - --include $(OBJS:.o=.d) - diff --git a/lib/stm32f2/exti.c b/lib/stm32f2/exti.c deleted file mode 100644 index 1db9ad7..0000000 --- a/lib/stm32f2/exti.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * 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 -#include -#include - -void exti_set_trigger(u32 extis, exti_trigger_type trig) -{ - switch (trig) { - case EXTI_TRIGGER_RISING: - EXTI_RTSR |= extis; - EXTI_FTSR &= ~extis; - break; - case EXTI_TRIGGER_FALLING: - EXTI_RTSR &= ~extis; - EXTI_FTSR |= extis; - break; - case EXTI_TRIGGER_BOTH: - EXTI_RTSR |= extis; - EXTI_FTSR |= extis; - break; - } -} - -void exti_enable_request(u32 extis) -{ - /* Enable interrupts. */ - EXTI_IMR |= extis; - - /* Enable events. */ - EXTI_EMR |= extis; -} - -void exti_disable_request(u32 extis) -{ - /* Disable interrupts. */ - EXTI_IMR &= ~extis; - - /* Disable events. */ - EXTI_EMR &= ~extis; -} - -/* - * Reset the interrupt request by writing a 1 to the corresponding - * pending bit register. - */ -void exti_reset_request(u32 extis) -{ - EXTI_PR = extis; -} - -/* - * Remap an external interrupt line to the corresponding pin on the - * specified GPIO port. - * - * TODO: This could be rewritten in fewer lines of code. - */ -void exti_select_source(u32 exti, u32 gpioport) -{ - u8 shift, bits; - - shift = bits = 0; - - switch (exti) { - case EXTI0: - case EXTI4: - case EXTI8: - case EXTI12: - shift = 0; - break; - case EXTI1: - case EXTI5: - case EXTI9: - case EXTI13: - shift = 4; - break; - case EXTI2: - case EXTI6: - case EXTI10: - case EXTI14: - shift = 8; - break; - case EXTI3: - case EXTI7: - case EXTI11: - case EXTI15: - shift = 12; - break; - } - - switch (gpioport) { - case GPIOA: - bits = 0xf; - break; - case GPIOB: - bits = 0xe; - break; - case GPIOC: - bits = 0xd; - break; - case GPIOD: - bits = 0xc; - break; - case GPIOE: - bits = 0xb; - break; - case GPIOF: - bits = 0xa; - break; - case GPIOG: - bits = 0x9; - break; - } - - /* Ensure that only valid EXTI lines are used. */ - if (exti < EXTI4) { - SYSCFG_EXTICR1 &= ~(0x000F << shift); - SYSCFG_EXTICR1 |= (~bits << shift); - } else if (exti < EXTI8) { - SYSCFG_EXTICR2 &= ~(0x000F << shift); - SYSCFG_EXTICR2 |= (~bits << shift); - } else if (exti < EXTI12) { - SYSCFG_EXTICR3 &= ~(0x000F << shift); - SYSCFG_EXTICR3 |= (~bits << shift); - } else if (exti < EXTI16) { - SYSCFG_EXTICR4 &= ~(0x000F << shift); - SYSCFG_EXTICR4 |= (~bits << shift); - } -} diff --git a/lib/stm32f2/flash.c b/lib/stm32f2/flash.c deleted file mode 100644 index e9bc73e..0000000 --- a/lib/stm32f2/flash.c +++ /dev/null @@ -1,250 +0,0 @@ -/* - * 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(); -} diff --git a/lib/stm32f2/gpio.c b/lib/stm32f2/gpio.c deleted file mode 100644 index 6e1ef08..0000000 --- a/lib/stm32f2/gpio.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2011 Fergus Noble - * - * 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 - -void gpio_mode_setup(u32 gpioport, u8 mode, u8 pull_up_down, u16 gpios) -{ - u16 i; - u32 moder, pupd; - - /* - * We want to set the config only for the pins mentioned in gpios, - * but keeping the others, so read out the actual config first. - */ - moder = GPIO_MODER(gpioport); - pupd = GPIO_PUPDR(gpioport); - - for (i = 0; i < 16; i++) { - if (!((1 << i) & gpios)) - continue; - - moder &= ~GPIO_MODE_MASK(i); - moder |= GPIO_MODE(i, mode); - pupd &= ~GPIO_PUPD_MASK(i); - pupd |= GPIO_PUPD(i, pull_up_down); - } - - /* Set mode and pull up/down control registers. */ - GPIO_MODER(gpioport) = moder; - GPIO_PUPDR(gpioport) = pupd; -} - -void gpio_set_output_options(u32 gpioport, u8 otype, u8 speed, u16 gpios) -{ - u16 i; - u32 ospeedr; - - if (otype == 0x1) - GPIO_OTYPER(gpioport) |= gpios; - else - GPIO_OTYPER(gpioport) &= ~gpios; - - ospeedr = GPIO_OSPEEDR(gpioport); - - for (i = 0; i < 16; i++) { - if (!((1 << i) & gpios)) - continue; - ospeedr &= ~GPIO_OSPEED_MASK(i); - ospeedr |= GPIO_OSPEED(i, speed); - } - - GPIO_OSPEEDR(gpioport) = ospeedr; -} - -void gpio_set_af(u32 gpioport, u8 alt_func_num, u16 gpios) -{ - u16 i; - u32 afrl, afrh; - - afrl = GPIO_AFRL(gpioport); - afrh = GPIO_AFRH(gpioport); - - for (i = 0; i < 8; i++) { - if (!((1 << i) & gpios)) - continue; - afrl &= GPIO_AFR_MASK(i); - afrl |= GPIO_AFR(i, alt_func_num); - } - - for (i = 8; i < 16; i++) { - if (!((1 << i) & gpios)) - continue; - afrl &= GPIO_AFR_MASK(i-8); - afrh |= GPIO_AFR(i-8, alt_func_num); - } - - GPIO_AFRL(gpioport) = afrl; - GPIO_AFRH(gpioport) = afrh; -} - -void gpio_set(u32 gpioport, u16 gpios) -{ - GPIO_BSRR(gpioport) = gpios; -} - -void gpio_clear(u32 gpioport, u16 gpios) -{ - GPIO_BSRR(gpioport) = gpios << 16; -} - -u16 gpio_get(u32 gpioport, u16 gpios) -{ - return gpio_port_read(gpioport) & gpios; -} - -void gpio_toggle(u32 gpioport, u16 gpios) -{ - GPIO_ODR(gpioport) = GPIO_IDR(gpioport) ^ gpios; -} - -u16 gpio_port_read(u32 gpioport) -{ - return (u16)GPIO_IDR(gpioport); -} - -void gpio_port_write(u32 gpioport, u16 data) -{ - GPIO_ODR(gpioport) = data; -} - -void gpio_port_config_lock(u32 gpioport, u16 gpios) -{ - u32 reg32; - - /* Special "Lock Key Writing Sequence", see datasheet. */ - GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ - GPIO_LCKR(gpioport) = ~GPIO_LCKK & gpios; /* Clear LCKK. */ - GPIO_LCKR(gpioport) = GPIO_LCKK | gpios; /* Set LCKK. */ - reg32 = GPIO_LCKR(gpioport); /* Read LCKK. */ - reg32 = GPIO_LCKR(gpioport); /* Read LCKK again. */ - - /* If (reg32 & GPIO_LCKK) is true, the lock is now active. */ -} diff --git a/lib/stm32f2/libopencm3_stm32f2.ld b/lib/stm32f2/libopencm3_stm32f2.ld deleted file mode 100644 index fda7d02..0000000 --- a/lib/stm32f2/libopencm3_stm32f2.ld +++ /dev/null @@ -1,63 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Uwe Hermann - * - * 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 . - */ - -/* 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 sections. */ -SECTIONS -{ - . = ORIGIN(rom); - - .text : { - *(.vectors) /* Vector table */ - *(.text*) /* Program code */ - *(.rodata*) /* Read-only data */ - _etext = .; - } >rom - - . = ORIGIN(ram); - - .data : { - _data = .; - *(.data*) /* Read-write initialized data */ - _edata = .; - } >ram AT >rom - - .bss : { - *(.bss*) /* Read-write zero initialized data */ - *(COMMON) - _ebss = .; - } >ram AT >rom - - /* - * 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) } - - end = .; -} - -PROVIDE(_stack = 0x20000800); - diff --git a/lib/stm32f2/rcc.c b/lib/stm32f2/rcc.c deleted file mode 100644 index 048f0ff..0000000 --- a/lib/stm32f2/rcc.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2009 Federico Ruiz-Ugalde - * Copyright (C) 2009 Uwe Hermann - * Copyright (C) 2010 Thomas Otto - * - * 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 -#include - -/* Set the default ppre1 and ppre2 peripheral clock frequencies after reset */ -u32 rcc_ppre1_frequency = 8000000; -u32 rcc_ppre2_frequency = 8000000; - -/* TODO: Create a table for these values */ -#define RCC_PLL_M 8 -#define RCC_PLL_N 336 -#define RCC_PLL_P 2 -#define RCC_PLL_Q 7 -#define RCC_PLLI2S_N 192 -#define RCC_PLLI2S_R 5 - -void rcc_osc_ready_int_clear(osc_t 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(osc_t 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(osc_t 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(osc_t 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; - } - - /* Shouldn't be reached. */ - return -1; -} - -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(osc_t 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(osc_t 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(osc_t 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(osc_t 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(osc_t 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(osc_t 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_peripheral_enable_clock(volatile u32 *reg, u32 en) -{ - *reg |= en; -} - -void rcc_peripheral_disable_clock(volatile u32 *reg, u32 en) -{ - *reg &= ~en; -} - -void rcc_peripheral_reset(volatile u32 *reg, u32 reset) -{ - *reg |= reset; -} - -void rcc_peripheral_clear_reset(volatile u32 *reg, u32 clear_reset) -{ - *reg &= ~clear_reset; -} - -void rcc_set_sysclk_source(u32 clk) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 1) | (1 << 0)); - RCC_CFGR = (reg32 | clk); -} - -void rcc_set_pll_source(u32 pllsrc) -{ - u32 reg32; - - reg32 = RCC_PLLCFGR; - reg32 &= ~(1 << 22); - RCC_PLLCFGR = (reg32 | (pllsrc << 22)); -} - -void rcc_set_ppre2(u32 ppre2) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 11) | (1 << 12) | (1 << 13)); - RCC_CFGR = (reg32 | (ppre2 << 11)); -} - -void rcc_set_ppre1(u32 ppre1) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 8) | (1 << 9) | (1 << 10)); - RCC_CFGR = (reg32 | (ppre1 << 8)); -} - -void rcc_set_hpre(u32 hpre) -{ - u32 reg32; - - reg32 = RCC_CFGR; - reg32 &= ~((1 << 4) | (1 << 5) | (1 << 6) | (1 << 7)); - RCC_CFGR = (reg32 | (hpre << 4)); -} - -void rcc_set_rtcpre(u32 rtcpre) -{ - u32 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(u32 pllm, u32 plln, u32 pllp, u32 pllq) -{ - RCC_PLLCFGR = pllm | - (plln << 6) | - (((pllp >> 1) - 1) << 16) | - (pllq << 24); -} - -void rcc_set_main_pll_hse(u32 pllm, u32 plln, u32 pllp, u32 pllq) -{ - RCC_PLLCFGR = pllm | - (plln << 6) | - (((pllp >> 1) - 1) << 16) | - RCC_PLLCFGR_PLLSRC | - (pllq << 24); -} - -u32 rcc_system_clock_source(void) -{ - /* Return the clock source which is used as system clock. */ - return ((RCC_CFGR & 0x000c) >> 2); -} - -void rcc_clock_setup_in_hse_8mhz_out_120mhz(void) -{ - /* 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); - rcc_set_sysclk_source(RCC_CFGR_SW_HSE); - - /* - * Set prescalers for AHB, ADC, ABP1, ABP2. - * Do this before touching the PLL (TODO: why?). - */ - rcc_set_hpre(RCC_CFGR_HPRE_DIV_NONE); /* Set. 120MHz Max. 120MHz */ - rcc_set_ppre1(RCC_CFGR_PPRE_DIV_4); /* Set. 30MHz Max. 30MHz */ - rcc_set_ppre2(RCC_CFGR_PPRE_DIV_2); /* Set. 60MHz Max. 60MHz */ - - rcc_set_main_pll_hse(RCC_PLL_M, RCC_PLL_N, RCC_PLL_P, RCC_PLL_Q); - - /* Enable PLL oscillator and wait for it to stabilize. */ - rcc_osc_on(PLL); - rcc_wait_for_osc_ready(PLL); - - /* - * @3.3V - * Sysclk runs with 120MHz -> 3 waitstates. - * 0WS from 0-30MHz - * 1WS from 30-60MHz - * 2WS from 60-90MHz - * 3WS from 90-120MHz - */ - flash_set_ws(FLASH_PRFTEN | FLASH_ICE | FLASH_DCE | FLASH_LATENCY_3WS); - - /* 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 = 30000000; - rcc_ppre2_frequency = 60000000; -} - -void rcc_backupdomain_reset(void) -{ - /* Set the backup domain software reset. */ - RCC_BDCR |= RCC_BDCR_BDRST; - - /* Clear the backup domain software reset. */ - RCC_BDCR &= ~RCC_BDCR_BDRST; -} diff --git a/lib/stm32f2/vector.c b/lib/stm32f2/vector.c deleted file mode 100644 index d6f70f8..0000000 --- a/lib/stm32f2/vector.c +++ /dev/null @@ -1,336 +0,0 @@ -/* - * This file is part of the libopencm3 project. - * - * Copyright (C) 2010 Piotr Esden-Tempski - * Copyright (C) 2011 Fergus Noble - * - * 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 . - */ - -#define WEAK __attribute__ ((weak)) - -/* Symbols exported by linker script */ -extern unsigned _etext, _data, _edata, _ebss, _stack; - -void main(void); -void reset_handler(void); -void blocking_handler(void); -void null_handler(void); - -void WEAK reset_handler(void); -void WEAK nmi_handler(void); -void WEAK hard_fault_handler(void); -void WEAK mem_manage_handler(void); -void WEAK bus_fault_handler(void); -void WEAK usage_fault_handler(void); -void WEAK sv_call_handler(void); -void WEAK debug_monitor_handler(void); -void WEAK pend_sv_handler(void); -void WEAK sys_tick_handler(void); -void WEAK wwdg_isr(void); -void WEAK pvd_isr(void); -void WEAK tamp_stamp_isr(void); -void WEAK rtc_wkup_isr(void); -void WEAK flash_isr(void); -void WEAK rcc_isr(void); -void WEAK exti0_isr(void); -void WEAK exti1_isr(void); -void WEAK exti2_isr(void); -void WEAK exti3_isr(void); -void WEAK exti4_isr(void); -void WEAK dma1_stream0_isr(void); -void WEAK dma1_stream1_isr(void); -void WEAK dma1_stream2_isr(void); -void WEAK dma1_stream3_isr(void); -void WEAK dma1_stream4_isr(void); -void WEAK dma1_stream5_isr(void); -void WEAK dma1_stream6_isr(void); -void WEAK adc_isr(void); -void WEAK can1_tx_isr(void); -void WEAK can1_rx0_isr(void); -void WEAK can1_rx1_isr(void); -void WEAK can1_sce_isr(void); -void WEAK exti9_5_isr(void); -void WEAK tim1_brk_tim9_isr(void); -void WEAK tim1_up_tim10_isr(void); -void WEAK tim1_trg_com_tim11_isr(void); -void WEAK tim1_cc_isr(void); -void WEAK tim2_isr(void); -void WEAK tim3_isr(void); -void WEAK tim4_isr(void); -void WEAK i2c1_ev_isr(void); -void WEAK i2c1_er_isr(void); -void WEAK i2c2_ev_isr(void); -void WEAK i2c2_er_isr(void); -void WEAK spi1_isr(void); -void WEAK spi2_isr(void); -void WEAK usart1_isr(void); -void WEAK usart2_isr(void); -void WEAK usart3_isr(void); -void WEAK exti15_10_isr(void); -void WEAK rtc_alarm_isr(void); -void WEAK usb_fs_wkup_isr(void); -void WEAK tim8_brk_tim12_isr(void); -void WEAK tim8_up_tim13_isr(void); -void WEAK tim8_trg_com_tim14_isr(void); -void WEAK tim8_cc_isr(void); -void WEAK dma1_stream7_isr(void); -void WEAK fsmc_isr(void); -void WEAK sdio_isr(void); -void WEAK tim5_isr(void); -void WEAK spi3_isr(void); -void WEAK usart4_isr(void); -void WEAK usart5_isr(void); -void WEAK tim6_dac_isr(void); -void WEAK tim7_isr(void); -void WEAK dma2_stream0_isr(void); -void WEAK dma2_stream1_isr(void); -void WEAK dma2_stream2_isr(void); -void WEAK dma2_stream3_isr(void); -void WEAK dma2_stream4_isr(void); -void WEAK eth_isr(void); -void WEAK eth_wkup_isr(void); -void WEAK can2_tx_isr(void); -void WEAK can2_rx0_isr(void); -void WEAK can2_rx1_isr(void); -void WEAK can2_sce_isr(void); -void WEAK otg_fs_isr(void); -void WEAK dma2_stream5_isr(void); -void WEAK dma2_stream6_isr(void); -void WEAK dma2_stream7_isr(void); -void WEAK usart6_isr(void); -void WEAK i2c3_ev_isr(void); -void WEAK i2c3_er_isr(void); -void WEAK otg_hs_ep1_out_isr(void); -void WEAK otg_hs_ep1_in_isr(void); -void WEAK otg_hs_wkup_isr(void); -void WEAK otg_hs_isr(void); -void WEAK dcmi_isr(void); -void WEAK cryp_isr(void); -void WEAK hash_rng_isr(void); - -__attribute__ ((section(".vectors"))) -void (*const vector_table[]) (void) = { - (void*)&_stack, - reset_handler, - nmi_handler, - hard_fault_handler, - mem_manage_handler, - bus_fault_handler, - usage_fault_handler, - 0, 0, 0, 0, /* Reserved */ - sv_call_handler, - debug_monitor_handler, - 0, /* Reserved */ - pend_sv_handler, - sys_tick_handler, - wwdg_isr, - pvd_isr, - tamp_stamp_isr, - rtc_wkup_isr, - flash_isr, - rcc_isr, - exti0_isr, - exti1_isr, - exti2_isr, - exti3_isr, - exti4_isr, - dma1_stream0_isr, - dma1_stream1_isr, - dma1_stream2_isr, - dma1_stream3_isr, - dma1_stream4_isr, - dma1_stream5_isr, - dma1_stream6_isr, - adc_isr, - can1_tx_isr, - can1_rx0_isr, - can1_rx1_isr, - can1_sce_isr, - exti9_5_isr, - tim1_brk_tim9_isr, - tim1_up_tim10_isr, - tim1_trg_com_tim11_isr, - tim1_cc_isr, - tim2_isr, - tim3_isr, - tim4_isr, - i2c1_ev_isr, - i2c1_er_isr, - i2c2_ev_isr, - i2c2_er_isr, - spi1_isr, - spi2_isr, - usart1_isr, - usart2_isr, - usart3_isr, - exti15_10_isr, - rtc_alarm_isr, - usb_fs_wkup_isr, - tim8_brk_tim12_isr, - tim8_up_tim13_isr, - tim8_trg_com_tim14_isr, - tim8_cc_isr, - dma1_stream7_isr, - fsmc_isr, - sdio_isr, - tim5_isr, - spi3_isr, - usart4_isr, - usart5_isr, - tim6_dac_isr, - tim7_isr, - dma2_stream0_isr, - dma2_stream1_isr, - dma2_stream2_isr, - dma2_stream3_isr, - dma2_stream4_isr, - eth_isr, - eth_wkup_isr, - can2_tx_isr, - can2_rx0_isr, - can2_rx1_isr, - can2_sce_isr, - otg_fs_isr, - dma2_stream5_isr, - dma2_stream6_isr, - dma2_stream7_isr, - usart6_isr, - i2c3_ev_isr, - i2c3_er_isr, - otg_hs_ep1_out_isr, - otg_hs_ep1_in_isr, - otg_hs_wkup_isr, - otg_hs_isr, - dcmi_isr, - cryp_isr, - hash_rng_isr, -}; - -void reset_handler(void) -{ - volatile unsigned *src, *dest; - asm("MSR msp, %0" : : "r"(&_stack)); - - for (src = &_etext, dest = &_data; dest < &_edata; src++, dest++) - *dest = *src; - - while (dest < &_ebss) - *dest++ = 0; - - /* Call the application's entry point. */ - main(); -} - -void blocking_handler(void) -{ - while (1) ; -} - -void null_handler(void) -{ - /* Do nothing. */ -} - -#pragma weak nmi_handler = null_handler -#pragma weak hard_fault_handler = blocking_handler -#pragma weak mem_manage_handler = blocking_handler -#pragma weak bus_fault_handler = blocking_handler -#pragma weak usage_fault_handler = blocking_handler -#pragma weak sv_call_handler = null_handler -#pragma weak debug_monitor_handler = null_handler -#pragma weak pend_sv_handler = null_handler -#pragma weak sys_tick_handler = null_handler -#pragma weak wwdg_isr = null_handler -#pragma weak pvd_isr = null_handler -#pragma weak tamp_stamp_isr = null_handler -#pragma weak rtc_wkup_isr = null_handler -#pragma weak flash_isr = null_handler -#pragma weak rcc_isr = null_handler -#pragma weak exti0_isr = null_handler -#pragma weak exti1_isr = null_handler -#pragma weak exti2_isr = null_handler -#pragma weak exti3_isr = null_handler -#pragma weak exti4_isr = null_handler -#pragma weak dma1_stream0_isr = null_handler -#pragma weak dma1_stream1_isr = null_handler -#pragma weak dma1_stream2_isr = null_handler -#pragma weak dma1_stream3_isr = null_handler -#pragma weak dma1_stream4_isr = null_handler -#pragma weak dma1_stream5_isr = null_handler -#pragma weak dma1_stream6_isr = null_handler -#pragma weak adc_isr = null_handler -#pragma weak can1_tx_isr = null_handler -#pragma weak can1_rx0_isr = null_handler -#pragma weak can1_rx1_isr = null_handler -#pragma weak can1_sce_isr = null_handler -#pragma weak exti9_5_isr = null_handler -#pragma weak tim1_brk_tim9_isr = null_handler -#pragma weak tim1_up_tim10_isr = null_handler -#pragma weak tim1_trg_com_tim11_isr = null_handler -#pragma weak tim1_cc_isr = null_handler -#pragma weak tim2_isr = null_handler -#pragma weak tim3_isr = null_handler -#pragma weak tim4_isr = null_handler -#pragma weak i2c1_ev_isr = null_handler -#pragma weak i2c1_er_isr = null_handler -#pragma weak i2c2_ev_isr = null_handler -#pragma weak i2c2_er_isr = null_handler -#pragma weak spi1_isr = null_handler -#pragma weak spi2_isr = null_handler -#pragma weak usart1_isr = null_handler -#pragma weak usart2_isr = null_handler -#pragma weak usart3_isr = null_handler -#pragma weak exti15_10_isr = null_handler -#pragma weak rtc_alarm_isr = null_handler -#pragma weak usb_fs_wkup_isr = null_handler -#pragma weak tim8_brk_tim12_isr = null_handler -#pragma weak tim8_up_tim13_isr = null_handler -#pragma weak tim8_trg_com_tim14_isr = null_handler -#pragma weak tim8_cc_isr = null_handler -#pragma weak dma1_stream7_isr = null_handler -#pragma weak fsmc_isr = null_handler -#pragma weak sdio_isr = null_handler -#pragma weak tim5_isr = null_handler -#pragma weak spi3_isr = null_handler -#pragma weak usart4_isr = null_handler -#pragma weak usart5_isr = null_handler -#pragma weak tim6_dac_isr = null_handler -#pragma weak tim7_isr = null_handler -#pragma weak dma2_stream0_isr = null_handler -#pragma weak dma2_stream1_isr = null_handler -#pragma weak dma2_stream2_isr = null_handler -#pragma weak dma2_stream3_isr = null_handler -#pragma weak dma2_stream4_isr = null_handler -#pragma weak eth_isr = null_handler -#pragma weak eth_wkup_isr = null_handler -#pragma weak can2_tx_isr = null_handler -#pragma weak can2_rx0_isr = null_handler -#pragma weak can2_rx1_isr = null_handler -#pragma weak can2_sce_isr = null_handler -#pragma weak otg_fs_isr = null_handler -#pragma weak dma2_stream5_isr = null_handler -#pragma weak dma2_stream6_isr = null_handler -#pragma weak dma2_stream7_isr = null_handler -#pragma weak usart6_isr = null_handler -#pragma weak i2c3_ev_isr = null_handler -#pragma weak i2c3_er_isr = null_handler -#pragma weak otg_hs_ep1_out_isr = null_handler -#pragma weak otg_hs_ep1_in_isr = null_handler -#pragma weak otg_hs_wkup_isr = null_handler -#pragma weak otg_hs_isr = null_handler -#pragma weak dcmi_isr = null_handler -#pragma weak cryp_isr = null_handler -#pragma weak hash_rng_isr = null_handler - -- cgit v1.2.3