]> git.donarmstrong.com Git - kiibohd-controller.git/blobdiff - Bootloader/dfu.c
Adding initial dfu-upload code and debugging for Bootloader.
[kiibohd-controller.git] / Bootloader / dfu.c
index 8a4aa7d2db6abe0c40df5d723ceacc794a56166b..e238ac3c00a637ec874f97093b97a7fbb30d6b89 100644 (file)
@@ -1,5 +1,5 @@
 /* Copyright (c) 2011,2012 Simon Schubert <2@0x2c.org>.
- * Modifications by Jacob Alexander 2014 <haata@kiibohd.com>
+ * Modifications by Jacob Alexander 2014-2015 <haata@kiibohd.com>
  *
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -19,6 +19,7 @@
 
 #include "usb.h"
 #include "dfu.h"
+#include "debug.h"
 
 
 
@@ -68,7 +69,8 @@ static int dfu_handle_control( struct usb_ctrl_req_t *req, void *data )
        struct dfu_ctx *ctx = data;
        int fail = 1;
 
-       switch ((enum dfu_ctrl_req_code)req->bRequest) {
+       switch ((enum dfu_ctrl_req_code)req->bRequest)
+       {
        case USB_CTRL_REQ_DFU_DNLOAD: {
                void *buf;
 
@@ -98,12 +100,92 @@ static int dfu_handle_control( struct usb_ctrl_req_t *req, void *data )
                        dfu_dnload_complete(NULL, 0, ctx);
                goto out_no_status;
        }
+       case USB_CTRL_REQ_DFU_UPLOAD: {
+               void *buf;
+               size_t len = 0;
+
+               switch ( ctx->state )
+               {
+               case DFU_STATE_dfuIDLE:
+                       break;
+               case DFU_STATE_dfuUPLOAD_IDLE:
+                       break;
+               default:
+                       goto err;
+               }
+
+               // Find which sector to read
+               ctx->status = ctx->setup_read(ctx->off, &len, &buf);
+               print("UPLOAD off:");
+               printHex( ctx->off );
+               print(" len:");
+               printHex( len );
+               print(" addr:");
+               printHex( (uint32_t)buf );
+               print( NL );
+
+               if ( ctx->status != DFU_STATUS_OK || len > req->wLength )
+               {
+                       ctx->state = DFU_STATE_dfuERROR;
+                       goto err_have_status;
+               }
+
+               // Send bytes to Host
+               if ( len > 0 )
+               {
+                       usb_ep0_rx( buf, len, NULL, NULL );
+               }
+               else
+               {
+                       ctx->state = DFU_STATE_dfuIDLE;
+               }
+
+               goto out_no_status;
+       }
        case USB_CTRL_REQ_DFU_GETSTATUS: {
                struct dfu_status_t st;
 
                st.bState = ctx->state;
                st.bStatus = ctx->status;
                st.bwPollTimeout = 1000; /* XXX */
+
+               // XXX FAKE WRITE
+               if ( ctx->state == DFU_STATE_dfuMANIFEST )
+               {
+                       uint8_t data[] = { 0x10, 0x20, 0x30, 0x40 };
+                       flash_program_longword((uintptr_t)&_app_rom, data);
+               }
+               /*
+
+                       uint32_t *position = &_app_rom + 0x100;
+               for ( ; position < &_app_rom + 0x200; position++ )
+               //for ( ; position < &_app_rom + 0x800; position++ )
+               {
+                       if ( *position != 0xFFFFFFFF )
+                       {
+                       while( 1 )
+                       {
+                               GPIOA_PTOR |= (1<<5);
+                               for (uint32_t d = 0; d < 7200000; d++ );
+                       }
+                       }
+               }*/
+
+               // Check to see if vector table was flashed correctly
+               // Return a flash error if it was not
+               if (_app_rom == 0xffffffff && ctx->state == DFU_STATE_dfuMANIFEST)
+                       st.bStatus = DFU_STATUS_errPROG;
+               //}
+               /*
+               if (ctx->state == DFU_STATE_dfuMANIFEST)
+               {
+                       uint8_t *addr = (uint8_t*)_app_rom;
+                       //while (*(addr++) != 0x80);
+                       //st.bStatus = DFU_STATUS_errPROG;
+                       st.bStatus = (uint8_t)((uint32_t)(&_app_rom) >> 16);
+               }
+               */
+
                /**
                 * If we're in DFU_STATE_dfuMANIFEST, we just finished
                 * the download, and we're just about to send our last
@@ -131,14 +213,13 @@ static int dfu_handle_control( struct usb_ctrl_req_t *req, void *data )
                switch (ctx->state) {
                case DFU_STATE_dfuIDLE:
                case DFU_STATE_dfuDNLOAD_IDLE:
-               /* case DFU_STATE_dfuUPLOAD_IDLE: */
+               case DFU_STATE_dfuUPLOAD_IDLE:
                        ctx->state = DFU_STATE_dfuIDLE;
                        break;
                default:
                        goto err;
                }
                break;
-       /* case USB_CTRL_REQ_DFU_UPLOAD: */
        default:
                return (0);
        }
@@ -156,9 +237,10 @@ out_no_status:
        return (1);
 }
 
-void dfu_init( dfu_setup_write_t setup_write, dfu_finish_write_t finish_write, struct dfu_ctx *ctx )
+void dfu_init( dfu_setup_read_t setup_read, dfu_setup_write_t setup_write, dfu_finish_write_t finish_write, struct dfu_ctx *ctx )
 {
        ctx->state = DFU_STATE_dfuIDLE;
+       ctx->setup_read = setup_read;
        ctx->setup_write = setup_write;
        ctx->finish_write = finish_write;
        usb_attach_function(&dfu_function, &ctx->header);