56#include "nrfx_power.h"
61#include "tusb_config.h"
68extern void tusb_hal_nrf_power_event(uint32_t event);
70#define SERIAL_NUMBER_STRING_SIZE 12
72static char serial[SERIAL_NUMBER_STRING_SIZE + 1];
81power_event_handler(nrfx_power_usb_evt_t event)
83 tusb_hal_nrf_power_event((uint32_t)event);
100#if defined(NRF52_SERIES) || defined(NRF52840_XXAA) \
101 || defined(NRF52833_XXAA) || defined(NRF52832_XXAA) \
102 || defined(NRF52820_XXAA) || defined(NRF52811_XXAA) \
103 || defined(NRF52810_XXAA) || defined(NRF52805_XXAA)
104 const uint16_t serial_num_high_bytes =
105 (uint16_t)NRF_FICR->DEVICEADDR[1] | 0xC000;
106 const uint32_t serial_num_low_bytes = NRF_FICR->DEVICEADDR[0];
108 const uint16_t serial_num_high_bytes =
109 (uint16_t)NRF_FICR->INFO.DEVICEID[1] | 0xC000;
110 const uint32_t serial_num_low_bytes = NRF_FICR->INFO.DEVICEID[0];
112 const nrfx_power_config_t power_config = { 0 };
113 const nrfx_power_usbevt_config_t power_usbevt_config = {
114 .handler = power_event_handler
117 nrfx_power_init(&power_config);
119 nrfx_power_usbevt_init(&power_usbevt_config);
121 nrfx_power_usbevt_enable();
125 SERIAL_NUMBER_STRING_SIZE + 1,
126 "%04"PRIX16
"%08"PRIX32,
127 serial_num_high_bytes,
128 serial_num_low_bytes);
132 nrfx_power_usb_state_t usb_reg = nrfx_power_usbstatus_get();
133 if(usb_reg == NRFX_POWER_USB_STATE_CONNECTED) {
134 tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_DETECTED);
135 }
else if(usb_reg == NRFX_POWER_USB_STATE_READY) {
136 tusb_hal_nrf_power_event(NRFX_POWER_USB_EVT_READY);
140#if CFG_TUD_DFU_RUNTIME
148#define BOOTLOADER_DFU_GPREGRET_MAGIC 0xB0u
149#define BOOTLOADER_DFU_START_BIT 0x01u
150#define BOOTLOADER_DFU_START (BOOTLOADER_DFU_GPREGRET_MAGIC | BOOTLOADER_DFU_START_BIT)
152#ifndef BOARD_DFU_SELF_RESET_PIN
158#define BOARD_DFU_SELF_RESET_PIN NRF_GPIO_PIN_MAP(0, 19)
162tud_dfu_runtime_reboot_to_dfu_cb(
void)
172#if BOARD_DFU_SELF_RESET_PIN >= 0
173 nrf_gpio_cfg_output(BOARD_DFU_SELF_RESET_PIN);
174 nrf_gpio_pin_clear(BOARD_DFU_SELF_RESET_PIN);
180 nrf_power_gpregret_set(NRF_POWER, 0, BOOTLOADER_DFU_START);
200#include "device/usbd_pvt.h"
202#define NORDIC_DFU_TRIGGER_CLASS 0xFFu
203#define NORDIC_DFU_TRIGGER_SUBCLASS 0x01u
204#define NORDIC_DFU_TRIGGER_PROTOCOL 0x01u
205#define NORDIC_DFU_TRIGGER_CS_FUNCTIONAL 0x21u
206#define NORDIC_DFU_TRIGGER_REQ_DETACH 0x00u
207#define NORDIC_DFU_TRIGGER_REQ_NORDIC_INFO 0x07u
208#define NORDIC_DFU_TRIGGER_REQ_SEM_VER 0x08u
210struct nordic_dfu_info {
212 uint32_t wFirmwareSize;
213 uint16_t wVersionMajor;
214 uint16_t wVersionMinor;
215 uint32_t wFirmwareID;
217 uint32_t wFlashPageSize;
218} __attribute__((packed));
220static const struct nordic_dfu_info nordic_info = {
226 .wFlashSize = 1024u * 1024u,
227 .wFlashPageSize = 4096u,
230static const char nordic_sem_ver[] =
"Contiki-NG DFU";
233nordic_dfu_trigger_init(
void)
238nordic_dfu_trigger_reset(uint8_t rhport)
244nordic_dfu_trigger_open(uint8_t rhport,
245 tusb_desc_interface_t
const *itf_desc,
251 if(itf_desc->bInterfaceClass != NORDIC_DFU_TRIGGER_CLASS
252 || itf_desc->bInterfaceSubClass != NORDIC_DFU_TRIGGER_SUBCLASS
253 || itf_desc->bInterfaceProtocol != NORDIC_DFU_TRIGGER_PROTOCOL) {
257 uint16_t drv_len =
sizeof(tusb_desc_interface_t);
258 uint8_t
const *p = tu_desc_next(itf_desc);
261 if(tu_desc_type(p) == NORDIC_DFU_TRIGGER_CS_FUNCTIONAL) {
262 drv_len += tu_desc_len(p);
269nordic_dfu_trigger_control_xfer_cb(uint8_t rhport, uint8_t stage,
270 tusb_control_request_t
const *request)
272 if(stage != CONTROL_STAGE_SETUP) {
277 if(request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD
278 && request->bRequest == TUSB_REQ_SET_INTERFACE
279 && request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE) {
280 tud_control_status(rhport, request);
293 if(request->bmRequestType_bit.type != TUSB_REQ_TYPE_VENDOR
294 && request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS) {
298 switch(request->bRequest) {
299 case NORDIC_DFU_TRIGGER_REQ_DETACH:
307 nrf_gpio_cfg_output(BOARD_DFU_SELF_RESET_PIN);
308 nrf_gpio_pin_clear(BOARD_DFU_SELF_RESET_PIN);
310 case NORDIC_DFU_TRIGGER_REQ_NORDIC_INFO:
311 return tud_control_xfer(rhport, request,
312 (
void *)&nordic_info,
sizeof(nordic_info));
313 case NORDIC_DFU_TRIGGER_REQ_SEM_VER:
314 return tud_control_xfer(rhport, request,
315 (
void *)nordic_sem_ver,
316 sizeof(nordic_sem_ver) - 1);
322static usbd_class_driver_t
const nordic_dfu_trigger_driver = {
323#if CFG_TUSB_DEBUG >= 2
324 .name =
"NORDIC-DFU",
326 .init = nordic_dfu_trigger_init,
327 .reset = nordic_dfu_trigger_reset,
328 .open = nordic_dfu_trigger_open,
329 .control_xfer_cb = nordic_dfu_trigger_control_xfer_cb,
338usbd_class_driver_t
const *
339usbd_app_driver_get_cb(uint8_t *driver_count)
342 return &nordic_dfu_trigger_driver;
359tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage,
360 tusb_control_request_t
const *request)
362 if(stage != CONTROL_STAGE_SETUP) {
369 if(request->bmRequestType_bit.type != TUSB_REQ_TYPE_CLASS
370 && request->bmRequestType_bit.type != TUSB_REQ_TYPE_VENDOR) {
374 switch(request->bRequest) {
375 case NORDIC_DFU_TRIGGER_REQ_DETACH:
377#if BOARD_DFU_SELF_RESET_PIN >= 0
378 nrf_gpio_cfg_output(BOARD_DFU_SELF_RESET_PIN);
379 nrf_gpio_pin_clear(BOARD_DFU_SELF_RESET_PIN);
381 nrf_power_gpregret_set(NRF_POWER, 0, BOOTLOADER_DFU_START);
384 case NORDIC_DFU_TRIGGER_REQ_NORDIC_INFO:
385 return tud_control_xfer(rhport, request,
386 (
void *)&nordic_info,
sizeof(nordic_info));
387 case NORDIC_DFU_TRIGGER_REQ_SEM_VER:
388 return tud_control_xfer(rhport, request,
389 (
void *)nordic_sem_ver,
390 sizeof(nordic_sem_ver) - 1);
void usb_interrupt_handler(void)
Handles the interrupt.
void usb_descriptor_set_serial(char *serial)
Set the serial.
void usb_arch_init(void)
Initialize the architecture specific USB driver.
#define PROCESS_NAME(name)
Declare the name of a process.
Header file for the Contiki process interface.
USB descriptors header file for the nRF.