Merge branch 'generalizations' into efm32

Conflicts:
	Makefile
This commit is contained in:
chrysn
2012-10-18 18:43:38 +02:00
154 changed files with 7142 additions and 2301 deletions

View File

@@ -40,7 +40,7 @@ $(SRCLIBDIR)/$(LIBNAME).ld: $(LIBNAME).ld
clean:
@printf " CLEAN lib/stm32/f1\n"
$(Q)rm -f *.o *.d
$(Q)rm -f *.o *.d ../*.o ../*.d
$(Q)rm -f $(SRCLIBDIR)/$(LIBNAME).a
$(Q)rm -f $(SRCLIBDIR)/$(LIBNAME).ld
$(Q)rm -f $(SRCLIBDIR)/$(LIBNAME)_rom_to_ram.ld

34
lib/cm3/assert.c Normal file
View File

@@ -0,0 +1,34 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2012 Tomaz Solc <tomaz.solc@tablix.org>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/assert.h>
void __attribute__((weak)) cm3_assert_failed(void)
{
while(1);
}
void __attribute__((weak)) cm3_assert_failed_verbose(
const char *file __attribute__((unused)),
int line __attribute__((unused)),
const char *func __attribute__((unused)),
const char *assert_expr __attribute__((unused)))
{
cm3_assert_failed();
}

View File

@@ -1,31 +1,9 @@
/** @defgroup STM32F_nvic_file NVIC
@ingroup STM32F_files
@brief <b>libopencm3 STM32F Nested Vectored Interrupt Controller</b>
@version 1.0.0
@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
@author @htmlonly &copy; @endhtmlonly 2012 Fergus Noble <fergusnoble@gmail.com>
@date 18 August 2012
The STM32F series provides up to 68 maskable user interrupts for the STM32F10x
series, and 87 for the STM32F2xx and STM32F4xx series.
The NVIC registers are defined by the ARM standards but the STM32F series have some
additional limitations
@see Cortex-M3 Devices Generic User Guide
@see STM32F10xxx Cortex-M3 programming manual
LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
* Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -40,10 +18,32 @@ LGPL License Terms @ref lgpl_license
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/** @defgroup CM3_nvic_file NVIC
@ingroup CM3_files
@brief <b>libopencm3 Cortex Nested Vectored Interrupt Controller</b>
@version 1.0.0
@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
@author @htmlonly &copy; @endhtmlonly 2012 Fergus Noble <fergusnoble@gmail.com>
@date 18 August 2012
Cortex processors provide 14 cortex-defined interrupts (NMI, usage faults,
systicks etc.) and varying numbers of implementation defined interrupts
(typically peripherial interrupts and DMA).
@see Cortex-M3 Devices Generic User Guide
@see STM32F10xxx Cortex-M3 programming manual
LGPL License Terms @ref lgpl_license
*/
/**@{*/
#include <libopencm3/stm32/nvic.h>
#include <libopencm3/cm3/nvic.h>
#include <libopencm3/cm3/scs.h>
/*-----------------------------------------------------------------------------*/
/** @brief NVIC Enable Interrupt
@@ -153,7 +153,18 @@ Control Register (SCB_AIRCR), as done in @ref scb_set_priority_grouping.
void nvic_set_priority(u8 irqn, u8 priority)
{
NVIC_IPR(irqn) = priority;
/* code from lpc43xx/nvic.c -- this is quite a hack and alludes to the
* negative interrupt numbers assigned to the system interrupts. better
* handling would mean signed integers. */
if(irqn>=NVIC_IRQ_COUNT)
{
/* Cortex-M system interrupts */
SCS_SHPR( (irqn&0xF)-4 ) = priority;
}else
{
/* Device specific interrupts */
NVIC_IPR(irqn) = priority;
}
}
/*-----------------------------------------------------------------------------*/
@@ -171,4 +182,3 @@ void nvic_generate_software_interrupt(u16 irqn)
NVIC_STIR |= irqn;
}
/**@}*/

View File

@@ -1,7 +1,8 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>,
* Copyright (C) 2012 chrysn <chrysn@fsfe.org>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
@@ -14,19 +15,26 @@
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/vector.h>
/* load optional platform dependent initialization routines */
#include "../dispatch/vector.c"
/* load the weak symbols for IRQ_HANDLERS */
#include "../dispatch/vector_nvic.c"
#define WEAK __attribute__ ((weak))
/* Symbols exported by the linker script(s): */
extern unsigned _data_loadaddr, _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);
@@ -37,28 +45,25 @@ void WEAK debug_monitor_handler(void);
void WEAK pend_sv_handler(void);
void WEAK sys_tick_handler(void);
/* TODO: Interrupt handler prototypes */
__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,
/* TODO: Interrupt handlers */
vector_table_t vector_table = {
.initial_sp_value = &_stack,
.reset = reset_handler,
.nmi = nmi_handler,
.hard_fault = hard_fault_handler,
.memory_manage_fault = mem_manage_handler,
.bus_fault = bus_fault_handler,
.usage_fault = usage_fault_handler,
.debug_monitor = debug_monitor_handler,
.sv_call = sv_call_handler,
.pend_sv = pend_sv_handler,
.systick = sys_tick_handler,
.irq = {
IRQ_HANDLERS
}
};
void reset_handler(void)
void WEAK reset_handler(void)
{
volatile unsigned *src, *dest;
@@ -70,6 +75,9 @@ void reset_handler(void)
while (dest < &_ebss)
*dest++ = 0;
/* might be provided by platform specific vector.c */
pre_main();
/* Call the application's entry point. */
main();
}
@@ -93,4 +101,3 @@ void null_handler(void)
#pragma weak debug_monitor_handler = null_handler
#pragma weak pend_sv_handler = null_handler
#pragma weak sys_tick_handler = null_handler
/* TODO: Interrupt handler weak aliases */

11
lib/dispatch/vector.c Normal file
View File

@@ -0,0 +1,11 @@
#if defined(STM32F4)
# include "../stm32/f4/vector.c"
#elif defined(LPC43XX)
# include "../lpc43xx/vector.c"
#else
static void pre_main(void) {}
#endif

View File

@@ -0,0 +1,19 @@
#if defined(STM32F1)
# include "../stm32/f1/vector_nvic.c"
#elif defined(STM32F2)
# include "../stm32/f2/vector_nvic.c"
#elif defined(STM32F4)
# include "../stm32/f4/vector_nvic.c"
#elif defined(TINYGECKO)
# include "../efm32/tinygecko/vector_nvic.c"
#elif defined(LPC43XX)
# include "../lpc43xx/vector_nvic.c"
#else
# warning"no chipset defined; user interrupts are disabled"
#define IRQ_HANDLERS
#endif

View File

@@ -28,8 +28,8 @@ CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \
-ffunction-sections -fdata-sections -MD
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = gpio.o vector.o
OBJS = gpio.o vector.o assert.o
# VPATH += ../usb
VPATH += ../cm3
include ../Makefile.include

View File

@@ -77,6 +77,8 @@ SECTIONS
. = ALIGN(4);
end = .;
_end = .;
__end = .;
}
PROVIDE(_stack = ORIGIN(ram) + LENGTH(ram));

View File

@@ -28,8 +28,8 @@ CFLAGS = -Os -g -Wall -Wextra -I../../include -fno-common \
-ffunction-sections -fdata-sections -MD
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = gpio.o
OBJS = gpio.o assert.o
# VPATH += ../usb
VPATH += ../cm3
include ../Makefile.include

View File

@@ -28,8 +28,8 @@ CFLAGS = -O0 -g -Wall -Wextra -I../../include -fno-common \
-ffunction-sections -fdata-sections -MD
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = gpio.o vector.o
OBJS = gpio.o vector.o assert.o
# VPATH += ../usb
VPATH += ../cm3
include ../Makefile.include

View File

@@ -1,95 +0,0 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#define WEAK __attribute__ ((weak))
/* Symbols exported by the linker script(s): */
extern unsigned _data_loadaddr, _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);
/* TODO: Interrupt handler prototypes */
__attribute__ ((section(".vectors")))
void (*const vector_table[]) (void) = {
(void*)&_stack, /* Addr: 0x0000_0000 */
reset_handler, /* Addr: 0x0000_0004 */
nmi_handler, /* Addr: 0x0000_0008 */
hard_fault_handler, /* Addr: 0x0000_000C */
mem_manage_handler, /* Addr: 0x0000_0010 */
bus_fault_handler, /* Addr: 0x0000_0014 */
usage_fault_handler, /* Addr: 0x0000_0018 */
0, 0, 0, 0, /* Reserved Addr: 0x0000_001C - 0x0000_002B */
sv_call_handler, /* Addr: 0x0000_002C */
debug_monitor_handler, /* Addr: 0x0000_0030 */
0, /* Reserved Addr: 0x0000_00034 */
pend_sv_handler, /* Addr: 0x0000_0038 */
sys_tick_handler, /* Addr: 0x0000_003C */
};
void reset_handler(void)
{
volatile unsigned *src, *dest;
__asm__("MSR msp, %0" : : "r"(&_stack));
for (src = &_data_loadaddr, 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
/* TODO: Interrupt handler weak aliases */

View File

@@ -31,8 +31,9 @@ CFLAGS = -O2 -g3 -Wall -Wextra -I../../include -fno-common \
-mfloat-abi=hard -mfpu=fpv4-sp-d16
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = gpio.o vector.o scu.o i2c.o ssp.o nvic.o systick.o
OBJS = gpio.o vector.o scu.o i2c.o ssp.o nvic.o systick.o \
assert.o
# VPATH += ../usb
VPATH += ../cm3
include ../Makefile.include

View File

@@ -1,76 +0,0 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Thomas Otto <tommi@viadmin.org>
* Copyright (C) 2012 Fergus Noble <fergusnoble@gmail.com>
* Copyright (C) 2012 Benjamin Vernoux <titanmkd@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/scs.h>
#include <libopencm3/lpc43xx/nvic.h>
void nvic_enable_irq(u8 irqn)
{
NVIC_ISER(irqn / 32) = (1 << (irqn % 32));
}
void nvic_disable_irq(u8 irqn)
{
NVIC_ICER(irqn / 32) = (1 << (irqn % 32));
}
u8 nvic_get_pending_irq(u8 irqn)
{
return NVIC_ISPR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0;
}
void nvic_set_pending_irq(u8 irqn)
{
NVIC_ISPR(irqn / 32) = (1 << (irqn % 32));
}
void nvic_clear_pending_irq(u8 irqn)
{
NVIC_ICPR(irqn / 32) = (1 << (irqn % 32));
}
u8 nvic_get_active_irq(u8 irqn)
{
return NVIC_IABR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0;
}
u8 nvic_get_irq_enabled(u8 irqn)
{
return NVIC_ISER(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0;
}
void nvic_set_priority(u8 irqn, u8 priority)
{
if(irqn>NVIC_M4_QEI_IRQ)
{
/* Cortex-M system interrupts */
SCS_SHPR( (irqn&0xF)-4 ) = priority;
}else
{
/* Device specific interrupts */
NVIC_IPR(irqn) = priority;
}
}
void nvic_generate_software_interrupt(u8 irqn)
{
if (irqn <= 239)
NVIC_STIR |= irqn;
}

View File

@@ -18,156 +18,16 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#define WEAK __attribute__ ((weak))
#include <libopencm3/cm3/common.h>
/* Symbols exported by the linker script(s): */
extern unsigned _data_loadaddr, _data, _edata, _ebss, _stack;
extern unsigned _etext_ram, _text_ram, _etext_rom;
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 dac_irqhandler(void);
void WEAK m0core_irqhandler(void);
void WEAK dma_irqhandler(void);
void WEAK ethernet_irqhandler(void);
void WEAK sdio_irqhandler(void);
void WEAK lcd_irqhandler(void);
void WEAK usb0_irqhandler(void);
void WEAK usb1_irqhandler(void);
void WEAK sct_irqhandler(void);
void WEAK ritimer_irqhandler(void);
void WEAK timer0_irqhandler(void);
void WEAK timer1_irqhandler(void);
void WEAK timer2_irqhandler(void);
void WEAK timer3_irqhandler(void);
void WEAK mcpwm_irqhandler(void);
void WEAK adc0_irqhandler(void);
void WEAK i2c0_irqhandler(void);
void WEAK i2c1_irqhandler(void);
void WEAK spi_irqhandler(void);
void WEAK adc1_irqhandler(void);
void WEAK ssp0_irqhandler(void);
void WEAK ssp1_irqhandler(void);
void WEAK usart0_irqhandler(void);
void WEAK uart1_irqhandler(void);
void WEAK usart2_irqhandler(void);
void WEAK usart3_irqhandler(void);
void WEAK i2s0_irqhandler(void);
void WEAK i2s1_irqhandler(void);
void WEAK spifi_irqhandler(void);
void WEAK sgpio_irqhandler(void);
void WEAK pin_int0_irqhandler(void);
void WEAK pin_int1_irqhandler(void);
void WEAK pin_int2_irqhandler(void);
void WEAK pin_int3_irqhandler(void);
void WEAK pin_int4_irqhandler(void);
void WEAK pin_int5_irqhandler(void);
void WEAK pin_int6_irqhandler(void);
void WEAK pin_int7_irqhandler(void);
void WEAK gint0_irqhandler(void);
void WEAK gint1_irqhandler(void);
void WEAK eventrouter_irqhandler(void);
void WEAK c_can1_irqhandler(void);
void WEAK atimer_irqhandler(void);
void WEAK rtc_irqhandler(void);
void WEAK wwdt_irqhandler(void);
void WEAK c_can0_irqhandler(void);
void WEAK qei_irqhandler(void);
__attribute__ ((section(".vectors")))
void (*const vector_table[]) (void) = {
/* Cortex-M4 interrupts */
(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,
/* LPC43xx interrupts */
dac_irqhandler,
m0core_irqhandler,
dma_irqhandler,
0, /* reserved */
0, /* reserved */
ethernet_irqhandler,
sdio_irqhandler,
lcd_irqhandler,
usb0_irqhandler,
usb1_irqhandler,
sct_irqhandler,
ritimer_irqhandler,
timer0_irqhandler,
timer1_irqhandler,
timer2_irqhandler,
timer3_irqhandler,
mcpwm_irqhandler,
adc0_irqhandler,
i2c0_irqhandler,
i2c1_irqhandler,
spi_irqhandler,
adc1_irqhandler,
ssp0_irqhandler,
ssp1_irqhandler,
usart0_irqhandler,
uart1_irqhandler,
usart2_irqhandler,
usart3_irqhandler,
i2s0_irqhandler,
i2s1_irqhandler,
spifi_irqhandler,
sgpio_irqhandler,
pin_int0_irqhandler,
pin_int1_irqhandler,
pin_int2_irqhandler,
pin_int3_irqhandler,
pin_int4_irqhandler,
pin_int5_irqhandler,
pin_int6_irqhandler,
pin_int7_irqhandler,
gint0_irqhandler,
gint1_irqhandler,
eventrouter_irqhandler,
c_can1_irqhandler,
0, /* reserved */
0, /* reserved */
atimer_irqhandler,
rtc_irqhandler,
0, /* reserved */
wwdt_irqhandler,
0, /* reserved */
c_can0_irqhandler,
qei_irqhandler,
};
#define MMIO32(addr) (*(volatile unsigned long*)(addr))
#define CREG_M4MEMMAP MMIO32( (0x40043000 + 0x100) )
void reset_handler(void)
static void pre_main(void)
{
volatile unsigned *src, *dest;
__asm__("MSR msp, %0" : : "r"(&_stack));
/* Copy the code from ROM to Real RAM (if enabled) */
if( (&_etext_ram-&_text_ram) > 0 )
{
@@ -185,80 +45,4 @@ void reset_handler(void)
/* Continue Execution in RAM */
}
for (src = &_data_loadaddr, 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 dac_irqhandler = null_handler
#pragma weak m0core_irqhandler = null_handler
#pragma weak dma_irqhandler = null_handler
#pragma weak ethernet_irqhandler = null_handler
#pragma weak sdio_irqhandler = null_handler
#pragma weak lcd_irqhandler = null_handler
#pragma weak usb0_irqhandler = null_handler
#pragma weak usb1_irqhandler = null_handler
#pragma weak sct_irqhandler = null_handler
#pragma weak ritimer_irqhandler = null_handler
#pragma weak timer0_irqhandler = null_handler
#pragma weak timer1_irqhandler = null_handler
#pragma weak timer2_irqhandler = null_handler
#pragma weak timer3_irqhandler = null_handler
#pragma weak mcpwm_irqhandler = null_handler
#pragma weak adc0_irqhandler = null_handler
#pragma weak i2c0_irqhandler = null_handler
#pragma weak i2c1_irqhandler = null_handler
#pragma weak spi_irqhandler = null_handler
#pragma weak adc1_irqhandler = null_handler
#pragma weak ssp0_irqhandler = null_handler
#pragma weak ssp1_irqhandler = null_handler
#pragma weak usart0_irqhandler = null_handler
#pragma weak uart1_irqhandler = null_handler
#pragma weak usart2_irqhandler = null_handler
#pragma weak usart3_irqhandler = null_handler
#pragma weak i2s0_irqhandler = null_handler
#pragma weak i2s1_irqhandler = null_handler
#pragma weak spifi_irqhandler = null_handler
#pragma weak sgpio_irqhandler = null_handler
#pragma weak pin_int0_irqhandler = null_handler
#pragma weak pin_int1_irqhandler = null_handler
#pragma weak pin_int2_irqhandler = null_handler
#pragma weak pin_int3_irqhandler = null_handler
#pragma weak pin_int4_irqhandler = null_handler
#pragma weak pin_int5_irqhandler = null_handler
#pragma weak pin_int6_irqhandler = null_handler
#pragma weak pin_int7_irqhandler = null_handler
#pragma weak gint0_irqhandler = null_handler
#pragma weak gint1_irqhandler = null_handler
#pragma weak eventrouter_irqhandler = null_handler
#pragma weak c_can1_irqhandler = null_handler
#pragma weak atimer_irqhandler = null_handler
#pragma weak rtc_irqhandler = null_handler
#pragma weak wwdt_irqhandler = null_handler
#pragma weak c_can0_irqhandler = null_handler
#pragma weak qei_irqhandler = null_handler

View File

@@ -1,3 +1,17 @@
/** @defgroup crc_file CRC
@ingroup STM32F_files
@brief <b>libopencm3 STM32Fxxx CRC</b>
@version 1.0.0
@author @htmlonly &copy; @endhtmlonly 2012 Karl Palsson <karlp@remake.is>
@date 15 October 2012
LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
@@ -19,11 +33,30 @@
#include <libopencm3/stm32/crc.h>
/**@{*/
/*-----------------------------------------------------------------------------*/
/** @brief CRC Reset.
Reset the CRC unit and forces the data register to all 1s.
*/
void crc_reset(void)
{
CRC_CR |= CRC_CR_RESET;
}
/*-----------------------------------------------------------------------------*/
/** @brief CRC Calculate.
Writes a data word to the register, the write operation stalling until the
computation is complete.
@param[in] data Unsigned int32.
@returns int32 Computed CRC result
*/
u32 crc_calculate(u32 data)
{
CRC_DR = data;
@@ -31,6 +64,16 @@ u32 crc_calculate(u32 data)
return CRC_DR;
}
/*-----------------------------------------------------------------------------*/
/** @brief CRC Calculate of a Block of Data.
Writes data words consecutively to the register, the write operation stalling
until the computation of each word is complete.
@param[in] datap Unsigned int32. pointer to an array of 32 bit data words.
@returns int32 Final computed CRC result
*/
u32 crc_calculate_block(u32 *datap, int size)
{
int i;
@@ -39,6 +82,5 @@ u32 crc_calculate_block(u32 *datap, int size)
}
return CRC_DR;
}
/**@}*/

View File

@@ -31,9 +31,9 @@ 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 desig.o crc.o
timer.o usb_f107.o desig.o crc.o assert.o dac.o iwdg.o pwr.o
VPATH += ../../usb:../
VPATH += ../../usb:../:../../cm3
include ../../Makefile.include

View File

@@ -44,12 +44,12 @@ conversion, which occurs after all channels have been scanned.
@section adc_api_ex Basic ADC Handling API.
Example 1: Simple single channel conversion polled. Enable the peripheral clock
and ADC, reset ADC and set the prescaler divider. Set dual mode to independent.
and ADC, reset ADC and set the prescaler divider. Set dual mode to independent
(default). Enable triggering for a software trigger.
@code
rcc_peripheral_enable_clock(&RCC_APB2ENR, RCC_APB2ENR_ADC1EN);
adc_power_on(ADC1);
adc_calibration(ADC1);
adc_off(ADC1);
rcc_peripheral_reset(&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST);
rcc_peripheral_clear_reset(&RCC_APB2RSTR, RCC_APB2RSTR_ADC1RST);
rcc_set_adcpre(RCC_CFGR_ADCPRE_PCLK2_DIV2);
@@ -58,6 +58,10 @@ and ADC, reset ADC and set the prescaler divider. Set dual mode to independent.
adc_set_single_conversion_mode(ADC1);
adc_set_sample_time(ADC1, ADC_CHANNEL0, ADC_SMPR1_SMP_1DOT5CYC);
adc_set_single_channel(ADC1, ADC_CHANNEL0);
adc_enable_trigger(ADC1, ADC_CR2_EXTSEL_SWSTART);
adc_power_on(ADC1);
adc_reset_calibration(ADC1);
adc_calibration(ADC1);
adc_start_conversion_regular(ADC1);
while (! adc_eoc(ADC1));
reg16 = adc_read_regular(ADC1);
@@ -102,38 +106,181 @@ LGPL License Terms @ref lgpl_license
#include <libopencm3/stm32/f1/adc.h>
void rcc_set_adc_clk(u32 prescaler)
/*-----------------------------------------------------------------------------*/
/** @brief ADC Power On
If the ADC is in power-down mode then it is powered up. The application needs
to wait a time of about 3 microseconds for stabilization before using the ADC.
If the ADC is already on this function call has no effect.
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
*/
void adc_power_on(u32 adc)
{
/* 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;
if (!(ADC_CR2(adc) & ADC_CR2_ADON))
ADC_CR2(adc) |= ADC_CR2_ADON;
}
/*-----------------------------------------------------------------------------*/
/** @brief ADC Read from a Conversion Result Register
/** @brief ADC Start a Conversion Without Trigger
This initiates a conversion by software without a trigger. The ADC needs to be
powered on before this is called, otherwise this function has no effect.
Note that this is not available in other STM32F families. To ensure code compatibility,
enable triggering and use a software trigger source @see adc_start_conversion_regular.
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
*/
void adc_start_conversion_direct(u32 adc)
{
if (ADC_CR2(adc) & ADC_CR2_ADON)
ADC_CR2(adc) |= ADC_CR2_ADON;
}
/*-----------------------------------------------------------------------------*/
/** @brief ADC Set Dual A/D Mode
The dual mode uses ADC1 as master and ADC2 in a slave arrangement. This setting
is applied to ADC1 only. Start of conversion when triggered can cause simultaneous
conversion with ADC2, or alternate conversion. Regular and injected conversions
can be configured, each one being separately simultaneous or alternate.
Fast interleaved mode starts ADC1 immediately on trigger, and ADC2 seven clock
cycles later.
Slow interleaved mode starts ADC1 immediately on trigger, and ADC2 fourteen clock
cycles later, followed by ADC1 fourteen cycles later again. This can only be used
on a single channel.
Alternate trigger mode must occur on an injected channel group, and alternates
between the ADCs on each trigger.
Note that sampling must not overlap between ADCs on the same channel.
Dual A/D converter modes possible:
@li IND: Independent mode.
@li CRSISM: Combined regular simultaneous + injected simultaneous mode.
@li CRSATM: Combined regular simultaneous + alternate trigger mode.
@li CISFIM: Combined injected simultaneous + fast interleaved mode.
@li CISSIM: Combined injected simultaneous + slow interleaved mode.
@li ISM: Injected simultaneous mode only.
@li RSM: Regular simultaneous mode only.
@li FIM: Fast interleaved mode only.
@li SIM: Slow interleaved mode only.
@li ATM: Alternate trigger mode only.
@param[in] mode Unsigned int32. Dual mode selection from @ref adc_cr1_dualmod
*/
void adc_set_dual_mode(u32 mode)
{
ADC1_CR1 |= mode;
}
/*-----------------------------------------------------------------------------*/
/** @brief ADC Read the End-of-Conversion Flag
This flag is set after all channels of a regular or injected group have been
converted.
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
@returns bool. End of conversion flag.
*/
bool adc_eoc(u32 adc)
{
return ((ADC_SR(adc) & ADC_SR_EOC) != 0);
}
/*-----------------------------------------------------------------------------*/
/** @brief ADC Read the End-of-Conversion Flag for Injected Conversion
This flag is set after all channels of an injected group have been converted.
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
@returns bool. End of conversion flag.
*/
bool adc_eoc_injected(u32 adc)
{
return ((ADC_SR(adc) & ADC_SR_JEOC) != 0);
}
/*-----------------------------------------------------------------------------*/
/** @brief ADC Read from the Regular Conversion Result Register
The result read back is 12 bits, right or left aligned within the first 16 bits.
For ADC1 only, the higher 16 bits will hold the result from ADC2 if
an appropriate dual mode has been set @see adc_set_dual_mode.
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
@returns Unsigned int32 conversion result.
*/
u32 adc_read_regular(u32 adc)
{
return ADC_DR(adc);
}
/*-----------------------------------------------------------------------------*/
/** @brief ADC Read from an Injected Conversion Result Register
The result read back from the selected injected result register (one of four) is
12 bits, right or left aligned within the first 16 bits. The result can have a
negative value if the injected channel offset has been set @see adc_set_injected_offset.
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
@param[in] reg Unsigned int8. Register number (1 ... 4).
@returns Unsigned int32 conversion result.
*/
void adc_read(u32 block, u32 channel)
u32 adc_read_injected(u32 adc, u8 reg)
{
/* TODO */
switch (reg) {
case 1:
return ADC_JDR1(adc);
case 2:
return ADC_JDR2(adc);
case 3:
return ADC_JDR3(adc);
case 4:
return ADC_JDR4(adc);
}
return 0;
}
/* FIXME: QUICK HACK to prevent compiler warnings. */
block = block;
channel = channel;
/*-----------------------------------------------------------------------------*/
/** @brief ADC Set the Injected Channel Data Offset
This value is subtracted from the injected channel results after conversion
is complete, and can result in negative results. A separate value can be specified
for each injected data register.
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
@param[in] reg Unsigned int8. Register number (1 ... 4).
@param[in] offset Unsigned int32.
*/
void adc_set_injected_offset(u32 adc, u8 reg, u32 offset)
{
switch (reg) {
case 1:
ADC_JOFR1(adc) = offset;
break;
case 2:
ADC_JOFR2(adc) = offset;
break;
case 3:
ADC_JOFR3(adc) = offset;
break;
case 4:
ADC_JOFR4(adc) = offset;
break;
}
}
/*-----------------------------------------------------------------------------*/
@@ -203,9 +350,11 @@ of the subgroup at the beginning of the whole group.
@param[in] length Unsigned int8. Number of channels in the group @ref adc_cr1_discnum
*/
void adc_enable_discontinous_mode_regular(u32 adc)
void adc_enable_discontinuous_mode_regular(u32 adc, u8 length)
{
ADC_CR1(adc) |= ADC_CR1_DISCEN;
if ( (length-1) > 7 ) return;
ADC_CR1(adc) |= ADC_CR1_DISCEN;
ADC_CR2(adc) |= ((length-1) << ADC_CR1_DISCNUM_SHIFT);
}
/*-----------------------------------------------------------------------------*/
@@ -214,7 +363,7 @@ void adc_enable_discontinous_mode_regular(u32 adc)
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
*/
void adc_disable_discontinous_mode_regular(u32 adc)
void adc_disable_discontinuous_mode_regular(u32 adc)
{
ADC_CR1(adc) &= ~ADC_CR1_DISCEN;
}
@@ -229,7 +378,7 @@ entire group has been converted.
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
*/
void adc_enable_discontinous_mode_injected(u32 adc)
void adc_enable_discontinuous_mode_injected(u32 adc)
{
ADC_CR1(adc) |= ADC_CR1_JDISCEN;
}
@@ -240,7 +389,7 @@ void adc_enable_discontinous_mode_injected(u32 adc)
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
*/
void adc_disable_discontinous_mode_injected(u32 adc)
void adc_disable_discontinuous_mode_injected(u32 adc)
{
ADC_CR1(adc) &= ~ADC_CR1_JDISCEN;
}
@@ -257,6 +406,7 @@ channels is disabled as required.
void adc_enable_automatic_injected_group_conversion(u32 adc)
{
adc_disable_external_trigger_injected(adc);
ADC_CR1(adc) |= ADC_CR1_JAUTO;
}
@@ -288,7 +438,7 @@ disabled.
void adc_enable_analog_watchdog_on_all_channels(u32 adc)
{
ADC_CR1(adc) |= ADC_CR1_AWDSGL;
ADC_CR1(adc) &= ~ADC_CR1_AWDSGL;
}
/*-----------------------------------------------------------------------------*/
@@ -315,7 +465,7 @@ void adc_enable_analog_watchdog_on_selected_channel(u32 adc, u8 channel)
if (channel < 18)
reg32 |= channel;
ADC_CR1(adc) = reg32;
ADC_CR1(adc) &= ~ADC_CR1_AWDSGL;
ADC_CR1(adc) |= ADC_CR1_AWDSGL;
}
/*-----------------------------------------------------------------------------*/
@@ -350,7 +500,7 @@ void adc_disable_scan_mode(u32 adc)
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
*/
void adc_enable_jeoc_interrupt(u32 adc)
void adc_enable_eoc_interrupt_injected(u32 adc)
{
ADC_CR1(adc) |= ADC_CR1_JEOCIE;
}
@@ -361,7 +511,7 @@ void adc_enable_jeoc_interrupt(u32 adc)
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
*/
void adc_disable_jeoc_interrupt(u32 adc)
void adc_disable_eoc_interrupt_injected(u32 adc)
{
ADC_CR1(adc) &= ~ADC_CR1_JEOCIE;
}
@@ -519,8 +669,7 @@ void adc_enable_external_trigger_regular(u32 adc, u32 trigger)
u32 reg32;
reg32 = (ADC_CR2(adc) & ~(ADC_CR2_EXTSEL_MASK));
if (trigger < 8)
reg32 |= (trigger);
reg32 |= (trigger);
ADC_CR2(adc) = reg32;
ADC_CR2(adc) |= ADC_CR2_EXTTRIG;
}
@@ -565,14 +714,12 @@ For ADC3
@param[in] trigger Unsigned int8. Trigger identifier @ref adc_trigger_injected_12
for ADC1 and ADC2, or @ref adc_trigger_injected_3 for ADC3
*/
void adc_enable_external_trigger_injected(u32 adc, u32 trigger)
{
u32 reg32;
reg32 = (ADC_CR2(adc) & ~(ADC_CR2_JEXTSEL_MASK)); /* Clear bits [12:14]. */
if (trigger < 8)
reg32 |= (trigger);
reg32 |= (trigger);
ADC_CR2(adc) = reg32;
ADC_CR2(adc) |= ADC_CR2_JEXTTRIG;
}
@@ -681,7 +828,7 @@ group immediately following completion of the previous channel group conversion.
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
*/
void adc_set_continous_conversion_mode(u32 adc)
void adc_set_continuous_conversion_mode(u32 adc)
{
ADC_CR2(adc) |= ADC_CR2_CONT;
}
@@ -707,7 +854,7 @@ If the ADC is in power-down mode then it is powered up. The application needs
to wait a time of about 3 microseconds for stabilization before using the ADC.
If the ADC is already on this function call will initiate a conversion.
@todo fix this.
@deprecated to be removed in a later release
@param[in] adc Unsigned int32. ADC block register address base @ref adc_reg_base
*/
@@ -740,7 +887,7 @@ The sampling time can be selected in ADC clock cycles from 1.5 to 239.5.
@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg
*/
void adc_set_conversion_time(u32 adc, u8 channel, u8 time)
void adc_set_sample_time(u32 adc, u8 channel, u8 time)
{
u32 reg32;
@@ -767,7 +914,7 @@ all channels.
@param[in] time Unsigned int8. Sampling time selection from @ref adc_sample_rg
*/
void adc_set_conversion_time_on_all_channels(u32 adc, u8 time)
void adc_set_sample_time_on_all_channels(u32 adc, u8 time)
{
u8 i;
u32 reg32 = 0;
@@ -871,12 +1018,24 @@ void adc_set_injected_sequence(u32 adc, u8 length, u8 channel[])
return;
for (i = 1; i <= length; i++)
reg32 |= (channel[i - 1] << ((i - 1) * 5));
reg32 |= (channel[4 - i] << ((4 - i) * 5));
reg32 |= ((length - 1) << ADC_JSQR_JL_LSB);
ADC_JSQR(adc) = reg32;
}
/*-----------------------------------------------------------------------------*/
/* Aliases */
#ifdef __GNUC__
void adc_set_continous_conversion_mode(u32 adc) __attribute__ ((alias("adc_set_continuous_conversion_mode")));
void adc_set_conversion_time(u32 adc, u8 channel, u8 time) __attribute__ ((alias ("adc_set_sample_time")));
void adc_set_conversion_time_on_all_channels(u32 adc, u8 time) __attribute__ ((alias ("adc_set_sample_time_on_all_channels")));
void adc_enable_jeoc_interrupt(u32 adc) __attribute__ ((alias ("adc_enable_eoc_interrupt_injected")));
void adc_disable_jeoc_interrupt(u32 adc) __attribute__ ((alias ("adc_disable_eoc_interrupt_injected")));
#endif
/**@}*/

View File

@@ -157,7 +157,7 @@ The wakeup pin is used for waking the processor from standby mode.
void pwr_enable_wakeup_pin(void)
{
PWR_CSR |= PWR_CR_EWUP;
PWR_CSR |= PWR_CSR_EWUP;
}
/*---------------------------------------------------------------------------*/
@@ -168,7 +168,7 @@ The wakeup pin is used for general purpose I/O.
void pwr_disable_wakeup_pin(void)
{
PWR_CSR &= ~PWR_CR_EWUP;
PWR_CSR &= ~PWR_CSR_EWUP;
}
/*---------------------------------------------------------------------------*/
@@ -183,7 +183,7 @@ threshold.
bool pwr_voltage_high(void)
{
return (PWR_CSR & PWR_CR_PVDO);
return (PWR_CSR & PWR_CSR_PVDO);
}
/*---------------------------------------------------------------------------*/
@@ -197,7 +197,7 @@ cleared by software (see @ref pwr_clear_standby_flag).
bool pwr_get_standby_flag(void)
{
return (PWR_CSR & PWR_CR_SBF);
return (PWR_CSR & PWR_CSR_SBF);
}
/*---------------------------------------------------------------------------*/
@@ -211,7 +211,7 @@ cleared by software (see @ref pwr_clear_wakeup_flag).
bool pwr_get_wakeup_flag(void)
{
return (PWR_CSR & PWR_CR_WUF);
return (PWR_CSR & PWR_CSR_WUF);
}
/**@}*/

View File

@@ -48,6 +48,7 @@ LGPL License Terms @ref lgpl_license
/**@{*/
#include <libopencm3/cm3/assert.h>
#include <libopencm3/stm32/f1/rcc.h>
#include <libopencm3/stm32/f1/flash.h>
@@ -166,8 +167,7 @@ int rcc_osc_ready_int_flag(osc_t osc)
break;
}
/* Shouldn't be reached. */
return -1;
cm3_assert_not_reached();
}
/*-----------------------------------------------------------------------------*/

View File

@@ -198,6 +198,31 @@ void timer_disable_irq(u32 timer_peripheral, u32 irq)
TIM_DIER(timer_peripheral) &= ~irq;
}
/*---------------------------------------------------------------------------*/
/** @brief Return Interrupt Source.
Returns true if the specified interrupt flag (UIF, TIF or CCxIF, with BIF or COMIF
for advanced timers) was set and the interrupt was enabled. If the specified flag
is not an interrupt flag, the function returns false.
@todo Timers 6-7, 9-14 have fewer interrupts, but invalid flags are not caught here.
@param[in] timer_peripheral Unsigned int32. Timer register address base @ref tim_reg_base
@param[in] flag Unsigned int32. Status register flag @ref tim_sr_values.
@returns boolean: flag set.
*/
bool timer_interrupt_source(u32 timer_peripheral, u32 flag)
{
/* flag not set or interrupt disabled or not an interrupt source */
if (((TIM_SR(timer_peripheral) & TIM_DIER(timer_peripheral) & flag) == 0) ||
(flag > TIM_SR_BIF)) return false;
/* Only an interrupt source for advanced timers */
if ((flag == TIM_SR_BIF) || (flag == TIM_SR_COMIF))
return ((timer_peripheral == TIM1) || (timer_peripheral == TIM8));
return true;
}
/*---------------------------------------------------------------------------*/
/** @brief Read a Status Flag.
@@ -1671,6 +1696,20 @@ u32 timer_get_counter(u32 timer_peripheral)
return TIM_CNT(timer_peripheral);
}
/*---------------------------------------------------------------------------*/
/** @brief Set Counter
Set the value of a timer's counter register contents.
@param[in] timer_peripheral Unsigned int32. Timer register address base
@param[in] Unsigned int32. Counter value.
*/
void timer_set_counter(u32 timer_peripheral, u32 count)
{
TIM_CNT(timer_peripheral) = count;
}
/*---------------------------------------------------------------------------*/
/** @brief Set Input Capture Filter Parameters

View File

@@ -1,296 +0,0 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#define WEAK __attribute__ ((weak))
/* Symbols exported by the linker script(s): */
extern unsigned _data_loadaddr, _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 uart4_isr(void);
void WEAK uart5_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, /* Addr: 0x0000_0000 */
reset_handler, /* Addr: 0x0000_0004 */
nmi_handler, /* Addr: 0x0000_0008 */
hard_fault_handler, /* Addr: 0x0000_000C */
mem_manage_handler, /* Addr: 0x0000_0010 */
bus_fault_handler, /* Addr: 0x0000_0014 */
usage_fault_handler, /* Addr: 0x0000_0018 */
0, 0, 0, 0, /* Reserved Addr: 0x0000_001C - 0x0000_002B */
sv_call_handler, /* Addr: 0x0000_002C */
debug_monitor_handler, /* Addr: 0x0000_0030*/
0, /* Reserved Addr: 0x0000_00034 */
pend_sv_handler, /* Addr: 0x0000_0038 */
sys_tick_handler, /* Addr: 0x0000_003C */
wwdg_isr, /* Addr: 0x0000_0040 */
pvd_isr, /* Addr: 0x0000_0044 */
tamper_isr, /* Addr: 0x0000_0048 */
rtc_isr, /* Addr: 0x0000_004C */
flash_isr, /* Addr: 0x0000_0050 */
rcc_isr, /* Addr: 0x0000_0054 */
exti0_isr, /* Addr: 0x0000_0058 */
exti1_isr, /* Addr: 0x0000_005C */
exti2_isr, /* Addr: 0x0000_0060 */
exti3_isr, /* Addr: 0x0000_0064 */
exti4_isr, /* Addr: 0x0000_0068 */
dma1_channel1_isr, /* Addr: 0x0000_006C */
dma1_channel2_isr, /* Addr: 0x0000_0070 */
dma1_channel3_isr, /* Addr: 0x0000_0074 */
dma1_channel4_isr, /* Addr: 0x0000_0078 */
dma1_channel5_isr, /* Addr: 0x0000_007C */
dma1_channel6_isr, /* Addr: 0x0000_0080 */
dma1_channel7_isr, /* Addr: 0x0000_0084 */
adc1_2_isr, /* Addr: 0x0000_0088 */
usb_hp_can_tx_isr, /* Addr: 0x0000_008C */
usb_lp_can_rx0_isr, /* Addr: 0x0000_0090 */
can_rx1_isr, /* Addr: 0x0000_0094 */
can_sce_isr, /* Addr: 0x0000_0098 */
exti9_5_isr, /* Addr: 0x0000_009C */
tim1_brk_isr, /* Addr: 0x0000_00A0 */
tim1_up_isr, /* Addr: 0x0000_00A4 */
tim1_trg_com_isr, /* Addr: 0x0000_00A8 */
tim1_cc_isr, /* Addr: 0x0000_00AC */
tim2_isr, /* Addr: 0x0000_00B0 */
tim3_isr, /* Addr: 0x0000_00B4 */
tim4_isr, /* Addr: 0x0000_00B8 */
i2c1_ev_isr, /* Addr: 0x0000_00BC */
i2c1_er_isr, /* Addr: 0x0000_00C0 */
i2c2_ev_isr, /* Addr: 0x0000_00C4 */
i2c2_er_isr, /* Addr: 0x0000_00C8 */
spi1_isr, /* Addr: 0x0000_00CC */
spi2_isr, /* Addr: 0x0000_00D0 */
usart1_isr, /* Addr: 0x0000_00D4 */
usart2_isr, /* Addr: 0x0000_00D8 */
usart3_isr, /* Addr: 0x0000_00DC */
exti15_10_isr, /* Addr: 0x0000_00E0 */
rtc_alarm_isr, /* Addr: 0x0000_00E4 */
usb_wakeup_isr, /* Addr: 0x0000_00E8 */
tim8_brk_isr, /* Addr: 0x0000_00EC */
tim8_up_isr, /* Addr: 0x0000_00F0 */
tim8_trg_com_isr, /* Addr: 0x0000_00F4 */
tim8_cc_isr, /* Addr: 0x0000_00F8 */
adc3_isr, /* Addr: 0x0000_00FC */
fsmc_isr, /* Addr: 0x0000_0100 */
sdio_isr, /* Addr: 0x0000_0104 */
tim5_isr, /* Addr: 0x0000_0108 */
spi3_isr, /* Addr: 0x0000_010C */
uart4_isr, /* Addr: 0x0000_0110 */
uart5_isr, /* Addr: 0x0000_0114 */
tim6_isr, /* Addr: 0x0000_0118 */
tim7_isr, /* Addr: 0x0000_011C */
dma2_channel1_isr, /* Addr: 0x0000_0120 */
dma2_channel2_isr, /* Addr: 0x0000_0124 */
dma2_channel3_isr, /* Addr: 0x0000_0128 */
dma2_channel4_5_isr, /* Addr: 0x0000_012C */
dma2_channel5_isr, /* Addr: 0x0000_0130 */
eth_isr, /* Addr: 0x0000_0134 */
eth_wkup_isr, /* Addr: 0x0000_0138 */
can2_tx_isr, /* Addr: 0x0000_013C */
can2_rx0_isr, /* Addr: 0x0000_0140 */
can2_rx1_isr, /* Addr: 0x0000_0144 */
can2_sce_isr, /* Addr: 0x0000_0148 */
otg_fs_isr, /* Addr: 0x0000_014C */
};
void reset_handler(void)
{
volatile unsigned *src, *dest;
__asm__("MSR msp, %0" : : "r"(&_stack));
for (src = &_data_loadaddr, 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 uart4_isr = null_handler
#pragma weak uart5_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

View File

@@ -29,8 +29,8 @@ CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = vector.o rcc.o gpio.o usart.o spi.o flash.o nvic.o \
i2c.o systick.o exti.o scb.o timer.o \
i2c.o systick.o exti.o scb.o timer.o assert.o
VPATH += ../../usb:../
VPATH += ../../usb:../:../../cm3
include ../../Makefile.include

View File

@@ -19,6 +19,7 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/assert.h>
#include <libopencm3/stm32/f2/rcc.h>
#include <libopencm3/stm32/f2/flash.h>
@@ -125,8 +126,7 @@ int rcc_osc_ready_int_flag(osc_t osc)
break;
}
/* Shouldn't be reached. */
return -1;
cm3_assert_not_reached();
}
void rcc_css_int_clear(void)

View File

@@ -1,336 +0,0 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
* Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#define WEAK __attribute__ ((weak))
/* Symbols exported by the linker script(s): */
extern unsigned _data_loadaddr, _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 uart4_isr(void);
void WEAK uart5_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,
uart4_isr,
uart5_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 = &_data_loadaddr, 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 uart4_isr = null_handler
#pragma weak uart5_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

View File

@@ -24,14 +24,16 @@ PREFIX ?= arm-none-eabi
CC = $(PREFIX)-gcc
AR = $(PREFIX)-ar
CFLAGS = -Os -g -Wall -Wextra -I../../../include -fno-common \
-mcpu=cortex-m3 -mthumb -Wstrict-prototypes \
-mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 \
-Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD -DSTM32F4
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS = vector.o rcc.o gpio.o usart.o spi.o flash.o nvic.o \
i2c.o systick.o exti.o scb.o pwr.o timer.o \
usb.o usb_standard.o usb_control.o usb_f107.o \
assert.o
VPATH += ../../usb:../
VPATH += ../../usb:../:../../cm3
include ../../Makefile.include

View File

@@ -19,6 +19,7 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/assert.h>
#include <libopencm3/stm32/f4/rcc.h>
#include <libopencm3/stm32/f4/pwr.h>
#include <libopencm3/stm32/f4/flash.h>
@@ -139,8 +140,7 @@ int rcc_osc_ready_int_flag(osc_t osc)
break;
}
/* Shouldn't be reached. */
return -1;
cm3_assert_not_reached();
}
void rcc_css_int_clear(void)

View File

@@ -18,319 +18,10 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#define WEAK __attribute__ ((weak))
#include <libopencm3/stm32/f4/scb.h>
/* Symbols exported by the linker script(s): */
extern unsigned _data_loadaddr, _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 uart4_isr(void);
void WEAK uart5_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,
uart4_isr,
uart5_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)
static void pre_main(void)
{
volatile unsigned *src, *dest;
__asm__("MSR msp, %0" : : "r"(&_stack));
for (src = &_data_loadaddr, dest = &_data; dest < &_edata; src++, dest++)
*dest = *src;
while (dest < &_ebss)
*dest++ = 0;
/* Call the application's entry point. */
main();
/* Enable access to Floating-Point coprocessor. */
SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11);
}
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 uart4_isr = null_handler
#pragma weak uart5_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

View File

@@ -1,3 +1,28 @@
/** @defgroup i2c_file I2C
@ingroup STM32F_files
@brief <b>libopencm3 STM32Fxxx I2C</b>
@version 1.0.0
@author @htmlonly &copy; @endhtmlonly 2010 Thomas Otto <tommi@viadmin.org>
@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net>
@date 15 October 2012
Devices can have up to two I2C peripherals. The peripherals support SMBus and
PMBus variants.
A peripheral begins after reset in Slave mode. To become a Master a start
condition must be generated. The peripheral will remain in Master mode unless
a multimaster contention is lost or a stop condition is generated.
@todo all sorts of lovely stuff like DMA, Interrupts, SMBus variant, Status
register access, Error conditions
LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
@@ -20,6 +45,17 @@
#include <libopencm3/stm32/i2c.h>
#include <libopencm3/stm32/f4/rcc.h>
/**@{*/
/*-----------------------------------------------------------------------------*/
/** @brief I2C Reset.
The I2C peripheral and all its associated configuration registers are placed in the
reset condition. The reset is effected via the RCC peripheral reset system.
@param[in] i2c Unsigned int32. I2C peripheral identifier @ref i2c_reg_base.
*/
void i2c_reset(u32 i2c)
{
switch (i2c) {
@@ -34,26 +70,69 @@ void i2c_reset(u32 i2c)
}
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Peripheral Enable.
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_peripheral_enable(u32 i2c)
{
I2C_CR1(i2c) |= I2C_CR1_PE;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Peripheral Disable.
This must not be reset while in Master mode until a communication has finished.
In Slave mode, the peripheral is disabled only after communication has ended.
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_peripheral_disable(u32 i2c)
{
I2C_CR1(i2c) &= ~I2C_CR1_PE;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Send Start Condition.
If in Master mode this will cause a restart condition to occur at the end of the
current transmission. If in Slave mode, this will initiate a start condition
when the current bus activity is completed.
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_send_start(u32 i2c)
{
I2C_CR1(i2c) |= I2C_CR1_START;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Send Stop Condition.
After the current byte transfer this will initiate a stop condition if in Master
mode, or simply release the bus if in Slave mode.
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_send_stop(u32 i2c)
{
I2C_CR1(i2c) |= I2C_CR1_STOP;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set the 7 bit Slave Address for the Peripheral.
This sets an address for Slave mode operation, in 7 bit form.
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] slave Unsigned int8. Slave address 0...127.
*/
void i2c_set_own_7bit_slave_address(u32 i2c, u8 slave)
{
I2C_OAR1(i2c) = (u16)(slave << 1);
@@ -61,21 +140,61 @@ void i2c_set_own_7bit_slave_address(u32 i2c, u8 slave)
I2C_OAR1(i2c) |= (1 << 14); /* Datasheet: always keep 1 by software. */
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set the 10 bit Slave Address for the Peripheral.
This sets an address for Slave mode operation, in 10 bit form.
@todo add "I2C_OAR1(i2c) |= (1 << 14);" as above
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] slave Unsigned int16. Slave address 0...1023.
*/
void i2c_set_own_10bit_slave_address(u32 i2c, u16 slave)
{
I2C_OAR1(i2c) = (u16)(I2C_OAR1_ADDMODE | slave);
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set Fast Mode.
Set the clock frequency to the high clock rate mode (up to 400kHz). The actual
clock frequency must be set with @ref i2c_set_clock_frequency
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_set_fast_mode(u32 i2c)
{
I2C_CCR(i2c) |= I2C_CCR_FS;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set Standard Mode.
Set the clock frequency to the standard clock rate mode (up to 100kHz). The actual
clock frequency must be set with @ref i2c_set_clock_frequency
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
*/
void i2c_set_standard_mode(u32 i2c)
{
I2C_CCR(i2c) &= ~I2C_CCR_FS;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set Peripheral Clock Frequency.
Set the peripheral clock frequency: 2MHz to 36MHz (the APB frequency). Note that
this is <b> not </b> the I2C bus clock. This is set in conjunction with the Clock
Control register to generate the Master bus clock, see @ref i2c_set_ccr
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] freq Unsigned int8. Clock Frequency Setting @ref i2c_clock.
*/
void i2c_set_clock_frequency(u32 i2c, u8 freq)
{
u16 reg16;
@@ -84,6 +203,21 @@ void i2c_set_clock_frequency(u32 i2c, u8 freq)
I2C_CR2(i2c) = reg16;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set Bus Clock Frequency.
Set the bus clock frequency. This is a 12 bit number (0...4095) calculated
from the formulae given in the STM32F1 reference manual in the description
of the CCR field. It is a divisor of the peripheral clock frequency
@ref i2c_set_clock_frequency modified by the fast mode setting
@ref i2c_set_fast_mode
@todo provide additional API assitance to set the clock, eg macros
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] freq Unsigned int16. Bus Clock Frequency Setting 0...4095.
*/
void i2c_set_ccr(u32 i2c, u16 freq)
{
u16 reg16;
@@ -92,17 +226,48 @@ void i2c_set_ccr(u32 i2c, u16 freq)
I2C_CCR(i2c) = reg16;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Set the Rise Time.
Set the maximum rise time on the bus according to the I2C specification, as 1
more than the specified rise time in peripheral clock cycles. This is a 6 bit
number.
@todo provide additional APIP assistance.
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] trise Unsigned int16. Rise Time Setting 0...63.
*/
void i2c_set_trise(u32 i2c, u16 trise)
{
I2C_TRISE(i2c) = trise;
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Send the 7-bit Slave Address.
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] slave Unsigned int16. Slave address 0...1023.
@param[in] readwrite Unsigned int8. Single bit to instruct slave to receive or send @ref i2c_rw.
*/
void i2c_send_7bit_address(u32 i2c, u8 slave, u8 readwrite)
{
I2C_DR(i2c) = (u8)((slave << 1) | readwrite);
}
/*-----------------------------------------------------------------------------*/
/** @brief I2C Send Data.
@param[in] i2c Unsigned int32. I2C register base address @ref i2c_reg_base.
@param[in] data Unsigned int8. Byte to send.
*/
void i2c_send_data(u32 i2c, u8 data)
{
I2C_DR(i2c) = data;
}
/**@}*/

View File

@@ -1,3 +1,43 @@
/** @defgroup spi_file SPI
@ingroup STM32F_files
@brief <b>libopencm3 STM32Fxxx SPI</b>
@version 1.0.0
@author @htmlonly &copy; @endhtmlonly 2009 Uwe Hermann <uwe@hermann-uwe.de>
@author @htmlonly &copy; @endhtmlonly 2012 Ken Sarkies <ksarkies@internode.on.net>
@date 15 October 2012
Devices can have up to three SPI peripherals. The common 4-wire full-duplex
mode of operation is supported, along with 3-wire variants using unidirectional
communication modes or half-duplex bidirectional communication. A variety of
options allows many of the SPI variants to be supported. Multimaster operation
is also supported. A CRC can be generated and checked in hardware.
@note Some JTAG pins need to be remapped if SPI is to be used.
@note The I2S protocol shares the SPI hardware so the two protocols cannot be
used at the same time on the same peripheral.
Example: 1Mbps, positive clock polarity, leading edge trigger, 8-bit words,
LSB first.
@code
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
@endcode
@todo need additional functions to aid ISRs in retrieving status
LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
@@ -41,6 +81,17 @@
* reg16 = spi_read(SPI1); // 16-bit read
*/
/**@{*/
/*-----------------------------------------------------------------------------*/
/** @brief SPI Reset.
The SPI peripheral and all its associated configuration registers are placed in the
reset condition. The reset is effected via the RCC peripheral reset system.
@param[in] spi_peripheral Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_reset(u32 spi_peripheral)
{
switch (spi_peripheral) {
@@ -59,6 +110,25 @@ void spi_reset(u32 spi_peripheral)
}
}
/*-----------------------------------------------------------------------------*/
/** @brief Configure the SPI as Master.
The SPI peripheral is configured as a master with communication parameters
baudrate, data format 8/16 bits, frame format lsb/msb first, clock polarity
and phase. The SPI enable, CRC enable and CRC next controls are not affected.
These must be controlled separately.
@todo NSS pin handling.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
@param[in] br Unsigned int32. Baudrate @ref spi_baudrate.
@param[in] cpol Unsigned int32. Clock polarity @ref spi_cpol.
@param[in] cpha Unsigned int32. Clock Phase @ref spi_cpha.
@param[in] dff Unsigned int32. Data frame format 8/16 bits @ref spi_dff.
@param[in] lsbfirst Unsigned int32. Frame format lsb/msb first @ref spi_lsbfirst.
@returns int. Error code.
*/
int spi_init_master(u32 spi, u32 br, u32 cpol, u32 cpha, u32 dff, u32 lsbfirst)
{
u32 reg32 = SPI_CR1(spi);
@@ -82,28 +152,66 @@ int spi_init_master(u32 spi, u32 br, u32 cpol, u32 cpha, u32 dff, u32 lsbfirst)
}
/* TODO: Error handling? */
/*-----------------------------------------------------------------------------*/
/** @brief SPI Enable.
The SPI peripheral is enabled.
@todo Error handling?
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_enable(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_SPE; /* Enable SPI. */
}
/* TODO: Error handling? */
/*-----------------------------------------------------------------------------*/
/** @brief SPI Disable.
The SPI peripheral is disabled.
@todo Follow procedure from section 23.3.8 in the TRM.
(possibly create a "clean disable" function separately)
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_disable(u32 spi)
{
u32 reg32;
/* TODO: Follow procedure from section 23.3.8 in the TRM. */
reg32 = SPI_CR1(spi);
reg32 &= ~(SPI_CR1_SPE); /* Disable SPI. */
SPI_CR1(spi) = reg32;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Data Write.
Data is written to the SPI interface.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
@param[in] data Unsigned int16. 8 or 16 bit data to be written.
*/
void spi_write(u32 spi, u16 data)
{
/* Write data (8 or 16 bits, depending on DFF) into DR. */
SPI_DR(spi) = data;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Data Write with Blocking.
Data is written to the SPI interface after the previous write transfer has finished.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
@param[in] data Unsigned int16. 8 or 16 bit data to be written.
*/
void spi_send(u32 spi, u16 data)
{
/* Wait for transfer finished. */
@@ -114,6 +222,15 @@ void spi_send(u32 spi, u16 data)
SPI_DR(spi) = data;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Data Read.
Data is read from the SPI interface after the incoming transfer has finished.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
@returns data Unsigned int16. 8 or 16 bit data.
*/
u16 spi_read(u32 spi)
{
/* Wait for transfer finished. */
@@ -124,6 +241,17 @@ u16 spi_read(u32 spi)
return SPI_DR(spi);
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Data Write and Read Exchange.
Data is written to the SPI interface, then a read is done after the incoming transfer
has finished.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
@param[in] data Unsigned int16. 8 or 16 bit data to be written.
@returns data Unsigned int16. 8 or 16 bit data.
*/
u16 spi_xfer(u32 spi, u16 data)
{
spi_write(spi, data);
@@ -136,98 +264,251 @@ u16 spi_xfer(u32 spi, u16 data)
return SPI_DR(spi);
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set Bidirectional Simplex Mode.
The SPI peripheral is set for bidirectional transfers in two-wire simplex mode
(using a clock wire and a bidirectional data wire).
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_bidirectional_mode(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_BIDIMODE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set Unidirectional Mode.
The SPI peripheral is set for unidirectional transfers. This is used in full duplex
mode or when the SPI is placed in two-wire simplex mode that uses a clock wire and a
unidirectional data wire.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_unidirectional_mode(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_BIDIMODE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set Bidirectional Simplex Receive Only Mode.
The SPI peripheral is set for bidirectional transfers in two-wire simplex mode
(using a clock wire and a bidirectional data wire), and is placed in a receive state.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_bidirectional_receive_only_mode(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_BIDIMODE;
SPI_CR1(spi) &= ~SPI_CR1_BIDIOE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set Bidirectional Simplex Receive Only Mode.
The SPI peripheral is set for bidirectional transfers in two-wire simplex mode
(using a clock wire and a bidirectional data wire), and is placed in a transmit state.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_bidirectional_transmit_only_mode(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_BIDIMODE;
SPI_CR1(spi) |= SPI_CR1_BIDIOE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Enable the CRC.
The SPI peripheral is set to use a CRC field for transmit and receive.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_enable_crc(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_CRCEN;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Disable the CRC.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_disable_crc(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_CRCEN;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Next Transmit is a Data Word
The next transmission to take place is a data word from the transmit buffer.
This must be called before transmission to distinguish between sending
of a data or CRC word.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_next_tx_from_buffer(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_CRCNEXT;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Next Transmit is a CRC Word
The next transmission to take place is a crc word from the hardware crc unit.
This must be called before transmission to distinguish between sending
of a data or CRC word.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_next_tx_from_crc(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_CRCNEXT;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set Data Frame Format to 8 bits
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_dff_8bit(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_DFF;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set Data Frame Format to 16 bits
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_dff_16bit(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_DFF;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set Full Duplex (3-wire) Mode
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_full_duplex_mode(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_RXONLY;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set Receive Only Mode for Simplex (2-wire) Unidirectional Transfers
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_receive_only_mode(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_RXONLY;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Enable Slave Management by Hardware
In slave mode the NSS hardware input is used as a select enable for the slave.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_disable_software_slave_management(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_SSM;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Enable Slave Management by Software
In slave mode the NSS hardware input is replaced by an internal software
enable/disable of the slave (@ref spi_set_nss_high).
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_enable_software_slave_management(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_SSM;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set the Software NSS Signal High
In slave mode, and only when software slave management is used, this replaces
the NSS signal with a slave select enable signal.
@todo these should perhaps be combined with an SSM enable as it is meaningless otherwise
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_nss_high(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_SSI;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set the Software NSS Signal Low
In slave mode, and only when software slave management is used, this replaces
the NSS signal with a slave select disable signal.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_nss_low(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_SSI;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set to Send LSB First
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_send_lsb_first(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_LSBFIRST;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set to Send MSB First
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_send_msb_first(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_LSBFIRST;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set the Baudrate Prescaler
@todo Why is this specification different to the spi_init_master baudrate values?
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
@param[in] baudrate Unsigned int8. Baudrate prescale value @ref spi_br_pre.
*/
void spi_set_baudrate_prescaler(u32 spi, u8 baudrate)
{
u32 reg32;
@@ -240,92 +521,217 @@ void spi_set_baudrate_prescaler(u32 spi, u8 baudrate)
SPI_CR1(spi) = reg32;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set to Master Mode
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_master_mode(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_MSTR;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set to Slave Mode
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_slave_mode(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_MSTR;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set the Clock Polarity to High when Idle
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_clock_polarity_1(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_CPOL;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set the Clock Polarity to Low when Idle
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_clock_polarity_0(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_CPOL;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set the Clock Phase to Capture on Trailing Edge
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_clock_phase_1(u32 spi)
{
SPI_CR1(spi) |= SPI_CR1_CPHA;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set the Clock Phase to Capture on Leading Edge
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_set_clock_phase_0(u32 spi)
{
SPI_CR1(spi) &= ~SPI_CR1_CPHA;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Enable the Transmit Buffer Empty Interrupt
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_enable_tx_buffer_empty_interrupt(u32 spi)
{
SPI_CR2(spi) |= SPI_CR2_TXEIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Disable the Transmit Buffer Empty Interrupt
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_disable_tx_buffer_empty_interrupt(u32 spi)
{
SPI_CR2(spi) &= ~SPI_CR2_TXEIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Enable the Receive Buffer Ready Interrupt
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_enable_rx_buffer_not_empty_interrupt(u32 spi)
{
SPI_CR2(spi) |= SPI_CR2_RXNEIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Disable the Receive Buffer Ready Interrupt
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_disable_rx_buffer_not_empty_interrupt(u32 spi)
{
SPI_CR2(spi) &= ~SPI_CR2_RXNEIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Enable the Error Interrupt
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_enable_error_interrupt(u32 spi)
{
SPI_CR2(spi) |= SPI_CR2_ERRIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Disable the Error Interrupt
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_disable_error_interrupt(u32 spi)
{
SPI_CR2(spi) &= ~SPI_CR2_ERRIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set the NSS Pin as an Output
Normally used in master mode to allows the master to place all devices on the
SPI bus into slave mode. Multimaster mode is not possible.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_enable_ss_output(u32 spi)
{
SPI_CR2(spi) |= SPI_CR2_SSOE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Set the NSS Pin as an Input
In master mode this allows the master to sense the presence of other masters. If
NSS is then pulled low the master is placed into slave mode. In slave mode NSS
becomes a slave enable.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_disable_ss_output(u32 spi)
{
SPI_CR2(spi) &= ~SPI_CR2_SSOE;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Enable Transmit Transfers via DMA
This allows transmissions to proceed unattended using DMA to move data to the
transmit buffer as it becomes available. The DMA channels provided for each
SPI peripheral are given in the Technical Manual DMA section.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_enable_tx_dma(u32 spi)
{
SPI_CR2(spi) |= SPI_CR2_TXDMAEN;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Disable Transmit Transfers via DMA
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_disable_tx_dma(u32 spi)
{
SPI_CR2(spi) &= ~SPI_CR2_TXDMAEN;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Enable Receive Transfers via DMA
This allows received data streams to proceed unattended using DMA to move data from
the receive buffer as data becomes available. The DMA channels provided for each
SPI peripheral are given in the Technical Manual DMA section.
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_enable_rx_dma(u32 spi)
{
SPI_CR2(spi) |= SPI_CR2_RXDMAEN;
}
/*-----------------------------------------------------------------------------*/
/** @brief SPI Disable Receive Transfers via DMA
@param[in] spi Unsigned int32. SPI peripheral identifier @ref spi_reg_base.
*/
void spi_disable_rx_dma(u32 spi)
{
SPI_CR2(spi) &= ~SPI_CR2_RXDMAEN;
}
/**@}*/

View File

@@ -1,3 +1,22 @@
/** @defgroup STM32F1xx_usart_file USART
@ingroup STM32F_files
@brief <b>libopencm3 STM32F USART</b>
@version 1.0.0
@author @htmlonly &copy; @endhtmlonly 2009 Uwe Hermann <uwe@hermann-uwe.de>
@date 30 August 2012
This library supports the USART/UART in the STM32F series
of ARM Cortex Microcontrollers by ST Microelectronics.
Devices can have up to 3 USARTs and 2 UARTs.
LGPL License Terms @ref lgpl_license
*/
/*
* This file is part of the libopencm3 project.
*
@@ -17,6 +36,8 @@
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/**@{*/
#include <libopencm3/stm32/usart.h>
#if defined(STM32F1)
@@ -29,6 +50,20 @@
# error "stm32 family not defined."
#endif
/*-----------------------------------------------------------------------------*/
/** @brief USART Set Baudrate.
The baud rate is computed from the APB high-speed prescaler clock (for USART1)
or the APB low-speed prescaler clock (for other USARTs). These values must
be correctly set before calling this function (refer to the rcc_clock_setup-*
functions in RCC).
@todo Add support for USART6 and oversampling in F2/F4
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] baud unsigned 32 bit. Baud rate specified in Hz.
*/
void usart_set_baudrate(u32 usart, u32 baud)
{
u32 clock = rcc_ppre1_frequency;
@@ -59,6 +94,16 @@ void usart_set_baudrate(u32 usart, u32 baud)
USART_BRR(usart) = ((2 * clock) + baud) / (2 * baud);
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Set Word Length.
The word length is set to 8 or 9 bits. Note that the last bit will be a parity bit
if parity is enabled, in which case the data length will be 7 or 8 bits respectively.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] bits unsigned 32 bit. Word length in bits 8 or 9.
*/
void usart_set_databits(u32 usart, u32 bits)
{
if (bits == 8)
@@ -67,6 +112,15 @@ void usart_set_databits(u32 usart, u32 bits)
USART_CR1(usart) |= USART_CR1_M; /* 9 data bits */
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Set Stop Bit(s).
The stop bits are specified as 0.5, 1, 1.5 or 2.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] stopbits unsigned 32 bit. Stop bits @ref usart_cr2_stopbits.
*/
void usart_set_stopbits(u32 usart, u32 stopbits)
{
u32 reg32;
@@ -76,6 +130,15 @@ void usart_set_stopbits(u32 usart, u32 stopbits)
USART_CR2(usart) = reg32;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Set Parity.
The parity bit can be selected as none, even or odd.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] parity unsigned 32 bit. Parity @ref usart_cr1_parity.
*/
void usart_set_parity(u32 usart, u32 parity)
{
u32 reg32;
@@ -85,6 +148,15 @@ void usart_set_parity(u32 usart, u32 parity)
USART_CR1(usart) = reg32;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Set Rx/Tx Mode.
The mode can be selected as Rx only, Tx only or Rx+Tx.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] mode unsigned 32 bit. Mode @ref usart_cr1_mode.
*/
void usart_set_mode(u32 usart, u32 mode)
{
u32 reg32;
@@ -94,6 +166,15 @@ void usart_set_mode(u32 usart, u32 mode)
USART_CR1(usart) = reg32;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Set Hardware Flow Control.
The flow control bit can be selected as none, RTS, CTS or RTS+CTS.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] flowcontrol unsigned 32 bit. Flowcontrol @ref usart_cr3_flowcontrol.
*/
void usart_set_flow_control(u32 usart, u32 flowcontrol)
{
u32 reg32;
@@ -103,46 +184,112 @@ void usart_set_flow_control(u32 usart, u32 flowcontrol)
USART_CR3(usart) = reg32;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Enable.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_enable(u32 usart)
{
USART_CR1(usart) |= USART_CR1_UE;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Disable.
At the end of the current frame, the USART is disabled to reduce power.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_disable(u32 usart)
{
USART_CR1(usart) &= ~USART_CR1_UE;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Send a Data Word.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] data unsigned 16 bit.
*/
void usart_send(u32 usart, u16 data)
{
/* Send data. */
USART_DR(usart) = (data & USART_DR_MASK);
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Read a Received Data Word.
If parity is enabled the MSB (bit 7 or 8 depending on the word length) is the parity bit.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@returns unsigned 16 bit data word.
*/
u16 usart_recv(u32 usart)
{
/* Receive data. */
return USART_DR(usart) & USART_DR_MASK;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Wait for Transmit Data Buffer Empty
Blocks until the transmit data buffer becomes empty and is ready to accept the
next data word.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
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);
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Wait for Received Data Available
Blocks until the receive data buffer holds a valid received data word.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_wait_recv_ready(u32 usart)
{
/* Wait until the data is ready to be received. */
while ((USART_SR(usart) & USART_SR_RXNE) == 0);
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Send Data Word with Blocking
Blocks until the transmit data buffer becomes empty then writes the next data word
for transmission.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] data unsigned 16 bit.
*/
void usart_send_blocking(u32 usart, u16 data)
{
usart_wait_send_ready(usart);
usart_send(usart, data);
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Read a Received Data Word with Blocking.
Wait until a data word has been received then return the word.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@returns unsigned 16 bit data word.
*/
u16 usart_recv_blocking(u32 usart)
{
usart_wait_recv_ready(usart);
@@ -150,22 +297,148 @@ u16 usart_recv_blocking(u32 usart)
return usart_recv(usart);
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Receiver DMA Enable.
DMA is available on:
@li USART1 Rx DMA1 channel 5.
@li USART2 Rx DMA1 channel 6.
@li USART3 Rx DMA1 channel 3.
@li UART4 Rx DMA2 channel 3.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_enable_rx_dma(u32 usart)
{
USART_CR3(usart) |= USART_CR3_DMAR;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Receiver DMA Disable.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_disable_rx_dma(u32 usart)
{
USART_CR3(usart) &= ~USART_CR3_DMAR;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Transmitter DMA Enable.
DMA is available on:
@li USART1 Tx DMA1 channel 4.
@li USART2 Tx DMA1 channel 7.
@li USART3 Tx DMA1 channel 2.
@li UART4 Tx DMA2 channel 5.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_enable_tx_dma(u32 usart)
{
USART_CR3(usart) |= USART_CR3_DMAT;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Transmitter DMA Disable.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_disable_tx_dma(u32 usart)
{
USART_CR3(usart) &= ~USART_CR3_DMAT;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Receiver Interrupt Enable.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_enable_rx_interrupt(u32 usart)
{
USART_CR1(usart) |= USART_CR1_RXNEIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Receiver Interrupt Disable.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_disable_rx_interrupt(u32 usart)
{
USART_CR1(usart) &= ~USART_CR1_RXNEIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Transmitter Interrupt Enable.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_enable_tx_interrupt(u32 usart)
{
USART_CR1(usart) |= USART_CR1_TXEIE;
}
/*-----------------------------------------------------------------------------*/
/** @brief USART Transmitter Interrupt Disable.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
*/
void usart_disable_tx_interrupt(u32 usart)
{
USART_CR1(usart) &= ~USART_CR1_TXEIE;
}
/*---------------------------------------------------------------------------*/
/** @brief USART Read a Status Flag.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] flag Unsigned int32. Status register flag @ref usart_sr_flags.
@returns boolean: flag set.
*/
bool usart_get_flag(u32 usart, u32 flag)
{
return ((USART_SR(usart) & flag) != 0);
}
/*---------------------------------------------------------------------------*/
/** @brief USART Return Interrupt Source.
Returns true if the specified interrupt flag (IDLE, RXNE, TC, TXE or OE) was
set and the interrupt was enabled. If the specified flag is not an interrupt
flag, the function returns false.
@todo These are the most important interrupts likely to be used. Others
relating to LIN break, and error conditions in multibuffer communication, need
to be added for completeness.
@param[in] usart unsigned 32 bit. USART block register address base @ref usart_reg_base
@param[in] flag Unsigned int32. Status register flag @ref usart_sr_flags.
@returns boolean: flag and interrupt enable both set.
*/
bool usart_get_interrupt_source(u32 usart, u32 flag)
{
u32 flag_set = (USART_SR(usart) & flag);
/* IDLE, RXNE, TC, TXE interrupts */
if ((flag >= USART_SR_IDLE) && (flag <= USART_SR_TXE))
return ((flag_set & USART_CR1(usart)) != 0);
/* Overrun error */
else if (flag == USART_SR_ORE)
return (flag_set && (USART_CR3(usart) & USART_CR3_CTSIE));
return (false);
}
/**@}*/