lpc176x: read chip id and use as usb serial. (#2184)
Signed-off-by: Matt Baker <baker.matt.j@gmail.com>
This commit is contained in:
parent
b0a158c271
commit
bab27651a1
10
src/Kconfig
10
src/Kconfig
|
@ -50,6 +50,10 @@ config SERIAL_BAUD
|
|||
Specify the baud rate of the serial port. This should be set
|
||||
to 250000. Read the FAQ before changing this value.
|
||||
|
||||
config HAVE_CHIPID
|
||||
bool
|
||||
default n
|
||||
|
||||
# Generic configuration options for USB
|
||||
menu "USB ids"
|
||||
depends on USBSERIAL
|
||||
|
@ -61,8 +65,12 @@ config USB_DEVICE_ID
|
|||
hex "USB device ID"
|
||||
default 0xabcd
|
||||
config USB_SERIAL_NUMBER
|
||||
string "USB serial number"
|
||||
string "USB serial number" if !USB_SERIAL_NUMBER_CHIPID
|
||||
default "12345"
|
||||
config USB_SERIAL_NUMBER_CHIPID
|
||||
depends on HAVE_CHIPID
|
||||
bool "USB serial number from CHIPID"
|
||||
default y
|
||||
|
||||
endmenu
|
||||
|
||||
|
|
|
@ -358,21 +358,34 @@ usb_req_get_descriptor(struct usb_ctrlrequest *req)
|
|||
{
|
||||
if (req->bRequestType != USB_DIR_IN)
|
||||
goto fail;
|
||||
uint_fast8_t i;
|
||||
void *desc = NULL;
|
||||
uint_fast8_t flags, size, i;
|
||||
for (i=0; i<ARRAY_SIZE(cdc_descriptors); i++) {
|
||||
const struct descriptor_s *d = &cdc_descriptors[i];
|
||||
if (READP(d->wValue) == req->wValue
|
||||
&& READP(d->wIndex) == req->wIndex) {
|
||||
uint_fast8_t size = READP(d->size);
|
||||
uint_fast8_t flags = NEED_PROGMEM ? UX_SEND_PROGMEM : UX_SEND;
|
||||
if (size > req->wLength)
|
||||
size = req->wLength;
|
||||
else if (size < req->wLength)
|
||||
flags |= UX_SEND_ZLP;
|
||||
usb_do_xfer((void*)READP(d->desc), size, flags);
|
||||
return;
|
||||
flags = NEED_PROGMEM ? UX_SEND_PROGMEM : UX_SEND;
|
||||
size = READP(d->size);
|
||||
desc = (void*)READP(d->desc);
|
||||
}
|
||||
}
|
||||
if (CONFIG_USB_SERIAL_NUMBER_CHIPID
|
||||
&& req->wValue == ((USB_DT_STRING<<8) | USB_STR_ID_SERIAL)
|
||||
&& req->wIndex == USB_LANGID_ENGLISH_US) {
|
||||
struct usb_string_descriptor *usbserial_serialid;
|
||||
usbserial_serialid = usbserial_get_serialid();
|
||||
flags = UX_SEND;
|
||||
size = usbserial_serialid->bLength;
|
||||
desc = (void*)usbserial_serialid;
|
||||
}
|
||||
if (desc) {
|
||||
if (size > req->wLength)
|
||||
size = req->wLength;
|
||||
else if (size < req->wLength)
|
||||
flags |= UX_SEND_ZLP;
|
||||
usb_do_xfer(desc, size, flags);
|
||||
return;
|
||||
}
|
||||
fail:
|
||||
usb_do_stall();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ void usb_stall_ep0(void);
|
|||
void usb_set_address(uint_fast8_t addr);
|
||||
void usb_set_configure(void);
|
||||
void usb_request_bootloader(void);
|
||||
struct usb_string_descriptor *usbserial_get_serialid(void);
|
||||
|
||||
// usb_cdc.c
|
||||
void usb_notify_bulk_in(void);
|
||||
|
|
|
@ -66,4 +66,8 @@ config SERIAL
|
|||
bool
|
||||
default y
|
||||
|
||||
config HAVE_CHIPID
|
||||
bool
|
||||
default y
|
||||
|
||||
endif
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "byteorder.h" // cpu_to_le32
|
||||
#include "command.h" // DECL_CONSTANT_STR
|
||||
#include "generic/usb_cdc.h" // usb_notify_ep0
|
||||
#include "generic/usbstd.h" // usb_string_descriptor
|
||||
#include "internal.h" // gpio_peripheral
|
||||
#include "sched.h" // DECL_INIT
|
||||
#include "usb_cdc_ep.h" // USB_CDC_EP_BULK_IN
|
||||
|
@ -34,6 +35,12 @@
|
|||
#define RD_EN (1<<0)
|
||||
#define WR_EN (1<<1)
|
||||
|
||||
// IAP interface
|
||||
#define IAP_LOCATION 0x1fff1ff1
|
||||
#define IAP_CMD_READ_UID 58
|
||||
#define IAP_UID_LEN 16
|
||||
typedef void (*IAP)(uint32_t *, uint32_t *);
|
||||
|
||||
static void
|
||||
usb_irq_disable(void)
|
||||
{
|
||||
|
@ -104,6 +111,16 @@ sie_select_and_clear(uint32_t idx)
|
|||
/****************************************************************
|
||||
* Interface
|
||||
****************************************************************/
|
||||
#define USB_STR_SERIAL_CHIPID u"0123456789ABCDEF0123456789ABCDEF"
|
||||
|
||||
#define SIZE_cdc_string_serial_chipid \
|
||||
(sizeof(cdc_string_serial_chipid) + sizeof(USB_STR_SERIAL_CHIPID) - 2)
|
||||
|
||||
static struct usb_string_descriptor cdc_string_serial_chipid = {
|
||||
.bLength = SIZE_cdc_string_serial_chipid,
|
||||
.bDescriptorType = USB_DT_STRING,
|
||||
.data = USB_STR_SERIAL_CHIPID,
|
||||
};
|
||||
|
||||
static int_fast8_t
|
||||
usb_write_packet(uint32_t ep, const void *data, uint_fast8_t len)
|
||||
|
@ -260,10 +277,36 @@ usb_request_bootloader(void)
|
|||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
struct usb_string_descriptor *
|
||||
usbserial_get_serialid(void)
|
||||
{
|
||||
return &cdc_string_serial_chipid;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* Setup and interrupts
|
||||
****************************************************************/
|
||||
static void
|
||||
usb_set_serial(void)
|
||||
{
|
||||
uint32_t iap_cmd_uid[5] = {IAP_CMD_READ_UID, 0, 0, 0, 0};
|
||||
uint32_t iap_resp[5];
|
||||
|
||||
IAP iap_entry = (IAP)IAP_LOCATION;
|
||||
__disable_irq();
|
||||
iap_entry(iap_cmd_uid, iap_resp);
|
||||
__enable_irq();
|
||||
|
||||
uint8_t *chipid = (uint8_t *)&iap_resp[1];
|
||||
uint8_t i, j, c;
|
||||
for (i = 0; i < IAP_UID_LEN; i++) {
|
||||
for (j = 0; j < 2; j++) {
|
||||
c = (chipid[i] >> 4*j) & 0xF;
|
||||
c = (c < 10) ? '0'+c : 'A'-10+c;
|
||||
cdc_string_serial_chipid.data[2*i+((j)?0:1)] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
USB_IRQHandler(void)
|
||||
|
@ -300,6 +343,9 @@ DECL_CONSTANT_STR("RESERVE_PINS_USB", "P0.30,P0.29,P2.9");
|
|||
void
|
||||
usbserial_init(void)
|
||||
{
|
||||
if (CONFIG_USB_SERIAL_NUMBER_CHIPID)
|
||||
usb_set_serial();
|
||||
|
||||
usb_irq_disable();
|
||||
// enable power
|
||||
enable_pclock(PCLK_USB);
|
||||
|
|
Loading…
Reference in New Issue