Browse Source

Fix up linker script; improve startup code; printf to USB.

pull/3/head
Damien 11 years ago
parent
commit
4a175e1f11
  1. 2
      stm/lib/usbd_cdc_core.h
  2. 6
      stm/lib/usbd_cdc_vcp.c
  3. 3
      stm/lib/usbd_conf.h
  4. 14
      stm/lib/usbd_pyb_core.c
  5. 142
      stm/main.c
  6. 3
      stm/malloc0.c
  7. 16
      stm/printf.c
  8. 28
      stm/startup_stm32f40xx.s
  9. 67
      stm/stm32f405.ld
  10. 17
      stm/usb.c

2
stm/lib/usbd_cdc_core.h

@ -97,7 +97,7 @@ typedef struct _CDC_IF_PROP
uint16_t (*pIf_Init) (void);
uint16_t (*pIf_DeInit) (void);
uint16_t (*pIf_Ctrl) (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
uint16_t (*pIf_DataTx) (uint8_t* Buf, uint32_t Len);
uint16_t (*pIf_DataTx) (const uint8_t* Buf, uint32_t Len);
uint16_t (*pIf_DataRx) (uint8_t* Buf, uint32_t Len);
}
CDC_IF_Prop_TypeDef;

6
stm/lib/usbd_cdc_vcp.c

@ -60,7 +60,7 @@ extern uint32_t APP_Rx_ptr_in; /* Increment this pointer or roll it back to
static uint16_t VCP_Init (void);
static uint16_t VCP_DeInit (void);
static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len);
static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len);
static uint16_t VCP_DataTx (const uint8_t* Buf, uint32_t Len);
static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len);
CDC_IF_Prop_TypeDef VCP_fops =
@ -181,7 +181,7 @@ static uint16_t VCP_Ctrl (uint32_t Cmd, uint8_t* Buf, uint32_t Len)
* @param Len: Number of data to be sent (in bytes)
* @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL
*/
static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
static uint16_t VCP_DataTx (const uint8_t* Buf, uint32_t Len)
{
for (int i = 0; i < Len; i++) {
APP_Rx_Buffer[APP_Rx_ptr_in] = Buf[i];
@ -212,7 +212,7 @@ static uint16_t VCP_DataTx (uint8_t* Buf, uint32_t Len)
* @retval Result of the opeartion: USBD_OK if all operations are OK else VCP_FAIL
*/
static uint16_t VCP_DataRx (uint8_t* Buf, uint32_t Len) {
printf("%.*s", (int)Len, Buf);
//printf("%.*s", (int)Len, Buf);
return USBD_OK;
}

3
stm/lib/usbd_conf.h

@ -20,7 +20,4 @@
#define MSC_MAX_PACKET 64
#define MSC_MEDIA_PACKET 4096
// for both?
#define APP_FOPS VCP_fops
#endif //__USBD_CONF__H__

14
stm/lib/usbd_pyb_core.c

@ -96,7 +96,7 @@ static uint8_t *usbd_pyb_GetCfgDesc (uint8_t speed, uint16_t *length);
/** @defgroup usbd_cdc_Private_Variables
* @{
*/
extern CDC_IF_Prop_TypeDef APP_FOPS;
extern CDC_IF_Prop_TypeDef VCP_fops;
extern uint8_t USBD_DeviceDesc [USB_SIZ_DEVICE_DESC];
__ALIGN_BEGIN static uint8_t usbd_cdc_AltSet __ALIGN_END = 0;
@ -322,7 +322,7 @@ static uint8_t usbd_pyb_Init(void *pdev, uint8_t cfgidx) {
*/
// Initialize the Interface physical components
APP_FOPS.pIf_Init();
VCP_fops.pIf_Init();
// Prepare Out endpoint to receive next packet */
DCD_EP_PrepareRx(pdev,
@ -367,7 +367,7 @@ static uint8_t usbd_pyb_DeInit(void *pdev, uint8_t cfgidx) {
DCD_EP_Close(pdev, CDC_CMD_EP);
// Restore default state of the Interface physical components
APP_FOPS.pIf_DeInit();
VCP_fops.pIf_DeInit();
//----------------------------------
// MSC component
@ -475,7 +475,7 @@ static uint8_t usbd_pyb_Setup(void *pdev, USB_SETUP_REQ *req) {
// Device-to-Host request
// Get the data to be sent to Host from interface layer
APP_FOPS.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength);
VCP_fops.pIf_Ctrl(req->bRequest, CmdBuff, req->wLength);
// Send the data to the host
return USBD_CtlSendData(pdev, CmdBuff, req->wLength);
@ -495,7 +495,7 @@ static uint8_t usbd_pyb_Setup(void *pdev, USB_SETUP_REQ *req) {
// Not a Data request
// Transfer the command to the interface layer */
return APP_FOPS.pIf_Ctrl(req->bRequest, NULL, 0);
return VCP_fops.pIf_Ctrl(req->bRequest, NULL, 0);
}
} else if (req->wIndex == 2) {
@ -537,7 +537,7 @@ static uint8_t usbd_pyb_Setup(void *pdev, USB_SETUP_REQ *req) {
static uint8_t usbd_pyb_EP0_RxReady(void *pdev) {
if (cdcCmd != NO_CMD) {
// Process the data
APP_FOPS.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
VCP_fops.pIf_Ctrl(cdcCmd, CmdBuff, cdcLen);
// Reset the command variable to default value
cdcCmd = NO_CMD;
@ -612,7 +612,7 @@ static uint8_t usbd_pyb_DataOut(void *pdev, uint8_t epnum) {
/* USB data will be immediately processed, this allow next USB traffic being
NAKed till the end of the application Xfer */
APP_FOPS.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt);
VCP_fops.pIf_DataRx(USB_Rx_Buffer, USB_Rx_Cnt);
// Prepare Out endpoint to receive next packet */
DCD_EP_PrepareRx(pdev,

142
stm/main.c

@ -6,7 +6,7 @@
void delay_ms(int ms);
void impl02_c_version() {
static void impl02_c_version() {
int x = 0;
while (x < 400) {
int y = 0;
@ -52,7 +52,7 @@ void gpio_pin_af(GPIO_TypeDef *gpio, uint32_t pin, uint32_t af) {
set_bits(&gpio->AFR[pin >> 3], 4 * (pin & 0x07), 0xf, af);
}
void mma_init() {
static void mma_init() {
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // enable I2C1
gpio_pin_init(GPIOB, 6 /* B6 is SCL */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */);
gpio_pin_init(GPIOB, 7 /* B7 is SDA */, 2 /* AF mode */, 1 /* open drain output */, 1 /* 25 MHz */, 0 /* no pull up or pull down */);
@ -82,14 +82,14 @@ void mma_init() {
// set START bit in CR1 to generate a start cond!
}
uint32_t i2c_get_sr() {
static uint32_t i2c_get_sr() {
// must read SR1 first, then SR2, as the read can clear some flags
uint32_t sr1 = I2C1->SR1;
uint32_t sr2 = I2C1->SR2;
return (sr2 << 16) | sr1;
}
void mma_restart(uint8_t addr, int write) {
static void mma_restart(uint8_t addr, int write) {
// send start condition
I2C1->CR1 |= I2C_CR1_START;
@ -112,7 +112,7 @@ void mma_restart(uint8_t addr, int write) {
}
}
void mma_start(uint8_t addr, int write) {
static void mma_start(uint8_t addr, int write) {
// wait until I2C is not busy
while (I2C1->SR2 & I2C_SR2_BUSY) {
}
@ -121,7 +121,7 @@ void mma_start(uint8_t addr, int write) {
mma_restart(addr, write);
}
void mma_send_byte(uint8_t data) {
static void mma_send_byte(uint8_t data) {
// send byte
I2C1->DR = data;
// wait for TRA, BUSY, MSL, TXE and BTF (byte transmitted)
@ -134,7 +134,7 @@ void mma_send_byte(uint8_t data) {
}
}
uint8_t mma_read_ack() {
static uint8_t mma_read_ack() {
// enable ACK of received byte
I2C1->CR1 |= I2C_CR1_ACK;
// wait for BUSY, MSL and RXNE (byte received)
@ -145,7 +145,7 @@ uint8_t mma_read_ack() {
return data;
}
uint8_t mma_read_nack() {
static uint8_t mma_read_nack() {
// disable ACK of received byte (to indicate end of receiving)
I2C1->CR1 &= (uint16_t)~((uint16_t)I2C_CR1_ACK);
// last byte should apparently also generate a stop condition
@ -158,7 +158,7 @@ uint8_t mma_read_nack() {
return data;
}
void mma_stop() {
static void mma_stop() {
// send stop condition
I2C1->CR1 |= I2C_CR1_STOP;
}
@ -440,6 +440,8 @@ py_obj_t pyb_sw() {
FATFS fatfs0;
#include "nlr.h"
/*
void g(uint i) {
printf("g:%d\n", i);
if (i & 1) {
@ -467,8 +469,13 @@ void f() {
void nlr_test() {
f(1);
}
*/
int dummy_bss;
int main() {
int dummy;
// should disable JTAG
qstr_init();
@ -486,12 +493,13 @@ int main() {
for (int i = 0; i < 2; i++) {
led_state(PYB_LEDR1_PORT_NUM, 1);
led_state(PYB_LEDR2_PORT_NUM, 0);
delay_ms(200);
delay_ms(100);
led_state(PYB_LEDR1_PORT_NUM, 0);
led_state(PYB_LEDR2_PORT_NUM, 1);
delay_ms(200);
delay_ms(100);
}
// turn LEDs off
led_state(PYB_LEDR1_PORT_NUM, 0);
led_state(PYB_LEDR2_PORT_NUM, 0);
led_state(PYB_LEDG1_PORT_NUM, 0);
@ -508,30 +516,48 @@ int main() {
}
*/
/*
extern int _sidata;
extern int _sdata;
extern int _edata;
extern int _sbss;
extern int _ebss;
delay_ms(2000);
printf("_sidata=%04x\n", _sidata);
printf("_sdata=%04x\n", _sdata);
printf("_edata=%04x\n", _edata);
printf("_sbss=%04x\n", _sbss);
printf("_ebss=%04x\n", _ebss);
//printf("sizeof(int)=%d\n", sizeof(int)); // 4
delay_ms(2000);
*/
// USB
if (1) {
void usb_init();
usb_init();
}
for (;;) {
led_state(PYB_LEDG1_PORT_NUM, 1);
delay_ms(100);
led_state(PYB_LEDG1_PORT_NUM, 0);
extern void *_sidata;
extern void *_sdata;
extern void *_edata;
extern void *_sbss;
extern void *_ebss;
extern void *_estack;
extern void *_etext;
extern void *_heap_start;
if (sw_get()) {
printf("_sidata=%p\n", &_sidata);
printf("_sdata=%p\n", &_sdata);
printf("_edata=%p\n", &_edata);
printf("_sbss=%p\n", &_sbss);
printf("_ebss=%p\n", &_ebss);
printf("_estack=%p\n", &_estack);
printf("_etext=%p\n", &_etext);
printf("_heap_start=%p\n", &_heap_start);
printf("&dummy=%p\n", &dummy);
printf("&dummy_bss=%p\n", &dummy_bss);
printf("dummy_bss=%x\n", dummy_bss);
//printf("sizeof(int)=%d\n", sizeof(int)); // 4
delay_ms(1000);
}
delay_ms(500);
}
//printf("init;al=%u\n", m_get_total_bytes_allocated()); // 1600, due to qstr_init
//delay_ms(1000);
nlr_test();
#if 1
// Python!
if (1) {
if (0) {
//const char *pysrc = "def f():\n x=x+1\nprint(42)\n";
const char *pysrc =
// impl01.py
@ -802,12 +828,6 @@ int main() {
//usb_vcp_init();
}
// USB testing
if (0) {
void usb_init();
usb_init();
}
int i = 0;
int n = 0;
@ -833,55 +853,3 @@ int main() {
return 0;
}
/*
void testf() {
testf(1, 2, 3);
testf(1, 2, 3, 4);
testf(1, 2, 3, 4, 5);
testf(1, 2, 3, 4, 5, 6);
testf(1, 2, 3, 4, 5, 6, 7);
}
int testg(int a, int b, int c, int d, int e) {
return a + b + c + d + testh(e);
}
int testh(int x, byte *y) {
return x + (y[-2] << 2);
}
*/
/*
void print_int(int x, int y, int z, int zz) {
printf("I %x %x %x %x", x, y, z, zz);
byte* ptr = (byte*)z;
printf("\nP %02x %02x %02x %02x", ptr[-4], ptr[-3], ptr[-2], ptr[-1]);
for (;;) {
}
}
void print_int_0(int x) { printf("P0 %x", x); }
void print_int_1(int x) { printf("P1 %x", x); }
void print_int_2(int x) { printf("P2 %x", x); }
void print_int_3(int x) { printf("P3 %x", x); }
void print_int_4(int x) { printf("P4 %x", x); }
typedef struct _b_t {
void (*m1)(void*, int);
void (*m2)(void*, int);
} b_t;
typedef struct _a_t {
b_t *b;
} a_t;
void b_m1(b_t*, int);
void b_m2(b_t*, int);
void f1(a_t *a) {
a->b->m1(a->b, 2);
a->b->m2(a->b, 4);
b_m1(a->b, 2);
b_m2(a->b, 4);
}
void b_m1(b_t *b, int x) {
b->m1(b, x);
}
*/

3
stm/malloc0.c

@ -5,7 +5,8 @@ static uint32_t mem = 0;
void *malloc(size_t n) {
if (mem == 0) {
mem = 0x20008000; // need to use big ram block so we can execute code from it; start up a bit in case that's where bss is...?
extern uint32_t _heap_start;
mem = &_heap_start; // need to use big ram block so we can execute code from it (is it true that we can't execute from CCM?)
}
void *ptr = (void*)mem;
mem = (mem + n + 3) & (~3);

16
stm/printf.c

@ -209,17 +209,17 @@ int pfenv_printf(pfenv_t *pfenv, const char *fmt, va_list args) {
}
void lcd_print_strn(const char *str, unsigned int len);
void usb_vcp_send(const char* str, int len);
void xxx(void *data, const char *str, unsigned int len) {
void stdout_print_strn(void *data, const char *str, unsigned int len) {
// send stdout to LCD and USB CDC VCP
lcd_print_strn(str, len);
usb_vcp_send(str, len);
}
pfenv_t pfenv_stdout = {0, xxx};
pfenv_t pfenv_stdout = {0, stdout_print_strn};
int printf(const char *fmt, ...) {
//pfenv_t pfenv;
//pfenv.data = 0;
//pfenv.print_strn = xxx;
va_list args;
va_start(args, fmt);
return pfenv_printf(&pfenv_stdout, fmt, args);
@ -228,15 +228,15 @@ int printf(const char *fmt, ...) {
// need this because gcc optimises printf("%c", c) -> putchar(c), and printf("a") -> putchar('a')
int putchar(int c) {
char chr = c;
xxx(0, &chr, 1);
stdout_print_strn(0, &chr, 1);
return chr;
}
// need this because gcc optimises printf("string\n") -> puts("string")
int puts(const char *s) {
xxx(0, s, strlen(s));
stdout_print_strn(0, s, strlen(s));
char chr = '\n';
xxx(0, &chr, 1);
stdout_print_strn(0, &chr, 1);
return 1;
}

28
stm/startup_stm32f40xx.s

@ -72,6 +72,7 @@ defined in linker script */
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
/*
movs r1, #0
b LoopCopyDataInit
@ -87,9 +88,23 @@ LoopCopyDataInit:
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
*/
ldr r0, =_sidata @ source pointer
ldr r1, =_sdata @ destination pointer
ldr r2, =_edata @ maximum destination pointer
b data_init_entry
data_init_loop:
ldr r3, [r0], #4
str r3, [r1], #4
data_init_entry:
cmp r1, r2
bcc data_init_loop
/* Zero fill the bss segment. */
/*
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2], #4
@ -98,6 +113,17 @@ LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
*/
movs r0, #0 @ source value
ldr r1, =_sbss @ destination pointer
ldr r2, =_ebss @ maximum destination pointer
b bss_init_entry
bss_init_loop:
str r0, [r1], #4
bss_init_entry:
cmp r1, r2
bcc bss_init_loop
/* Call the clock system intitialization function.*/
bl SystemInit

67
stm/stm32f405.ld

@ -2,27 +2,22 @@
GNU linker script for STM32F405
*/
/* Entry Point */
ENTRY(Reset_Handler)
/* Specify the memory areas */
MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 0x100000 /* 1 MiB */
RAM_CCM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0x010000 /* 64 KiB */
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 0x020000 /* 128 KiB */
}
/* define stack size and heap size here */
stack_size = 2048;
heap_size = 0x4000; /* 16KiB */
/* define beginning and ending of stack */
_stack_start = ORIGIN(RAM) + LENGTH(RAM);
_stack_end = _stack_start - stack_size;
_estack = _stack_end;
/* produce a link error if there is not this amount of RAM for these sections */
_minimum_stack_size = 2K;
_minimum_heap_size = 16K;
/* Define output sections */
/* top end of the stack */
_estack = ORIGIN(RAM) + LENGTH(RAM);
/* define output sections */
SECTIONS
{
/* The startup code goes first into FLASH */
@ -30,6 +25,7 @@ SECTIONS
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
@ -43,10 +39,13 @@ SECTIONS
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */
/* *(.glue_7) */ /* glue arm to thumb code */
/* *(.glue_7t) */ /* glue thumb to arm code */
. = ALIGN(4);
_etext = .; /* define a global symbols at end of code */
_etext = .; /* define a global symbol at end of code */
_sidata = _etext; /* This is used by the startup in order to initialize the .data secion */
} >FLASH
/*
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
@ -58,51 +57,51 @@ SECTIONS
*(.ARM.exidx*)
__exidx_end = .;
} >FLASH
*/
/* used by the startup to initialize data */
_sidata = .;
/* Initialized data sections goes into RAM, load LMA copy after code */
/* This is the initialized data section
The program executes knowing that the data is in the RAM
but the loader puts the initial values in the FLASH (inidata).
It is one task of the startup to copy the initial values from FLASH to RAM. */
.data : AT ( _sidata )
{
. = ALIGN(4);
_sdata = .; /* create a global symbol at data start */
_sdata = .; /* create a global symbol at data start; used by startup code in order to initialise the .data section in RAM */
*(.data) /* .data sections */
*(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .; /* define a global symbol at data end */
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
} >RAM
/* Uninitialized data section */
. = ALIGN(4);
.bss :
{
/* Used by the startup in order to initialize the .bss secion */
_sbss = .; /* define a global symbol at bss start */
__bss_start__ = _sbss;
. = ALIGN(4);
_sbss = .; /* define a global symbol at bss start; used by startup code */
*(.bss)
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end */
__bss_end__ = _ebss;
_ebss = .; /* define a global symbol at bss end; used by startup code */
} >RAM
. = ALIGN(4);
/* this is to define the start of the heap, and make sure we have a minimum size */
.heap :
{
_heap_start = .;
. = . + heap_size;
} > RAM
. = ALIGN(4);
_heap_start = .; /* define a global symbol at heap start */
. = . + _minimum_heap_size;
} >RAM
. = ALIGN(4);
. = _stack_end;
/* this just checks there is enough RAM for the stack */
.stack :
{
. = . + stack_size;
} > RAM
. = ALIGN(4);
. = . + _minimum_stack_size;
. = ALIGN(4);
} >RAM
/* Remove information from the standard libraries */
/*

17
stm/usb.c

@ -1,21 +1,22 @@
#include "usb_core.h"
#include "usbd_core.h"
#include "usbd_cdc_core.h"
#include "usbd_pyb_core.h"
#include "usbd_usr.h"
#include "usbd_desc.h"
//extern CDC_IF_Prop_TypeDef APP_FOPS;
extern CDC_IF_Prop_TypeDef VCP_fops;
int is_enabled = 0;
USB_OTG_CORE_HANDLE USB_OTG_dev;
void usb_vcp_init() {
//USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_CDC_cb, &USR_cb);
void usb_init() {
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb);
is_enabled = 1;
}
void usb_vcp_send(const char* str, int len) {
//APP_FOPS.pIf_DataTx(str, len);
}
void usb_init() {
USBD_Init(&USB_OTG_dev, USB_OTG_FS_CORE_ID, &USR_desc, &USBD_PYB_cb, &USR_cb);
if (is_enabled) {
VCP_fops.pIf_DataTx((const uint8_t*)str, len);
}
}

Loading…
Cancel
Save