STM32F103 port

This commit is contained in:
ksb 2009-07-12 15:52:28 +00:00
parent 030933ee2e
commit baa0dd90c9
12 changed files with 2489 additions and 0 deletions

View file

@ -0,0 +1,184 @@
# Adapted from Makefile.msp430
# Default to STM32F103CB
SUBTARGET = CB
### Code common for all ARM CPUs
CONTIKI_CPU_ARM=$(CONTIKI)/cpu/arm/
CONTIKI_CPU_ARM_COMMON=$(CONTIKI_CPU_ARM)/common
### Define the CPU directory
CONTIKI_CPU=$(CONTIKI_CPU_ARM)/stm32f103
### Define the source files we have in the STM32F103 port
CONTIKI_CPU_DIRS = . ../common/dbg-io ../common/usb loader
STM32F103 = clock.c debug-uart.c # interrupt-utils.c newlib-syscalls.c sys-interrupt.c rtimer-arch.c rtimer-arch-interrupt.c uip-log.c
# SYSAPPS = codeprop-otf.c
# APPDIRS += $(CONTIKI)/cpu/at91sam7s/loader
# ELFLOADER = elfloader-otf.c elfloader-arm.c symtab.c cfs-ram.c
include $(CONTIKI_CPU_ARM_COMMON)/usb/Makefile.usb
include $(CONTIKI_CPU_ARM_COMMON)/SD-card/Makefile.sdcard
TARGETLIBS = random.c dbg-printf.c dbg-puts.c dbg-putchar.c dbg-sprintf.c dbg-snprintf.c strformat.c
CONTIKI_TARGET_SOURCEFILES += $(STM32F103) $(SYSAPPS) $(ELFLOADER) \
$(TARGETLIBS) $(UIPDRIVERS) $(USB)
CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES)
THREADS =
### Compiler definitions
CC = arm-elf-gcc
LD = arm-elf-ld
AS = arm-elf-as
AR = arm-elf-ar
NM = arm-elf-nm
OBJCOPY = arm-elf-objcopy
STRIP = arm-elf-strip
XSLTPROC=xsltproc
PROJECT_OBJECTFILES += ${addprefix $(OBJECTDIR)/,$(CONTIKI_TARGET_MAIN:.c=.o)}
LINKERSCRIPT = $(CONTIKI_CPU)/STM32F103$(SUBTARGET).ld
STARTUP=${addprefix $(OBJECTDIR)/,startup-STM32F10x.o}
# JTAG program upload
OPENOCD = openocd
OPENOCD_DIR = $(CONTIKI_CPU_ARM)/openocd/
OPENOCD_CFG = arm7_wig.cfg
# USB program upload
SAMIAM=Sam_I_Am
SAMIAM_TTY=/dev/ttyACM0
ARCH_FLAGS= -march=armv7-m -mthumb
CFLAGSNO = -I. -I$(CONTIKI)/core -I$(CONTIKI_CPU) -I$(CONTIKI_CPU)/loader \
-I$(CONTIKI_CPU)/dbg-io \
-I$(CONTIKI_CPU)/FWLib/FWLib/library/inc/ \
-I$(CONTIKI)/platform/$(TARGET) \
${addprefix -I,$(APPDIRS)} \
-DWITH_UIP -DWITH_ASCII -DMCK=$(MCK) \
-Wall $(ARCH_FLAGS) -g -D SUBTARGET=$(SUBTARGET)
CFLAGS += $(CFLAGSNO) -O -DRUN_AS_SYSTEM -DROM_RUN
LDFLAGS += -L $(CONTIKI_CPU) -T $(LINKERSCRIPT) -nostartfiles
CDEPFLAGS = $(CFLAGS) -D __MAKING_DEPS__
### Setup directory search path for source files
CUSTOM_RULE_C_TO_OBJECTDIR_O=yes
CUSTOM_RULE_C_TO_O=yes
%.o: %.c
$(CC) $(CFLAGS) $< -c
$(OBJECTDIR)/%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
CUSTOM_RULE_S_TO_OBJECTDIR_O = yes
%.o: %.S
$(CC) $(CFLAGS) $< -c
$(OBJECTDIR)/%.o: %.S
$(CC) $(CFLAGS) $< -c -o $@
CUSTOM_RULE_C_TO_CO=yes
%.co: %.c
$(CC) $(CFLAGS) $< -c -o $@
CUSTOM_RULE_C_TO_CE=yes
%.ce: %.o
$(LD) $(LDFLAGS) --relocatable -T $(CONTIKI_CPU)/merge-rodata.ld $< -o $@
$(STRIP) -K _init -K _fini --strip-unneeded -g -x $@
CUSTOM_RULE_LINK=yes
%-stripped.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
$(STRIP) --strip-unneeded -g -x $@
%-stripped.o: %.o
$(STRIP) --strip-unneeded -g -x -o $@ $<
%.o: ${CONTIKI_TARGET}/loader/%.S
$(AS) -o $(notdir $(<:.S=.o)) $<
%-nosyms.$(TARGET): %.co $(PROJECT_OBJECTFILES) contiki-$(TARGET).a $(STARTUP) # $(OBJECTDIR)/empty-symbols.o
$(CC) $(LDFLAGS) $(CFLAGS) -nostartfiles -o $@ $(filter-out %.a,$^) $(filter %.a,$^) -lc $(filter %.a,$^)
%.ihex: %.$(TARGET)
$(OBJCOPY) $^ -O ihex $@
%.bin: %.$(TARGET)
$(OBJCOPY) -O binary $< $@
.PHONY: symbols.c
ifdef CORE
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) contiki-$(TARGET).a $(STARTUP) $(OBJECTDIR)/symbols.o
$(CC) $(LDFLAGS) $(CFLAGS) -nostartfiles -o $@ $(filter-out %.a,$^) $(filter %.a,$^) -lc $(filter %.a,$^)
symbols.c: $(CORE)
$(NM) $< | awk -f $(CONTIKI_CPU)/builtins.awk -f ../../tools/mknmlist > symbols.c
else
%.$(TARGET): %-nosyms.$(TARGET)
ln -sf $< $@
endif
empty-symbols.c:
@${CONTIKI}/tools/make-empty-symbols
upload_ocd_%: %.bin
# Clear lock bits
$(OPENOCD) -s $(OPENOCD_DIR) -f $(OPENOCD_CFG) -c init -c "reset halt;sleep 250;flash probe 0;stm32x mass_erase 0; sleep 500;flash write_bank 0 $< 0;reset halt;resume;sleep 500;exit"
upload_%: %.ihex
# Clear lock bits
$(SAMIAM) "open $(SAMIAM_TTY) , writew 0xffffff64 5a000004"
$(SAMIAM) "open $(SAMIAM_TTY) , writew 0xffffff64 5a002004"
$(SAMIAM) "open $(SAMIAM_TTY) , flash $< , go"
ocd_reset:
$(OPENOCD) -s $(OPENOCD_DIR) -f $(OPENOCD_CFG) -c init -c "reset halt;resume" -c exit
# Don't use core/loader/elfloader.c, use elfloader-otf.c instead
$(OBJECTDIR)/elfloader.o:
echo -n >$@
clean: clean_cpu
.PHONY: stm32test_clean
clean_cpu:
-rm -rf $(BUILTSRCDIR)
.PRECIOUS: %-nosyms.$(TARGET)

View file

@ -0,0 +1,119 @@
MEMORY
{
CODE (rx) : ORIGIN = 0x8000000, LENGTH = 128K
DATA (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
}
/* Section Definitions */
SECTIONS
{
/* Make sure the vector table is at address 0 */
.vectrom :
{
KEEP(*(.isr_vector))
} >CODE =0
.text :
{
KEEP(*(.init))
*(.text .text.*)
KEEP(*(.fini))
} >CODE =0
. = ALIGN(4);
.rodata :
{
*(.rodata .rodata.*)
*(.gnu.linkonce.r.*)
} >CODE
_etext = . ;
PROVIDE (etext = .);
.data :
{
_data = . ;
*(.data)
_edata = . ;
PROVIDE (edata = .);
} >DATA AT >CODE
. = ALIGN(4);
/* .bss section which is used for uninitialized data */
.bss :
{
__bss_start = . ;
__bss_start__ = . ;
*(.bss)
*(COMMON)
__bss_end = . ;
__bss_end__ = . ;
*(.noinit)
} >DATA
. = ALIGN(4);
_end = .;
PROVIDE (end = .);
Main_Stack_Size = 0x00000200;
Process_Stack_Size = 0x00000200;
Stack_Size = Main_Stack_Size + Process_Stack_Size;
.stack ORIGIN(DATA) + LENGTH(DATA) - Stack_Size :
{
__stack_start__ = . ;
Main_Stack_Start = . ;
. += Main_Stack_Size;
Main_Stack_End = . ;
Process_Stack_Start = . ;
. += Process_Stack_Size;
Process_Stack_End = . ;
. = ALIGN(4);
__stack_end__ = . ;
Top_Stack = .;
} >DATA
__heap_start__ = __bss_end__ ;
__heap_end__ = __stack_start__ ;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/* DWARF debug sections.
Symbols in the DWARF debugging sections are relative to the beginning
of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View file

@ -0,0 +1,184 @@
#include <debug-uart.h>
#include <string.h>
#include <stm32f10x_map.h>
#include <stm32f10x_dma.h>
#include <gpio.h>
#include <nvic.h>
#ifndef DBG_UART
#define DBG_UART USART1
#endif
#ifndef DBG_DMA_NO
#define DBG_DMA_NO 1
#endif
#ifndef DBG_DMA_CHANNEL_NO
#define DBG_DMA_CHANNEL_NO 4
#endif
#define _DBG_DMA_NAME(x) DMA##x
#define DBG_DMA_NAME(x) _DBG_DMA_NAME(x)
#define DBG_DMA DBG_DMA_NAME(DBG_DMA_NO)
#define _DMA_CHANNEL_NAME(x,c) DMA ## x ## _Channel ## c
#define DMA_CHANNEL_NAME(x,c) _DMA_CHANNEL_NAME(x,c)
#define DBG_DMA_CHANNEL DMA_CHANNEL_NAME(DBG_DMA_NO, DBG_DMA_CHANNEL_NO)
#define _DBG_DMA_CHANNEL_IFCR_CGIF(c) DMA_IFCR_CGIF ## c
#define _XDBG_DMA_CHANNEL_IFCR_CGIF(c) _DBG_DMA_CHANNEL_IFCR_CGIF(c)
#define DBG_DMA_CHANNEL_IFCR_CGIF \
_XDBG_DMA_CHANNEL_IFCR_CGIF(DBG_DMA_CHANNEL_NO)
#ifndef DBG_XMIT_BUFFER_LEN
#define DBG_XMIT_BUFFER_LEN 1024
#endif
static unsigned char xmit_buffer[DBG_XMIT_BUFFER_LEN];
#define XMIT_BUFFER_END &xmit_buffer[DBG_XMIT_BUFFER_LEN]
void
dbg_setup_uart_default()
{
RCC->APB2ENR |= (RCC_APB2ENR_AFIOEN
| RCC_APB2ENR_IOPAEN| RCC_APB2ENR_IOPBEN
| RCC_APB2ENR_USART1EN );
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
AFIO_REMAP( AFIO_MAPR_USART1_REMAP, AFIO_MAPR_USART1_REMAP);
GPIO_CONF_OUTPUT_PORT(B,6,ALT_PUSH_PULL,50);
GPIO_CONF_INPUT_PORT(B,7,FLOATING);
USART1->CR1 = USART_CR1_UE;
USART1->CR2 = 0;
USART1->CR3 = USART_CR3_DMAT;
USART1->CR1 |= USART_CR1_TE;
USART1->BRR= 0x1a1;
}
/* Valid data in head to tail-1 */
/* Read position */
static unsigned char * volatile xmit_buffer_head = xmit_buffer;
/* Write position */
static unsigned char * volatile xmit_buffer_tail = xmit_buffer;
/* xmit_buffer_head == xmit_buffer_tail means empty so we can only store
DBG_XMIT_BUFFER_LEN-1 characters */
volatile unsigned char dma_running = 0;
static unsigned char * volatile dma_end;
void
DMA1_Channel4_handler() __attribute__((interrupt));
static void
update_dma(void)
{
if (xmit_buffer_tail == xmit_buffer_head) return;
DBG_DMA_CHANNEL->CCR = (DMA_Priority_Low |
DMA_PeripheralDataSize_Byte |
DMA_MemoryDataSize_Byte |
DMA_PeripheralInc_Disable |
DMA_MemoryInc_Enable |
DMA_Mode_Normal |
DMA_DIR_PeripheralDST |
DMA_CCR4_TCIE
);
DBG_DMA_CHANNEL->CPAR = (u32)&DBG_UART->DR;
DBG_DMA_CHANNEL->CMAR = (u32)xmit_buffer_head;
if (xmit_buffer_head < xmit_buffer_tail) {
DBG_DMA_CHANNEL->CNDTR = xmit_buffer_tail - xmit_buffer_head;
dma_end = xmit_buffer_tail;
} else {
DBG_DMA_CHANNEL->CNDTR = XMIT_BUFFER_END - xmit_buffer_head;
dma_end = xmit_buffer;
}
NVIC_ENABLE_INT(DMA1_Channel4_IRQChannel);
NVIC_SET_PRIORITY(DMA1_Channel4_IRQChannel, 2);
DBG_DMA_CHANNEL->CCR |=DMA_CCR4_EN;
}
void
DMA1_Channel4_handler()
{
DBG_DMA->IFCR = DBG_DMA_CHANNEL_IFCR_CGIF;
xmit_buffer_head = dma_end;
if (xmit_buffer_tail == xmit_buffer_head) {
dma_running = 0;
return;
}
update_dma();
}
unsigned int
dbg_send_bytes(const unsigned char *seq, unsigned int len)
{
/* Since each of the pointers should be read atomically
there's no need to disable interrupts */
unsigned char *head = xmit_buffer_head;
unsigned char *tail = xmit_buffer_tail;
if (tail >= head) {
/* Free space wraps */
unsigned int xfer_len = XMIT_BUFFER_END - tail;
unsigned int free = DBG_XMIT_BUFFER_LEN - (tail - head) - 1;
if (len > free) len = free;
if (xfer_len < len) {
memcpy(tail, seq, xfer_len);
seq += xfer_len;
xfer_len = len - xfer_len;
memcpy(xmit_buffer, seq, xfer_len);
tail = xmit_buffer + xfer_len;
} else {
memcpy(tail, seq, len);
tail += len;
if (tail == XMIT_BUFFER_END) tail = xmit_buffer;
}
} else {
/* Free space continuous */
unsigned int free = (head - tail) - 1;
if (len > free) len = free;
memcpy(tail, seq, len);
tail += len;
}
xmit_buffer_tail = tail;
if (!dma_running) {
dma_running = 1;
update_dma();
}
return len;
}
static unsigned char dbg_write_overrun = 0;
void
dbg_putchar(const char ch)
{
if (dbg_write_overrun) {
if (dbg_send_bytes((const unsigned char*)"^",1) != 1) return;
}
dbg_write_overrun = 0;
if (dbg_send_bytes((const unsigned char*)&ch,1) != 1) {
dbg_write_overrun = 1;
}
}
void
dbg_blocking_putchar(const char ch)
{
if (dbg_write_overrun) {
while (dbg_send_bytes((const unsigned char*)"^",1) != 1);
}
dbg_write_overrun = 0;
while (dbg_send_bytes((const unsigned char*)&ch,1) != 1);
}
void
dbg_drain()
{
while(xmit_buffer_tail != xmit_buffer_head);
}

View file

@ -0,0 +1,27 @@
#ifndef __DEBUG_UART_H__1V2039076V__
#define __DEBUG_UART_H__1V2039076V__
#ifndef dbg_setup_uart
#define dbg_setup_uart dbg_setup_uart_default
#endif
void
dbg_setup_uart();
void
dbg_set_input_handler(void (*handler)(const char *inp, unsigned int len));
unsigned int
dbg_send_bytes(const unsigned char *seq, unsigned int len);
void
dbg_putchar(const char ch);
void
dbg_blocking_putchar(const char ch);
void
dbg_drain();
#endif /* __DEBUG_UART_H__1V2039076V__ */

69
cpu/arm/stm32f103/gpio.h Normal file
View file

@ -0,0 +1,69 @@
#ifndef __GPIO_H__LK7NAD1HN8__
#define __GPIO_H__LK7NAD1HN8__
#include <stm32f10x_map.h>
#define _GPIO_INPUT_ANALOG(h,l) 0
#define _GPIO_INPUT_FLOATING(h,l) (l)
#define _GPIO_INPUT_PU_PD(h,l) (h)
#define _GPIO_OUTPUT_PUSH_PULL(h,l) 0
#define _GPIO_OUTPUT_OPEN_DRAIN(h,l) (l)
#define _GPIO_OUTPUT_ALT_PUSH_PULL(h,l) (h)
#define _GPIO_OUTPUT_ALT_OPEN_DRAIN(h,l) ((h)|(l))
#define _GPIO_OUTPUT_SPEED_10(h,l) (l)
#define _GPIO_OUTPUT_SPEED_2(h,l) (h)
#define _GPIO_OUTPUT_SPEED_50(h,l) ((h)|(l))
#define _GPIO_INPUT_CNF(bit,mode) \
_GPIO_INPUT_##mode(_GPIO_CONF_BIT_REG_##bit(GPIO_,_CNF##bit##_1),\
_GPIO_CONF_BIT_REG_##bit(GPIO_,_CNF##bit##_0))
#define _GPIO_OUTPUT_CNF(bit,mode) \
_GPIO_OUTPUT_##mode(_GPIO_CONF_BIT_REG_##bit(GPIO_,_CNF##bit##_1),\
_GPIO_CONF_BIT_REG_##bit(GPIO_,_CNF##bit##_0))
#define _GPIO_OUTPUT_SPEED(bit,speed) \
_GPIO_OUTPUT_SPEED_##speed(_GPIO_CONF_BIT_REG_##bit(GPIO_,_MODE##bit##_1),\
_GPIO_CONF_BIT_REG_##bit(GPIO_,_MODE##bit##_0))
#define _GPIO_CONF_BIT_REG_0(a,c) a##CRL##c
#define _GPIO_CONF_BIT_REG_1(a,c) a##CRL##c
#define _GPIO_CONF_BIT_REG_2(a,c) a##CRL##c
#define _GPIO_CONF_BIT_REG_3(a,c) a##CRL##c
#define _GPIO_CONF_BIT_REG_4(a,c) a##CRL##c
#define _GPIO_CONF_BIT_REG_5(a,c) a##CRL##c
#define _GPIO_CONF_BIT_REG_6(a,c) a##CRL##c
#define _GPIO_CONF_BIT_REG_7(a,c) a##CRL##c
#define _GPIO_CONF_BIT_REG_8(a,c) a##CRH##c
#define _GPIO_CONF_BIT_REG_9(a,c) a##CRH##c
#define _GPIO_CONF_BIT_REG_10(a,c) a##CRH##c
#define _GPIO_CONF_BIT_REG_11(a,c) a##CRH##c
#define _GPIO_CONF_BIT_REG_12(a,c) a##CRH##c
#define _GPIO_CONF_BIT_REG_13(a,c) a##CRH##c
#define _GPIO_CONF_BIT_REG_14(a,c) a##CRH##c
#define _GPIO_CONF_BIT_REG_15(a,c) a##CRH##c
#define _GPIO_CONF_BIT_REG(b) _GPIO_CONF_BIT_REG_##b(,)
#define _GPIO_CONF_MASK(bit) (_GPIO_CONF_BIT_REG_##bit(GPIO_,_CNF##bit) \
|_GPIO_CONF_BIT_REG_##bit(GPIO_,_MODE##bit))
#define GPIO_CONF_INPUT_PORT(port,bit,mode) MODIFY_REG(GPIO##port -> _GPIO_CONF_BIT_REG(bit),_GPIO_CONF_MASK(bit), _GPIO_INPUT_CNF(bit,mode))
#define GPIO_CONF_OUTPUT_PORT(port,bit,mode,speed) MODIFY_REG(GPIO##port -> _GPIO_CONF_BIT_REG(bit),_GPIO_CONF_MASK(bit), _GPIO_OUTPUT_CNF(bit,mode) | _GPIO_OUTPUT_SPEED(bit,speed))
#ifndef AFIO_MAPR_SWJ_CFG_VALUE
#define AFIO_MAPR_SWJ_CFG_VALUE AFIO_MAPR_SWJ_CFG_RESET
#endif
#define AFIO_REMAP(mask,value) \
MODIFY_REG(AFIO->MAPR, AFIO_MAPR_SWJ_CFG | mask, AFIO_MAPR_SWJ_CFG_VALUE | value);
#endif /* __GPIO_H__LK7NAD1HN8__ */

16
cpu/arm/stm32f103/nvic.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef __NVIC_H__LE94F5JS4D__
#define __NVIC_H__LE94F5JS4D__
#include <stm32f10x_map.h>
#include <stm32f10x_nvic.h>
#define NVIC_ENABLE_INT(i) WRITE_REG(NVIC->ISER[(i)/32], 1<<((i) & 0x1f))
#define NVIC_DISABLE_INT(i) WRITE_REG(NVIC->ICER[(i)/32], 1<<((i) & 0x1f))
#define NVIC_SET_PENDING(i) WRITE_REG(NVIC->ISPR[(i)/32], 1<<((i) & 0x1f))
#define NVIC_CLEAR_PENDING(i) WRITE_REG(NVIC->ICPR[(i)/32], 1<<((i) & 0x1f))
#define NVIC_SET_PRIORITY(i,p) \
MODIFY_REG(NVIC->IPR[(i)/4], 0xf<<(((i)&3)*8), (p)<<(((i)&3)*8))
#define NVIC_SET_SYSTICK_PRI(p) MODIFY_REG(SCB->SHPR[2], 0xf<<24, (p)<<24)
#endif /* __NVIC_H__LE94F5JS4D__ */

View file

@ -0,0 +1,19 @@
/**
* \file
* Header file for the STM32F103-specific rtimer code
* \author
* Simon Berg <ksb@users.sourceforge.net>
*/
#ifndef __RTIMER_ARCH_H__
#define __RTIMER_ARCH_H__
#include "sys/rtimer.h"
#define RTIMER_ARCH_SECOND (MCK/1024)
void rtimer_arch_set(rtimer_clock_t t);
rtimer_clock_t rtimer_arch_now(void);
#endif /* __RTIMER_ARCH_H__ */

View file

@ -0,0 +1,359 @@
#include <stm32f10x_map.h>
#include <sdcard.h>
#include <sys/process.h>
#include <sys/etimer.h>
#include <cfs/cfs.h>
#include <efs.h>
#include <ls.h>
#include <interfaces/sd.h>
#include <gpio.h>
#include <stdio.h>
process_event_t sdcard_inserted_event;
process_event_t sdcard_removed_event;
static struct process *event_process = NULL;
#if 0
#undef TXT
#define TXT(x) x
#undef DBG
#define DBG(x) printf x
#endif
static void
init_spi()
{
SPI1->CR1 &= ~SPI_CR1_SPE;
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;
GPIO_CONF_INPUT_PORT(A,0,FLOATING);
GPIO_CONF_INPUT_PORT(A,1,FLOATING);
GPIO_CONF_OUTPUT_PORT(A,4,PUSH_PULL,50);
GPIOA->BSRR = GPIO_BSRR_BS4;
GPIO_CONF_OUTPUT_PORT(A,5,ALT_PUSH_PULL,50);
GPIO_CONF_INPUT_PORT(A,6,FLOATING);
GPIO_CONF_OUTPUT_PORT(A,7,ALT_PUSH_PULL,50);
RCC->APB2ENR |= RCC_APB2ENR_SPI1EN;
SPI1->CR2 = SPI_CR2_SSOE;
SPI1->CR1 = (SPI_CR1_SPE
| (SPI_CR1_BR_2) /* fPCLK / 32 */
| SPI_CR1_MSTR
| SPI_CR1_CPOL | SPI_CR1_CPHA
| SPI_CR1_SSM | SPI_CR1_SSI);
}
void
if_spiInit(hwInterface *iface)
{
unsigned int i;
GPIOA->BSRR = GPIO_BSRR_BS4;
for(i=0;i<20;i++) {
if_spiSend(iface, 0xff);
}
GPIOA->BSRR = GPIO_BSRR_BR4;
}
/* Borrowed from at91_spi.c (c)2006 Martin Thomas */
esint8
if_initInterface(hwInterface* file, eint8* opts)
{
euint32 sc;
if_spiInit(file);
if(sd_Init(file)<0) {
DBG((TXT("Card failed to init, breaking up...\n")));
return(-1);
}
if(sd_State(file)<0){
DBG((TXT("Card didn't return the ready state, breaking up...\n")
));
return(-2);
}
sd_getDriveSize(file, &sc);
file->sectorCount = sc/512;
DBG((TXT("Card Capacity is %lu Bytes (%lu Sectors)\n"), sc, file->sectorCount));
return(0);
}
/* Borrowed from lpc2000_spi.c (c)2005 Martin Thomas */
esint8
if_readBuf(hwInterface* file,euint32 address,euint8* buf)
{
return(sd_readSector(file,address,buf,512));
}
esint8
if_writeBuf(hwInterface* file,euint32 address,euint8* buf)
{
return(sd_writeSector(file,address, buf));
}
esint8
if_setPos(hwInterface* file,euint32 address)
{
return(0);
}
euint8
if_spiSend(hwInterface *iface, euint8 outgoing)
{
euint8 ingoing;
SPI1->DR = outgoing;
while(!(SPI1->SR & SPI_SR_RXNE));
ingoing = SPI1->DR;
/* printf(">%02x <%02x\n", outgoing, ingoing); */
return ingoing;
}
#define MAX_FDS 4
static EmbeddedFileSystem sdcard_efs;
static File file_descriptors[MAX_FDS];
static int
find_free_fd()
{
int fd;
for (fd = 0; fd < MAX_FDS; fd++) {
if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) {
return fd;
}
}
return -1;
}
static File *
get_file(int fd)
{
if (sdcard_efs.myCard.sectorCount == 0) return NULL;
if (fd >= MAX_FDS || fd < 0) return NULL;
if (!file_getAttr(&file_descriptors[fd], FILE_STATUS_OPEN)) return NULL;
return &file_descriptors[fd];
}
int
cfs_open (const char *name, int flags)
{
eint8 mode;
int fd;
if (sdcard_efs.myCard.sectorCount == 0) return -1;
fd = find_free_fd();
if (fd < 0) return -1;
if (flags == CFS_READ) {
mode = MODE_READ;
} else {
mode = MODE_APPEND;
}
if (file_fopen(&file_descriptors[fd], &sdcard_efs.myFs,
(char*)name, mode) < 0) {
return -1;
}
return fd;
}
void
cfs_close(int fd)
{
File *file = get_file(fd);
if (!file) return;
file_fclose(file);
fs_flushFs(&sdcard_efs.myFs);
}
int
cfs_read (int fd, void *buf, unsigned int len)
{
File *file = get_file(fd);
if (!file) return 0;
return file_read(file, len, (euint8*)buf);
}
int
cfs_write (int fd, const void *buf, unsigned int len)
{
File *file = get_file(fd);
if (!file) return 0;
return file_write(file, len, (euint8*)buf);
}
cfs_offset_t
cfs_seek (int fd, cfs_offset_t offset, int whence)
{
File *file = get_file(fd);
if (!file) return 0;
/* TODO take whence int account */
if (file_setpos(file, offset) != 0) return -1;
return file->FilePtr;
}
int
cfs_remove(const char *name)
{
return (rmfile(&sdcard_efs.myFs,(euint8*)name) == 0) ? 0 : -1;
}
/* Cause a compile time error if expr is false */
#ifdef __GNUC__
#define COMPILE_TIME_CHECK(expr) \
(void) (__builtin_choose_expr ((expr), 0, ((void)0))+3)
#else
#define COMPILE_TIME_CHECK(expr)
#endif
#define MAX_DIR_LISTS 4
DirList dir_lists[MAX_DIR_LISTS];
static DirList *
find_free_dir_list()
{
unsigned int l;
for(l = 0; l < MAX_DIR_LISTS; l++) {
if (dir_lists[l].fs == NULL) {
return &dir_lists[l];
}
}
return NULL;
}
int
cfs_opendir (struct cfs_dir *dirp, const char *name)
{
DirList *dirs;
COMPILE_TIME_CHECK(sizeof(DirList*) <= sizeof(struct cfs_dir));
if (sdcard_efs.myCard.sectorCount == 0) return -1;
dirs = find_free_dir_list();
if (!dirs) return -1;
if (ls_openDir(dirs, &sdcard_efs.myFs, (eint8*)name) != 0) {
dirs->fs = NULL;
return -1;
}
*(DirList**)dirp = dirs;
return 0;
}
int
cfs_readdir (struct cfs_dir *dirp, struct cfs_dirent *dirent)
{
euint8 *start;
euint8 *end;
char *to = dirent->name;
DirList *dirs = *(DirList**)dirp;
if (sdcard_efs.myCard.sectorCount == 0) return 1;
if (ls_getNext(dirs) != 0) return 1;
start = dirs->currentEntry.FileName;
end = start + 7;
while(end > start) {
if (*end > ' ') {
end++;
break;
}
end--;
}
while(start < end) {
*to++ = *start++;
}
start = dirs->currentEntry.FileName + 8;
end = start + 3;
if (*start > ' ') {
*to++ = '.';
*to++ = *start++;
while(start < end && *start > ' ') {
*to++ = *start++;
}
}
*to = '\0';
if (dirs->currentEntry.Attribute & ATTR_DIRECTORY) {
dirent->size = 0;
} else {
dirent->size = dirs->currentEntry.FileSize;
}
return 0;
}
void
cfs_closedir (struct cfs_dir *dirp)
{
(*(DirList**)dirp)->fs = NULL;
}
PROCESS(sdcard_process, "SD card process");
PROCESS_THREAD(sdcard_process, ev , data)
{
int fd;
static struct etimer timer;
PROCESS_BEGIN();
/* Mark all file descriptors as free */
for (fd = 0; fd < MAX_FDS; fd++) {
file_setAttr(&file_descriptors[fd], FILE_STATUS_OPEN,0);
}
/* Card not inserted */
sdcard_efs.myCard.sectorCount = 0;
init_spi();
etimer_set(&timer, CLOCK_SECOND);
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_EXIT ||
ev== PROCESS_EVENT_TIMER || ev == PROCESS_EVENT_POLL);
if (ev == PROCESS_EVENT_EXIT) break;
if (ev == PROCESS_EVENT_TIMER) {
if (!(GPIOA->IDR & (1<<0))) {
if (sdcard_efs.myCard.sectorCount == 0) {
etimer_set(&timer,CLOCK_SECOND/2);
PROCESS_WAIT_EVENT_UNTIL(ev== PROCESS_EVENT_TIMER);
if (efs_init(&sdcard_efs,0) == 0) {
if (event_process) {
process_post(event_process, sdcard_inserted_event, NULL);
}
printf("SD card inserted\n");
} else {
printf("SD card insertion failed\n");
}
}
} else {
if (sdcard_efs.myCard.sectorCount != 0) {
/* Card removed */
fs_umount(&sdcard_efs.myFs);
sdcard_efs.myCard.sectorCount = 0;
if (event_process) {
process_post(event_process, sdcard_removed_event, NULL);
}
printf("SD card removed\n");
}
}
etimer_set(&timer, CLOCK_SECOND);
}
}
PROCESS_END();
}
void
sdcard_init()
{
sdcard_inserted_event = process_alloc_event();
sdcard_removed_event = process_alloc_event();
process_start(&sdcard_process, NULL);
}
int
sdcard_ready()
{
return sdcard_efs.myCard.sectorCount > 0;
}
void
sdcard_event_process(struct process *p)
{
event_process = p;
}

View file

@ -0,0 +1,284 @@
#include <stdint.h>
#include <stm32f10x_map.h>
extern int main(void);
typedef void (*ISR_func)(void);
#define SECTION(x) __attribute__ ((section(#x)))
#define ISR_VECTOR_SECTION SECTION(.isr_vector)
static void sys_reset(void) __attribute__((naked));
void NMI_handler(void) __attribute__((interrupt));
void HardFault_handler(void) __attribute__((interrupt));
void MemManage_handler(void) __attribute__((interrupt));
void BusFault_handler(void) __attribute__((interrupt));
void UsageFault_handler(void) __attribute__((interrupt));
static void unhandled_int(void) __attribute__((interrupt));
#define UNHANDLED_ALIAS __attribute__((weak, alias("unhandled_int")));
void Main_Stack_End(void);
void HardFault_handler(void)__attribute__((weak, alias("dHardFault_handler")));
void MemManage_handler(void)__attribute__((weak, alias("dMemManage_handler")));
void BusFault_handler(void) __attribute__((weak, alias("dBusFault_handler")));
void UsageFault_handler(void)__attribute__((weak, alias("dUsageFault_handler")));
void Reserved_handler(void) UNHANDLED_ALIAS;
void SVCall_handler(void) UNHANDLED_ALIAS;
void DebugMonitor_handler(void) UNHANDLED_ALIAS;
void PendSV_handler(void) UNHANDLED_ALIAS;
void SysTick_handler(void) UNHANDLED_ALIAS;
void WWDG_handler(void) UNHANDLED_ALIAS;
void PVD_handler(void) UNHANDLED_ALIAS;
void TAMPER_handler(void) UNHANDLED_ALIAS;
void RTC_handler(void) UNHANDLED_ALIAS;
void FLASH_handler(void) UNHANDLED_ALIAS;
void RCC_handler(void) UNHANDLED_ALIAS;
void EXTI0_handler(void) UNHANDLED_ALIAS;
void EXTI1_handler(void) UNHANDLED_ALIAS;
void EXTI2_handler(void) UNHANDLED_ALIAS;
void EXTI3_handler(void) UNHANDLED_ALIAS;
void EXTI4_handler(void) UNHANDLED_ALIAS;
void DMA1_Channel1_handler(void) UNHANDLED_ALIAS;
void DMA1_Channel2_handler(void) UNHANDLED_ALIAS;
void DMA1_Channel3_handler(void) UNHANDLED_ALIAS;
void DMA1_Channel4_handler(void) UNHANDLED_ALIAS;
void DMA1_Channel5_handler(void) UNHANDLED_ALIAS;
void DMA1_Channel6_handler(void) UNHANDLED_ALIAS;
void DMA1_Channel7_handler(void) UNHANDLED_ALIAS;
void ADC1_2_handler(void) UNHANDLED_ALIAS;
void USB_HP_CAN_TX_handler(void) UNHANDLED_ALIAS;
void USB_LP_CAN_RX0_handler(void) UNHANDLED_ALIAS;
void CAN_RX1_handler(void) UNHANDLED_ALIAS;
void CAN_SCE_handler(void) UNHANDLED_ALIAS;
void EXTI9_5_handler(void) UNHANDLED_ALIAS;
void TIM1_BRK_handler(void) UNHANDLED_ALIAS;
void TIM1_UP_handler(void) UNHANDLED_ALIAS;
void TIM1_TRG_COM_handler(void) UNHANDLED_ALIAS;
void TIM1_CC_handler(void) UNHANDLED_ALIAS;
void TIM2_handler(void) UNHANDLED_ALIAS;
void TIM3_handler(void) UNHANDLED_ALIAS;
void TIM4_handler(void) UNHANDLED_ALIAS;
void I2C1_EV_handler(void) UNHANDLED_ALIAS;
void I2C1_ER_handler(void) UNHANDLED_ALIAS;
void I2C2_EV_handler(void) UNHANDLED_ALIAS;
void I2C2_ER_handler(void) UNHANDLED_ALIAS;
void SPI1_handler(void) UNHANDLED_ALIAS;
void SPI2_handler(void) UNHANDLED_ALIAS;
void USART1_handler(void) UNHANDLED_ALIAS;
void USART2_handler(void) UNHANDLED_ALIAS;
void USART3_handler(void) UNHANDLED_ALIAS;
void EXTI15_10_handler(void) UNHANDLED_ALIAS;
void RTCAlarm_handler(void) UNHANDLED_ALIAS;
void USBWakeup_handler(void) UNHANDLED_ALIAS;
void TIM8_BRK_handler(void) UNHANDLED_ALIAS;
void TIM8_UP_handler(void) UNHANDLED_ALIAS;
void TIM8_TRG_COM_handler(void) UNHANDLED_ALIAS;
void TIM8_CC_handler(void) UNHANDLED_ALIAS;
void ADC3_handler(void) UNHANDLED_ALIAS;
void FSMC_handler(void) UNHANDLED_ALIAS;
void SDIO_handler(void) UNHANDLED_ALIAS;
void TIM5_handler(void) UNHANDLED_ALIAS;
void SPI3_handler(void) UNHANDLED_ALIAS;
void UART4_handler(void) UNHANDLED_ALIAS;
void UART5_handler(void) UNHANDLED_ALIAS;
void TIM6_handler(void) UNHANDLED_ALIAS;
void TIM7_handler(void) UNHANDLED_ALIAS;
void DMA2_Channel1_handler(void) UNHANDLED_ALIAS;
void DMA2_Channel2_handler(void) UNHANDLED_ALIAS;
void DMA2_Channel3_handler(void) UNHANDLED_ALIAS;
void DMA2_Channel4_5_handler(void) UNHANDLED_ALIAS;
const ISR_func isr_vector[76] ISR_VECTOR_SECTION =
{
Main_Stack_End,
sys_reset,
NMI_handler,
HardFault_handler,
MemManage_handler,
BusFault_handler,
UsageFault_handler,
Reserved_handler,
Reserved_handler,
Reserved_handler,
Reserved_handler,
SVCall_handler,
DebugMonitor_handler,
Reserved_handler,
PendSV_handler,
SysTick_handler,
WWDG_handler,
PVD_handler,
TAMPER_handler,
RTC_handler,
FLASH_handler,
RCC_handler,
EXTI0_handler,
EXTI1_handler,
EXTI2_handler,
EXTI3_handler,
EXTI4_handler,
DMA1_Channel1_handler,
DMA1_Channel2_handler,
DMA1_Channel3_handler,
DMA1_Channel4_handler,
DMA1_Channel5_handler,
DMA1_Channel6_handler,
DMA1_Channel7_handler,
ADC1_2_handler,
USB_HP_CAN_TX_handler,
USB_LP_CAN_RX0_handler,
CAN_RX1_handler,
CAN_SCE_handler,
EXTI9_5_handler,
TIM1_BRK_handler,
TIM1_UP_handler,
TIM1_TRG_COM_handler,
TIM1_CC_handler,
TIM2_handler,
TIM3_handler,
TIM4_handler,
I2C1_EV_handler,
I2C1_ER_handler,
I2C2_EV_handler,
I2C2_ER_handler,
SPI1_handler,
SPI2_handler,
USART1_handler,
USART2_handler,
USART3_handler,
EXTI15_10_handler,
RTCAlarm_handler,
USBWakeup_handler,
TIM8_BRK_handler,
TIM8_UP_handler,
TIM8_TRG_COM_handler,
TIM8_CC_handler,
ADC3_handler,
FSMC_handler,
SDIO_handler,
TIM5_handler,
SPI3_handler,
UART4_handler,
UART5_handler,
TIM6_handler,
TIM7_handler,
DMA2_Channel1_handler,
DMA2_Channel2_handler,
DMA2_Channel3_handler,
DMA2_Channel4_5_handler
};
extern uint8_t _data[];
extern uint8_t _etext[];
extern uint8_t _edata[];
static void
copy_initialized(void)
{
uint8_t *ram = _data;
uint8_t *rom = _etext;
while(ram < _edata) {
*ram++ = *rom++;
}
}
extern uint8_t __bss_start[];
extern uint8_t __bss_end[];
static void
clear_bss(void)
{
uint8_t *m = __bss_start;
while(m < __bss_end) {
*m++ = 0;
}
}
static void
start_hse_clock(void)
{
/* Start external oscillator */
RCC->CR |= RCC_CR_HSEON;
/* Wait for oscillator to stabilize */
while(!(RCC->CR & RCC_CR_HSERDY));
}
static void
use_pll()
{
RCC->CFGR = (RCC_CFGR_MCO_NOCLOCK
| RCC_CFGR_PLLMULL6 /* PLL at 48MHz */
| RCC_CFGR_PLLSRC /* PLL runs on HSE */
| RCC_CFGR_PPRE2_DIV1 /* APB2 at 48MHz */
| RCC_CFGR_PPRE1_DIV2 /* APB1 at 24MHz */
| RCC_CFGR_HPRE_DIV1 /* AHB at 48 MHz */
| RCC_CFGR_USBPRE /* USB clock at same speed as PLL */
);
RCC->CR |= RCC_CR_PLLON;
/* Wait for PLL */
while(!(RCC->CR & RCC_CR_PLLRDY));
/* Switch to PLL as system clock */
MODIFY_REG(RCC->CFGR, RCC_CFGR_SW,RCC_CFGR_SW_PLL);
}
static void
enable_fault_exceptions(void)
{
SCB->SHCSR |= (SCB_SHCSR_MEMFAULTENA | SCB_SHCSR_BUSFAULTENA
| SCB_SHCSR_USGFAULTENA);
}
static void
sys_reset(void)
{
copy_initialized();
clear_bss();
enable_fault_exceptions();
start_hse_clock();
use_pll();
main();
while(1);
}
void
NMI_handler(void)
{
while(1);
}
static void
unhandled_int(void)
{
while(1);
}
static void
dHardFault_handler(void)
{
while(1);
}
static void
dUsageFault_handler(void)
{
while(1);
}
static void
dMemManage_handler(void)
{
while(1);
}
static void
dBusFault_handler(void)
{
while(1);
}

View file

@ -0,0 +1,27 @@
#define _RCC
#define _DMA
#define _GPIOA
#define _GPIOB
#define _GPIOC
#define _BKP
#define _AFIO
#define _USART1
#define _NVIC
#define _SysTick
#define _USB
#define _TIM2
#define _TIM3
#define _DMA1_Channel1
#define _DMA1_Channel2
#define _DMA1_Channel3
#define _DMA1_Channel4
#define _DMA1_Channel5
#define _DMA1_Channel6
#define _DMA2_Channel1
#define _DMA2_Channel2
#define _DMA2_Channel3
#define _DMA2_Channel4
#define _DMA2_Channel5
#define _SPI1
#define _SPI2
#define _EXTI

1184
cpu/arm/stm32f103/usb-arch.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,17 @@
#include <usb-api.h>
#ifdef USB_STM32F103_ENABLE_ALT_COPY
/* Use an alternate data copying function */
#define USB_BUFFER_ARCH_ALT_COPY USB_BUFFER_ARCH_FLAG_1
/* Copy len bytes of data from the buffer to dedicated USB
memory. buffer->data must be updated */
extern void
copy_to_hw_buffer(USBBuffer *buffer,unsigned int offset, unsigned int len);
/* Copy len bytes of data to the buffer from dedicated USB memory.
buffer->data must be updated */
extern void
copy_from_hw_buffer(USBBuffer *buffer,unsigned int offset, unsigned int len);
#endif