mirror of
git://projects.qi-hardware.com/ben-wpan.git
synced 2024-11-26 12:08:28 +02:00
atusb/fw3: split USB driver into chip-specifc and general part
- usb/usb.c: moved chip-specific functions to usb/atu2.c - Makefile (USB_OBJS): added usb/atu2.c - usb/usb.h, usb/usb.c, ep0.c: made argument to my_setup and user_setup "const" - usb/ubs.h (handle_setup): call from chip driver to generic stack - usb/ubs.h (set_addr): call from generic stack to chip driver
This commit is contained in:
parent
908e04c309
commit
983d330294
@ -24,7 +24,7 @@ CC = $(AVR_PREFIX)gcc
|
|||||||
OBJCOPY = $(AVR_PREFIX)objcopy
|
OBJCOPY = $(AVR_PREFIX)objcopy
|
||||||
#OBJDUMP = $(AVR_PREFIX)objdump
|
#OBJDUMP = $(AVR_PREFIX)objdump
|
||||||
|
|
||||||
USB_OBJS = usb.o
|
USB_OBJS = usb.o atu2.o
|
||||||
OBJS = atusb.o board.o spi.o descr.o ep0.o $(USB_OBJS)
|
OBJS = atusb.o board.o spi.o descr.o ep0.o $(USB_OBJS)
|
||||||
|
|
||||||
vpath %.c usb/
|
vpath %.c usb/
|
||||||
|
@ -57,7 +57,7 @@ static void do_buf_write(void *user)
|
|||||||
#define BUILD_OFFSET 7 /* '#' plus "65535" plus ' ' */
|
#define BUILD_OFFSET 7 /* '#' plus "65535" plus ' ' */
|
||||||
|
|
||||||
|
|
||||||
static int my_setup(struct setup_request *setup)
|
static int my_setup(const struct setup_request *setup)
|
||||||
{
|
{
|
||||||
unsigned tmp;
|
unsigned tmp;
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
|
223
atusb/fw3/usb/atu2.c
Normal file
223
atusb/fw3/usb/atu2.c
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* u/atu2.c - Chip-specific driver for Atmel ATxxxU2 USB chips
|
||||||
|
*
|
||||||
|
* Written 2008-2011 by Werner Almesberger
|
||||||
|
* Copyright 2008-2011 Werner Almesberger
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Known issues:
|
||||||
|
* - no suspend/resume
|
||||||
|
* - EP0-sized packets cause an (otherwise harmless) SUEND at the end of the
|
||||||
|
* packet
|
||||||
|
* - #ifdef hell
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code follows the register read/write sequences from the examples in
|
||||||
|
* SiLabs/MCU/Examples/C8051F326_7/USB_Interrupt/Firmware/F326_USB_Main.c and
|
||||||
|
* SiLabs/MCU/Examples/C8051F326_7/USB_Interrupt/Firmware/F326_USB_ISR.c
|
||||||
|
*
|
||||||
|
* More resources:
|
||||||
|
* http://www.beyondlogic.org/usbnutshell/usb1.htm
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define F_CPU 8000000UL
|
||||||
|
#include <util/delay.h>
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include "usb.h"
|
||||||
|
#include "../board.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
#define BUG_ON(cond) do { if (cond) panic(); } while (0)
|
||||||
|
#else
|
||||||
|
#define BUG_ON(cond)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define NUM_EPS 1
|
||||||
|
|
||||||
|
|
||||||
|
struct ep_descr eps[NUM_EPS];
|
||||||
|
|
||||||
|
|
||||||
|
static uint16_t usb_read_word(void)
|
||||||
|
{
|
||||||
|
uint8_t low;
|
||||||
|
|
||||||
|
low = UEDATX;
|
||||||
|
return low | UEDATX << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void enable_addr(void *user)
|
||||||
|
{
|
||||||
|
while (!(UEINTX & (1 << TXINI)));
|
||||||
|
UDADDR |= 1 << ADDEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int set_addr(uint8_t addr)
|
||||||
|
{
|
||||||
|
UDADDR = addr;
|
||||||
|
usb_send(&eps[0], NULL, 0, enable_addr, NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ep_setup(void)
|
||||||
|
{
|
||||||
|
struct setup_request setup;
|
||||||
|
|
||||||
|
BUG_ON(UEBCLX < 8);
|
||||||
|
|
||||||
|
setup.bmRequestType = UEDATX;
|
||||||
|
setup.bRequest = UEDATX;
|
||||||
|
setup.wValue = usb_read_word();
|
||||||
|
setup.wIndex = usb_read_word();
|
||||||
|
setup.wLength = usb_read_word();
|
||||||
|
|
||||||
|
if (!handle_setup(&setup))
|
||||||
|
return 0;
|
||||||
|
if (!(setup.bmRequestType & 0x80) && eps[0].state == EP_IDLE)
|
||||||
|
usb_send(&eps[0], NULL, 0, NULL, NULL);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int ep_rx(struct ep_descr *ep)
|
||||||
|
{
|
||||||
|
uint8_t size;
|
||||||
|
|
||||||
|
size = UEBCLX;
|
||||||
|
if (size > ep->end-ep->buf)
|
||||||
|
return 0;
|
||||||
|
while (size--)
|
||||||
|
*ep->buf++ = UEDATX;
|
||||||
|
if (ep->buf == ep->end) {
|
||||||
|
ep->state = EP_IDLE;
|
||||||
|
if (ep->callback)
|
||||||
|
ep->callback(ep->user);
|
||||||
|
if (ep == &eps[0])
|
||||||
|
usb_send(ep, NULL, 0, NULL, NULL);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ep_tx(struct ep_descr *ep)
|
||||||
|
{
|
||||||
|
uint8_t size = ep->end-ep->buf;
|
||||||
|
uint8_t left;
|
||||||
|
|
||||||
|
if (size > ep->size)
|
||||||
|
size = ep->size;
|
||||||
|
for (left = size; left; left--)
|
||||||
|
UEDATX = *ep->buf++;
|
||||||
|
if (size == ep->size)
|
||||||
|
return;
|
||||||
|
ep->state = EP_IDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void handle_ep(int n)
|
||||||
|
{
|
||||||
|
struct ep_descr *ep = eps+n;
|
||||||
|
|
||||||
|
UENUM = n;
|
||||||
|
if (UEINTX & (1 << RXSTPI)) {
|
||||||
|
/* @@@ EP_RX. EP_TX: cancel */
|
||||||
|
if (!ep_setup())
|
||||||
|
goto stall;
|
||||||
|
UEINTX &= ~(1 << RXSTPI);
|
||||||
|
}
|
||||||
|
if (UEINTX & (1 << RXOUTI)) {
|
||||||
|
/* @@ EP_TX: cancel */
|
||||||
|
if (ep->state != EP_RX)
|
||||||
|
goto stall;
|
||||||
|
if (!ep_rx(ep))
|
||||||
|
goto stall;
|
||||||
|
// UEINTX &= ~(1 << RXOUTI);
|
||||||
|
UEINTX &= ~(1 << RXOUTI | 1 << FIFOCON);
|
||||||
|
}
|
||||||
|
if (UEINTX & (1 << STALLEDI)) {
|
||||||
|
ep->state = EP_IDLE;
|
||||||
|
UEINTX &= ~(1 << STALLEDI);
|
||||||
|
}
|
||||||
|
if (UEINTX & (1 << TXINI)) {
|
||||||
|
/* @@ EP_RX: cancel */
|
||||||
|
if (ep->state == EP_TX) {
|
||||||
|
ep_tx(ep);
|
||||||
|
UEINTX &= ~(1 << TXINI);
|
||||||
|
if (ep->state == EP_IDLE && ep->callback)
|
||||||
|
ep->callback(ep->user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
stall:
|
||||||
|
UEINTX &= ~(1 << RXSTPI | 1 << RXOUTI | 1 << STALLEDI);
|
||||||
|
ep->state = EP_IDLE;
|
||||||
|
UECONX |= 1 << STALLRQ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void usb_poll(void)
|
||||||
|
{
|
||||||
|
uint8_t flags, i;
|
||||||
|
|
||||||
|
flags = UEINT;
|
||||||
|
for (i = 0; i != NUM_EPS; i++)
|
||||||
|
if (1 || flags & (1 << i))
|
||||||
|
handle_ep(i);
|
||||||
|
/* @@@ USB bus reset */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void ep_init(void)
|
||||||
|
{
|
||||||
|
UENUM = 0;
|
||||||
|
UECONX = (1 << RSTDT) | (1 << EPEN); /* enable */
|
||||||
|
UECFG0X = 0; /* control, direction is ignored */
|
||||||
|
UECFG1X = 3 << EPSIZE0; /* 64 bytes */
|
||||||
|
UECFG1X |= 1 << ALLOC;
|
||||||
|
|
||||||
|
while (!(UESTA0X & (1 << CFGOK)));
|
||||||
|
|
||||||
|
eps[0].state = EP_IDLE;
|
||||||
|
eps[0].size = 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void usb_init(void)
|
||||||
|
{
|
||||||
|
USBCON |= 1 << FRZCLK; /* freeze the clock */
|
||||||
|
|
||||||
|
/* enable the PLL and wait for it to lock */
|
||||||
|
PLLCSR &= ~(1 << PLLP2 | 1 << PLLP1 | 1 << PLLP0);
|
||||||
|
PLLCSR |= 1 << PLLE;
|
||||||
|
while (!(PLLCSR & (1 << PLOCK)));
|
||||||
|
|
||||||
|
USBCON &= ~(1 << USBE); /* reset the controller */
|
||||||
|
USBCON |= 1 << USBE;
|
||||||
|
|
||||||
|
USBCON &= ~(1 << FRZCLK); /* thaw the clock */
|
||||||
|
|
||||||
|
UDCON &= ~(1 << DETACH); /* attach the pull-up */
|
||||||
|
UDCON |= 1 << RSTCPU; /* reset CPU on bus reset */
|
||||||
|
|
||||||
|
ep_init();
|
||||||
|
}
|
@ -29,10 +29,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#define F_CPU 8000000UL
|
|
||||||
#include <util/delay.h>
|
|
||||||
|
|
||||||
#include <avr/io.h>
|
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "../board.h"
|
#include "../board.h"
|
||||||
|
|
||||||
@ -50,17 +46,12 @@ extern void panic(void);
|
|||||||
#define BUG_ON(cond)
|
#define BUG_ON(cond)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ep_descr eps[5];
|
int (*user_setup)(const struct setup_request *setup);
|
||||||
|
|
||||||
int (*user_setup)(struct setup_request *setup);
|
|
||||||
int (*user_get_descriptor)(uint8_t type, uint8_t index,
|
int (*user_get_descriptor)(uint8_t type, uint8_t index,
|
||||||
const uint8_t * const *reply, uint8_t *size);
|
const uint8_t * const *reply, uint8_t *size);
|
||||||
void (*user_reset)(void);
|
void (*user_reset)(void);
|
||||||
|
|
||||||
|
|
||||||
static uint8_t addr;
|
|
||||||
|
|
||||||
|
|
||||||
void usb_io(struct ep_descr *ep, enum ep_state state, uint8_t *buf,
|
void usb_io(struct ep_descr *ep, enum ep_state state, uint8_t *buf,
|
||||||
uint8_t size, void (*callback)(void *user), void *user)
|
uint8_t size, void (*callback)(void *user), void *user)
|
||||||
{
|
{
|
||||||
@ -73,15 +64,6 @@ void usb_io(struct ep_descr *ep, enum ep_state state, uint8_t *buf,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static uint16_t usb_read_word(void)
|
|
||||||
{
|
|
||||||
uint8_t low;
|
|
||||||
|
|
||||||
low = UEDATX;
|
|
||||||
return low | UEDATX << 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int get_descriptor(uint8_t type, uint8_t index, uint16_t length)
|
static int get_descriptor(uint8_t type, uint8_t index, uint16_t length)
|
||||||
{
|
{
|
||||||
const uint8_t *reply;
|
const uint8_t *reply;
|
||||||
@ -111,33 +93,9 @@ static int get_descriptor(uint8_t type, uint8_t index, uint16_t length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void enable_addr(void *user)
|
int handle_setup(const struct setup_request *setup)
|
||||||
{
|
{
|
||||||
while (!(UEINTX & (1 << TXINI)));
|
switch (setup->bmRequestType | setup->bRequest << 8) {
|
||||||
UDADDR = addr | 1 << ADDEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Process a SETUP packet. Hardware ensures that length is 8 bytes.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
static int handle_setup(void)
|
|
||||||
{
|
|
||||||
struct setup_request setup;
|
|
||||||
|
|
||||||
BUG_ON(UEBCLX < 8);
|
|
||||||
|
|
||||||
setup.bmRequestType = UEDATX;
|
|
||||||
setup.bRequest = UEDATX;
|
|
||||||
setup.wValue = usb_read_word();
|
|
||||||
setup.wIndex = usb_read_word();
|
|
||||||
setup.wLength = usb_read_word();
|
|
||||||
|
|
||||||
// UEINTX &= ~(1 << RXSTPI);
|
|
||||||
|
|
||||||
switch (setup.bmRequestType | setup.bRequest << 8) {
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Device request
|
* Device request
|
||||||
@ -146,7 +104,7 @@ static int handle_setup(void)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
case FROM_DEVICE(GET_STATUS):
|
case FROM_DEVICE(GET_STATUS):
|
||||||
if (setup.wLength != 2)
|
if (setup->wLength != 2)
|
||||||
return 0;
|
return 0;
|
||||||
usb_send(&eps[0], "\000", 2, NULL, NULL);
|
usb_send(&eps[0], "\000", 2, NULL, NULL);
|
||||||
break;
|
break;
|
||||||
@ -155,13 +113,11 @@ static int handle_setup(void)
|
|||||||
case TO_DEVICE(SET_FEATURE):
|
case TO_DEVICE(SET_FEATURE):
|
||||||
return 0;
|
return 0;
|
||||||
case TO_DEVICE(SET_ADDRESS):
|
case TO_DEVICE(SET_ADDRESS):
|
||||||
addr = setup.wValue;
|
set_addr(setup->wValue);
|
||||||
UDADDR = addr;
|
|
||||||
usb_send(&eps[0], NULL, 0, enable_addr, NULL);
|
|
||||||
break;
|
break;
|
||||||
case FROM_DEVICE(GET_DESCRIPTOR):
|
case FROM_DEVICE(GET_DESCRIPTOR):
|
||||||
if (!get_descriptor(setup.wValue >> 8, setup.wValue,
|
if (!get_descriptor(setup->wValue >> 8, setup->wValue,
|
||||||
setup.wLength))
|
setup->wLength))
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case TO_DEVICE(SET_DESCRIPTOR):
|
case TO_DEVICE(SET_DESCRIPTOR):
|
||||||
@ -170,7 +126,7 @@ static int handle_setup(void)
|
|||||||
usb_send(&eps[0], "", 1, NULL, NULL);
|
usb_send(&eps[0], "", 1, NULL, NULL);
|
||||||
break;
|
break;
|
||||||
case TO_DEVICE(SET_CONFIGURATION):
|
case TO_DEVICE(SET_CONFIGURATION):
|
||||||
if (setup.wValue != config_descriptor[5])
|
if (setup->wValue != config_descriptor[5])
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -191,8 +147,8 @@ static int handle_setup(void)
|
|||||||
const uint8_t *interface_descriptor =
|
const uint8_t *interface_descriptor =
|
||||||
config_descriptor+9;
|
config_descriptor+9;
|
||||||
|
|
||||||
if (setup.wIndex != interface_descriptor[2] ||
|
if (setup->wIndex != interface_descriptor[2] ||
|
||||||
setup.wValue != interface_descriptor[3])
|
setup->wValue != interface_descriptor[3])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -213,136 +169,8 @@ static int handle_setup(void)
|
|||||||
default:
|
default:
|
||||||
if (!user_setup)
|
if (!user_setup)
|
||||||
return 0;
|
return 0;
|
||||||
if (!user_setup(&setup))
|
return user_setup(setup);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(setup.bmRequestType & 0x80) && eps[0].state == EP_IDLE)
|
|
||||||
usb_send(&eps[0], NULL, 0, NULL, NULL);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ep_rx(struct ep_descr *ep)
|
|
||||||
{
|
|
||||||
uint8_t size;
|
|
||||||
|
|
||||||
size = UEBCLX;
|
|
||||||
if (size > ep->end-ep->buf)
|
|
||||||
return 0;
|
|
||||||
while (size--)
|
|
||||||
*ep->buf++ = UEDATX;
|
|
||||||
if (ep->buf == ep->end) {
|
|
||||||
ep->state = EP_IDLE;
|
|
||||||
if (ep->callback)
|
|
||||||
ep->callback(ep->user);
|
|
||||||
if (ep == &eps[0])
|
|
||||||
usb_send(ep, NULL, 0, NULL, NULL);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ep_tx(struct ep_descr *ep)
|
|
||||||
{
|
|
||||||
uint8_t size = ep->end-ep->buf;
|
|
||||||
uint8_t left;
|
|
||||||
|
|
||||||
if (size > ep->size)
|
|
||||||
size = ep->size;
|
|
||||||
for (left = size; left; left--)
|
|
||||||
UEDATX = *ep->buf++;
|
|
||||||
if (size == ep->size)
|
|
||||||
return;
|
|
||||||
ep->state = EP_IDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void handle_ep(int n)
|
|
||||||
{
|
|
||||||
struct ep_descr *ep = eps+n;
|
|
||||||
|
|
||||||
UENUM = n;
|
|
||||||
if (UEINTX & (1 << RXSTPI)) {
|
|
||||||
/* @@@ EP_RX. EP_TX: cancel */
|
|
||||||
if (!handle_setup())
|
|
||||||
goto stall;
|
|
||||||
UEINTX &= ~(1 << RXSTPI);
|
|
||||||
}
|
|
||||||
if (UEINTX & (1 << RXOUTI)) {
|
|
||||||
/* @@ EP_TX: cancel */
|
|
||||||
if (ep->state != EP_RX)
|
|
||||||
goto stall;
|
|
||||||
if (!ep_rx(ep))
|
|
||||||
goto stall;
|
|
||||||
// UEINTX &= ~(1 << RXOUTI);
|
|
||||||
UEINTX &= ~(1 << RXOUTI | 1 << FIFOCON);
|
|
||||||
}
|
|
||||||
if (UEINTX & (1 << STALLEDI)) {
|
|
||||||
ep->state = EP_IDLE;
|
|
||||||
UEINTX &= ~(1 << STALLEDI);
|
|
||||||
}
|
|
||||||
if (UEINTX & (1 << TXINI)) {
|
|
||||||
/* @@ EP_RX: cancel */
|
|
||||||
if (ep->state == EP_TX) {
|
|
||||||
ep_tx(ep);
|
|
||||||
UEINTX &= ~(1 << TXINI);
|
|
||||||
if (ep->state == EP_IDLE && ep->callback)
|
|
||||||
ep->callback(ep->user);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
|
|
||||||
stall:
|
|
||||||
UEINTX &= ~(1 << RXSTPI | 1 << RXOUTI | 1 << STALLEDI);
|
|
||||||
ep->state = EP_IDLE;
|
|
||||||
UECONX |= 1 << STALLRQ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void usb_poll(void)
|
|
||||||
{
|
|
||||||
uint8_t flags, i;
|
|
||||||
|
|
||||||
flags = UEINT;
|
|
||||||
for (i = 0; i != NUM_EPS; i++)
|
|
||||||
if (1 || flags & (1 << i))
|
|
||||||
handle_ep(i);
|
|
||||||
/* @@@ USB bus reset */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void ep_init(void)
|
|
||||||
{
|
|
||||||
UENUM = 0;
|
|
||||||
UECONX = (1 << RSTDT) | (1 << EPEN); /* enable */
|
|
||||||
UECFG0X = 0; /* control, direction is ignored */
|
|
||||||
UECFG1X = 3 << EPSIZE0; /* 64 bytes */
|
|
||||||
UECFG1X |= 1 << ALLOC;
|
|
||||||
|
|
||||||
while (!(UESTA0X & (1 << CFGOK)));
|
|
||||||
|
|
||||||
eps[0].state = EP_IDLE;
|
|
||||||
eps[0].size = 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void usb_init(void)
|
|
||||||
{
|
|
||||||
USBCON |= 1 << FRZCLK; /* freeze the clock */
|
|
||||||
|
|
||||||
/* enable the PLL and wait for it to lock */
|
|
||||||
PLLCSR &= ~(1 << PLLP2 | 1 << PLLP1 | 1 << PLLP0);
|
|
||||||
PLLCSR |= 1 << PLLE;
|
|
||||||
while (!(PLLCSR & (1 << PLOCK)));
|
|
||||||
|
|
||||||
USBCON &= ~(1 << USBE); /* reset the controller */
|
|
||||||
USBCON |= 1 << USBE;
|
|
||||||
|
|
||||||
USBCON &= ~(1 << FRZCLK); /* thaw the clock */
|
|
||||||
|
|
||||||
UDCON &= ~(1 << DETACH); /* attach the pull-up */
|
|
||||||
UDCON |= 1 << RSTCPU; /* reset CPU on bus reset */
|
|
||||||
|
|
||||||
ep_init();
|
|
||||||
}
|
|
||||||
|
@ -124,7 +124,7 @@ extern const uint8_t device_descriptor[];
|
|||||||
extern const uint8_t config_descriptor[];
|
extern const uint8_t config_descriptor[];
|
||||||
extern struct ep_descr eps[];
|
extern struct ep_descr eps[];
|
||||||
|
|
||||||
extern int (*user_setup)(struct setup_request *setup);
|
extern int (*user_setup)(const struct setup_request *setup);
|
||||||
extern int (*user_get_descriptor)(uint8_t type, uint8_t index,
|
extern int (*user_get_descriptor)(uint8_t type, uint8_t index,
|
||||||
const uint8_t * const *reply, uint8_t *size);
|
const uint8_t * const *reply, uint8_t *size);
|
||||||
extern void (*user_reset)(void);
|
extern void (*user_reset)(void);
|
||||||
@ -139,7 +139,8 @@ extern void (*user_reset)(void);
|
|||||||
void usb_io(struct ep_descr *ep, enum ep_state state, uint8_t *buf,
|
void usb_io(struct ep_descr *ep, enum ep_state state, uint8_t *buf,
|
||||||
uint8_t size, void (*callback)(void *user), void *user);
|
uint8_t size, void (*callback)(void *user), void *user);
|
||||||
|
|
||||||
|
int handle_setup(const struct setup_request *setup);
|
||||||
|
int set_addr(uint8_t addr);
|
||||||
void usb_init(void);
|
void usb_init(void);
|
||||||
void usb_poll(void);
|
void usb_poll(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user