From 0a4c73a63a342446f51fd8b56b4c527853aa17a4 Mon Sep 17 00:00:00 2001 From: Sean Cross Date: Thu, 28 Mar 2019 11:13:25 +0800 Subject: [PATCH] sw: wip commit -- dfu state machine works, spi broken Need to fix SPI and SB_WARMBOOT, but the DFU state machine now works. Signed-off-by: Sean Cross --- sw/include/generated/csr.h | 130 +++++++++------------------------- sw/include/generated/mem.h | 3 + sw/include/system.h | 11 +++ sw/include/usb.h | 4 +- sw/src/dfu.c | 20 ++++-- sw/src/main.c | 78 ++++---------------- sw/src/spi.c | 6 +- sw/src/usb-dev.c | 25 +++++-- sw/src/usb-epfifo.c | 20 +++++- sw/third_party/libbase/uart.c | 5 ++ 10 files changed, 127 insertions(+), 175 deletions(-) diff --git a/sw/include/generated/csr.h b/sw/include/generated/csr.h index 1555156..ebfec91 100644 --- a/sw/include/generated/csr.h +++ b/sw/include/generated/csr.h @@ -12,6 +12,33 @@ extern uint32_t csr_readl(uint32_t addr); #include #endif /* ! CSR_ACCESSORS_DEFINED */ +/* bbspi */ +#define CSR_BBSPI_BASE 0xe0005000 +#define CSR_BBSPI_DO_ADDR 0xe0005000 +#define CSR_BBSPI_DO_SIZE 1 +static inline unsigned char bbspi_do_read(void) { + unsigned char r = csr_readl(0xe0005000); + return r; +} +static inline void bbspi_do_write(unsigned char value) { + csr_writel(value, 0xe0005000); +} +#define CSR_BBSPI_OE_ADDR 0xe0005004 +#define CSR_BBSPI_OE_SIZE 1 +static inline unsigned char bbspi_oe_read(void) { + unsigned char r = csr_readl(0xe0005004); + return r; +} +static inline void bbspi_oe_write(unsigned char value) { + csr_writel(value, 0xe0005004); +} +#define CSR_BBSPI_DI_ADDR 0xe0005008 +#define CSR_BBSPI_DI_SIZE 1 +static inline unsigned char bbspi_di_read(void) { + unsigned char r = csr_readl(0xe0005008); + return r; +} + /* ctrl */ #define CSR_CTRL_BASE 0xe0000000 #define CSR_CTRL_RESET_ADDR 0xe0000000 @@ -54,31 +81,16 @@ static inline unsigned int ctrl_bus_errors_read(void) { return r; } -/* picospi */ -#define CSR_PICOSPI_BASE 0xe0005000 -#define CSR_PICOSPI_DO_ADDR 0xe0005000 -#define CSR_PICOSPI_DO_SIZE 1 -static inline unsigned char picospi_do_read(void) { - unsigned char r = csr_readl(0xe0005000); +/* reboot */ +#define CSR_REBOOT_BASE 0xe0005800 +#define CSR_REBOOT_CTRL_ADDR 0xe0005800 +#define CSR_REBOOT_CTRL_SIZE 1 +static inline unsigned char reboot_ctrl_read(void) { + unsigned char r = csr_readl(0xe0005800); return r; } -static inline void picospi_do_write(unsigned char value) { - csr_writel(value, 0xe0005000); -} -#define CSR_PICOSPI_OE_ADDR 0xe0005004 -#define CSR_PICOSPI_OE_SIZE 1 -static inline unsigned char picospi_oe_read(void) { - unsigned char r = csr_readl(0xe0005004); - return r; -} -static inline void picospi_oe_write(unsigned char value) { - csr_writel(value, 0xe0005004); -} -#define CSR_PICOSPI_DI_ADDR 0xe0005008 -#define CSR_PICOSPI_DI_SIZE 1 -static inline unsigned char picospi_di_read(void) { - unsigned char r = csr_readl(0xe0005008); - return r; +static inline void reboot_ctrl_write(unsigned char value) { + csr_writel(value, 0xe0005800); } /* timer0 */ @@ -177,78 +189,6 @@ static inline void timer0_ev_enable_write(unsigned char value) { csr_writel(value, 0xe0002840); } -/* uart */ -#define CSR_UART_BASE 0xe0001800 -#define CSR_UART_RXTX_ADDR 0xe0001800 -#define CSR_UART_RXTX_SIZE 1 -static inline unsigned char uart_rxtx_read(void) { - unsigned char r = csr_readl(0xe0001800); - return r; -} -static inline void uart_rxtx_write(unsigned char value) { - csr_writel(value, 0xe0001800); -} -#define CSR_UART_TXFULL_ADDR 0xe0001804 -#define CSR_UART_TXFULL_SIZE 1 -static inline unsigned char uart_txfull_read(void) { - unsigned char r = csr_readl(0xe0001804); - return r; -} -#define CSR_UART_RXEMPTY_ADDR 0xe0001808 -#define CSR_UART_RXEMPTY_SIZE 1 -static inline unsigned char uart_rxempty_read(void) { - unsigned char r = csr_readl(0xe0001808); - return r; -} -#define CSR_UART_EV_STATUS_ADDR 0xe000180c -#define CSR_UART_EV_STATUS_SIZE 1 -static inline unsigned char uart_ev_status_read(void) { - unsigned char r = csr_readl(0xe000180c); - return r; -} -static inline void uart_ev_status_write(unsigned char value) { - csr_writel(value, 0xe000180c); -} -#define CSR_UART_EV_PENDING_ADDR 0xe0001810 -#define CSR_UART_EV_PENDING_SIZE 1 -static inline unsigned char uart_ev_pending_read(void) { - unsigned char r = csr_readl(0xe0001810); - return r; -} -static inline void uart_ev_pending_write(unsigned char value) { - csr_writel(value, 0xe0001810); -} -#define CSR_UART_EV_ENABLE_ADDR 0xe0001814 -#define CSR_UART_EV_ENABLE_SIZE 1 -static inline unsigned char uart_ev_enable_read(void) { - unsigned char r = csr_readl(0xe0001814); - return r; -} -static inline void uart_ev_enable_write(unsigned char value) { - csr_writel(value, 0xe0001814); -} - -/* uart_phy */ -#define CSR_UART_PHY_BASE 0xe0001000 -#define CSR_UART_PHY_TUNING_WORD_ADDR 0xe0001000 -#define CSR_UART_PHY_TUNING_WORD_SIZE 4 -static inline unsigned int uart_phy_tuning_word_read(void) { - unsigned int r = csr_readl(0xe0001000); - r <<= 8; - r |= csr_readl(0xe0001004); - r <<= 8; - r |= csr_readl(0xe0001008); - r <<= 8; - r |= csr_readl(0xe000100c); - return r; -} -static inline void uart_phy_tuning_word_write(unsigned int value) { - csr_writel(value >> 24, 0xe0001000); - csr_writel(value >> 16, 0xe0001004); - csr_writel(value >> 8, 0xe0001008); - csr_writel(value, 0xe000100c); -} - /* usb */ #define CSR_USB_BASE 0xe0004800 #define CSR_USB_PULLUP_OUT_ADDR 0xe0004800 diff --git a/sw/include/generated/mem.h b/sw/include/generated/mem.h index 1e2c605..880c8f6 100644 --- a/sw/include/generated/mem.h +++ b/sw/include/generated/mem.h @@ -1,6 +1,9 @@ #ifndef __GENERATED_MEM_H #define __GENERATED_MEM_H +#define VEXRISCV_DEBUG_BASE 0xf00f0000 +#define VEXRISCV_DEBUG_SIZE 0x00000010 + #define SRAM_BASE 0x10000000 #define SRAM_SIZE 0x00020000 diff --git a/sw/include/system.h b/sw/include/system.h index 2d108d2..d9bb543 100644 --- a/sw/include/system.h +++ b/sw/include/system.h @@ -56,4 +56,15 @@ static inline void mtspr(unsigned long add, unsigned long val) } #endif +#include + +__attribute__((noreturn)) static inline void reboot(void) { + reboot_ctrl_write(0xac); + while (1); +} + +__attribute__((noreturn)) static inline void reboot_to_image(uint8_t image_index) { + reboot_ctrl_write(0xac | image_index); + while (1); +} #endif /* __SYSTEM_H */ diff --git a/sw/include/usb.h b/sw/include/usb.h index 38ad0cd..d99f9bd 100644 --- a/sw/include/usb.h +++ b/sw/include/usb.h @@ -11,14 +11,16 @@ struct usb_setup_request; void usb_isr(void); void usb_init(void); void usb_connect(void); +void usb_disconnect(void); -void usb_poll(void); int usb_irq_happened(void); void usb_setup(struct usb_device *dev, const struct usb_setup_request *setup); int usb_send(struct usb_device *dev, int epnum, const void *data, int total_count); int usb_ack(struct usb_device *dev, int epnum); int usb_err(struct usb_device *dev, int epnum); int usb_recv(struct usb_device *dev, void *buffer, unsigned int buffer_len); +void usb_poll(struct usb_device *dev); +int usb_wait_for_send_done(struct usb_device *dev); #ifdef __cplusplus } diff --git a/sw/src/dfu.c b/sw/src/dfu.c index 018c0b4..2bceec2 100644 --- a/sw/src/dfu.c +++ b/sw/src/dfu.c @@ -73,7 +73,7 @@ static struct toboot_state { static dfu_state_t dfu_state = dfuIDLE; static dfu_status_t dfu_status = OK; -static unsigned dfu_poll_timeout = 1; +static unsigned dfu_poll_timeout_ms = 100; static uint32_t dfu_buffer[DFU_TRANSFER_SIZE/4]; static uint32_t dfu_buffer_offset; @@ -200,10 +200,18 @@ uint8_t dfu_getstate(void) return dfu_state; } +unsigned last_blockNum; +unsigned last_blockLength; +unsigned last_packetOffset; +unsigned last_packetLength; bool dfu_download(unsigned blockNum, unsigned blockLength, unsigned packetOffset, unsigned packetLength, const uint8_t *data) { // uint32_t i; + last_packetLength = packetLength; + last_packetOffset = packetOffset; + last_blockLength = blockLength; + last_blockNum = blockNum; if (packetOffset + packetLength > DFU_TRANSFER_SIZE || packetOffset + packetLength > blockLength) { @@ -374,13 +382,13 @@ bool dfu_getstatus(uint8_t status[8]) // Ready to reboot. The main thread will take care of this. Also let the DFU tool // know to leave us alone until this happens. dfu_state = dfuMANIFEST; - dfu_poll_timeout = 10; + dfu_poll_timeout_ms = 10; break; case dfuMANIFEST: // Perform the reboot dfu_state = dfuMANIFEST_WAIT_RESET; - dfu_poll_timeout = 1000; + dfu_poll_timeout_ms = 1000; break; default: @@ -388,9 +396,9 @@ bool dfu_getstatus(uint8_t status[8]) } status[0] = dfu_status; - status[1] = dfu_poll_timeout; - status[2] = dfu_poll_timeout >> 8; - status[3] = dfu_poll_timeout >> 16; + status[1] = dfu_poll_timeout_ms; + status[2] = dfu_poll_timeout_ms >> 8; + status[3] = dfu_poll_timeout_ms >> 16; status[4] = dfu_state; status[5] = 0; // iString diff --git a/sw/src/main.c b/sw/src/main.c index 9d03ffb..743c5ab 100644 --- a/sw/src/main.c +++ b/sw/src/main.c @@ -4,8 +4,8 @@ #include #include #include - -#include "spi.h" +#include +#include #include struct ff_spi *spi; @@ -19,10 +19,13 @@ void isr(void) if (irqs & (1 << USB_INTERRUPT)) usb_isr(); +#ifdef CSR_UART_BASE if (irqs & (1 << UART_INTERRUPT)) uart_isr(); +#endif } +#ifdef CSR_UART_BASE static void rv_putchar(void *ignored, char c) { (void)ignored; @@ -32,10 +35,13 @@ static void rv_putchar(void *ignored, char c) return; uart_write(c); } +#endif static void init(void) { +#ifdef CSR_UART_BASE init_printf(NULL, rv_putchar); +#endif irq_setmask(0); irq_setie(1); uart_init(); @@ -82,71 +88,15 @@ int main(int argc, char **argv) init(); - // // picospi_cfg_write(0); - // picospi_oe_write(0xff); - // picospi_do_write(0); - // // uint8_t last_value = 0; - // printf("\nToggling: %02x ", picospi_oe_read()); - // while (1) { - // // uint8_t new_value = picospi_di_read(); - // // if (new_value != last_value) { - // // printf("SPI %02x -> %02x\n", last_value, new_value); - // // last_value = new_value; - // // } - // // picospi_oe_write(0xff); - // // printf("\b0"); - // // picospi_oe_write(0x00); - // // printf("\b1"); - - // // picospi_do_write(0x00); - // // printf("\b0"); - // // picospi_do_write(0xff); - // // printf("\b1"); - // } - // printf("\nPress any key to read..."); - // while(1) { - // uart_read(); - // struct spi_id id = spiId(spi); - // printf("Manufacturer ID: %s (%02x)\n", id.manufacturer, id.manufacturer_id); - // if (id.manufacturer_id != id._manufacturer_id) - // printf("!! JEDEC Manufacturer ID: %02x\n", - // id._manufacturer_id); - // printf("Memory model: %s (%02x)\n", id.model, id.memory_type); - // printf("Memory size: %s (%02x)\n", id.capacity, id.memory_size); - // printf("Device ID: %02x\n", id.device_id); - // if (id.device_id != id.signature) - // printf("!! Electronic Signature: %02x\n", id.signature); - // printf("Serial number: %02x %02x %02x %02x\n", id.serial[0], id.serial[1], id.serial[2], id.serial[3]); - // printf("Status 1: %02x\n", spiReadStatus(spi, 1)); - // printf("Status 2: %02x\n", spiReadStatus(spi, 2)); - // printf("Status 3: %02x\n", spiReadStatus(spi, 3)); - // } - // puts("\nPress any key to start..."); - // uart_read(); - - // printf("\n\nUSB API: %s\n", usb_hw_api()); - // puts("Enabling USB"); usb_connect(); - // printf("USB enabled.\n"); - // usb_print_status(); - int last = 0; + int i; while (1) { - // if (usb_irq_happened() != last) { - // last = usb_irq_happened(); - // // printf("USB %d IRQ happened\n", last); - // } - usb_poll(); - /* - printf("Press any key to send... "); - uart_read(); - printf("Sending... "); - bfr[0] = 0; - bfr[1] = ~0; - bfr[2] = 0; - usb_send(NULL, 0, bfr, 1); - printf("Sent\n"); - */ + usb_poll(NULL); + i++; + + // if (i > 200) + // reboot_ctrl_write(0xac); } return 0; } \ No newline at end of file diff --git a/sw/src/spi.c b/sw/src/spi.c index 83e4cf5..3f276e9 100644 --- a/sw/src/spi.c +++ b/sw/src/spi.c @@ -24,7 +24,7 @@ static void gpioSetMode(int pin, int mode) { oe_mirror |= 1 << pin; else oe_mirror &= ~(1 << pin); - picospi_oe_write(oe_mirror); + bbspi_oe_write(oe_mirror); } static void gpioWrite(int pin, int val) { @@ -32,11 +32,11 @@ static void gpioWrite(int pin, int val) { do_mirror |= 1 << pin; else do_mirror &= ~(1 << pin); - picospi_do_write(do_mirror); + bbspi_do_write(do_mirror); } static int gpioRead(int pin) { - return !!(picospi_di_read() & (1 << pin)); + return !!(bbspi_di_read() & (1 << pin)); } #define SPI_ONLY_SINGLE diff --git a/sw/src/usb-dev.c b/sw/src/usb-dev.c index ddca6d7..9788fe8 100644 --- a/sw/src/usb-dev.c +++ b/sw/src/usb-dev.c @@ -2,7 +2,7 @@ #include #include #include - +#include #include #include @@ -10,7 +10,7 @@ static uint8_t reply_buffer[8]; static uint8_t usb_configuration = 0; #define USB_MAX_PACKET_SIZE 64 -static uint8_t rx_buffer[USB_MAX_PACKET_SIZE]; +static uint32_t rx_buffer[USB_MAX_PACKET_SIZE/4]; void usb_setup(struct usb_device *dev, const struct usb_setup_request *setup) { @@ -167,22 +167,39 @@ void usb_setup(struct usb_device *dev, const struct usb_setup_request *setup) int bytes_remaining = setup->wLength; int ep0_rx_offset = 0; while (bytes_remaining > 0) { + // Fill the buffer, or if there is enough space transfer the whole packet. unsigned int len = setup->wLength; if (len > sizeof(rx_buffer)) len = sizeof(rx_buffer); + unsigned int i; + for (i = 0; i < sizeof(rx_buffer)/4; i++) + rx_buffer[i] = 0xffffffff; // Receive DATA packets (which are automatically ACKed) - usb_recv(dev, rx_buffer, len); + len = usb_recv(dev, (void *)rx_buffer, len); // Append the data to the download buffer. - dfu_download(setup->wValue, setup->wLength, ep0_rx_offset, len, rx_buffer); + dfu_download(setup->wValue, setup->wLength, ep0_rx_offset, len, (void *)rx_buffer); bytes_remaining -= len; ep0_rx_offset += len; } return; + case 0x0021: // DFU_DETACH + // Send the "ACK" packet and wait for it + // to be received. + usb_ack(dev, 0); + usb_wait_for_send_done(dev); + usb_disconnect(); + + // Issue a reboot + reboot_to_image(1); + while (1) + ; + return; + case 0x03a1: // DFU_GETSTATUS if (setup->wIndex > 0) { diff --git a/sw/src/usb-epfifo.c b/sw/src/usb-epfifo.c index 61823e9..4d1af1a 100644 --- a/sw/src/usb-epfifo.c +++ b/sw/src/usb-epfifo.c @@ -4,6 +4,7 @@ #include #include #include +#include #ifdef CSR_USB_EP_0_OUT_EV_PENDING_ADDR @@ -39,6 +40,10 @@ enum epfifo_response { #define USB_EV_ERROR 1 #define USB_EV_PACKET 2 +void usb_disconnect(void) { + usb_pullup_out_write(0); +} + void usb_connect(void) { usb_ep_0_out_ev_pending_write(usb_ep_0_out_ev_enable_read()); @@ -56,6 +61,7 @@ void usb_connect(void) { } void usb_init(void) { + usb_pullup_out_write(0); return; } @@ -115,6 +121,14 @@ int usb_send(struct usb_device *dev, int epnum, const void *data, int total_coun return 0; } +int usb_wait_for_send_done(struct usb_device *dev) { + while (current_data && current_length) + usb_poll(dev); + while (usb_ep_0_in_respond_read() == EPF_ACK) + ; + return 0; +} + void usb_isr(void) { irq_count++; uint8_t ep0o_pending = usb_ep_0_out_ev_pending_read(); @@ -133,7 +147,7 @@ void usb_isr(void) { usb_ep_0_out_obuf_head_write(0); } usb_ep_0_out_ev_pending_write(ep0o_pending); - usb_ep0out_buffer_len[usb_ep0out_wr_ptr] = byte_count; + usb_ep0out_buffer_len[usb_ep0out_wr_ptr] = byte_count - 2 /* Strip off CRC16 */; usb_ep0out_wr_ptr = (usb_ep0out_wr_ptr + 1) & (EP0OUT_BUFFERS-1); if (last_tok == USB_PID_SETUP) { @@ -154,6 +168,7 @@ void usb_isr(void) { usb_ep_0_in_respond_write(EPF_NAK); } + return; } @@ -214,7 +229,8 @@ int usb_recv(struct usb_device *dev, void *buffer, unsigned int buffer_len) { return 0; } -void usb_poll(void) { +void usb_poll(struct usb_device *dev) { + (void)dev; // If some data was received, then process it. if (usb_ep0out_rd_ptr != usb_ep0out_wr_ptr) { const struct usb_setup_request *request = (const struct usb_setup_request *)(usb_ep0out_buffer[usb_ep0out_rd_ptr]); diff --git a/sw/third_party/libbase/uart.c b/sw/third_party/libbase/uart.c index eda088a..f14b300 100644 --- a/sw/third_party/libbase/uart.c +++ b/sw/third_party/libbase/uart.c @@ -3,6 +3,7 @@ #include #include +#ifdef CSR_UART_BASE /* * Buffer sizes must be a power of 2 so that modulos can be computed * with logical AND. @@ -108,3 +109,7 @@ void uart_sync(void) { while(tx_consume != tx_produce); } +#else /* !CSR_UART_BASE */ +void uart_init(void) {} +void uart_isr(void) {} +#endif \ No newline at end of file