mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-16 21:28:33 +03:00
this adds the DFU as application, allowing to flash the bootloader. a USB DFU alternative is added to flash the bootloader partition. when the DFU is started as bootloader, the partition/alternative to flash the bootloader is marked as "not available", and ineffective. the same happens for the application partition when DFU is started as application. this distinction is make at compile time, not at runtime, because of size restrictions (the bootloader was already close to the 16 kB limit). *_dfu_flash.bin should not be mixed with *_dfu_dfu.bin. *_dfu_dfu.bin should be flashed as application using the already existing DFU bootloader. once this images is started (as application), the *_dfu_flash.bin should be flashed as bootloader using the DFU application. once the DFU bootloader has been flashed, soft resetting (not re-powering) will cause the bootloader to start, allowing to flash the application with a normal image (e.g. not DFU), replacing the DFU application. this switch to DFU only happens after downloading (e.g. flashing). it is planned to have the DFU application erase itself after flashing, but this is currently not implemented. Change-Id: Ic273bb593a7669111b0219fe301d7897419167c8
136 lines
3.7 KiB
C
136 lines
3.7 KiB
C
#ifndef _USB_DEV_DFU_H
|
|
#define _USB_DEV_DFU_H
|
|
|
|
#include <stdint.h>
|
|
#include <board.h>
|
|
#include <usb/include/USBDescriptors.h>
|
|
#include <usb/include/USBDDriver.h>
|
|
|
|
#if 0
|
|
/* This is valid for CCID */
|
|
#define CONFIG_DFU_NUM_APP_IF 1
|
|
#define CONFIG_DFU_NUM_APP_STR 4
|
|
#else
|
|
/* This is valid for CDC-Serial */
|
|
#define CONFIG_DFU_NUM_APP_IF 2
|
|
#define CONFIG_DFU_NUM_APP_STR 2
|
|
#endif
|
|
|
|
struct USBStringDescriptor {
|
|
USBGenericDescriptor hdr;
|
|
unsigned short wData[];
|
|
} __attribute__((packed));
|
|
|
|
|
|
#ifdef BOARD_USB_DFU
|
|
|
|
#include <usb/common/dfu/usb_dfu.h>
|
|
|
|
/* for board-specific config */
|
|
#include <board.h>
|
|
|
|
struct dfu_desc {
|
|
USBConfigurationDescriptor ucfg;
|
|
USBInterfaceDescriptor uif[BOARD_DFU_NUM_IF];
|
|
struct usb_dfu_func_descriptor func_dfu;
|
|
} __attribute__ ((packed));
|
|
|
|
/* USB DFU functional descriptor */
|
|
#define DFU_FUNC_DESC { \
|
|
.bLength = USB_DT_DFU_SIZE, \
|
|
.bDescriptorType = USB_DT_DFU, \
|
|
.bmAttributes = USB_DFU_CAN_UPLOAD | USB_DFU_CAN_DOWNLOAD, \
|
|
.wDetachTimeOut = 0xff00, \
|
|
.wTransferSize = BOARD_DFU_PAGE_SIZE, \
|
|
.bcdDFUVersion = 0x0100, \
|
|
}
|
|
|
|
/* Number of DFU interface during runtime mode */
|
|
#define DFURT_NUM_IF 1
|
|
|
|
/* to be used by the runtime as part of its USB descriptor structure
|
|
* declaration */
|
|
#define DFURT_IF_DESCRIPTOR_STRUCT \
|
|
USBInterfaceDescriptor dfu_rt; \
|
|
struct usb_dfu_func_descriptor func_dfu;
|
|
|
|
/* to be used by the runtime as part of its USB Dsecriptor structure
|
|
* definition */
|
|
#define DFURT_IF_DESCRIPTOR(dfuIF, dfuSTR) \
|
|
.dfu_rt = { \
|
|
.bLength = sizeof(USBInterfaceDescriptor), \
|
|
.bDescriptorType = USBGenericDescriptor_INTERFACE, \
|
|
.bInterfaceNumber = dfuIF, \
|
|
.bAlternateSetting = 0, \
|
|
.bNumEndpoints = 0, \
|
|
.bInterfaceClass = 0xFE, \
|
|
.bInterfaceSubClass = 0x01, \
|
|
.bInterfaceProtocol = 0x01, \
|
|
.iInterface = dfuSTR, \
|
|
}, \
|
|
.func_dfu = DFU_FUNC_DESC \
|
|
|
|
/* provided by dfu_desc.c */
|
|
extern const struct dfu_desc dfu_cfg_descriptor;
|
|
extern const USBDDriverDescriptors dfu_descriptors;
|
|
|
|
#else /* BOARD_USB_DFU */
|
|
|
|
/* no DFU bootloader is being used */
|
|
#define DFURT_NUM_IF 0
|
|
#define DFURT_IF_DESCRIPTOR_STRUCT
|
|
#define DFURT_IF_DESCRIPTOR(a, b)
|
|
|
|
#endif /* BOARD_USB_DFU */
|
|
|
|
/* magic value we use during boot to detect if we should start in DFU
|
|
* mode or runtime mode */
|
|
#define USB_DFU_MAGIC 0xDFDFDFDF
|
|
|
|
/* The API between the core DFU handler and the board/soc specific code */
|
|
|
|
struct dfudata {
|
|
uint32_t magic;
|
|
uint8_t status;
|
|
uint32_t state;
|
|
int past_manifest;
|
|
unsigned int total_bytes;
|
|
};
|
|
|
|
/* RAM address for this magic value above */
|
|
extern struct dfudata _g_dfu;
|
|
extern struct dfudata *g_dfu;
|
|
|
|
void set_usb_serial_str(void);
|
|
|
|
void DFURT_SwitchToDFU(void);
|
|
|
|
/* call-backs from DFU USB function driver to the board/SOC */
|
|
extern int USBDFU_handle_dnload(uint8_t altif, unsigned int offset,
|
|
uint8_t *data, unsigned int len);
|
|
extern int USBDFU_handle_upload(uint8_t altif, unsigned int offset,
|
|
uint8_t *data, unsigned int req_len);
|
|
extern int USBDFU_OverrideEnterDFU(void);
|
|
|
|
/* function to be called at end of EP0 handler during runtime */
|
|
void USBDFU_Runtime_RequestHandler(const USBGenericRequest *request);
|
|
|
|
/* function to be called at end of EP0 handler during DFU mode */
|
|
void USBDFU_DFU_RequestHandler(const USBGenericRequest *request);
|
|
|
|
/* initialization of USB DFU driver (in DFU mode */
|
|
void USBDFU_Initialize(const USBDDriverDescriptors *pDescriptors);
|
|
|
|
/* USBD tells us to switch from DFU mode to application mode */
|
|
void USBDFU_SwitchToApp(void);
|
|
|
|
/* USBD tells us to switch from to DFU mode */
|
|
void USBDFU_SwitchToDFU(void);
|
|
|
|
/* Return values to be used by USBDFU_handle_{dn,up}load */
|
|
#define DFU_RET_NOTHING 0
|
|
#define DFU_RET_ZLP 1
|
|
#define DFU_RET_STALL 2
|
|
|
|
#endif
|