diff --git a/bootloader/bootloader-usb.c b/bootloader/bootloader-usb.c index a1e85ffef8e2850641cf80b5e8af1228ab5691e5..9ee893e236246e70ef00983572ad108972e03998 100644 --- a/bootloader/bootloader-usb.c +++ b/bootloader/bootloader-usb.c @@ -54,8 +54,8 @@ #include "card10.h" /***** Definitions *****/ -#define EVENT_ENUM_COMP MAXUSB_NUM_EVENTS -#define EVENT_REMOTE_WAKE (EVENT_ENUM_COMP + 1) +#define EVENT_ENUM_COMP MAXUSB_NUM_EVENTS +#define EVENT_REMOTE_WAKE (EVENT_ENUM_COMP + 1) /***** Global Data *****/ volatile int configured; @@ -75,252 +75,256 @@ static void usb_app_wakeup(void); /* This EP assignment must match the Configuration Descriptor */ static const msc_cfg_t msc_cfg = { - 1, /* EP OUT */ - MXC_USBHS_MAX_PACKET, /* OUT max packet size */ - 2, /* EP IN */ - MXC_USBHS_MAX_PACKET, /* IN max packet size */ + 1, /* EP OUT */ + MXC_USBHS_MAX_PACKET, /* OUT max packet size */ + 2, /* EP IN */ + MXC_USBHS_MAX_PACKET, /* IN max packet size */ }; static const msc_idstrings_t ids = { - "MAXIM", /* Vendor string. Maximum of 8 bytes */ - "MSC Example", /* Product string. Maximum of 16 bytes */ - "1.0" /* Version string. Maximum of 4 bytes */ + "MAXIM", /* Vendor string. Maximum of 8 bytes */ + "MSC Example", /* Product string. Maximum of 16 bytes */ + "1.0" /* Version string. Maximum of 4 bytes */ }; /* Functions to control "disk" memory. See msc.h for definitions. */ static const msc_mem_t mem = { - mscmem_init, - mscmem_start, - mscmem_stop, - mscmem_ready, - mscmem_size, - mscmem_read, - mscmem_write, + mscmem_init, mscmem_start, mscmem_stop, mscmem_ready, + mscmem_size, mscmem_read, mscmem_write, }; /* This callback is used to allow the driver to call part specific initialization functions. */ int usb_startup_cb() { - const sys_cfg_usbhs_t sys_usbhs_cfg = NULL; - return SYS_USBHS_Init(&sys_usbhs_cfg); + const sys_cfg_usbhs_t sys_usbhs_cfg = NULL; + return SYS_USBHS_Init(&sys_usbhs_cfg); } int usb_shutdown_cb() { - return SYS_USBHS_Shutdown(); + return SYS_USBHS_Shutdown(); } /* User-supplied function to delay usec micro-seconds */ void delay_us(unsigned int usec) { - /* mxc_delay() takes unsigned long, so can't use it directly */ - mxc_delay(usec); + /* mxc_delay() takes unsigned long, so can't use it directly */ + mxc_delay(usec); } - /******************************************************************************/ void run_usbmsc(void) { - maxusb_cfg_options_t usb_opts; - - printf("Waiting for VBUS...\n"); - - /* Initialize state */ - configured = 0; - suspended = 0; - event_flags = 0; - remote_wake_en = 0; - - /* Start out in full speed */ - usb_opts.enable_hs = 0; - usb_opts.delay_us = delay_us; /* Function which will be used for delays */ - usb_opts.init_callback = usb_startup_cb; - usb_opts.shutdown_callback = usb_shutdown_cb; - - /* Initialize the usb module */ - if (usb_init(&usb_opts) != 0) { - printf("usb_init() failed\n"); - while (1); - } - - /* Initialize the enumeration module */ - if (enum_init() != 0) { - printf("enum_init() failed\n"); - while (1); - } - - /* Register enumeration data */ - enum_register_descriptor(ENUM_DESC_DEVICE, (uint8_t*)&device_descriptor, 0); - enum_register_descriptor(ENUM_DESC_CONFIG, (uint8_t*)&config_descriptor, 0); - enum_register_descriptor(ENUM_DESC_STRING, lang_id_desc, 0); - enum_register_descriptor(ENUM_DESC_STRING, mfg_id_desc, 1); - enum_register_descriptor(ENUM_DESC_STRING, prod_id_desc, 2); - enum_register_descriptor(ENUM_DESC_STRING, serial_id_desc, 3); - - /* Handle configuration */ - enum_register_callback(ENUM_SETCONFIG, setconfig_callback, NULL); - - /* Handle feature set/clear */ - enum_register_callback(ENUM_SETFEATURE, setfeature_callback, NULL); - enum_register_callback(ENUM_CLRFEATURE, clrfeature_callback, NULL); - - /* Initialize the class driver */ - if (msc_init(&config_descriptor.msc_interface_descriptor, &ids, &mem) != 0) { - printf("msc_init() failed\n"); - while (1); - } - - /* Register callbacks */ - usb_event_enable(MAXUSB_EVENT_NOVBUS, event_callback, NULL); - usb_event_enable(MAXUSB_EVENT_VBUS, event_callback, NULL); - - /* Start with USB in low power mode */ - usb_app_sleep(); - NVIC_EnableIRQ(USB_IRQn); - - /* Wait for events */ - while (1) { - - if (suspended || !configured) { - //LED_Off(0); - } else { - //LED_On(0); - } - - if (event_flags) { - /* Display events */ - if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_NOVBUS)) { - MXC_CLRBIT(&event_flags, MAXUSB_EVENT_NOVBUS); - printf("VBUS Disconnect\n"); - } else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_VBUS)) { - MXC_CLRBIT(&event_flags, MAXUSB_EVENT_VBUS); - printf("VBUS Connect\n"); - } else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_BRST)) { - MXC_CLRBIT(&event_flags, MAXUSB_EVENT_BRST); - printf("Bus Reset\n"); - } else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_SUSP)) { - MXC_CLRBIT(&event_flags, MAXUSB_EVENT_SUSP); - printf("Suspended\n"); - } else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_DPACT)) { - MXC_CLRBIT(&event_flags, MAXUSB_EVENT_DPACT); - printf("Resume\n"); - } else if (MXC_GETBIT(&event_flags, EVENT_ENUM_COMP)) { - MXC_CLRBIT(&event_flags, EVENT_ENUM_COMP); - printf("Enumeration complete.\n"); - } else if (MXC_GETBIT(&event_flags, EVENT_REMOTE_WAKE)) { - MXC_CLRBIT(&event_flags, EVENT_REMOTE_WAKE); - printf("Remote Wakeup\n"); - } - } - - card10_poll(); - } + maxusb_cfg_options_t usb_opts; + + printf("Waiting for VBUS...\n"); + + /* Initialize state */ + configured = 0; + suspended = 0; + event_flags = 0; + remote_wake_en = 0; + + /* Start out in full speed */ + usb_opts.enable_hs = 0; + usb_opts.delay_us = + delay_us; /* Function which will be used for delays */ + usb_opts.init_callback = usb_startup_cb; + usb_opts.shutdown_callback = usb_shutdown_cb; + + /* Initialize the usb module */ + if (usb_init(&usb_opts) != 0) { + printf("usb_init() failed\n"); + while (1) + ; + } + + /* Initialize the enumeration module */ + if (enum_init() != 0) { + printf("enum_init() failed\n"); + while (1) + ; + } + + /* Register enumeration data */ + enum_register_descriptor( + ENUM_DESC_DEVICE, (uint8_t *)&device_descriptor, 0 + ); + enum_register_descriptor( + ENUM_DESC_CONFIG, (uint8_t *)&config_descriptor, 0 + ); + enum_register_descriptor(ENUM_DESC_STRING, lang_id_desc, 0); + enum_register_descriptor(ENUM_DESC_STRING, mfg_id_desc, 1); + enum_register_descriptor(ENUM_DESC_STRING, prod_id_desc, 2); + enum_register_descriptor(ENUM_DESC_STRING, serial_id_desc, 3); + + /* Handle configuration */ + enum_register_callback(ENUM_SETCONFIG, setconfig_callback, NULL); + + /* Handle feature set/clear */ + enum_register_callback(ENUM_SETFEATURE, setfeature_callback, NULL); + enum_register_callback(ENUM_CLRFEATURE, clrfeature_callback, NULL); + + /* Initialize the class driver */ + if (msc_init(&config_descriptor.msc_interface_descriptor, &ids, &mem) != + 0) { + printf("msc_init() failed\n"); + while (1) + ; + } + + /* Register callbacks */ + usb_event_enable(MAXUSB_EVENT_NOVBUS, event_callback, NULL); + usb_event_enable(MAXUSB_EVENT_VBUS, event_callback, NULL); + + /* Start with USB in low power mode */ + usb_app_sleep(); + NVIC_EnableIRQ(USB_IRQn); + + /* Wait for events */ + while (1) { + if (suspended || !configured) { + //LED_Off(0); + } else { + //LED_On(0); + } + + if (event_flags) { + /* Display events */ + if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_NOVBUS)) { + MXC_CLRBIT(&event_flags, MAXUSB_EVENT_NOVBUS); + printf("VBUS Disconnect\n"); + } else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_VBUS)) { + MXC_CLRBIT(&event_flags, MAXUSB_EVENT_VBUS); + printf("VBUS Connect\n"); + } else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_BRST)) { + MXC_CLRBIT(&event_flags, MAXUSB_EVENT_BRST); + printf("Bus Reset\n"); + } else if (MXC_GETBIT(&event_flags, MAXUSB_EVENT_SUSP)) { + MXC_CLRBIT(&event_flags, MAXUSB_EVENT_SUSP); + printf("Suspended\n"); + } else if (MXC_GETBIT( + &event_flags, MAXUSB_EVENT_DPACT)) { + MXC_CLRBIT(&event_flags, MAXUSB_EVENT_DPACT); + printf("Resume\n"); + } else if (MXC_GETBIT(&event_flags, EVENT_ENUM_COMP)) { + MXC_CLRBIT(&event_flags, EVENT_ENUM_COMP); + printf("Enumeration complete.\n"); + } else if (MXC_GETBIT(&event_flags, EVENT_REMOTE_WAKE)) { + MXC_CLRBIT(&event_flags, EVENT_REMOTE_WAKE); + printf("Remote Wakeup\n"); + } + } + + card10_poll(); + } } /******************************************************************************/ static int setconfig_callback(usb_setup_pkt *sud, void *cbdata) { - /* Confirm the configuration value */ - if (sud->wValue == config_descriptor.config_descriptor.bConfigurationValue) { - configured = 1; - MXC_SETBIT(&event_flags, EVENT_ENUM_COMP); - return msc_configure(&msc_cfg); /* Configure the device class */ - } else if (sud->wValue == 0) { - configured = 0; - return msc_deconfigure(); - } - - return -1; + /* Confirm the configuration value */ + if (sud->wValue == + config_descriptor.config_descriptor.bConfigurationValue) { + configured = 1; + MXC_SETBIT(&event_flags, EVENT_ENUM_COMP); + return msc_configure(&msc_cfg); /* Configure the device class */ + } else if (sud->wValue == 0) { + configured = 0; + return msc_deconfigure(); + } + + return -1; } /******************************************************************************/ static int setfeature_callback(usb_setup_pkt *sud, void *cbdata) { - if(sud->wValue == FEAT_REMOTE_WAKE) { - remote_wake_en = 1; - } else { - // Unknown callback - return -1; - } - - return 0; + if (sud->wValue == FEAT_REMOTE_WAKE) { + remote_wake_en = 1; + } else { + // Unknown callback + return -1; + } + + return 0; } /******************************************************************************/ static int clrfeature_callback(usb_setup_pkt *sud, void *cbdata) { - if(sud->wValue == FEAT_REMOTE_WAKE) { - remote_wake_en = 0; - } else { - // Unknown callback - return -1; - } - - return 0; + if (sud->wValue == FEAT_REMOTE_WAKE) { + remote_wake_en = 0; + } else { + // Unknown callback + return -1; + } + + return 0; } /******************************************************************************/ static void usb_app_sleep(void) { - /* TODO: Place low-power code here */ - suspended = 1; + /* TODO: Place low-power code here */ + suspended = 1; } /******************************************************************************/ static void usb_app_wakeup(void) { - /* TODO: Place low-power code here */ - suspended = 0; + /* TODO: Place low-power code here */ + suspended = 0; } /******************************************************************************/ static int event_callback(maxusb_event_t evt, void *data) { - /* Set event flag */ - MXC_SETBIT(&event_flags, evt); - - printf("event: %d\n", evt); - switch (evt) { - case MAXUSB_EVENT_NOVBUS: - usb_event_disable(MAXUSB_EVENT_BRST); - usb_event_disable(MAXUSB_EVENT_SUSP); - usb_event_disable(MAXUSB_EVENT_DPACT); - usb_disconnect(); - configured = 0; - enum_clearconfig(); - msc_deconfigure(); - usb_app_sleep(); - break; - case MAXUSB_EVENT_VBUS: - usb_event_clear(MAXUSB_EVENT_BRST); - usb_event_enable(MAXUSB_EVENT_BRST, event_callback, NULL); - usb_event_clear(MAXUSB_EVENT_SUSP); - usb_event_enable(MAXUSB_EVENT_SUSP, event_callback, NULL); - usb_connect(); - usb_app_sleep(); - break; - case MAXUSB_EVENT_BRST: - usb_app_wakeup(); - enum_clearconfig(); - msc_deconfigure(); - configured = 0; - suspended = 0; - break; - case MAXUSB_EVENT_SUSP: - usb_app_sleep(); - break; - case MAXUSB_EVENT_DPACT: - usb_app_wakeup(); - break; - default: - break; - } - - return 0; + /* Set event flag */ + MXC_SETBIT(&event_flags, evt); + + printf("event: %d\n", evt); + switch (evt) { + case MAXUSB_EVENT_NOVBUS: + usb_event_disable(MAXUSB_EVENT_BRST); + usb_event_disable(MAXUSB_EVENT_SUSP); + usb_event_disable(MAXUSB_EVENT_DPACT); + usb_disconnect(); + configured = 0; + enum_clearconfig(); + msc_deconfigure(); + usb_app_sleep(); + break; + case MAXUSB_EVENT_VBUS: + usb_event_clear(MAXUSB_EVENT_BRST); + usb_event_enable(MAXUSB_EVENT_BRST, event_callback, NULL); + usb_event_clear(MAXUSB_EVENT_SUSP); + usb_event_enable(MAXUSB_EVENT_SUSP, event_callback, NULL); + usb_connect(); + usb_app_sleep(); + break; + case MAXUSB_EVENT_BRST: + usb_app_wakeup(); + enum_clearconfig(); + msc_deconfigure(); + configured = 0; + suspended = 0; + break; + case MAXUSB_EVENT_SUSP: + usb_app_sleep(); + break; + case MAXUSB_EVENT_DPACT: + usb_app_wakeup(); + break; + default: + break; + } + + return 0; } /******************************************************************************/ void USB_IRQHandler(void) { - usb_event_handler(); + usb_event_handler(); } diff --git a/bootloader/main.c b/bootloader/main.c index 25247fca469c5f57d4c6a1b6f93461abaccb14e8..3bb2ba178fb787db374b0c9da78cf835b5c7e015 100644 --- a/bootloader/main.c +++ b/bootloader/main.c @@ -21,8 +21,8 @@ #include "pmic.h" -#define GPIO_PORT_IN PORT_1 -#define GPIO_PIN_IN PIN_6 +#define GPIO_PORT_IN PORT_1 +#define GPIO_PIN_IN PIN_6 #define PARTITION_START (0x10000000 + 64 * 1024) #define PARTITION_END (0x10000000 + 1024 * 1024 - 1) @@ -34,153 +34,176 @@ FATFS FatFs; bool mount(void) { - FRESULT res; - res=f_mount(&FatFs,"/",0); - if(res != FR_OK) { - printf("f_mount error %d\n", res); - return false; - } - - res = f_opendir(&dir, "0:"); - if(res != FR_OK) { - printf("f_opendir error %d\n", res); - return false; - } - - return true; + FRESULT res; + res = f_mount(&FatFs, "/", 0); + if (res != FR_OK) { + printf("f_mount error %d\n", res); + return false; + } + + res = f_opendir(&dir, "0:"); + if (res != FR_OK) { + printf("f_opendir error %d\n", res); + return false; + } + + return true; } bool check_integrity(void) { - FIL file; - UINT readbytes; - char *filename = "card10.bin"; - uint8_t data[512]; - FRESULT res; - - res=f_open(&file, filename, FA_OPEN_EXISTING|FA_READ); - if(res != FR_OK) { - Paint_DrawString_EN(0, 16*2, "card10.bin not found", &Font16, 0x0000, 0xffff); - LCD_Update(); - - printf("f_open error %d\n", res); - return false; - } - - uint16_t crcval = 0; - do { - res = f_read(&file, data, sizeof(data), &readbytes); - if(res != FR_OK) { - printf("f_read error %d\n", res); - crcval = 1; // Make sure to fail the test - break; - } - crcval = crc16_ccitt(crcval, data, readbytes); - } while (readbytes == sizeof(data)); - - f_close(&file); - - if(crcval == 0) { - return true; - } else { - Paint_DrawString_EN(0, 16*2, "Integrity check failed", &Font16, 0x0000, 0xffff); - LCD_Update(); - printf("CRC check failed. Final CRC: %d\n", crcval); - return false; - } + FIL file; + UINT readbytes; + char *filename = "card10.bin"; + uint8_t data[512]; + FRESULT res; + + res = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ); + if (res != FR_OK) { + Paint_DrawString_EN( + 0, + 16 * 2, + "card10.bin not found", + &Font16, + 0x0000, + 0xffff + ); + LCD_Update(); + + printf("f_open error %d\n", res); + return false; + } + + uint16_t crcval = 0; + do { + res = f_read(&file, data, sizeof(data), &readbytes); + if (res != FR_OK) { + printf("f_read error %d\n", res); + crcval = 1; // Make sure to fail the test + break; + } + crcval = crc16_ccitt(crcval, data, readbytes); + } while (readbytes == sizeof(data)); + + f_close(&file); + + if (crcval == 0) { + return true; + } else { + Paint_DrawString_EN( + 0, + 16 * 2, + "Integrity check failed", + &Font16, + 0x0000, + 0xffff + ); + LCD_Update(); + printf("CRC check failed. Final CRC: %d\n", crcval); + return false; + } } bool is_update_needed(void) { - FIL file; - UINT readbytes; - char *filename = "card10.bin"; - uint8_t data[512]; - FRESULT res; - - res=f_open(&file, filename, FA_OPEN_EXISTING|FA_READ); - if(res != FR_OK) { - printf("f_open error %d\n", res); - return false; - } - - uint8_t *partition = (uint8_t *)(intptr_t)PARTITION_START; - bool different = false; - do { - res = f_read(&file, data, sizeof(data), &readbytes); - if(res != FR_OK) { - printf("f_read error %d\n", res); - break; /* Going to return false, don't want to use this file */ - } - if(memcmp(partition, data, readbytes)) { - different = true; - break; - } - partition += readbytes; - } while (readbytes == sizeof(data)); - - f_close(&file); - - return different; + FIL file; + UINT readbytes; + char *filename = "card10.bin"; + uint8_t data[512]; + FRESULT res; + + res = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ); + if (res != FR_OK) { + printf("f_open error %d\n", res); + return false; + } + + uint8_t *partition = (uint8_t *)(intptr_t)PARTITION_START; + bool different = false; + do { + res = f_read(&file, data, sizeof(data), &readbytes); + if (res != FR_OK) { + printf("f_read error %d\n", res); + break; /* Going to return false, don't want to use this file */ + } + if (memcmp(partition, data, readbytes)) { + different = true; + break; + } + partition += readbytes; + } while (readbytes == sizeof(data)); + + f_close(&file); + + return different; } void erase_partition(void) { - int ret = FLC_MultiPageErase(PARTITION_START, PARTITION_END); - if(ret != E_NO_ERROR) { - printf("FLC_MultiPageErase failed with %d\n", ret); - while(1); - } + int ret = FLC_MultiPageErase(PARTITION_START, PARTITION_END); + if (ret != E_NO_ERROR) { + printf("FLC_MultiPageErase failed with %d\n", ret); + while (1) + ; + } } void flash_partition(void) { - FIL file; - UINT readbytes; - char *filename = "card10.bin"; - uint8_t data[512]; - FRESULT res; - - res=f_open(&file, filename, FA_OPEN_EXISTING|FA_READ); - if(res != FR_OK) { - printf("f_open error %d\n", res); - while(1); - } - - uint32_t partition = PARTITION_START; - - ICC_Disable(); - do { - res = f_read(&file, data, sizeof(data), &readbytes); - if(res != FR_OK) { - printf("f_read error %d\n", res); - break; /* Going to return false, don't want to use this file */ - } - int ret = FLC_Write(partition, readbytes, (uint32_t *)data); /* wild cast. not sure if this works */ - if(ret != E_NO_ERROR) { - printf("FLC_Write failed with %d\n", ret); - while(1); - } - partition += readbytes; - } while (readbytes == sizeof(data)); - ICC_Enable(); - - f_close(&file); + FIL file; + UINT readbytes; + char *filename = "card10.bin"; + uint8_t data[512]; + FRESULT res; + + res = f_open(&file, filename, FA_OPEN_EXISTING | FA_READ); + if (res != FR_OK) { + printf("f_open error %d\n", res); + while (1) + ; + } + + uint32_t partition = PARTITION_START; + + ICC_Disable(); + do { + res = f_read(&file, data, sizeof(data), &readbytes); + if (res != FR_OK) { + printf("f_read error %d\n", res); + break; /* Going to return false, don't want to use this file */ + } + int ret = FLC_Write( + partition, + readbytes, + (uint32_t * + ) + data); /* wild cast. not sure if this works */ + if (ret != E_NO_ERROR) { + printf("FLC_Write failed with %d\n", ret); + while (1) + ; + } + partition += readbytes; + } while (readbytes == sizeof(data)); + ICC_Enable(); + + f_close(&file); } -static inline void boot(const void * vtable){ - SCB->VTOR = (uintptr_t) vtable; +static inline void boot(const void *vtable) +{ + SCB->VTOR = (uintptr_t)vtable; // Reset stack pointer & branch to the new reset vector. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdeprecated" - __asm( "mov r0, %0\n" - "ldr sp, [r0]\n" - "ldr r0, [r0, #4]\n" - "bx r0\n" - : - : "r"(vtable) - : "%sp", "r0"); + __asm("mov r0, %0\n" + "ldr sp, [r0]\n" + "ldr r0, [r0, #4]\n" + "bx r0\n" + : + : "r"(vtable) + : "%sp", "r0"); #pragma GCC diagnostic pop }; @@ -202,64 +225,87 @@ static void pmic_button(bool falling) /******************************************************************************/ int main(void) { - printf("\n\nBootloader\n"); - card10_init(); - - pmic_set_button_callback(pmic_button); - - Paint_DrawString_EN(0, 16*0, "Bootloader", &Font16, 0x0000, 0xffff); - Paint_DrawString_EN(0, 16*1, __DATE__, &Font16, 0x0000, 0xffff); - - LCD_Update(); - - // If the button is pressed, we go into MSC mode. - if (PB_Get(3)) { - Paint_DrawString_EN(0, 16*2, "USB activated. Waiting.", &Font16, 0x0000, 0xffff); - LCD_Update(); - run_usbmsc(); - - // If we return, don't try to boot. Maybe rather trigger a software reset. - // Reason: Not sure in which state the USB peripheral is and what kind - // of interrupts are active. - while(1); - } - - if(mount()) { - if(check_integrity()) { - printf("Found valid application image\n"); - if(is_update_needed()) { - printf("Trying to update application from external flash\n"); - Paint_DrawString_EN(0, 16*4, "Updating...", &Font16, 0x0000, 0xffff); - LCD_Update(); - erase_partition(); - flash_partition(); - } else { - printf("No update needed\n"); - } - } else { - printf("Integrity check failed\n"); - } - } else { - Paint_DrawString_EN(0, 16*2, "Failed to mount file system", &Font16, 0x0000, 0xffff); - LCD_Update(); - printf("Failed to mount the external flash\n"); - } - - - printf("Trying to boot\n"); - Paint_DrawString_EN(0, 16*4, "Trying to boot", &Font16, 0x0000, 0xffff); - LCD_Update(); - //while(1); - // boot partition - boot((uintptr_t *) PARTITION_START); - - while (1) { - // Should never be reached. - } + printf("\n\nBootloader\n"); + card10_init(); + + pmic_set_button_callback(pmic_button); + + Paint_DrawString_EN(0, 16 * 0, "Bootloader", &Font16, 0x0000, 0xffff); + Paint_DrawString_EN(0, 16 * 1, __DATE__, &Font16, 0x0000, 0xffff); + + LCD_Update(); + + // If the button is pressed, we go into MSC mode. + if (PB_Get(3)) { + Paint_DrawString_EN( + 0, + 16 * 2, + "USB activated. Waiting.", + &Font16, + 0x0000, + 0xffff + ); + LCD_Update(); + run_usbmsc(); + + // If we return, don't try to boot. Maybe rather trigger a software reset. + // Reason: Not sure in which state the USB peripheral is and what kind + // of interrupts are active. + while (1) + ; + } + + if (mount()) { + if (check_integrity()) { + printf("Found valid application image\n"); + if (is_update_needed()) { + printf("Trying to update application from external flash\n"); + Paint_DrawString_EN( + 0, + 16 * 4, + "Updating...", + &Font16, + 0x0000, + 0xffff + ); + LCD_Update(); + erase_partition(); + flash_partition(); + } else { + printf("No update needed\n"); + } + } else { + printf("Integrity check failed\n"); + } + } else { + Paint_DrawString_EN( + 0, + 16 * 2, + "Failed to mount file system", + &Font16, + 0x0000, + 0xffff + ); + LCD_Update(); + printf("Failed to mount the external flash\n"); + } + + printf("Trying to boot\n"); + Paint_DrawString_EN( + 0, 16 * 4, "Trying to boot", &Font16, 0x0000, 0xffff + ); + LCD_Update(); + //while(1); + // boot partition + boot((uintptr_t *)PARTITION_START); + + while (1) { + // Should never be reached. + } } /******************************************************************************/ void SysTick_Handler(void) { - mxc_delay_handler(); + mxc_delay_handler(); } diff --git a/bootloader/mscmem.c b/bootloader/mscmem.c index d1764817487883f2072a28c027b9f0f31f41899d..8e2febd8da19c6d004c394fe1cbc9134fa477fc6 100644 --- a/bootloader/mscmem.c +++ b/bootloader/mscmem.c @@ -6,47 +6,47 @@ /******************************************************************************/ int mscmem_init() { - printf("%s\n", __func__); + printf("%s\n", __func__); return mx25_init(); } /******************************************************************************/ uint32_t mscmem_size(void) { - printf("%s\n", __func__); + printf("%s\n", __func__); return mx25_size(); } /******************************************************************************/ -int mscmem_read(uint32_t lba, uint8_t* buffer) +int mscmem_read(uint32_t lba, uint8_t *buffer) { - //printf("%s\n", __func__); + //printf("%s\n", __func__); return mx25_read(lba, buffer); } /******************************************************************************/ -int mscmem_write(uint32_t lba, uint8_t* buffer) +int mscmem_write(uint32_t lba, uint8_t *buffer) { - //printf("%s\n", __func__); - return mx25_write(lba, buffer); + //printf("%s\n", __func__); + return mx25_write(lba, buffer); } /******************************************************************************/ int mscmem_start() { - printf("%s\n", __func__); - return mx25_start(); + printf("%s\n", __func__); + return mx25_start(); } /******************************************************************************/ int mscmem_stop() { - printf("%s\n", __func__); - return mx25_stop(); + printf("%s\n", __func__); + return mx25_stop(); } /******************************************************************************/ int mscmem_ready() { - //printf("%s\n", __func__); - return mx25_ready(); + //printf("%s\n", __func__); + return mx25_ready(); } diff --git a/lib/card10/card10.c b/lib/card10/card10.c index eaedb136674ad91e3b4ff798f625bc886025ad18..2b3e3a317a043823e1fdb97f527627e522fa7657 100644 --- a/lib/card10/card10.c +++ b/lib/card10/card10.c @@ -28,150 +28,165 @@ * Current suspicion is that the SDK is buggy. * * At 12 MHz things seem stable*/ -#define SPI_SPEED (12 * 1000 * 1000) // Bit Rate. Display has 15 MHz limit +#define SPI_SPEED (12 * 1000 * 1000) // Bit Rate. Display has 15 MHz limit -const gpio_cfg_t bhi_interrupt_pin = {PORT_0, PIN_13, GPIO_FUNC_IN, GPIO_PAD_PULL_UP}; +const gpio_cfg_t bhi_interrupt_pin = { + PORT_0, PIN_13, GPIO_FUNC_IN, GPIO_PAD_PULL_UP +}; void card10_init(void) { - printf("card10 init...\n"); + printf("card10 init...\n"); - //Setup the I2CM - I2C_Shutdown(MXC_I2C0_BUS0); - I2C_Init(MXC_I2C0_BUS0, I2C_FAST_MODE, NULL); + //Setup the I2CM + I2C_Shutdown(MXC_I2C0_BUS0); + I2C_Init(MXC_I2C0_BUS0, I2C_FAST_MODE, NULL); - I2C_Shutdown(MXC_I2C1_BUS0); - I2C_Init(MXC_I2C1_BUS0, I2C_FAST_MODE, NULL); + I2C_Shutdown(MXC_I2C1_BUS0); + I2C_Init(MXC_I2C1_BUS0, I2C_FAST_MODE, NULL); - portexpander_init(); + portexpander_init(); - GPIO_Init(); + GPIO_Init(); - PB_Init(); + PB_Init(); - pmic_init(); - pmic_set_led(0, 0); - pmic_set_led(1, 0); - pmic_set_led(2, 0); - TMR_Delay(MXC_TMR0, MSEC(1000), 0); + pmic_init(); + pmic_set_led(0, 0); + pmic_set_led(1, 0); + pmic_set_led(2, 0); + TMR_Delay(MXC_TMR0, MSEC(1000), 0); - // Enable 32 kHz output - RTC_SquareWave(MXC_RTC, SQUARE_WAVE_ENABLED, F_32KHZ, NOISE_IMMUNE_MODE, NULL); + // Enable 32 kHz output + RTC_SquareWave( + MXC_RTC, SQUARE_WAVE_ENABLED, F_32KHZ, NOISE_IMMUNE_MODE, NULL + ); - // Enable SPI - sys_cfg_spi_t spi17y_master_cfg; + // Enable SPI + sys_cfg_spi_t spi17y_master_cfg; - spi17y_master_cfg.map = MAP_A; - spi17y_master_cfg.ss0 = Enable; - spi17y_master_cfg.ss1 = Disable; - spi17y_master_cfg.ss2 = Disable; + spi17y_master_cfg.map = MAP_A; + spi17y_master_cfg.ss0 = Enable; + spi17y_master_cfg.ss1 = Disable; + spi17y_master_cfg.ss2 = Disable; - if (SPI_Init(SPI0, 0, SPI_SPEED, spi17y_master_cfg) != 0) { - printf("Error configuring SPI\n"); - while (1); - } - - if (SPI_Init(SPI2, 0, SPI_SPEED, spi17y_master_cfg) != 0) { - printf("Error configuring SPI\n"); - while (1); - } + if (SPI_Init(SPI0, 0, SPI_SPEED, spi17y_master_cfg) != 0) { + printf("Error configuring SPI\n"); + while (1) + ; + } - display_init(); + if (SPI_Init(SPI2, 0, SPI_SPEED, spi17y_master_cfg) != 0) { + printf("Error configuring SPI\n"); + while (1) + ; + } - leds_init(); + display_init(); - GPIO_Config(&bhi_interrupt_pin); + leds_init(); + GPIO_Config(&bhi_interrupt_pin); } static uint32_t ecg_read_reg(uint8_t reg) { - spi_req_t req; - uint8_t tx_data[] = {(reg << 1) | 1, 0, 0, 0}; - uint8_t rx_data[] = {0, 0, 0, 0}; - req.tx_data = tx_data; - req.rx_data = rx_data; - req.len = 4; - req.bits = 8; - req.width = SPI17Y_WIDTH_1; - req.ssel = 0; - req.deass = 1; - req.ssel_pol = SPI17Y_POL_LOW; - req.tx_num = 0; - req.rx_num = 0; - - SPI_MasterTrans(SPI0, &req); - - return (rx_data[1] << 16) | (rx_data[2] << 8) | rx_data[3]; + spi_req_t req; + uint8_t tx_data[] = { (reg << 1) | 1, 0, 0, 0 }; + uint8_t rx_data[] = { 0, 0, 0, 0 }; + req.tx_data = tx_data; + req.rx_data = rx_data; + req.len = 4; + req.bits = 8; + req.width = SPI17Y_WIDTH_1; + req.ssel = 0; + req.deass = 1; + req.ssel_pol = SPI17Y_POL_LOW; + req.tx_num = 0; + req.rx_num = 0; + + SPI_MasterTrans(SPI0, &req); + + return (rx_data[1] << 16) | (rx_data[2] << 8) | rx_data[3]; } void card10_diag(void) { - uint8_t dummy[1] = {0}; - // "7-bit addresses 0b0000xxx and 0b1111xxx are reserved" - for (int addr = 0x8; addr < 0x78; ++addr) { - // A 0 byte write does not seem to work so always send a single byte. - int res = I2C_MasterWrite(MXC_I2C0_BUS0, addr << 1, dummy, 1, 0); - if(res == 1) { - printf("Found (7 bit) address 0x%02x on I2C0\n", addr); - } - - res = I2C_MasterWrite(MXC_I2C1_BUS0, addr << 1, dummy, 1, 0); - if(res == 1) { - printf("Found (7 bit) address 0x%02x on I2C1\n", addr); - } - } - - if(bhy_driver_init(bhy1_fw)) { - printf("Failed to init bhy\n"); - } else { - /* wait for the bhy trigger the interrupt pin go down and up again */ - while (GPIO_InGet(&bhi_interrupt_pin)); - while (!GPIO_InGet(&bhi_interrupt_pin)); - - /* the remapping matrix for BHI and Magmetometer should be configured here to make sure rotation vector is */ - /* calculated in a correct coordinates system. */ - int8_t bhy_mapping_matrix_config[3*3] = {0,-1,0,1,0,0,0,0,1}; - int8_t mag_mapping_matrix_config[3*3] = {-1,0,0,0,1,0,0,0,-1}; - bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_ACC, bhy_mapping_matrix_config); - bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_MAG, mag_mapping_matrix_config); - bhy_mapping_matrix_set(PHYSICAL_SENSOR_INDEX_GYRO, bhy_mapping_matrix_config); - - /* the sic matrix should be calculated for customer platform by logging uncalibrated magnetometer data. */ - /* the sic matrix here is only an example array (identity matrix). Customer should generate their own matrix. */ - /* This affects magnetometer fusion performance. */ - float sic_array[9] = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; - bhy_set_sic_matrix(sic_array); - } - - - - struct bme680_dev gas_sensor; - gas_sensor.dev_id = BME680_I2C_ADDR_PRIMARY; - gas_sensor.intf = BME680_I2C_INTF; - gas_sensor.read = card10_bosch_i2c_read; - gas_sensor.write = card10_bosch_i2c_write; - gas_sensor.delay_ms = card10_bosch_delay; - gas_sensor.amb_temp = 25; - - int8_t rslt = BME680_OK; - rslt = bme680_init(&gas_sensor); - if(rslt != BME680_OK) { - printf("Failed to init BME680\n"); - } - - struct bma400_dev bma; - bma.intf_ptr = NULL; /* To attach your interface device reference */ - bma.delay_ms = card10_bosch_delay; - bma.dev_id = BMA400_I2C_ADDRESS_SDO_LOW; - bma.read = card10_bosch_i2c_read_ex; - bma.write = card10_bosch_i2c_write_ex; - bma.intf = BMA400_I2C_INTF; - - rslt = bma400_init(&bma); - if (rslt == BMA400_OK) { - printf("BMA400 found with chip ID 0x%X\r\n", bma.chip_id); - } + uint8_t dummy[1] = { 0 }; + // "7-bit addresses 0b0000xxx and 0b1111xxx are reserved" + for (int addr = 0x8; addr < 0x78; ++addr) { + // A 0 byte write does not seem to work so always send a single byte. + int res = + I2C_MasterWrite(MXC_I2C0_BUS0, addr << 1, dummy, 1, 0); + if (res == 1) { + printf("Found (7 bit) address 0x%02x on I2C0\n", addr); + } + + res = I2C_MasterWrite(MXC_I2C1_BUS0, addr << 1, dummy, 1, 0); + if (res == 1) { + printf("Found (7 bit) address 0x%02x on I2C1\n", addr); + } + } + + if (bhy_driver_init(bhy1_fw)) { + printf("Failed to init bhy\n"); + } else { + /* wait for the bhy trigger the interrupt pin go down and up again */ + while (GPIO_InGet(&bhi_interrupt_pin)) + ; + while (!GPIO_InGet(&bhi_interrupt_pin)) + ; + + /* the remapping matrix for BHI and Magmetometer should be configured here to make sure rotation vector is */ + /* calculated in a correct coordinates system. */ + int8_t bhy_mapping_matrix_config[3 * 3] = { 0, -1, 0, 1, 0, + 0, 0, 0, 1 }; + int8_t mag_mapping_matrix_config[3 * 3] = { -1, 0, 0, 0, 1, + 0, 0, 0, -1 }; + bhy_mapping_matrix_set( + PHYSICAL_SENSOR_INDEX_ACC, bhy_mapping_matrix_config + ); + bhy_mapping_matrix_set( + PHYSICAL_SENSOR_INDEX_MAG, mag_mapping_matrix_config + ); + bhy_mapping_matrix_set( + PHYSICAL_SENSOR_INDEX_GYRO, bhy_mapping_matrix_config + ); + + /* the sic matrix should be calculated for customer platform by logging uncalibrated magnetometer data. */ + /* the sic matrix here is only an example array (identity matrix). Customer should generate their own matrix. */ + /* This affects magnetometer fusion performance. */ + float sic_array[9] = { 1.0, 0.0, 0.0, 0.0, 1.0, + 0.0, 0.0, 0.0, 1.0 }; + bhy_set_sic_matrix(sic_array); + } + + struct bme680_dev gas_sensor; + gas_sensor.dev_id = BME680_I2C_ADDR_PRIMARY; + gas_sensor.intf = BME680_I2C_INTF; + gas_sensor.read = card10_bosch_i2c_read; + gas_sensor.write = card10_bosch_i2c_write; + gas_sensor.delay_ms = card10_bosch_delay; + gas_sensor.amb_temp = 25; + + int8_t rslt = BME680_OK; + rslt = bme680_init(&gas_sensor); + if (rslt != BME680_OK) { + printf("Failed to init BME680\n"); + } + + struct bma400_dev bma; + bma.intf_ptr = NULL; /* To attach your interface device reference */ + bma.delay_ms = card10_bosch_delay; + bma.dev_id = BMA400_I2C_ADDRESS_SDO_LOW; + bma.read = card10_bosch_i2c_read_ex; + bma.write = card10_bosch_i2c_write_ex; + bma.intf = BMA400_I2C_INTF; + + rslt = bma400_init(&bma); + if (rslt == BMA400_OK) { + printf("BMA400 found with chip ID 0x%X\r\n", bma.chip_id); + } #if 0 for(int i=0; i<0x20; i++) { @@ -179,44 +194,44 @@ void card10_diag(void) printf("ECG: %02x: 0x%06x\n", i, val); } #else - uint32_t val = ecg_read_reg(0xf); - printf("ECG: %02x: 0x%06lx (should be 0x5139a0)\n", 0xf, val); + uint32_t val = ecg_read_reg(0xf); + printf("ECG: %02x: 0x%06lx (should be 0x5139a0)\n", 0xf, val); #endif - } -void core1_start(void) { - //MXC_GCR->gp0 = (uint32_t)(&__isr_vector_core1); - MXC_GCR->gp0 = 0x10080000; - MXC_GCR->perckcn1 &= ~MXC_F_GCR_PERCKCN1_CPU1; +void core1_start(void) +{ + //MXC_GCR->gp0 = (uint32_t)(&__isr_vector_core1); + MXC_GCR->gp0 = 0x10080000; + MXC_GCR->perckcn1 &= ~MXC_F_GCR_PERCKCN1_CPU1; } -void core1_stop(void) { - MXC_GCR->perckcn1 |= MXC_F_GCR_PERCKCN1_CPU1; +void core1_stop(void) +{ + MXC_GCR->perckcn1 |= MXC_F_GCR_PERCKCN1_CPU1; } void card10_poll(void) { - pmic_poll(); + pmic_poll(); } void GPIO0_IRQHandler(void) { - GPIO_Handler(PORT_0); + GPIO_Handler(PORT_0); } void GPIO1_IRQHandler(void) { - GPIO_Handler(PORT_1); + GPIO_Handler(PORT_1); } void GPIO2_IRQHandler(void) { - GPIO_Handler(PORT_2); + GPIO_Handler(PORT_2); } void GPIO3_IRQHandler(void) { - GPIO_Handler(PORT_3); + GPIO_Handler(PORT_3); } -