tbm: initial commit

tags/0.1.0
S.J.R. van Schaik 7 years ago
parent edd4ee8d03
commit e946d0ce3d
  1. 13
      Makefile
  2. 0
      debug.c
  3. 2
      flash.scr
  4. 16
      main.c
  5. 269
      shell.c
  6. 8
      shell.h
  7. 154
      spi_flash.c
  8. 33
      spi_flash.h
  9. 183
      support/libopencm3.rules.mk
  10. 6
      support/libopencm3.target.mk
  11. 32
      support/stm32f0-discovery.ld
  12. 649
      support/stm32f042.ld
  13. 69
      usart.c
  14. 8
      usart.h

@ -0,0 +1,13 @@
BINARY = tbm
LDSCRIPT = support/stm32f0-discovery.ld
OPENCM3_DIR = libopencm3
OBJS += main.o
OBJS += shell.o
OBJS += spi_flash.o
OBJS += usart.o
include support/libopencm3.target.mk
include support/libopencm3.rules.mk

@ -0,0 +1,2 @@
load
run

@ -0,0 +1,16 @@
#include <stdio.h>
#include "shell.h"
#include "spi_flash.h"
#include "usart.h"
int main(void)
{
FILE *fp;
init_spi();
fp = init_usart(USART1);
cmd_loop(fp, "tbm # ");
return 0;
}

@ -0,0 +1,269 @@
#define _GNU_SOURCE
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/usart.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stddef.h>
#include <limits.h>
#include <sys/types.h>
#include "shell.h"
#include "spi_flash.h"
#include "usart.h"
static void do_probe(FILE *fp, const char *s);
static void do_read(FILE *fp, const char *s);
static void do_write(FILE *fp, const char *s);
static void do_erase(FILE *fp, const char *s);
struct cmd cmds[] = {
{ "probe", do_probe },
{ "read", do_read },
{ "write", do_write },
{ "erase", do_erase },
{ NULL, NULL },
};
/* TODO: implement a parser for hex arrays that is more user-friendly.
* Also implement dry runs for programmers. */
static void parse_hex(FILE *fp, char *buf, size_t len)
{
size_t i;
char s[3];
for (i = 0; i < len; ++i) {
memset(s, '\0', 3);
while ((s[0] = fgetc(fp)) && !isxdigit(s[0]))
fputc(s[0], fp);
fputc(s[0], fp);
while ((s[1] = fgetc(fp)) && !isxdigit(s[1]))
fputc(s[1], fp);
fputc(s[1], fp);
*buf++ = strtoul(s, NULL, 16);
}
}
static void print_hex_ascii(FILE *fp, const char *buf, size_t len)
{
size_t i, j;
char c;
for (j = 0; j < len; j += 16, buf += 16) {
for (i = 0; i < 16; ++i) {
fprintf(fp, "%02x", buf[i]);
}
fprintf(fp, " ");
for (i = 0; i < 16; ++i) {
c = buf[i];
fprintf(fp, "%c", isalnum(c) ? c : '.');
}
fprintf(fp, "\r\n");
}
}
static char *prompt(FILE *fp, const char *prefix)
{
char *alloc, *line, *s;
size_t nbytes = 0, nalloc_bytes = 16;
char c;
fprintf(fp, prefix);
if (!(line = malloc(nalloc_bytes)))
return NULL;
s = line;
while ((c = fgetc(fp)) && c != '\r') {
fputc(c, fp);
if (nbytes + 1 >= nalloc_bytes) {
nalloc_bytes *= 2;
if (!(alloc = realloc(line, nalloc_bytes)))
goto err_free_line;
line = alloc;
}
*s++ = c;
nbytes++;
}
fprintf(fp, "\r\n");
*s = '\0';
return line;
err_free_line:
free(line);
return NULL;
}
static void do_probe(FILE *fp, const char *s)
{
char cmd[1] = { CMD_READ_ID };
char buf[6];
(void)s;
spi_send_cmd(SPI1, cmd, 1, buf, 6);
fprintf(fp, "JEDEC ID: %02x%02x%02x\r\n", buf[0], buf[1], buf[2]);
}
static void do_read(FILE *fp, const char *s)
{
char buf[256], *end = NULL;
size_t addr, len, nbytes;
if (strncmp(s, "0x", 2) == 0)
s += 2;
addr = strtoull(s, &end, 16);
s = end;
if (errno == EINVAL || errno == ERANGE)
return;
s += strspn(s, " \r\n");
if (strncmp(s, "0x", 2) == 0)
s += 2;
len = strtoull(s, &end, 16);
s = end;
if (errno == EINVAL || errno == ERANGE)
return;
if (!len)
return;
while (len) {
nbytes = (len > 256) ? 256 : len;
spi_flash_read(SPI1, addr, buf, nbytes);
print_hex_ascii(fp, buf, nbytes);
addr += nbytes;
len -= nbytes;
}
}
static void do_write(FILE *fp, const char *s)
{
char buf[256], *end = NULL;
size_t addr, len, nbytes;
if (strncmp(s, "0x", 2) == 0)
s += 2;
addr = strtoull(s, &end, 16);
s = end;
if (errno == EINVAL || errno == ERANGE)
return;
s += strspn(s, " \r\n");
if (strncmp(s, "0x", 2) == 0)
s += 2;
len = strtoull(s, &end, 16);
s = end;
if (errno == EINVAL || errno == ERANGE)
return;
if (!len)
return;
while (len) {
nbytes = (len > 256) ? 256 : len;
parse_hex(fp, buf, nbytes);
fprintf(fp, "\r\n");
print_hex_ascii(fp, buf, nbytes);
spi_flash_write(SPI1, addr, buf, nbytes);
addr += nbytes;
len -= nbytes;
}
}
static void do_erase(FILE *fp, const char *s)
{
char *end = NULL;
size_t addr, len;
(void)fp;
if (strncmp(s, "0x", 2) == 0)
s += 2;
addr = strtoull(s, &end, 16);
s = end;
if (errno == EINVAL || errno == ERANGE)
return;
s += strspn(s, " \r\n");
if (strncmp(s, "0x", 2) == 0)
s += 2;
len = strtoull(s, &end, 16);
s = end;
if (errno == EINVAL || errno == ERANGE)
return;
if (!len)
return;
spi_flash_erase(fp, SPI1, addr, len);
}
static void parse_cmd(FILE *fp, const char *s)
{
struct cmd *cmd;
const char *args;
char *key;
size_t n;
n = strcspn(s, " \r\n");
key = strndup(s, n);
args = s + n;
args += strspn(args, " \r\n");
for (cmd = cmds; cmd->key; cmd++) {
if (strcmp(cmd->key, key) == 0)
cmd->exec(fp, args);
}
}
void cmd_loop(FILE *fp, const char *show)
{
char *line;
while (1) {
line = prompt(fp, show);
parse_cmd(fp, line);
free(line);
}
}

@ -0,0 +1,8 @@
#pragma once
struct cmd {
const char *key;
void (* exec)(FILE *fp, const char *s);
};
void cmd_loop(FILE *fp, const char *s);

@ -0,0 +1,154 @@
#define _GNU_SOURCE
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/usart.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stddef.h>
#include <limits.h>
#include <sys/types.h>
#include "spi_flash.h"
void init_spi(void)
{
/* Set up clocks for SPI 1 */
rcc_clock_setup_in_hsi_out_48mhz();
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_SPI1);
/* Set up GPIOs for SPI 1 */
gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO4);
gpio_set(GPIOA, GPIO4);
gpio_mode_setup(GPIOB, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO3 | GPIO4 | GPIO5);
gpio_set_af(GPIOB, GPIO_AF0, GPIO3 | GPIO4 | GPIO5);
spi_set_master_mode(SPI1);
spi_set_baudrate_prescaler(SPI1, SPI_CR1_BR_FPCLK_DIV_64);
spi_set_clock_polarity_0(SPI1);
spi_set_clock_phase_0(SPI1);
spi_set_full_duplex_mode(SPI1);
spi_set_unidirectional_mode(SPI1); /* bidirectional but in 3-wire */
spi_set_data_size(SPI1, SPI_CR2_DS_8BIT);
spi_enable_software_slave_management(SPI1);
spi_send_msb_first(SPI1);
spi_set_nss_high(SPI1);
spi_fifo_reception_threshold_8bit(SPI1);
SPI_I2SCFGR(SPI1) &= ~SPI_I2SCFGR_I2SMOD;
spi_enable(SPI1);
}
void spi_send_cmd(uint32_t dev, const char *cmd, size_t cmd_len,
char *data, size_t data_len)
{
size_t i;
gpio_clear(GPIOA, GPIO4);
for (i = 0; i < cmd_len; ++i) {
spi_send8(dev, *cmd++);
(void)spi_read8(dev);
}
for (i = 0; i < data_len; ++i) {
spi_send8(dev, 0);
*data++ = spi_read8(dev);
}
gpio_set(GPIOA, GPIO4);
}
static void spi_flash_addr(char *cmd, uint32_t addr)
{
cmd[1] = addr >> 16;
cmd[2] = addr >> 8;
cmd[3] = addr;
}
static void spi_enable_write(uint32_t dev)
{
char cmd[1] = { CMD_WRITE_ENABLE };
spi_send_cmd(dev, cmd, 1, NULL, 0);
}
static void spi_disable_write(uint32_t dev)
{
char cmd[1] = { CMD_WRITE_DISABLE };
spi_send_cmd(dev, cmd, 1, NULL, 0);
}
void spi_flash_read(uint32_t dev, uint32_t addr, char *data, size_t len)
{
char cmd[4] = { CMD_READ_ARRAY_SLOW };
spi_flash_addr(cmd, addr);
spi_send_cmd(dev, cmd, 4, data, len);
}
void spi_flash_write(uint32_t dev, uint32_t addr, char *data, size_t len)
{
char cmd[4] = { CMD_PAGE_PROGRAM };
size_t i;
spi_enable_write(dev);
spi_flash_addr(cmd, addr);
gpio_clear(GPIOA, GPIO4);
for (i = 0; i < 4; ++i) {
spi_send8(dev, cmd[i]);
(void)spi_read8(dev);
}
for (i = 0; i < len; ++i) {
spi_send8(dev, data[i]);
(void)spi_read8(dev);
}
gpio_set(GPIOA, GPIO4);
spi_disable_write(dev);
}
void spi_flash_erase(FILE *fp, uint32_t dev, uint32_t addr, size_t len)
{
char cmd[4];
size_t size;
spi_enable_write(dev);
addr = ROUND_UP(addr, 4 * KIB);
for (; len; addr += size, len -= size) {
if (IS_ROUND(addr, 64 * KIB) && IS_ROUND(len, 64 * KIB))
size = 64 * KIB;
else if (IS_ROUND(addr, 32 * KIB) && IS_ROUND(len, 32 * KIB))
size = 32 * KIB;
else if (IS_ROUND(addr, 4 * KIB) && IS_ROUND(len, 4 * KIB))
size = 4 * KIB;
else
size = 0;
switch (size) {
case 64 * KIB: cmd[0] = CMD_ERASE_64K; break;
case 32 * KIB: cmd[0] = CMD_ERASE_32K; break;
case 4 * KIB: cmd[0] = CMD_ERASE_4K; break;
default: goto err_disable_write;
};
fprintf(fp, "addr: %lx; size: %u\n", addr, size);
spi_flash_addr(cmd, addr);
spi_send_cmd(dev, cmd, 4, NULL, 0);
}
err_disable_write:
spi_disable_write(dev);
}

@ -0,0 +1,33 @@
#pragma once
/* Human-readable sizes */
#define KIB 1024
#define MIB (1024 * KIB)
#define GIB (1024 * GIB)
/* Read commands */
#define CMD_READ_ARRAY_SLOW 0x03
#define CMD_READ_ID 0x9f
/* Write commands */
#define CMD_PAGE_PROGRAM 0x02
#define CMD_WRITE_DISABLE 0x04
#define CMD_WRITE_ENABLE 0x06
/* Erase commands */
#define CMD_ERASE_4K 0x20
#define CMD_ERASE_32K 0x52
#define CMD_ERASE_64K 0xD8
#define CMD_ERASE_CHIP 0x60
/* Rounding */
#define IS_ROUND(x, k) (!((x) & ((k) - 1)))
#define ROUND_DOWN(x, k) ((x) & ~((k) - 1))
#define ROUND_UP(x, k) (((x) + (k) - 1) & ~((k) - 1))
void init_spi(void);
void spi_send_cmd(uint32_t dev, const char *cmd, size_t cmd_len,
char *data, size_t data_len);
void spi_flash_read(uint32_t dev, uint32_t addr, char *data, size_t len);
void spi_flash_write(uint32_t dev, uint32_t addr, char *data, size_t len);
void spi_flash_erase(FILE *fp, uint32_t dev, uint32_t addr, size_t len);

@ -0,0 +1,183 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
## Copyright (C) 2013 Frantisek Burian <BuFran@seznam.cz>
##
## 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/>.
##
# Be silent per default, but 'make V=1' will show all compiler calls.
ifneq ($(V),1)
Q := @
NULL := 2>/dev/null
endif
###############################################################################
# Executables
PREFIX ?= arm-none-eabi
CC := $(PREFIX)-gcc
LD := $(PREFIX)-gcc
AR := $(PREFIX)-ar
AS := $(PREFIX)-as
OBJCOPY := $(PREFIX)-objcopy
OBJDUMP := $(PREFIX)-objdump
GDB := $(PREFIX)-gdb
STFLASH = $(shell which st-flash)
STYLECHECK := /checkpatch.pl
STYLECHECKFLAGS := --no-tree -f --terse --mailback
STYLECHECKFILES := $(shell find . -name '*.[ch]')
###############################################################################
# Source files
LDSCRIPT ?= $(BINARY).ld
ifeq ($(strip $(OPENCM3_DIR)),)
# user has not specified the library path, so we try to detect it
# where we search for the library
LIBPATHS := ./libopencm3 ../../../../libopencm3 ../../../../../libopencm3
OPENCM3_DIR := $(wildcard $(LIBPATHS:=/locm3.sublime-project))
OPENCM3_DIR := $(firstword $(dir $(OPENCM3_DIR)))
ifeq ($(strip $(OPENCM3_DIR)),)
$(warning Cannot find libopencm3 library in the standard search paths.)
$(error Please specify it through OPENCM3_DIR variable!)
endif
endif
ifeq ($(V),1)
$(info Using $(OPENCM3_DIR) path to library)
endif
INCLUDE_DIR = $(OPENCM3_DIR)/include
LIB_DIR = $(OPENCM3_DIR)/lib
SCRIPT_DIR = $(OPENCM3_DIR)/scripts
###############################################################################
# C flags
CFLAGS += -Os -g
CFLAGS += -Wextra -Wshadow -Wimplicit-function-declaration
CFLAGS += -Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes
CFLAGS += -fno-common -ffunction-sections -fdata-sections
CPPFLAGS += -MD
CPPFLAGS += -Wall -Wundef
CPPFLAGS += -I$(INCLUDE_DIR) $(DEFS)
###############################################################################
# Linker flags
LDFLAGS += --static -nostartfiles
LDFLAGS += -L$(LIB_DIR)
LDFLAGS += -T$(LDSCRIPT)
LDFLAGS += -Wl,-Map=$(*).map
LDFLAGS += -Wl,--gc-sections
ifeq ($(V),99)
LDFLAGS += -Wl,--print-gc-sections
endif
###############################################################################
# Used libraries
LDLIBS += -l$(LIBNAME)
LDLIBS += -Wl,--start-group -lc -lgcc -lnosys -Wl,--end-group
###############################################################################
###############################################################################
###############################################################################
.SUFFIXES: .elf .bin .hex .srec .list .map .images
.SECONDEXPANSION:
.SECONDARY:
all: elf
elf: $(BINARY).elf
bin: $(BINARY).bin
hex: $(BINARY).hex
srec: $(BINARY).srec
list: $(BINARY).list
images: $(BINARY).images
flash: $(BINARY).flash
$(LDSCRIPT):
ifeq (,$(wildcard $(LDSCRIPT)))
$(error Unable to find specified linker script: $(LDSCRIPT))
endif
%.images: %.bin %.hex %.srec %.list %.map
@#printf "*** $* images generated ***\n"
%.bin: %.elf
@#printf " OBJCOPY $(*).bin\n"
$(Q)$(OBJCOPY) -Obinary $(*).elf $(*).bin
%.hex: %.elf
@#printf " OBJCOPY $(*).hex\n"
$(Q)$(OBJCOPY) -Oihex $(*).elf $(*).hex
%.srec: %.elf
@#printf " OBJCOPY $(*).srec\n"
$(Q)$(OBJCOPY) -Osrec $(*).elf $(*).srec
%.list: %.elf
@#printf " OBJDUMP $(*).list\n"
$(Q)$(OBJDUMP) -S $(*).elf > $(*).list
%.elf %.map: $(OBJS) $(LDSCRIPT) $(LIB_DIR)/lib$(LIBNAME).a
@#printf " LD $(*).elf\n"
$(Q)$(LD) $(LDFLAGS) $(ARCH_FLAGS) $(OBJS) $(LDLIBS) -o $(*).elf
%.o: %.c
@#printf " CC $(*).c\n"
$(Q)$(CC) $(CFLAGS) $(CPPFLAGS) $(ARCH_FLAGS) -o $(*).o -c $(*).c
clean:
@#printf " CLEAN\n"
$(Q)$(RM) *.o *.d *.elf *.bin *.hex *.srec *.list *.map
stylecheck: $(STYLECHECKFILES:=.stylecheck)
styleclean: $(STYLECHECKFILES:=.styleclean)
# the cat is due to multithreaded nature - we like to have consistent chunks of text on the output
%.stylecheck: %
$(Q)$(SCRIPT_DIR)$(STYLECHECK) $(STYLECHECKFLAGS) $* > $*.stylecheck; \
if [ -s $*.stylecheck ]; then \
cat $*.stylecheck; \
else \
rm -f $*.stylecheck; \
fi;
%.styleclean:
$(Q)rm -f $*.stylecheck;
%.flash: %.elf
@printf " GDB $(*).elf (flash)\n"
$(Q)$(GDB) --batch \
-ex 'target extended-remote $(STLINK_PORT)' \
-x flash.scr \
$(*).elf
.PHONY: images clean stylecheck styleclean elf bin hex srec list
-include $(OBJS:.o=.d)

@ -0,0 +1,6 @@
LIBNAME = opencm3_stm32f0
DEFS += -DSTM32F0
FP_FLAGS ?= -msoft-float
ARCH_FLAGS = -mthumb -mcpu=cortex-m0 $(FP_FLAGS)
STLINK_PORT ?= :4242

@ -0,0 +1,32 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
* Copyright (C) 2011 Stephen Caudle <scaudle@doceme.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/* Linker script for ST STM32F0DISCOVERY (STM32F051R8T6, 64K flash, 8K RAM). */
/* Define memory regions. */
MEMORY
{
rom (rx) : ORIGIN = 0x08000000, LENGTH = 64K
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 8K
}
/* Include the common ld script. */
INCLUDE libopencm3_stm32f0.ld

@ -0,0 +1,649 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/frameworks-d876e21057f406b37686f3dc7b9666f5957cda4847a48ec11e040df065624617.css" media="all" rel="stylesheet" />
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/github-05196ad2eeaad9504e7bb3adc33d4d19adc2bad851a35ed9b9b0f73702c554f5.css" media="all" rel="stylesheet" />
<link crossorigin="anonymous" href="https://assets-cdn.github.com/assets/site-dd6d43570c14503704e8983a7dd8e62484a668da1ce4ce997929ae2f367584c0.css" media="all" rel="stylesheet" />
<meta name="viewport" content="width=device-width">
<title>stm32f0_libopencm3_template/stm32f042.ld at master · hexagon5un/stm32f0_libopencm3_template · GitHub</title>
<link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub">
<link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub">
<meta property="fb:app_id" content="1401488693436528">
<link rel="assets" href="https://assets-cdn.github.com/">
<meta name="pjax-timeout" content="1000">
<meta name="request-id" content="BB5E:386B:99A8F1:F9FC95:58B02434" data-pjax-transient>
<meta name="selected-link" value="repo_source" data-pjax-transient>
<meta name="google-site-verification" content="KT5gs8h0wvaagLKAVWq8bbeNwnZZK1r1XQysX3xurLU">
<meta name="google-site-verification" content="ZzhVyEFwb7w3e0-uOTltm8Jsck2F5StVihD0exw2fsA">
<meta name="google-analytics" content="UA-3769691-2">
<meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" /><meta content="https://collector.githubapp.com/github-external/browser_event" name="octolytics-event-url" /><meta content="BB5E:386B:99A8F1:F9FC95:58B02434" name="octolytics-dimension-request_id" />
<meta content="/&lt;user-name&gt;/&lt;repo-name&gt;/blob/show" data-pjax-transient="true" name="analytics-location" />
<meta class="js-ga-set" name="dimension1" content="Logged Out">
<meta name="hostname" content="github.com">
<meta name="user-login" content="">
<meta name="expected-hostname" content="github.com">
<meta name="js-proxy-site-detection-payload" content="MDRiN2ZjODAzOTc3OGE3MjRlZTdiMDEyZjFlZDViZWI0ZTA2NGVkYmE0ZDJmZjQ1OGNiZWQ2ODNiOTllODViM3x7InJlbW90ZV9hZGRyZXNzIjoiMTQ1LjEwOS42Mi4yNDciLCJyZXF1ZXN0X2lkIjoiQkI1RTozODZCOjk5QThGMTpGOUZDOTU6NThCMDI0MzQiLCJ0aW1lc3RhbXAiOjE0ODc5Mzg2MTIsImhvc3QiOiJnaXRodWIuY29tIn0=">
<meta name="html-safe-nonce" content="fb19cedee2c0b12accfe12d68383502249b0e148">
<meta http-equiv="x-pjax-version" content="d315960581ecedf86906f3f215b9732a">
<meta name="description" content="stm32f0_libopencm3_template - The simplest possible working OpenCM3 application for the STM32f0 chips.">
<meta name="go-import" content="github.com/hexagon5un/stm32f0_libopencm3_template git https://github.com/hexagon5un/stm32f0_libopencm3_template.git">
<meta content="1560700" name="octolytics-dimension-user_id" /><meta content="hexagon5un" name="octolytics-dimension-user_login" /><meta content="54214757" name="octolytics-dimension-repository_id" /><meta content="hexagon5un/stm32f0_libopencm3_template" name="octolytics-dimension-repository_nwo" /><meta content="true" name="octolytics-dimension-repository_public" /><meta content="false" name="octolytics-dimension-repository_is_fork" /><meta content="54214757" name="octolytics-dimension-repository_network_root_id" /><meta content="hexagon5un/stm32f0_libopencm3_template" name="octolytics-dimension-repository_network_root_nwo" />
<link href="https://github.com/hexagon5un/stm32f0_libopencm3_template/commits/master.atom" rel="alternate" title="Recent Commits to stm32f0_libopencm3_template:master" type="application/atom+xml">
<link rel="canonical" href="https://github.com/hexagon5un/stm32f0_libopencm3_template/blob/master/support/stm32f042.ld" data-pjax-transient>
<meta name="browser-stats-url" content="https://api.github.com/_private/browser/stats">
<meta name="browser-errors-url" content="https://api.github.com/_private/browser/errors">
<link rel="mask-icon" href="https://assets-cdn.github.com/pinned-octocat.svg" color="#000000">
<link rel="icon" type="image/x-icon" href="https://assets-cdn.github.com/favicon.ico">
<meta name="theme-color" content="#1e2327">
</head>
<body class="logged-out env-production vis-public page-blob">
<div class="position-relative js-header-wrapper ">
<a href="#start-of-content" tabindex="1" class="accessibility-aid js-skip-to-content">Skip to content</a>
<div id="js-pjax-loader-bar" class="pjax-loader-bar"><div class="progress"></div></div>
<header class="site-header js-details-container Details" role="banner">
<div class="container-responsive">
<a class="header-logo-invertocat" href="https://github.com/" aria-label="Homepage" data-ga-click="(Logged out) Header, go to homepage, icon:logo-wordmark">
<svg aria-hidden="true" class="octicon octicon-mark-github" height="32" version="1.1" viewBox="0 0 16 16" width="32"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
</a>
<button class="btn-link float-right site-header-toggle js-details-target" type="button" aria-label="Toggle navigation">
<svg aria-hidden="true" class="octicon octicon-three-bars" height="24" version="1.1" viewBox="0 0 12 16" width="18"><path fill-rule="evenodd" d="M11.41 9H.59C0 9 0 8.59 0 8c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zm0-4H.59C0 5 0 4.59 0 4c0-.59 0-1 .59-1H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1h.01zM.59 11H11.4c.59 0 .59.41.59 1 0 .59 0 1-.59 1H.59C0 13 0 12.59 0 12c0-.59 0-1 .59-1z"/></svg>
</button>
<div class="site-header-menu">
<nav class="site-header-nav">
<a href="/personal" class="js-selected-navigation-item nav-item" data-ga-click="Header, click, Nav menu - item:personal" data-selected-links="/personal /personal">
Personal
</a> <a href="/open-source" class="js-selected-navigation-item nav-item" data-ga-click="Header, click, Nav menu - item:opensource" data-selected-links="/open-source /open-source/stories /open-source">
Open source
</a> <a href="/business" class="js-selected-navigation-item nav-item" data-ga-click="Header, click, Nav menu - item:business" data-selected-links="/business /business/partners /business/features /business/customers /business/why-github-for-work /business/security /business">
Business
</a> <a href="/explore" class="js-selected-navigation-item nav-item" data-ga-click="Header, click, Nav menu - item:explore" data-selected-links="/explore /trending /trending/developers /integrations /integrations/feature/code /integrations/feature/collaborate /integrations/feature/ship /showcases /explore">
Explore
</a> <a href="/pricing" class="js-selected-navigation-item nav-item" data-ga-click="Header, click, Nav menu - item:pricing" data-selected-links="/pricing /pricing">
Pricing
</a> </nav>
<div class="site-header-actions">
<div class="header-search scoped-search site-scoped-search js-site-search" role="search">
<!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="/hexagon5un/stm32f0_libopencm3_template/search" class="js-site-search-form" data-scoped-search-url="/hexagon5un/stm32f0_libopencm3_template/search" data-unscoped-search-url="/search" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
<label class="form-control header-search-wrapper js-chromeless-input-container">
<div class="header-search-scope">This repository</div>
<input type="text"
class="form-control header-search-input js-site-search-focus js-site-search-field is-clearable"
data-hotkey="s"
name="q"
placeholder="Search"
aria-label="Search this repository"
data-unscoped-placeholder="Search GitHub"
data-scoped-placeholder="Search"
autocapitalize="off">
</label>
</form></div>
<a class="text-bold" href="/login?return_to=%2Fhexagon5un%2Fstm32f0_libopencm3_template%2Fblob%2Fmaster%2Fsupport%2Fstm32f042.ld" data-ga-click="(Logged out) Header, clicked Sign in, text:sign-in">Sign in</a>
<span class="text-gray">or</span>
<a class="text-bold" href="/join?source=header-repo" data-ga-click="(Logged out) Header, clicked Sign up, text:sign-up">Sign up</a>
</div>
</div>
</div>
</header>
</div>
<div id="start-of-content" class="accessibility-aid"></div>
<div id="js-flash-container">
</div>
<div role="main">
<div itemscope itemtype="http://schema.org/SoftwareSourceCode">
<div id="js-repo-pjax-container" data-pjax-container>
<div class="pagehead repohead instapaper_ignore readability-menu experiment-repo-nav">
<div class="container repohead-details-container">
<ul class="pagehead-actions">
<li>
<a href="/login?return_to=%2Fhexagon5un%2Fstm32f0_libopencm3_template"
class="btn btn-sm btn-with-count tooltipped tooltipped-n"
aria-label="You must be signed in to watch a repository" rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-eye" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.06 2C3 2 0 8 0 8s3 6 8.06 6C13 14 16 8 16 8s-3-6-7.94-6zM8 12c-2.2 0-4-1.78-4-4 0-2.2 1.8-4 4-4 2.22 0 4 1.8 4 4 0 2.22-1.78 4-4 4zm2-4c0 1.11-.89 2-2 2-1.11 0-2-.89-2-2 0-1.11.89-2 2-2 1.11 0 2 .89 2 2z"/></svg>
Watch
</a>
<a class="social-count" href="/hexagon5un/stm32f0_libopencm3_template/watchers"
aria-label="2 users are watching this repository">
2
</a>
</li>
<li>
<a href="/login?return_to=%2Fhexagon5un%2Fstm32f0_libopencm3_template"
class="btn btn-sm btn-with-count tooltipped tooltipped-n"
aria-label="You must be signed in to star a repository" rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-star" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14 7 11.67 11.33 14l-.93-4.74z"/></svg>
Star
</a>
<a class="social-count js-social-count" href="/hexagon5un/stm32f0_libopencm3_template/stargazers"
aria-label="1 user starred this repository">
1
</a>
</li>
<li>
<a href="/login?return_to=%2Fhexagon5un%2Fstm32f0_libopencm3_template"
class="btn btn-sm btn-with-count tooltipped tooltipped-n"
aria-label="You must be signed in to fork a repository" rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-repo-forked" height="16" version="1.1" viewBox="0 0 10 16" width="10"><path fill-rule="evenodd" d="M8 1a1.993 1.993 0 0 0-1 3.72V6L5 8 3 6V4.72A1.993 1.993 0 0 0 2 1a1.993 1.993 0 0 0-1 3.72V6.5l3 3v1.78A1.993 1.993 0 0 0 5 15a1.993 1.993 0 0 0 1-3.72V9.5l3-3V4.72A1.993 1.993 0 0 0 8 1zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3 10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zm3-10c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
Fork
</a>
<a href="/hexagon5un/stm32f0_libopencm3_template/network" class="social-count"
aria-label="1 user forked this repository">
1
</a>
</li>
</ul>
<h1 class="public ">
<svg aria-hidden="true" class="octicon octicon-repo" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M4 9H3V8h1v1zm0-3H3v1h1V6zm0-2H3v1h1V4zm0-2H3v1h1V2zm8-1v12c0 .55-.45 1-1 1H6v2l-1.5-1.5L3 16v-2H1c-.55 0-1-.45-1-1V1c0-.55.45-1 1-1h10c.55 0 1 .45 1 1zm-1 10H1v2h2v-1h3v1h5v-2zm0-10H2v9h9V1z"/></svg>
<span class="author" itemprop="author"><a href="/hexagon5un" class="url fn" rel="author">hexagon5un</a></span><!--
--><span class="path-divider">/</span><!--
--><strong itemprop="name"><a href="/hexagon5un/stm32f0_libopencm3_template" data-pjax="#js-repo-pjax-container">stm32f0_libopencm3_template</a></strong>
</h1>
</div>
<div class="container">
<nav class="reponav js-repo-nav js-sidenav-container-pjax"
itemscope
itemtype="http://schema.org/BreadcrumbList"
role="navigation"
data-pjax="#js-repo-pjax-container">
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
<a href="/hexagon5un/stm32f0_libopencm3_template" class="js-selected-navigation-item selected reponav-item" data-hotkey="g c" data-selected-links="repo_source repo_downloads repo_commits repo_releases repo_tags repo_branches /hexagon5un/stm32f0_libopencm3_template" itemprop="url">
<svg aria-hidden="true" class="octicon octicon-code" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M9.5 3L8 4.5 11.5 8 8 11.5 9.5 13 14 8 9.5 3zm-5 0L0 8l4.5 5L6 11.5 2.5 8 6 4.5 4.5 3z"/></svg>
<span itemprop="name">Code</span>
<meta itemprop="position" content="1">
</a> </span>
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
<a href="/hexagon5un/stm32f0_libopencm3_template/issues" class="js-selected-navigation-item reponav-item" data-hotkey="g i" data-selected-links="repo_issues repo_labels repo_milestones /hexagon5un/stm32f0_libopencm3_template/issues" itemprop="url">
<svg aria-hidden="true" class="octicon octicon-issue-opened" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"/></svg>
<span itemprop="name">Issues</span>
<span class="counter">0</span>
<meta itemprop="position" content="2">
</a> </span>
<span itemscope itemtype="http://schema.org/ListItem" itemprop="itemListElement">
<a href="/hexagon5un/stm32f0_libopencm3_template/pulls" class="js-selected-navigation-item reponav-item" data-hotkey="g p" data-selected-links="repo_pulls /hexagon5un/stm32f0_libopencm3_template/pulls" itemprop="url">
<svg aria-hidden="true" class="octicon octicon-git-pull-request" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 11.28V5c-.03-.78-.34-1.47-.94-2.06C9.46 2.35 8.78 2.03 8 2H7V0L4 3l3 3V4h1c.27.02.48.11.69.31.21.2.3.42.31.69v6.28A1.993 1.993 0 0 0 10 15a1.993 1.993 0 0 0 1-3.72zm-1 2.92c-.66 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2zM4 3c0-1.11-.89-2-2-2a1.993 1.993 0 0 0-1 3.72v6.56A1.993 1.993 0 0 0 2 15a1.993 1.993 0 0 0 1-3.72V4.72c.59-.34 1-.98 1-1.72zm-.8 10c0 .66-.55 1.2-1.2 1.2-.65 0-1.2-.55-1.2-1.2 0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2zM2 4.2C1.34 4.2.8 3.65.8 3c0-.65.55-1.2 1.2-1.2.65 0 1.2.55 1.2 1.2 0 .65-.55 1.2-1.2 1.2z"/></svg>
<span itemprop="name">Pull requests</span>
<span class="counter">0</span>
<meta itemprop="position" content="3">
</a> </span>
<a href="/hexagon5un/stm32f0_libopencm3_template/projects" class="js-selected-navigation-item reponav-item" data-selected-links="repo_projects new_repo_project repo_project /hexagon5un/stm32f0_libopencm3_template/projects">
<svg aria-hidden="true" class="octicon octicon-project" height="16" version="1.1" viewBox="0 0 15 16" width="15"><path fill-rule="evenodd" d="M10 12h3V2h-3v10zm-4-2h3V2H6v8zm-4 4h3V2H2v12zm-1 1h13V1H1v14zM14 0H1a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h13a1 1 0 0 0 1-1V1a1 1 0 0 0-1-1z"/></svg>
Projects
<span class="counter">0</span>
</a>
<a href="/hexagon5un/stm32f0_libopencm3_template/pulse" class="js-selected-navigation-item reponav-item" data-selected-links="pulse /hexagon5un/stm32f0_libopencm3_template/pulse">
<svg aria-hidden="true" class="octicon octicon-pulse" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M11.5 8L8.8 5.4 6.6 8.5 5.5 1.6 2.38 8H0v2h3.6l.9-1.8.9 5.4L9 8.5l1.6 1.5H14V8z"/></svg>
Pulse
</a>
<a href="/hexagon5un/stm32f0_libopencm3_template/graphs" class="js-selected-navigation-item reponav-item" data-selected-links="repo_graphs repo_contributors /hexagon5un/stm32f0_libopencm3_template/graphs">
<svg aria-hidden="true" class="octicon octicon-graph" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M16 14v1H0V0h1v14h15zM5 13H3V8h2v5zm4 0H7V3h2v10zm4 0h-2V6h2v7z"/></svg>
Graphs
</a>
</nav>
</div>
</div>
<div class="container new-discussion-timeline experiment-repo-nav">
<div class="repository-content">
<a href="/hexagon5un/stm32f0_libopencm3_template/blob/c74b2a199ef51b73a1e019aefb8ea10453810f0b/support/stm32f042.ld" class="d-none js-permalink-shortcut" data-hotkey="y">Permalink</a>
<!-- blob contrib key: blob_contributors:v21:927ed12541fefdabe9e6ba3c92db5ece -->
<div class="file-navigation js-zeroclipboard-container">
<div class="select-menu branch-select-menu js-menu-container js-select-menu float-left">
<button class="btn btn-sm select-menu-button js-menu-target css-truncate" data-hotkey="w"
type="button" aria-label="Switch branches or tags" tabindex="0" aria-haspopup="true">
<i>Branch:</i>
<span class="js-select-button css-truncate-target">master</span>
</button>
<div class="select-menu-modal-holder js-menu-content js-navigation-container" data-pjax aria-hidden="true">
<div class="select-menu-modal">
<div class="select-menu-header">
<svg aria-label="Close" class="octicon octicon-x js-menu-close" height="16" role="img" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
<span class="select-menu-title">Switch branches/tags</span>
</div>
<div class="select-menu-filters">
<div class="select-menu-text-filter">
<input type="text" aria-label="Filter branches/tags" id="context-commitish-filter-field" class="form-control js-filterable-field js-navigation-enable" placeholder="Filter branches/tags">
</div>
<div class="select-menu-tabs">
<ul>
<li class="select-menu-tab">
<a href="#" data-tab-filter="branches" data-filter-placeholder="Filter branches/tags" class="js-select-menu-tab" role="tab">Branches</a>
</li>
<li class="select-menu-tab">
<a href="#" data-tab-filter="tags" data-filter-placeholder="Find a tag…" class="js-select-menu-tab" role="tab">Tags</a>
</li>
</ul>
</div>
</div>
<div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="branches" role="menu">
<div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
<a class="select-menu-item js-navigation-item js-navigation-open selected"
href="/hexagon5un/stm32f0_libopencm3_template/blob/master/support/stm32f042.ld"
data-name="master"
data-skip-pjax="true"
rel="nofollow">
<svg aria-hidden="true" class="octicon octicon-check select-menu-item-icon" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M12 5l-8 8-4-4 1.5-1.5L4 10l6.5-6.5z"/></svg>
<span class="select-menu-item-text css-truncate-target js-select-menu-filter-text">
master
</span>
</a>
</div>
<div class="select-menu-no-results">Nothing to show</div>
</div>
<div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket" data-tab-filter="tags">
<div data-filterable-for="context-commitish-filter-field" data-filterable-type="substring">
</div>
<div class="select-menu-no-results">Nothing to show</div>
</div>
</div>
</div>
</div>
<div class="BtnGroup float-right">
<a href="/hexagon5un/stm32f0_libopencm3_template/find/master"
class="js-pjax-capture-input btn btn-sm BtnGroup-item"
data-pjax
data-hotkey="t">
Find file
</a>
<button aria-label="Copy file path to clipboard" class="js-zeroclipboard btn btn-sm BtnGroup-item tooltipped tooltipped-s" data-copied-hint="Copied!" type="button">Copy path</button>
</div>
<div class="breadcrumb js-zeroclipboard-target">
<span class="repo-root js-repo-root"><span class="js-path-segment"><a href="/hexagon5un/stm32f0_libopencm3_template"><span>stm32f0_libopencm3_template</span></a></span></span><span class="separator">/</span><span class="js-path-segment"><a href="/hexagon5un/stm32f0_libopencm3_template/tree/master/support"><span>support</span></a></span><span class="separator">/</span><strong class="final-path">stm32f042.ld</strong>
</div>
</div>
<div class="commit-tease">
<span class="float-right">
<a class="commit-tease-sha" href="/hexagon5un/stm32f0_libopencm3_template/commit/8bb1e121c5c2dcaecd3fe21bb451533ac673a522" data-pjax>
8bb1e12
</a>
<relative-time datetime="2016-03-19T19:15:36Z">Mar 19, 2016</relative-time>
</span>
<div>
<img alt="" class="avatar" data-canonical-src="https://1.gravatar.com/avatar/a8edc34b75970fefe210fd3d4ef93a10?d=https%3A%2F%2Fassets-cdn.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png&amp;r=x&amp;s=140" height="20" src="https://camo.githubusercontent.com/a790acf3dfbefac38fd3f439c026f1575f3df4de/68747470733a2f2f312e67726176617461722e636f6d2f6176617461722f61386564633334623735393730666566653231306664336434656639336131303f643d68747470732533412532462532466173736574732d63646e2e6769746875622e636f6d253246696d6167657325324667726176617461727325324667726176617461722d757365722d3432302e706e6726723d7826733d313430" width="20" />
<span class="user-mention">Elliot Williams</span>
<a href="/hexagon5un/stm32f0_libopencm3_template/commit/8bb1e121c5c2dcaecd3fe21bb451533ac673a522" class="message" data-pjax="true" title="Added a linker file for STM32F042">Added a linker file for STM32F042</a>
</div>
<div class="commit-tease-contributors">
<button type="button" class="btn-link muted-link contributors-toggle" data-facebox="#blob_contributors_box">
<strong>0</strong>
contributors
</button>
</div>
<div id="blob_contributors_box" style="display:none">
<h2 class="facebox-header" data-facebox-id="facebox-header">Users who have contributed to this file</h2>
<ul class="facebox-user-list" data-facebox-id="facebox-description">
</ul>
</div>
</div>
<div class="file">
<div class="file-header">
<div class="file-actions">
<div class="BtnGroup">
<a href="/hexagon5un/stm32f0_libopencm3_template/raw/master/support/stm32f042.ld" class="btn btn-sm BtnGroup-item" id="raw-url">Raw</a>
<a href="/hexagon5un/stm32f0_libopencm3_template/blame/master/support/stm32f042.ld" class="btn btn-sm js-update-url-with-hash BtnGroup-item" data-hotkey="b">Blame</a>
<a href="/hexagon5un/stm32f0_libopencm3_template/commits/master/support/stm32f042.ld" class="btn btn-sm BtnGroup-item" rel="nofollow">History</a>
</div>
<button type="button" class="btn-octicon disabled tooltipped tooltipped-nw"
aria-label="You must be signed in to make or propose changes">
<svg aria-hidden="true" class="octicon octicon-pencil" height="16" version="1.1" viewBox="0 0 14 16" width="14"><path fill-rule="evenodd" d="M0 12v3h3l8-8-3-3-8 8zm3 2H1v-2h1v1h1v1zm10.3-9.3L12 6 9 3l1.3-1.3a.996.996 0 0 1 1.41 0l1.59 1.59c.39.39.39 1.02 0 1.41z"/></svg>
</button>
<button type="button" class="btn-octicon btn-octicon-danger disabled tooltipped tooltipped-nw"
aria-label="You must be signed in to make or propose changes">
<svg aria-hidden="true" class="octicon octicon-trashcan" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M11 2H9c0-.55-.45-1-1-1H5c-.55 0-1 .45-1 1H2c-.55 0-1 .45-1 1v1c0 .55.45 1 1 1v9c0 .55.45 1 1 1h7c.55 0 1-.45 1-1V5c.55 0 1-.45 1-1V3c0-.55-.45-1-1-1zm-1 12H3V5h1v8h1V5h1v8h1V5h1v8h1V5h1v9zm1-10H2V3h9v1z"/></svg>
</button>
</div>
<div class="file-info">
33 lines (28 sloc)
<span class="file-info-divider"></span>
1.1 KB
</div>
</div>
<div itemprop="text" class="blob-wrapper data type-linker-script">
<table class="highlight tab-size js-file-line-container" data-tab-size="8">
<tr>
<td id="L1" class="blob-num js-line-number" data-line-number="1"></td>
<td id="LC1" class="blob-code blob-code-inner js-file-line">/*</td>
</tr>
<tr>
<td id="L2" class="blob-num js-line-number" data-line-number="2"></td>
<td id="LC2" class="blob-code blob-code-inner js-file-line"> * This file is part of the libopencm3 project.</td>
</tr>
<tr>
<td id="L3" class="blob-num js-line-number" data-line-number="3"></td>
<td id="LC3" class="blob-code blob-code-inner js-file-line"> *</td>
</tr>
<tr>
<td id="L4" class="blob-num js-line-number" data-line-number="4"></td>
<td id="LC4" class="blob-code blob-code-inner js-file-line"> * Copyright (C) 2009 Uwe Hermann &lt;uwe@hermann-uwe.de&gt;</td>
</tr>
<tr>
<td id="L5" class="blob-num js-line-number" data-line-number="5"></td>
<td id="LC5" class="blob-code blob-code-inner js-file-line"> * Copyright (C) 2011 Stephen Caudle &lt;scaudle@doceme.com&gt;</td>
</tr>
<tr>
<td id="L6" class="blob-num js-line-number" data-line-number="6"></td>
<td id="LC6" class="blob-code blob-code-inner js-file-line"> *</td>
</tr>
<tr>
<td id="L7" class="blob-num js-line-number" data-line-number="7"></td>
<td id="LC7" class="blob-code blob-code-inner js-file-line"> * This library is free software: you can redistribute it and/or modify</td>
</tr>
<tr>
<td id="L8" class="blob-num js-line-number" data-line-number="8"></td>
<td id="LC8" class="blob-code blob-code-inner js-file-line"> * it under the terms of the GNU Lesser General Public License as published by</td>
</tr>
<tr>
<td id="L9" class="blob-num js-line-number" data-line-number="9"></td>
<td id="LC9" class="blob-code blob-code-inner js-file-line"> * the Free Software Foundation, either version 3 of the License, or</td>
</tr>
<tr>
<td id="L10" class="blob-num js-line-number" data-line-number="10"></td>
<td id="LC10" class="blob-code blob-code-inner js-file-line"> * (at your option) any later version.</td>
</tr>
<tr>
<td id="L11" class="blob-num js-line-number" data-line-number="11"></td>
<td id="LC11" class="blob-code blob-code-inner js-file-line"> *</td>
</tr>
<tr>
<td id="L12" class="blob-num js-line-number" data-line-number="12"></td>
<td id="LC12" class="blob-code blob-code-inner js-file-line"> * This library is distributed in the hope that it will be useful,</td>
</tr>
<tr>
<td id="L13" class="blob-num js-line-number" data-line-number="13"></td>
<td id="LC13" class="blob-code blob-code-inner js-file-line"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</td>
</tr>
<tr>
<td id="L14" class="blob-num js-line-number" data-line-number="14"></td>
<td id="LC14" class="blob-code blob-code-inner js-file-line"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</td>
</tr>
<tr>
<td id="L15" class="blob-num js-line-number" data-line-number="15"></td>
<td id="LC15" class="blob-code blob-code-inner js-file-line"> * GNU Lesser General Public License for more details.</td>
</tr>
<tr>
<td id="L16" class="blob-num js-line-number" data-line-number="16"></td>
<td id="LC16" class="blob-code blob-code-inner js-file-line"> *</td>
</tr>
<tr>
<td id="L17" class="blob-num js-line-number" data-line-number="17"></td>
<td id="LC17" class="blob-code blob-code-inner js-file-line"> * You should have received a copy of the GNU Lesser General Public License</td>
</tr>
<tr>
<td id="L18" class="blob-num js-line-number" data-line-number="18"></td>
<td id="LC18" class="blob-code blob-code-inner js-file-line"> * along with this library. If not, see &lt;http://www.gnu.org/licenses/&gt;.</td>
</tr>
<tr>
<td id="L19" class="blob-num js-line-number" data-line-number="19"></td>
<td id="LC19" class="blob-code blob-code-inner js-file-line"> */</td>
</tr>
<tr>
<td id="L20" class="blob-num js-line-number" data-line-number="20"></td>
<td id="LC20" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="L21" class="blob-num js-line-number" data-line-number="21"></td>
<td id="LC21" class="blob-code blob-code-inner js-file-line">/* Linker script for ST STM32F0DISCOVERY (STM32F051R8T6, 64K flash, 8K RAM). */</td>
</tr>
<tr>
<td id="L22" class="blob-num js-line-number" data-line-number="22"></td>
<td id="LC22" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="L23" class="blob-num js-line-number" data-line-number="23"></td>
<td id="LC23" class="blob-code blob-code-inner js-file-line">/* Define memory regions. */</td>
</tr>
<tr>
<td id="L24" class="blob-num js-line-number" data-line-number="24"></td>
<td id="LC24" class="blob-code blob-code-inner js-file-line">MEMORY</td>
</tr>
<tr>
<td id="L25" class="blob-num js-line-number" data-line-number="25"></td>
<td id="LC25" class="blob-code blob-code-inner js-file-line">{</td>
</tr>
<tr>
<td id="L26" class="blob-num js-line-number" data-line-number="26"></td>
<td id="LC26" class="blob-code blob-code-inner js-file-line"> rom (rx) : ORIGIN = 0x08000000, LENGTH = 0x8000</td>
</tr>
<tr>
<td id="L27" class="blob-num js-line-number" data-line-number="27"></td>
<td id="LC27" class="blob-code blob-code-inner js-file-line"> ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x1800</td>
</tr>
<tr>
<td id="L28" class="blob-num js-line-number" data-line-number="28"></td>
<td id="LC28" class="blob-code blob-code-inner js-file-line">}</td>
</tr>
<tr>
<td id="L29" class="blob-num js-line-number" data-line-number="29"></td>
<td id="LC29" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
<tr>
<td id="L30" class="blob-num js-line-number" data-line-number="30"></td>
<td id="LC30" class="blob-code blob-code-inner js-file-line">/* Include the common ld script. */</td>
</tr>
<tr>
<td id="L31" class="blob-num js-line-number" data-line-number="31"></td>
<td id="LC31" class="blob-code blob-code-inner js-file-line">INCLUDE libopencm3_stm32f0.ld</td>
</tr>
<tr>
<td id="L32" class="blob-num js-line-number" data-line-number="32"></td>
<td id="LC32" class="blob-code blob-code-inner js-file-line">
</td>
</tr>
</table>
</div>
</div>
<button type="button" data-facebox="#jump-to-line" data-facebox-class="linejump" data-hotkey="l" class="d-none">Jump to Line</button>
<div id="jump-to-line" style="display:none">
<!-- '"` --><!-- </textarea></xmp> --></option></form><form accept-charset="UTF-8" action="" class="js-jump-to-line-form" method="get"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="&#x2713;" /></div>
<input class="form-control linejump-input js-jump-to-line-field" type="text" placeholder="Jump to line&hellip;" aria-label="Jump to line" autofocus>
<button type="submit" class="btn">Go</button>
</form></div>
</div>
<div class="modal-backdrop js-touch-events"></div>
</div>
</div>
</div>
</div>
<div class="container site-footer-container">
<div class="site-footer" role="contentinfo">
<ul class="site-footer-links float-right">
<li><a href="https://github.com/contact" data-ga-click="Footer, go to contact, text:contact">Contact GitHub</a></li>
<li><a href="https://developer.github.com" data-ga-click="Footer, go to api, text:api">API</a></li>
<li><a href="https://training.github.com" data-ga-click="Footer, go to training, text:training">Training</a></li>
<li><a href="https://shop.github.com" data-ga-click="Footer, go to shop, text:shop">Shop</a></li>
<li><a href="https://github.com/blog" data-ga-click="Footer, go to blog, text:blog">Blog</a></li>
<li><a href="https://github.com/about" data-ga-click="Footer, go to about, text:about">About</a></li>
</ul>
<a href="https://github.com" aria-label="Homepage" class="site-footer-mark" title="GitHub">
<svg aria-hidden="true" class="octicon octicon-mark-github" height="24" version="1.1" viewBox="0 0 16 16" width="24"><path fill-rule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0 0 16 8c0-4.42-3.58-8-8-8z"/></svg>
</a>
<ul class="site-footer-links">
<li>&copy; 2017 <span title="0.09905s from github-fe126-cp1-prd.iad.github.net">GitHub</span>, Inc.</li>
<li><a href="https://github.com/site/terms" data-ga-click="Footer, go to terms, text:terms">Terms</a></li>
<li><a href="https://github.com/site/privacy" data-ga-click="Footer, go to privacy, text:privacy">Privacy</a></li>
<li><a href="https://github.com/security" data-ga-click="Footer, go to security, text:security">Security</a></li>
<li><a href="https://status.github.com/" data-ga-click="Footer, go to status, text:status">Status</a></li>
<li><a href="https://help.github.com" data-ga-click="Footer, go to help, text:help">Help</a></li>
</ul>
</div>
</div>
<div id="ajax-error-message" class="ajax-error-message flash flash-error">
<svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
<button type="button" class="flash-close js-flash-close js-ajax-error-dismiss" aria-label="Dismiss error">
<svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
</button>
You can't perform that action at this time.
</div>
<script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/compat-8e19569aacd39e737a14c8515582825f3c90d1794c0e5539f9b525b8eb8b5a8e.js"></script>
<script crossorigin="anonymous" src="https://assets-cdn.github.com/assets/frameworks-506169cb2fe76254b921e8c944dd406e5cab2d719e657eace8ada98486231472.js"></script>
<script async="async" crossorigin="anonymous" src="https://assets-cdn.github.com/assets/github-ca0d7593e02f66f0e077e6af00e2777dbc4e8928d61b88078131e9344d065f32.js"></script>
<div class="js-stale-session-flash stale-session-flash flash flash-warn flash-banner d-none">
<svg aria-hidden="true" class="octicon octicon-alert" height="16" version="1.1" viewBox="0 0 16 16" width="16"><path fill-rule="evenodd" d="M8.865 1.52c-.18-.31-.51-.5-.87-.5s-.69.19-.87.5L.275 13.5c-.18.31-.18.69 0 1 .19.31.52.5.87.5h13.7c.36 0 .69-.19.86-.5.17-.31.18-.69.01-1L8.865 1.52zM8.995 13h-2v-2h2v2zm0-3h-2V6h2v4z"/></svg>
<span class="signed-in-tab-flash">You signed in with another tab or window. <a href="">Reload</a> to refresh your session.</span>
<span class="signed-out-tab-flash">You signed out in another tab or window. <a href="">Reload</a> to refresh your session.</span>
</div>
<div class="facebox" id="facebox" style="display:none;">
<div class="facebox-popup">
<div class="facebox-content" role="dialog" aria-labelledby="facebox-header" aria-describedby="facebox-description">
</div>
<button type="button" class="facebox-close js-facebox-close" aria-label="Close modal">
<svg aria-hidden="true" class="octicon octicon-x" height="16" version="1.1" viewBox="0 0 12 16" width="12"><path fill-rule="evenodd" d="M7.48 8l3.75 3.75-1.48 1.48L6 9.48l-3.75 3.75-1.48-1.48L4.52 8 .77 4.25l1.48-1.48L6 6.52l3.75-3.75 1.48 1.48z"/></svg>
</button>
</div>
</div>
</body>
</html>

@ -0,0 +1,69 @@
#define _GNU_SOURCE
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/usart.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stddef.h>
#include <limits.h>
#include <sys/types.h>
#include "usart.h"
static ssize_t usart_read(void *cookie, char *buf, size_t n)
{
uint32_t dev = (uint32_t)cookie;
size_t nbytes = 0;
while (n-- > 0) {
*buf++ = (char)usart_recv_blocking(dev);
nbytes++;
}
return nbytes;
}
static ssize_t usart_write(void *cookie, const char *buf, size_t n)
{
uint32_t dev = (uint32_t)cookie;
size_t nbytes = 0;
while (n-- > 0) {
usart_send_blocking(dev, *buf++);
nbytes++;
};
return nbytes;
}
FILE *init_usart(uint32_t dev)
{
cookie_io_functions_t stub = { usart_read, usart_write, NULL, NULL };
FILE *fp;
/* Set up clocks for USART 1 */
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_USART1);
/* Set up GPIOs for USART 1 */
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO9 | GPIO10);
gpio_set_af(GPIOA, GPIO_AF1, GPIO9 | GPIO10);
gpio_set_af(GPIOA, GPIO_AF1, GPIO10);
usart_set_baudrate(dev, 115200);
usart_set_databits(dev, 8);
usart_set_parity(dev, USART_PARITY_NONE);
usart_set_stopbits(dev, USART_CR2_STOP_1_0BIT);
usart_set_mode(dev, USART_MODE_TX_RX);
usart_set_flow_control(dev, USART_FLOWCONTROL_NONE);
usart_enable(dev);
fp = fopencookie((void *)dev, "rw+", stub);
setvbuf(fp, NULL, _IONBF, 0);
return fp;
}

@ -0,0 +1,8 @@
#pragma once
#include <libopencm3/stm32/usart.h>
#include <stdint.h>
#include <stdio.h>
FILE *init_usart(uint32_t dev);
Loading…
Cancel
Save