diff --git a/stm/lib/usbd_cdc_core.h b/stm/lib/usbd_cdc_core.h index 3187deb3dc..026462143f 100644 --- a/stm/lib/usbd_cdc_core.h +++ b/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; diff --git a/stm/lib/usbd_cdc_vcp.c b/stm/lib/usbd_cdc_vcp.c index 9cf8fb2589..b7330d9f6a 100644 --- a/stm/lib/usbd_cdc_vcp.c +++ b/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; } diff --git a/stm/lib/usbd_conf.h b/stm/lib/usbd_conf.h index 4bab9e3c26..60243d2f6a 100644 --- a/stm/lib/usbd_conf.h +++ b/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__ diff --git a/stm/lib/usbd_pyb_core.c b/stm/lib/usbd_pyb_core.c index 9c0f1caa01..ea8f05a81c 100644 --- a/stm/lib/usbd_pyb_core.c +++ b/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, diff --git a/stm/main.c b/stm/main.c index 9eb31db537..a45a90c5ec 100644 --- a/stm/main.c +++ b/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); -} -*/ diff --git a/stm/malloc0.c b/stm/malloc0.c index 55c1ae8044..1b45846e6f 100644 --- a/stm/malloc0.c +++ b/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); diff --git a/stm/printf.c b/stm/printf.c index 1cdb6a48f6..edfee8e912 100644 --- a/stm/printf.c +++ b/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; } diff --git a/stm/startup_stm32f40xx.s b/stm/startup_stm32f40xx.s index 194ebac359..a9f21f0b05 100644 --- a/stm/startup_stm32f40xx.s +++ b/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 diff --git a/stm/stm32f405.ld b/stm/stm32f405.ld index bab2474578..cca49bfbd2 100644 --- a/stm/stm32f405.ld +++ b/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 */ +/* produce a link error if there is not this amount of RAM for these sections */ +_minimum_stack_size = 2K; +_minimum_heap_size = 16K; -/* define beginning and ending of stack */ -_stack_start = ORIGIN(RAM) + LENGTH(RAM); -_stack_end = _stack_start - stack_size; -_estack = _stack_end; - -/* 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 */ /* diff --git a/stm/usb.c b/stm/usb.c index eea7e5a0a6..fdb088638b 100644 --- a/stm/usb.c +++ b/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_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); + is_enabled = 1; +} + +void usb_vcp_send(const char* str, int len) { + if (is_enabled) { + VCP_fops.pIf_DataTx((const uint8_t*)str, len); + } }