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 <sean@xobs.io>
This commit is contained in:
20
sw/src/dfu.c
20
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
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
#include <uart.h>
|
||||
#include <usb.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "spi.h"
|
||||
#include <dfu.h>
|
||||
#include <spi.h>
|
||||
#include <generated/csr.h>
|
||||
|
||||
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;
|
||||
}
|
@ -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
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <unistd.h>
|
||||
#include <usb.h>
|
||||
#include <dfu.h>
|
||||
|
||||
#include <system.h>
|
||||
#include <printf.h>
|
||||
|
||||
#include <usb-desc.h>
|
||||
@ -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)
|
||||
{
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
#include <printf.h>
|
||||
#include <uart.h>
|
||||
#include <usb.h>
|
||||
|
||||
#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]);
|
||||
|
Reference in New Issue
Block a user