From 20dc0e6c8e365c1f4188189d506163d589c3bade Mon Sep 17 00:00:00 2001 From: Bdale Garbee Date: Sun, 22 Apr 2018 19:00:03 -0600 Subject: add a warning about Google limiting per-day access until/unless we pay --- src/stmf0/ao_usb_stm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/stmf0') diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c index bf08abc1..483d2419 100644 --- a/src/stmf0/ao_usb_stm.c +++ b/src/stmf0/ao_usb_stm.c @@ -1447,7 +1447,7 @@ ao_usb_enable(void) ao_arch_release_interrupts(); - for (t = 0; t < 1000; t++) + for (t = 0; t < 50000; t++) ao_arch_nop(); /* Enable USB pull-up */ -- cgit v1.2.3 From 772b5f1cb625fba1396a57b47498ef805ae1a9a8 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 1 May 2018 23:36:16 -0700 Subject: altos/stmf0: Change tests for AO_BOOT_CHAIN and AO_BOOT_PIN to #if Were #ifdef, which meant that #define AO_BOOT_PIN 0 didn't work right. Signed-off-by: Keith Packard --- src/stmf0/ao_interrupt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/stmf0') diff --git a/src/stmf0/ao_interrupt.c b/src/stmf0/ao_interrupt.c index fcd330f1..0d6f6113 100644 --- a/src/stmf0/ao_interrupt.c +++ b/src/stmf0/ao_interrupt.c @@ -69,9 +69,9 @@ stm_flash_size(void) { void start(void) { -#ifdef AO_BOOT_CHAIN +#if AO_BOOT_CHAIN if (ao_boot_check_chain()) { -#ifdef AO_BOOT_PIN +#if AO_BOOT_PIN ao_boot_check_pin(); #endif } -- cgit v1.2.3 From 980e3dc43ac4712680a370756e5112e9f330aa9a Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 1 May 2018 23:36:57 -0700 Subject: altos/stmf0: whitespace fix Trailing whitespace. Signed-off-by: Keith Packard --- src/stmf0/ao_flash_loader_stm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/stmf0') diff --git a/src/stmf0/ao_flash_loader_stm.c b/src/stmf0/ao_flash_loader_stm.c index a8d1701b..18bf272c 100644 --- a/src/stmf0/ao_flash_loader_stm.c +++ b/src/stmf0/ao_flash_loader_stm.c @@ -34,7 +34,7 @@ main(void) #ifdef AO_FLASH_LOADER_INIT AO_FLASH_LOADER_INIT; -#endif +#endif ao_flash_task(); return 0; } -- cgit v1.2.3 From 08e543cd8b761e4cbbfa97404fcd5394f65a0e9e Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 1 May 2018 23:44:00 -0700 Subject: altos/stmf0: Set 0x0 mapping to Main Flash for boot loader When DFU finishes loading firmware and jumps to the application, it leaves the mapping of addresses starting at 0x0 set to System flash, which prevents the boot loader from receiving interrupts and requires a power cycle during flash & cal. Signed-off-by: Keith Packard --- src/stmf0/ao_interrupt.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/stmf0') diff --git a/src/stmf0/ao_interrupt.c b/src/stmf0/ao_interrupt.c index 0d6f6113..a67f6f1a 100644 --- a/src/stmf0/ao_interrupt.c +++ b/src/stmf0/ao_interrupt.c @@ -76,13 +76,17 @@ void start(void) #endif } #endif -#if RELOCATE_INTERRUPT /* Turn on syscfg */ stm_rcc.apb2enr |= (1 << STM_RCC_APB2ENR_SYSCFGCOMPEN); +#if RELOCATE_INTERRUPT memcpy(&__interrupt_start__, &__interrupt_rom__, &__interrupt_end__ - &__interrupt_start__); stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) | (STM_SYSCFG_CFGR1_MEM_MODE_SRAM << STM_SYSCFG_CFGR1_MEM_MODE); +#else + /* Switch to Main Flash mode (DFU loader leaves us in System mode) */ + stm_syscfg.cfgr1 = (stm_syscfg.cfgr1 & ~(STM_SYSCFG_CFGR1_MEM_MODE_MASK << STM_SYSCFG_CFGR1_MEM_MODE)) | + (STM_SYSCFG_CFGR1_MEM_MODE_MAIN_FLASH << STM_SYSCFG_CFGR1_MEM_MODE); #endif memcpy(&__data_start__, &__text_end__, &__data_end__ - &__data_start__); memset(&__bss_start__, '\0', &__bss_end__ - &__bss_start__); -- cgit v1.2.3 From b15549d8c5277ba3aa425e232473a17dc136e5a4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 6 May 2018 21:09:22 -0700 Subject: altos/stmf0: Toggle IN2 SW_BUF bit when sending data This tells the hardware we're done writing data to the second input buffer and allows it to be switched from NAK to VALID. Signed-off-by: Keith Packard --- src/stmf0/ao_usb_stm.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/stmf0') diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c index 483d2419..3d227f20 100644 --- a/src/stmf0/ao_usb_stm.c +++ b/src/stmf0/ao_usb_stm.c @@ -1132,6 +1132,9 @@ _ao_usb_in2_send(void) /* Toggle our usage */ ao_usb_in_tx2_which = 1 - ao_usb_in_tx2_which; + /* Toggle the SW_BUF flag */ + _ao_usb_toggle_dtog(AO_USB_IN2_EPR, 1, 0); + /* Mark the outgoing buffer as valid */ _ao_usb_set_stat_tx(AO_USB_IN2_EPR, STM_USB_EPR_STAT_TX_VALID); -- cgit v1.2.3 From a06c283c358455008cd1e5376ccc0b6f72c7ac87 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 6 May 2018 21:11:02 -0700 Subject: altos/stmf0: Add IN3 alternate endpoint support This adds the code necessary to drive another IN endpoint. Signed-off-by: Keith Packard --- src/stmf0/ao_usb_stm.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) (limited to 'src/stmf0') diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c index 3d227f20..a99b4cff 100644 --- a/src/stmf0/ao_usb_stm.c +++ b/src/stmf0/ao_usb_stm.c @@ -113,6 +113,12 @@ static uint8_t ao_usb_in_tx2_which; static uint8_t ao_usb_tx2_count; #endif +#if AO_USB_HAS_IN3 +static uint16_t ao_usb_in_tx3_offset; +static uint8_t ao_usb_in_tx3_which; +static uint8_t ao_usb_tx3_count; +#endif + /* * End point register indices */ @@ -122,6 +128,7 @@ static uint8_t ao_usb_tx2_count; #define AO_USB_OUT_EPR 2 #define AO_USB_IN_EPR 3 #define AO_USB_IN2_EPR 4 +#define AO_USB_IN3_EPR 5 /* Marks when we don't need to send an IN packet. * This happens only when the last IN packet is not full, @@ -146,6 +153,16 @@ static uint16_t in2_count; static uint8_t ao_usb_in2_flushed; #endif +#if AO_USB_HAS_IN3 +/* Marks when we have delivered an IN packet to the hardware + * and it has not been received yet. ao_sleep on this address + * to wait for it to be delivered. + */ +static uint8_t ao_usb_in3_pending; +static uint16_t in3_count; +static uint8_t ao_usb_in3_flushed; +#endif + /* Marks when an OUT packet has been received by the hardware * but not pulled to the shadow buffer. */ @@ -423,6 +440,11 @@ ao_usb_alloc_buffers(void) ao_usb_in_tx2_offset = sram_addr; sram_addr += AO_USB_IN_SIZE * 2; #endif +#if AO_USB_HAS_IN3 + sram_addr += (sram_addr & 1); + ao_usb_in_tx3_offset = sram_addr; + sram_addr += AO_USB_IN_SIZE * 2; +#endif } static void @@ -558,6 +580,25 @@ ao_usb_set_configuration(void) ao_usb_in_tx2_which = 0; #endif +#if AO_USB_HAS_IN3 + /* Set up the IN3 end point */ + stm_usb_bdt[AO_USB_IN3_EPR].double_tx[0].addr = ao_usb_in_tx3_offset; + stm_usb_bdt[AO_USB_IN3_EPR].double_tx[0].count = 0; + stm_usb_bdt[AO_USB_IN3_EPR].double_tx[1].addr = ao_usb_in_tx3_offset + AO_USB_IN_SIZE; + stm_usb_bdt[AO_USB_IN3_EPR].double_tx[1].count = 0; + + ao_usb_init_ep(AO_USB_IN3_EPR, + AO_USB_IN3_EP, + STM_USB_EPR_EP_TYPE_BULK, + STM_USB_EPR_STAT_RX_DISABLED, + STM_USB_EPR_STAT_TX_NAK, + STM_USB_EPR_EP_KIND_DBL_BUF, + 0, 1); + + /* First transmit data goes to buffer 0 */ + ao_usb_in_tx3_which = 0; +#endif + ao_usb_in_flushed = 0; ao_usb_in_pending = 0; ao_wakeup(&ao_usb_in_pending); @@ -567,6 +608,12 @@ ao_usb_set_configuration(void) ao_wakeup(&ao_usb_in2_pending); #endif +#if AO_USB_HAS_IN3 + ao_usb_in3_flushed = 0; + ao_usb_in3_pending = 0; + ao_wakeup(&ao_usb_in3_pending); +#endif + ao_usb_out_avail = 0; ao_usb_configuration = 0; @@ -995,6 +1042,16 @@ stm_usb_isr(void) ao_wakeup(&ao_usb_in2_pending); } break; +#endif +#if AO_USB_HAS_IN3 + case AO_USB_IN3_EPR: + ++in3_count; + _tx_dbg1("TX3 ISR", epr); + if (ao_usb_epr_ctr_tx(epr)) { + ao_usb_in3_pending = 0; + ao_wakeup(&ao_usb_in3_pending); + } + break; #endif case AO_USB_INT_EPR: #if USB_STATUS @@ -1202,6 +1259,94 @@ ao_usb_putchar2(char c) } #endif +#if AO_USB_HAS_IN3 +/* Queue the current IN buffer for transmission */ +static void +_ao_usb_in3_send(void) +{ + _tx_dbg0("in3_send start"); + debug ("send3 %d\n", ao_usb_tx3_count); + while (ao_usb_in3_pending) + ao_sleep(&ao_usb_in3_pending); + ao_usb_in3_pending = 1; + if (ao_usb_tx3_count != AO_USB_IN_SIZE) + ao_usb_in3_flushed = 1; + stm_usb_bdt[AO_USB_IN3_EPR].double_tx[ao_usb_in_tx3_which].count = ao_usb_tx3_count; + ao_usb_tx3_count = 0; + + /* Toggle our usage */ + ao_usb_in_tx3_which = 1 - ao_usb_in_tx3_which; + + /* Toggle the SW_BUF flag */ + _ao_usb_toggle_dtog(AO_USB_IN3_EPR, 1, 0); + + /* Mark the outgoing buffer as valid */ + _ao_usb_set_stat_tx(AO_USB_IN3_EPR, STM_USB_EPR_STAT_TX_VALID); + + _tx_dbg0("in3_send end"); +} + +/* Wait for a free IN buffer. Interrupts are blocked */ +static void +_ao_usb_in3_wait(void) +{ + for (;;) { + /* Check if the current buffer is writable */ + if (ao_usb_tx3_count < AO_USB_IN_SIZE) + break; + + _tx_dbg0("in3_wait top"); + /* Wait for an IN buffer to be ready */ + while (ao_usb_in3_pending) + ao_sleep(&ao_usb_in3_pending); + _tx_dbg0("in_wait bottom"); + } +} + +void +ao_usb_flush3(void) +{ + if (!ao_usb_running) + return; + + /* Anytime we've sent a character since + * the last time we flushed, we'll need + * to send a packet -- the only other time + * we would send a packet is when that + * packet was full, in which case we now + * want to send an empty packet + */ + ao_arch_block_interrupts(); + while (!ao_usb_in3_flushed) { + _tx_dbg0("flush3 top"); + _ao_usb_in3_send(); + _tx_dbg0("flush3 end"); + } + ao_arch_release_interrupts(); +} + +void +ao_usb_putchar3(char c) +{ + if (!ao_usb_running) + return; + + ao_arch_block_interrupts(); + _ao_usb_in3_wait(); + + ao_usb_in3_flushed = 0; + ao_usb_tx_byte(ao_usb_in_tx3_offset + AO_USB_IN_SIZE * ao_usb_in_tx3_which + ao_usb_tx3_count++, c); + + /* Send the packet when full */ + if (ao_usb_tx3_count == AO_USB_IN_SIZE) { + _tx_dbg0("putchar3 full"); + _ao_usb_in3_send(); + _tx_dbg0("putchar3 flushed"); + } + ao_arch_release_interrupts(); +} +#endif + #if AO_USB_HAS_OUT static void _ao_usb_out_recv(void) -- cgit v1.2.3 From 4451f7b6bade66775a197b93c6e70ba15f1826ce Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Sun, 6 May 2018 21:11:48 -0700 Subject: altos/stmf0: Fix up USB debug code At least make it compile. In this configuration, it's dumping out IN3 endpoint register values. Signed-off-by: Keith Packard --- src/stmf0/ao_usb_stm.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src/stmf0') diff --git a/src/stmf0/ao_usb_stm.c b/src/stmf0/ao_usb_stm.c index a99b4cff..c4860d8e 100644 --- a/src/stmf0/ao_usb_stm.c +++ b/src/stmf0/ao_usb_stm.c @@ -1689,9 +1689,9 @@ struct ao_usb_dbg { #endif }; -#define NUM_USB_DBG 128 +#define NUM_USB_DBG 16 -struct ao_usb_dbg dbg[128]; +struct ao_usb_dbg dbg[NUM_USB_DBG]; int dbg_i; static void _dbg(int line, char *msg, uint32_t value) @@ -1703,11 +1703,11 @@ static void _dbg(int line, char *msg, uint32_t value) asm("mrs %0,primask" : "=&r" (primask)); dbg[dbg_i].primask = primask; #if TX_DBG - dbg[dbg_i].in_count = in_count; - dbg[dbg_i].in_epr = stm_usb.epr[AO_USB_IN_EPR]; - dbg[dbg_i].in_pending = ao_usb_in_pending; - dbg[dbg_i].tx_count = ao_usb_tx_count; - dbg[dbg_i].in_flushed = ao_usb_in_flushed; + dbg[dbg_i].in_count = in3_count; + dbg[dbg_i].in_epr = stm_usb.epr[AO_USB_IN3_EPR].r; + dbg[dbg_i].in_pending = ao_usb_in3_pending; + dbg[dbg_i].tx_count = ao_usb_tx3_count; + dbg[dbg_i].in_flushed = ao_usb_in3_flushed; #endif #if RX_DBG dbg[dbg_i].rx_count = ao_usb_rx_count; -- cgit v1.2.3 From bc70f92966221f941b96177b401744a7aca24814 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 7 May 2018 09:42:28 -0700 Subject: altos/stmf0: leave ao_power_gpio names undefined without power management Should make it more obvious at compile time that you've done something wrong. Signed-off-by: Keith Packard --- src/stmf0/ao_arch_funcs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/stmf0') diff --git a/src/stmf0/ao_arch_funcs.h b/src/stmf0/ao_arch_funcs.h index 56a3bc75..96c033f9 100644 --- a/src/stmf0/ao_arch_funcs.h +++ b/src/stmf0/ao_arch_funcs.h @@ -171,10 +171,12 @@ ao_spi_try_get_mask(struct stm_gpio *reg, uint16_t mask, uint8_t bus, uint32_t s #define ao_spi_get_bit(reg,bit,pin,bus,speed) ao_spi_get_mask(reg,(1<