Browse Source

dfu app-detach support

master
Olaf Rempel 12 years ago
parent
commit
a81d25a84d
2 changed files with 37 additions and 5 deletions
  1. +14
    -0
      include/at91_udp.h
  2. +23
    -5
      src/at91_udp.c

+ 14
- 0
include/at91_udp.h View File

@@ -1,6 +1,20 @@
#ifndef AT91_UDP_H_
#define AT91_UDP_H_

#include <stdint.h>

void ep_transfer_send(uint32_t ep,
char *data,
uint32_t length,
void (*complete_cb)(void));

void ep_transfer_receive(uint32_t ep,
char *data,
uint32_t length,
void (*complete_cb)(void));

void ep_send_stall(uint32_t ep);

void at91_udp_init(void);

#endif /*AT91_UDP_H_*/

+ 23
- 5
src/at91_udp.c View File

@@ -185,7 +185,16 @@ static const struct my_config cfg_descriptor = {
},
};

static const struct dfu_status dfu_status = {
/* not const! */
static struct usb_cdc_line_coding cdc_line_coding = {
.dwDTERate = 9600,
.bCharFormat = USB_CDC_1_STOP_BITS,
.bParityType = USB_CDC_NO_PARITY,
.bDataBits = 8,
};

/* not const! */
static struct dfu_status dfu_status = {
.bStatus = DFU_STATUS_OK,
.bState = DFU_STATE_appIDLE,
};
@@ -389,6 +398,7 @@ static void ep_handle_ctrlrequest(struct usb_ctrlrequest *req)
// TODO: follow current_interface
switch (req->bRequest) {
case USB_REQ_DFU_DETACH: /* 0x00 */
dfu_status.bStatus = DFU_STATE_appDETACH;
ep_transfer_send(0, NULL, 0, NULL);
break;

@@ -397,7 +407,11 @@ static void ep_handle_ctrlrequest(struct usb_ctrlrequest *req)
break;

case USB_CDC_REQ_SET_LINE_CODING: /* 0x20 */
/* TODO: read 7 bytes to dummy buffer */
ep_transfer_receive(0, (char *)&cdc_line_coding, sizeof(cdc_line_coding), NULL);
break;

case USB_CDC_REQ_GET_LINE_CODING: /* 0x21 */
ep_transfer_send(0, (char *)&cdc_line_coding, sizeof(cdc_line_coding), NULL);
break;

case USB_CDC_REQ_SET_CONTROL_LINE_STATE: /* 0x22 */
@@ -511,9 +525,7 @@ static void udp_handle_ep(uint32_t ep)
/* test again */
if (transfer->length == transfer->curpos) {
ctx->flags &= ~CTX_OUT;

if (transfer->complete_cb)
transfer->complete_cb();
transfer_cb = transfer->complete_cb;
}
}

@@ -564,6 +576,12 @@ static void udp_isr(void)
udp->UDP_IDR = AT91C_UDP_EPINT1 | AT91C_UDP_EPINT2 | AT91C_UDP_EPINT3 |
AT91C_UDP_RXSUSP | AT91C_UDP_RXRSM | AT91C_UDP_SOFINT |
AT91C_UDP_WAKEUP;

if (dfu_status.bStatus == DFU_STATE_appDETACH) {
void (* bootloader)(void) = (void *)0x13c000;
bootloader();
while (1);
}
}

/* Handle Endpoint Interrupts */


Loading…
Cancel
Save