This commit is contained in:
rogerclarkmelbourne 2015-02-20 10:07:29 +11:00
commit 4e808480ca
99 changed files with 10594 additions and 1005 deletions

6
.gitignore vendored
View File

@ -1 +1,7 @@
.DS_store
other/maple-bootloader/.dep
other/maple-bootloader/TAGS
other/maple-bootloader/tags
other/maple-bootloader/cscope.out
other/maple-bootloader/build
other/maple-bootloader/*~

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "tools/macosx/stlink/texan_stlink_src"]
path = tools/macosx/stlink/texan_stlink_src
url = https://github.com/texane/stlink.git
[submodule "drivers/win/src/pbatard_libwdi"]
path = drivers/win/src/pbatard_libwdi
url = https://github.com/pbatard/libwdi.git

View File

@ -6,6 +6,8 @@ menu.debug_menu=Debug mode
menu.cpu_upload_menu=CPU & Upload mode
menu.HS_IO=High speed I/O commands
menu.upload_method=Upload method
nano.name= Maple mini generic
@ -285,32 +287,38 @@ maple_mini.build.gcc_ver=gcc-arm-none-eabi-4.8.3-2014q1
#maple_miniRAM.build.gcc_ver=gcc-arm-none-eabi-4.8.3-2014q1
##############################################################
maple_STM32.name=STM32 to Flash - No bootloader
genericSTM32.name=STM32 to Flash - No bootloader
maple_STM32.upload.tool=serial_upload
maple_STM32.upload.protocol=stm_serial
maple_STM32.upload.maximum_size=108000
maple_STM32.upload.use_1200bps_touch=false
maple_STM32.upload.file_type=bin
maple_STM32.upload.ram.maximum_size=17000
maple_STM32.upload.flash.maximum_size=108000
genericSTM32.menu.upload_method.serialMethod=Serial
genericSTM32.menu.upload_method.serialMethod.upload.protocol=maple_serial
genericSTM32.menu.upload_method.serialMethod.upload.tool=serial_upload
genericSTM32.menu.upload_method.STLinkMethod=STLink
genericSTM32.menu.upload_method.STLinkMethod.upload.protocol=STLink
genericSTM32.menu.upload_method.STLinkMethod.upload.tool=stlink_upload
maple_STM32.upload.usbID=1EAF:0003
maple_STM32.upload.altID=1
maple_STM32.upload.auto_reset=true
#genericSTM32.upload.tool=upload_router
genericSTM32.upload.maximum_size=108000
genericSTM32.upload.use_1200bps_touch=false
genericSTM32.upload.file_type=bin
genericSTM32.upload.ram.maximum_size=17000
genericSTM32.upload.flash.maximum_size=108000
maple_STM32.build.mcu=cortex-m3
maple_STM32.build.f_cpu=72000000L
maple_STM32.build.core=maple
maple_STM32.build.extra_flags=-DMCU_STM32F103CB -mthumb -DSTM32_MEDIUM_DENSITY -march=armv7-m -D__STM32F1XX__
maple_STM32.build.ldscript=ld/jtag.ld
maple_STM32.build.variant=maple_mini
maple_STM32.build.variant_system_lib=libmaple.a
maple_STM32.build.vect=VECT_TAB_FLASH
maple_STM32.build.density=STM32_MEDIUM_DENSITY
maple_STM32.build.error_led_port=GPIOB
maple_STM32.build.error_led_pin=1
maple_STM32.build.gcc_ver=gcc-arm-none-eabi-4.8.3-2014q1
genericSTM32.upload.usbID=1EAF:0003
genericSTM32.upload.altID=1
genericSTM32.upload.auto_reset=true
genericSTM32.build.mcu=cortex-m3
genericSTM32.build.f_cpu=72000000L
genericSTM32.build.core=maple
genericSTM32.build.extra_flags=-DMCU_STM32F103CB -mthumb -DSTM32_MEDIUM_DENSITY -march=armv7-m -D__STM32F1XX__
genericSTM32.build.ldscript=ld/jtag.ld
genericSTM32.build.variant=maple_mini
genericSTM32.build.variant_system_lib=libmaple.a
genericSTM32.build.vect=VECT_TAB_FLASH
genericSTM32.build.density=STM32_MEDIUM_DENSITY
genericSTM32.build.error_led_port=GPIOB
genericSTM32.build.error_led_pin=1
genericSTM32.build.gcc_ver=gcc-arm-none-eabi-4.8.3-2014q1
##############################################################
@ -371,3 +379,4 @@ nucleo_f103rb.build.error_led_port=GPIOB
nucleo_f103rb.build.error_led_pin=1
nucleo_f103rb.build.gcc_ver=gcc-arm-none-eabi-4.8.3-2014q1

View File

@ -39,4 +39,6 @@ void yield(void);
}
#endif // __cplusplus
#include "variant.h"
#endif

View File

@ -261,8 +261,10 @@ static ONE_DESCRIPTOR String_Descriptor[N_STRING_DESCRIPTORS] = {
/* I/O state */
#define CDC_SERIAL_BUFFER_SIZE 512
/* Received data */
static volatile uint8 vcomBufferRx[USB_CDCACM_RX_EPSIZE];
static volatile uint8 vcomBufferRx[CDC_SERIAL_BUFFER_SIZE];
/* Read index into vcomBufferRx */
static volatile uint32 rx_offset = 0;
/* Number of bytes left to transmit */
@ -445,14 +447,13 @@ uint32 usb_cdcacm_rx(uint8* buf, uint32 len) {
/* Mark bytes as read. */
n_unread_bytes -= n_copied;
rx_offset += n_copied;
rx_offset = (rx_offset + n_copied) % CDC_SERIAL_BUFFER_SIZE;
/* If all bytes have been read, re-enable the RX endpoint, which
* was set to NAK when the current batch of bytes was received. */
if (n_unread_bytes == 0) {
if (n_unread_bytes <= (CDC_SERIAL_BUFFER_SIZE - USB_CDCACM_RX_EPSIZE)) {
usb_set_ep_rx_count(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_EPSIZE);
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID);
rx_offset = 0;
}
return n_copied;
@ -463,13 +464,31 @@ uint32 usb_cdcacm_rx(uint8* buf, uint32 len) {
* Looks at unread bytes without marking them as read. */
uint32 usb_cdcacm_peek(uint8* buf, uint32 len) {
int i;
uint32 head = rx_offset;
if (len > n_unread_bytes) {
len = n_unread_bytes;
}
for (i = 0; i < len; i++) {
buf[i] = vcomBufferRx[i + rx_offset];
buf[i] = vcomBufferRx[head];
head = (head + 1) % CDC_SERIAL_BUFFER_SIZE;
}
return len;
}
uint32 usb_cdcacm_peek_ex(uint8* buf, uint32 offset, uint32 len) {
int i;
uint32 head = (rx_offset + offset) % CDC_SERIAL_BUFFER_SIZE;
if (len + offset > n_unread_bytes) {
len = n_unread_bytes - offset;
}
for (i = 0; i < len; i++) {
buf[i] = vcomBufferRx[head];
head = (head + 1) % CDC_SERIAL_BUFFER_SIZE;
}
return len;
@ -478,15 +497,12 @@ uint32 usb_cdcacm_peek(uint8* buf, uint32 len) {
/* Roger Clark. Added. for Arduino 1.0 API support of Serial.peek() */
int usb_cdcacm_peek_char()
{
return 2;
/*
if (n_unread_bytes == 0)
{
return -1;
}
return vcomBufferRx[rx_offset];
*/
}
uint8 usb_cdcacm_get_dtr() {
@ -531,19 +547,29 @@ static void vcomDataTxCb(void) {
}
static void vcomDataRxCb(void) {
uint32 ep_rx_size;
uint32 tail = (rx_offset + n_unread_bytes) % CDC_SERIAL_BUFFER_SIZE;
uint8 ep_rx_data[USB_CDCACM_RX_EPSIZE];
uint32 i;
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_NAK);
n_unread_bytes = usb_get_ep_rx_count(USB_CDCACM_RX_ENDP);
ep_rx_size = usb_get_ep_rx_count(USB_CDCACM_RX_ENDP);
/* This copy won't overwrite unread bytes, since we've set the RX
* endpoint to NAK, and will only set it to VALID when all bytes
* have been read. */
usb_copy_from_pma((uint8*)vcomBufferRx, n_unread_bytes,
usb_copy_from_pma((uint8*)ep_rx_data, ep_rx_size,
USB_CDCACM_RX_ADDR);
for (i = 0; i < ep_rx_size; i++) {
vcomBufferRx[tail] = ep_rx_data[i];
tail = (tail + 1) % CDC_SERIAL_BUFFER_SIZE;
}
if (n_unread_bytes == 0) {
n_unread_bytes += ep_rx_size;
if (n_unread_bytes <= (CDC_SERIAL_BUFFER_SIZE - USB_CDCACM_RX_EPSIZE)) {
usb_set_ep_rx_count(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_EPSIZE);
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID);
rx_offset = 0;
}
if (rx_hook) {

View File

@ -1,711 +0,0 @@
/******************************************************************************
* The MIT License
*
* Copyright (c) 2011 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*****************************************************************************/
/**
* @file libmaple/usb/stm32f1/usb_cdcacm.c
* @brief USB CDC ACM (a.k.a. virtual serial terminal, VCOM).
*
* FIXME: this works on the STM32F1 USB peripherals, and probably no
* place else. Nonportable bits really need to be factored out, and
* the result made cleaner.
*/
#include <libmaple/usb_cdcacm.h>
#include <libmaple/usb.h>
#include <libmaple/nvic.h>
#include <libmaple/delay.h>
/* Private headers */
#include "usb_lib_globals.h"
#include "usb_reg_map.h"
/* usb_lib headers */
#include "usb_type.h"
#include "usb_core.h"
#include "usb_def.h"
/******************************************************************************
******************************************************************************
***
*** HACK ALERT! FIXME FIXME FIXME FIXME!
***
*** A bunch of LeafLabs-specific configuration lives in here for
*** now. This mess REALLY needs to get teased apart, with
*** appropriate pieces moved into Wirish.
***
******************************************************************************
*****************************************************************************/
#if !(defined(BOARD_maple) || defined(BOARD_maple_RET6) || \
defined(BOARD_maple_mini) || defined(BOARD_maple_native))
#warning USB CDC ACM relies on LeafLabs board-specific configuration.\
You may have problems on non-LeafLabs boards.
#endif
static void vcomDataTxCb(void);
static void vcomDataRxCb(void);
static uint8* vcomGetSetLineCoding(uint16);
static void usbInit(void);
static void usbReset(void);
static RESULT usbDataSetup(uint8 request);
static RESULT usbNoDataSetup(uint8 request);
static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting);
static uint8* usbGetDeviceDescriptor(uint16 length);
static uint8* usbGetConfigDescriptor(uint16 length);
static uint8* usbGetStringDescriptor(uint16 length);
static void usbSetConfiguration(void);
static void usbSetDeviceAddress(void);
/*
* Descriptors
*/
/* FIXME move to Wirish */
#define LEAFLABS_ID_VENDOR 0x1EAF
#define MAPLE_ID_PRODUCT 0x0004
static const usb_descriptor_device usbVcomDescriptor_Device =
USB_CDCACM_DECLARE_DEV_DESC(LEAFLABS_ID_VENDOR, MAPLE_ID_PRODUCT);
typedef struct {
usb_descriptor_config_header Config_Header;
usb_descriptor_interface CCI_Interface;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_IntHeader;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_CallManagement;
CDC_FUNCTIONAL_DESCRIPTOR(1) CDC_Functional_ACM;
CDC_FUNCTIONAL_DESCRIPTOR(2) CDC_Functional_Union;
usb_descriptor_endpoint ManagementEndpoint;
usb_descriptor_interface DCI_Interface;
usb_descriptor_endpoint DataOutEndpoint;
usb_descriptor_endpoint DataInEndpoint;
} __packed usb_descriptor_config;
#define MAX_POWER (100 >> 1)
static const usb_descriptor_config usbVcomDescriptor_Config = {
.Config_Header = {
.bLength = sizeof(usb_descriptor_config_header),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURATION,
.wTotalLength = sizeof(usb_descriptor_config),
.bNumInterfaces = 0x02,
.bConfigurationValue = 0x01,
.iConfiguration = 0x00,
.bmAttributes = (USB_CONFIG_ATTR_BUSPOWERED |
USB_CONFIG_ATTR_SELF_POWERED),
.bMaxPower = MAX_POWER,
},
.CCI_Interface = {
.bLength = sizeof(usb_descriptor_interface),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = 0x00,
.bAlternateSetting = 0x00,
.bNumEndpoints = 0x01,
.bInterfaceClass = USB_INTERFACE_CLASS_CDC,
.bInterfaceSubClass = USB_INTERFACE_SUBCLASS_CDC_ACM,
.bInterfaceProtocol = 0x01, /* Common AT Commands */
.iInterface = 0x00,
},
.CDC_Functional_IntHeader = {
.bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2),
.bDescriptorType = 0x24,
.SubType = 0x00,
.Data = {0x01, 0x10},
},
.CDC_Functional_CallManagement = {
.bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2),
.bDescriptorType = 0x24,
.SubType = 0x01,
.Data = {0x03, 0x01},
},
.CDC_Functional_ACM = {
.bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(1),
.bDescriptorType = 0x24,
.SubType = 0x02,
.Data = {0x06},
},
.CDC_Functional_Union = {
.bLength = CDC_FUNCTIONAL_DESCRIPTOR_SIZE(2),
.bDescriptorType = 0x24,
.SubType = 0x06,
.Data = {0x00, 0x01},
},
.ManagementEndpoint = {
.bLength = sizeof(usb_descriptor_endpoint),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN |
USB_CDCACM_MANAGEMENT_ENDP),
.bmAttributes = USB_EP_TYPE_INTERRUPT,
.wMaxPacketSize = USB_CDCACM_MANAGEMENT_EPSIZE,
.bInterval = 0xFF,
},
.DCI_Interface = {
.bLength = sizeof(usb_descriptor_interface),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = 0x01,
.bAlternateSetting = 0x00,
.bNumEndpoints = 0x02,
.bInterfaceClass = USB_INTERFACE_CLASS_DIC,
.bInterfaceSubClass = 0x00, /* None */
.bInterfaceProtocol = 0x00, /* None */
.iInterface = 0x00,
},
.DataOutEndpoint = {
.bLength = sizeof(usb_descriptor_endpoint),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_OUT |
USB_CDCACM_RX_ENDP),
.bmAttributes = USB_EP_TYPE_BULK,
.wMaxPacketSize = USB_CDCACM_RX_EPSIZE,
.bInterval = 0x00,
},
.DataInEndpoint = {
.bLength = sizeof(usb_descriptor_endpoint),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = (USB_DESCRIPTOR_ENDPOINT_IN | USB_CDCACM_TX_ENDP),
.bmAttributes = USB_EP_TYPE_BULK,
.wMaxPacketSize = USB_CDCACM_TX_EPSIZE,
.bInterval = 0x00,
},
};
/*
String Descriptors:
we may choose to specify any or none of the following string
identifiers:
iManufacturer: LeafLabs
iProduct: Maple
iSerialNumber: NONE
iConfiguration: NONE
iInterface(CCI): NONE
iInterface(DCI): NONE
*/
/* Unicode language identifier: 0x0409 is US English */
/* FIXME move to Wirish */
static const usb_descriptor_string usbVcomDescriptor_LangID = {
.bLength = USB_DESCRIPTOR_STRING_LEN(1),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {0x09, 0x04},
};
/* FIXME move to Wirish */
static const usb_descriptor_string usbVcomDescriptor_iManufacturer = {
.bLength = USB_DESCRIPTOR_STRING_LEN(8),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {'L', 0, 'e', 0, 'a', 0, 'f', 0,
'L', 0, 'a', 0, 'b', 0, 's', 0},
};
/* FIXME move to Wirish */
static const usb_descriptor_string usbVcomDescriptor_iProduct = {
.bLength = USB_DESCRIPTOR_STRING_LEN(5),
.bDescriptorType = USB_DESCRIPTOR_TYPE_STRING,
.bString = {'M', 0, 'a', 0, 'p', 0, 'l', 0, 'e', 0},
};
static ONE_DESCRIPTOR Device_Descriptor = {
(uint8*)&usbVcomDescriptor_Device,
sizeof(usb_descriptor_device)
};
static ONE_DESCRIPTOR Config_Descriptor = {
(uint8*)&usbVcomDescriptor_Config,
sizeof(usb_descriptor_config)
};
#define N_STRING_DESCRIPTORS 3
static ONE_DESCRIPTOR String_Descriptor[N_STRING_DESCRIPTORS] = {
{(uint8*)&usbVcomDescriptor_LangID, USB_DESCRIPTOR_STRING_LEN(1)},
{(uint8*)&usbVcomDescriptor_iManufacturer,USB_DESCRIPTOR_STRING_LEN(8)},
{(uint8*)&usbVcomDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(5)}
};
/*
* Etc.
*/
/* I/O state */
/* Received data */
static volatile uint8 vcomBufferRx[USB_CDCACM_RX_EPSIZE];
/* Read index into vcomBufferRx */
static volatile uint32 rx_offset = 0;
/* Number of bytes left to transmit */
static volatile uint32 n_unsent_bytes = 0;
/* Are we currently sending an IN packet? */
static volatile uint8 transmitting = 0;
/* Number of unread bytes */
static volatile uint32 n_unread_bytes = 0;
/* Other state (line coding, DTR/RTS) */
static volatile usb_cdcacm_line_coding line_coding = {
/* This default is 115200 baud, 8N1. */
.dwDTERate = 115200,
.bCharFormat = USB_CDCACM_STOP_BITS_1,
.bParityType = USB_CDCACM_PARITY_NONE,
.bDataBits = 8,
};
/* DTR in bit 0, RTS in bit 1. */
static volatile uint8 line_dtr_rts = 0;
/*
* Endpoint callbacks
*/
static void (*ep_int_in[7])(void) =
{vcomDataTxCb,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process};
static void (*ep_int_out[7])(void) =
{NOP_Process,
NOP_Process,
vcomDataRxCb,
NOP_Process,
NOP_Process,
NOP_Process,
NOP_Process};
/*
* Globals required by usb_lib/
*
* Mark these weak so they can be overriden to implement other USB
* functionality.
*/
#define NUM_ENDPTS 0x04
__weak DEVICE Device_Table = {
.Total_Endpoint = NUM_ENDPTS,
.Total_Configuration = 1
};
#define MAX_PACKET_SIZE 0x40 /* 64B, maximum for USB FS Devices */
__weak DEVICE_PROP Device_Property = {
.Init = usbInit,
.Reset = usbReset,
.Process_Status_IN = NOP_Process,
.Process_Status_OUT = NOP_Process,
.Class_Data_Setup = usbDataSetup,
.Class_NoData_Setup = usbNoDataSetup,
.Class_Get_Interface_Setting = usbGetInterfaceSetting,
.GetDeviceDescriptor = usbGetDeviceDescriptor,
.GetConfigDescriptor = usbGetConfigDescriptor,
.GetStringDescriptor = usbGetStringDescriptor,
.RxEP_buffer = NULL,
.MaxPacketSize = MAX_PACKET_SIZE
};
__weak USER_STANDARD_REQUESTS User_Standard_Requests = {
.User_GetConfiguration = NOP_Process,
.User_SetConfiguration = usbSetConfiguration,
.User_GetInterface = NOP_Process,
.User_SetInterface = NOP_Process,
.User_GetStatus = NOP_Process,
.User_ClearFeature = NOP_Process,
.User_SetEndPointFeature = NOP_Process,
.User_SetDeviceFeature = NOP_Process,
.User_SetDeviceAddress = usbSetDeviceAddress
};
/*
* User hooks
*/
static void (*rx_hook)(unsigned, void*) = 0;
static void (*iface_setup_hook)(unsigned, void*) = 0;
void usb_cdcacm_set_hooks(unsigned hook_flags, void (*hook)(unsigned, void*)) {
if (hook_flags & USB_CDCACM_HOOK_RX) {
rx_hook = hook;
}
if (hook_flags & USB_CDCACM_HOOK_IFACE_SETUP) {
iface_setup_hook = hook;
}
}
/*
* CDC ACM interface
*/
void usb_cdcacm_enable(gpio_dev *disc_dev, uint8 disc_bit) {
/* Present ourselves to the host. Writing 0 to "disc" pin must
* pull USB_DP pin up while leaving USB_DM pulled down by the
* transceiver. See USB 2.0 spec, section 7.1.7.3. */
gpio_set_mode(disc_dev, disc_bit, GPIO_OUTPUT_PP);
gpio_write_bit(disc_dev, disc_bit, 0);
/* Initialize the USB peripheral. */
usb_init_usblib(USBLIB, ep_int_in, ep_int_out);
}
void usb_cdcacm_disable(gpio_dev *disc_dev, uint8 disc_bit) {
/* Turn off the interrupt and signal disconnect (see e.g. USB 2.0
* spec, section 7.1.7.3). */
nvic_irq_disable(NVIC_USB_LP_CAN_RX0);
gpio_write_bit(disc_dev, disc_bit, 1);
}
void usb_cdcacm_putc(char ch) {
while (!usb_cdcacm_tx((uint8*)&ch, 1))
;
}
/* This function is non-blocking.
*
* It copies data from a usercode buffer into the USB peripheral TX
* buffer, and returns the number of bytes copied. */
uint32 usb_cdcacm_tx(const uint8* buf, uint32 len) {
/* Last transmission hasn't finished, so abort. */
if (usb_cdcacm_is_transmitting()) {
return 0;
}
/* We can only put USB_CDCACM_TX_EPSIZE bytes in the buffer. */
if (len > USB_CDCACM_TX_EPSIZE) {
len = USB_CDCACM_TX_EPSIZE;
}
/* Queue bytes for sending. */
if (len) {
usb_copy_to_pma(buf, len, USB_CDCACM_TX_ADDR);
}
// We still need to wait for the interrupt, even if we're sending
// zero bytes. (Sending zero-size packets is useful for flushing
// host-side buffers.)
usb_set_ep_tx_count(USB_CDCACM_TX_ENDP, len);
n_unsent_bytes = len;
transmitting = 1;
usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_VALID);
return len;
}
uint32 usb_cdcacm_data_available(void) {
return n_unread_bytes;
}
uint8 usb_cdcacm_is_transmitting(void) {
return transmitting;
}
uint16 usb_cdcacm_get_pending(void) {
return n_unsent_bytes;
}
/* Nonblocking byte receive.
*
* Copies up to len bytes from our private data buffer (*NOT* the PMA)
* into buf and deq's the FIFO. */
uint32 usb_cdcacm_rx(uint8* buf, uint32 len) {
/* Copy bytes to buffer. */
uint32 n_copied = usb_cdcacm_peek(buf, len);
/* Mark bytes as read. */
n_unread_bytes -= n_copied;
rx_offset += n_copied;
/* If all bytes have been read, re-enable the RX endpoint, which
* was set to NAK when the current batch of bytes was received. */
if (n_unread_bytes == 0) {
usb_set_ep_rx_count(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_EPSIZE);
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID);
rx_offset = 0;
}
return n_copied;
}
/* Nonblocking byte lookahead.
*
* Looks at unread bytes without marking them as read. */
uint32 usb_cdcacm_peek(uint8* buf, uint32 len) {
int i;
if (len > n_unread_bytes) {
len = n_unread_bytes;
}
for (i = 0; i < len; i++) {
buf[i] = vcomBufferRx[i + rx_offset];
}
return len;
}
uint8 usb_cdcacm_get_dtr() {
return ((line_dtr_rts & USB_CDCACM_CONTROL_LINE_DTR) != 0);
}
uint8 usb_cdcacm_get_rts() {
return ((line_dtr_rts & USB_CDCACM_CONTROL_LINE_RTS) != 0);
}
void usb_cdcacm_get_line_coding(usb_cdcacm_line_coding *ret) {
ret->dwDTERate = line_coding.dwDTERate;
ret->bCharFormat = line_coding.bCharFormat;
ret->bParityType = line_coding.bParityType;
ret->bDataBits = line_coding.bDataBits;
}
int usb_cdcacm_get_baud(void) {
return line_coding.dwDTERate;
}
int usb_cdcacm_get_stop_bits(void) {
return line_coding.bCharFormat;
}
int usb_cdcacm_get_parity(void) {
return line_coding.bParityType;
}
int usb_cdcacm_get_n_data_bits(void) {
return line_coding.bDataBits;
}
/*
* Callbacks
*/
static void vcomDataTxCb(void) {
n_unsent_bytes = 0;
transmitting = 0;
}
static void vcomDataRxCb(void) {
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_NAK);
n_unread_bytes = usb_get_ep_rx_count(USB_CDCACM_RX_ENDP);
/* This copy won't overwrite unread bytes, since we've set the RX
* endpoint to NAK, and will only set it to VALID when all bytes
* have been read. */
usb_copy_from_pma((uint8*)vcomBufferRx, n_unread_bytes,
USB_CDCACM_RX_ADDR);
if (n_unread_bytes == 0) {
usb_set_ep_rx_count(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_EPSIZE);
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID);
rx_offset = 0;
}
if (rx_hook) {
rx_hook(USB_CDCACM_HOOK_RX, 0);
}
}
static uint8* vcomGetSetLineCoding(uint16 length) {
if (length == 0) {
pInformation->Ctrl_Info.Usb_wLength = sizeof(struct usb_cdcacm_line_coding);
}
return (uint8*)&line_coding;
}
static void usbInit(void) {
pInformation->Current_Configuration = 0;
USB_BASE->CNTR = USB_CNTR_FRES;
USBLIB->irq_mask = 0;
USB_BASE->CNTR = USBLIB->irq_mask;
USB_BASE->ISTR = 0;
USBLIB->irq_mask = USB_CNTR_RESETM | USB_CNTR_SUSPM | USB_CNTR_WKUPM;
USB_BASE->CNTR = USBLIB->irq_mask;
USB_BASE->ISTR = 0;
USBLIB->irq_mask = USB_ISR_MSK;
USB_BASE->CNTR = USBLIB->irq_mask;
nvic_irq_enable(NVIC_USB_LP_CAN_RX0);
USBLIB->state = USB_UNCONNECTED;
}
#define BTABLE_ADDRESS 0x00
static void usbReset(void) {
pInformation->Current_Configuration = 0;
/* current feature is current bmAttributes */
pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED |
USB_CONFIG_ATTR_SELF_POWERED);
USB_BASE->BTABLE = BTABLE_ADDRESS;
/* setup control endpoint 0 */
usb_set_ep_type(USB_EP0, USB_EP_EP_TYPE_CONTROL);
usb_set_ep_tx_stat(USB_EP0, USB_EP_STAT_TX_STALL);
usb_set_ep_rx_addr(USB_EP0, USB_CDCACM_CTRL_RX_ADDR);
usb_set_ep_tx_addr(USB_EP0, USB_CDCACM_CTRL_TX_ADDR);
usb_clear_status_out(USB_EP0);
usb_set_ep_rx_count(USB_EP0, pProperty->MaxPacketSize);
usb_set_ep_rx_stat(USB_EP0, USB_EP_STAT_RX_VALID);
/* setup management endpoint 1 */
usb_set_ep_type(USB_CDCACM_MANAGEMENT_ENDP, USB_EP_EP_TYPE_INTERRUPT);
usb_set_ep_tx_addr(USB_CDCACM_MANAGEMENT_ENDP,
USB_CDCACM_MANAGEMENT_ADDR);
usb_set_ep_tx_stat(USB_CDCACM_MANAGEMENT_ENDP, USB_EP_STAT_TX_NAK);
usb_set_ep_rx_stat(USB_CDCACM_MANAGEMENT_ENDP, USB_EP_STAT_RX_DISABLED);
/* TODO figure out differences in style between RX/TX EP setup */
/* set up data endpoint OUT (RX) */
usb_set_ep_type(USB_CDCACM_RX_ENDP, USB_EP_EP_TYPE_BULK);
usb_set_ep_rx_addr(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_ADDR);
usb_set_ep_rx_count(USB_CDCACM_RX_ENDP, USB_CDCACM_RX_EPSIZE);
usb_set_ep_rx_stat(USB_CDCACM_RX_ENDP, USB_EP_STAT_RX_VALID);
/* set up data endpoint IN (TX) */
usb_set_ep_type(USB_CDCACM_TX_ENDP, USB_EP_EP_TYPE_BULK);
usb_set_ep_tx_addr(USB_CDCACM_TX_ENDP, USB_CDCACM_TX_ADDR);
usb_set_ep_tx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_TX_NAK);
usb_set_ep_rx_stat(USB_CDCACM_TX_ENDP, USB_EP_STAT_RX_DISABLED);
USBLIB->state = USB_ATTACHED;
SetDeviceAddress(0);
/* Reset the RX/TX state */
n_unread_bytes = 0;
n_unsent_bytes = 0;
rx_offset = 0;
transmitting = 0;
}
static RESULT usbDataSetup(uint8 request) {
uint8* (*CopyRoutine)(uint16) = 0;
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
switch (request) {
case USB_CDCACM_GET_LINE_CODING:
CopyRoutine = vcomGetSetLineCoding;
break;
case USB_CDCACM_SET_LINE_CODING:
CopyRoutine = vcomGetSetLineCoding;
break;
default:
break;
}
/* Call the user hook. */
if (iface_setup_hook) {
uint8 req_copy = request;
iface_setup_hook(USB_CDCACM_HOOK_IFACE_SETUP, &req_copy);
}
}
if (CopyRoutine == NULL) {
return USB_UNSUPPORT;
}
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine)(0);
return USB_SUCCESS;
}
static RESULT usbNoDataSetup(uint8 request) {
RESULT ret = USB_UNSUPPORT;
if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
switch (request) {
case USB_CDCACM_SET_COMM_FEATURE:
/* We support set comm. feature, but don't handle it. */
ret = USB_SUCCESS;
break;
case USB_CDCACM_SET_CONTROL_LINE_STATE:
/* Track changes to DTR and RTS. */
line_dtr_rts = (pInformation->USBwValues.bw.bb0 &
(USB_CDCACM_CONTROL_LINE_DTR |
USB_CDCACM_CONTROL_LINE_RTS));
ret = USB_SUCCESS;
break;
}
/* Call the user hook. */
if (iface_setup_hook) {
uint8 req_copy = request;
iface_setup_hook(USB_CDCACM_HOOK_IFACE_SETUP, &req_copy);
}
}
return ret;
}
static RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) {
if (alt_setting > 0) {
return USB_UNSUPPORT;
} else if (interface > 1) {
return USB_UNSUPPORT;
}
return USB_SUCCESS;
}
static uint8* usbGetDeviceDescriptor(uint16 length) {
return Standard_GetDescriptorData(length, &Device_Descriptor);
}
static uint8* usbGetConfigDescriptor(uint16 length) {
return Standard_GetDescriptorData(length, &Config_Descriptor);
}
static uint8* usbGetStringDescriptor(uint16 length) {
uint8 wValue0 = pInformation->USBwValue0;
if (wValue0 > N_STRING_DESCRIPTORS) {
return NULL;
}
return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]);
}
static void usbSetConfiguration(void) {
if (pInformation->Current_Configuration != 0) {
USBLIB->state = USB_CONFIGURED;
}
}
static void usbSetDeviceAddress(void) {
USBLIB->state = USB_ADDRESSED;
}

View File

@ -260,6 +260,11 @@ static void ifaceSetupHook(unsigned hook, void *requestvp) {
reset_state = DTR_NEGEDGE;
}
#endif
if ((usb_cdcacm_get_baud() == 1200) && (reset_state == DTR_NEGEDGE)) {
iwdg_init(IWDG_PRE_4, 10);
while (1);
}
}
#define RESET_DELAY 100000
@ -295,7 +300,7 @@ static void rxHook(unsigned hook, void *ignored) {
// Peek at the waiting bytes, looking for reset sequence,
// bailing on mismatch.
usb_cdcacm_peek(chkBuf, 4);
usb_cdcacm_peek_ex(chkBuf, usb_cdcacm_data_available() - 4, 4);
for (unsigned i = 0; i < sizeof(magic); i++) {
if (chkBuf[i] != magic[i]) {
return;

View File

@ -57,6 +57,7 @@
#include <wirish_debug.h>
#include <wirish_math.h>
#include <wirish_time.h>
#include <wirish_constants.h>
#if STM32_MCU_SERIES == STM32_SERIES_F1 /* FIXME [0.0.13?] port to F2 */
//#include <HardwareSPI.h>
@ -85,9 +86,6 @@ typedef unsigned int word;
#define true 0x1
#define false 0x0
#define LSBFIRST 0
#define MSBFIRST 1
#define lowByte(w) ((w) & 0xFF)
#define highByte(w) (((w) >> 8) & 0xFF)
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)

View File

@ -0,0 +1,17 @@
#ifndef _WIRING_CONSTANTS_
#define _WIRING_CONSTANTS_
#ifdef __cplusplus
extern "C"{
#endif
enum BitOrder {
LSBFIRST = 0,
MSBFIRST = 1
};
#ifdef __cplusplus
}
#endif
#endif

View File

@ -102,10 +102,6 @@ static inline long map(long value, long fromStart, long fromEnd,
#define EULER 2.718281828459045235360287471352
#define SERIAL 0x0
#define DISPLAY 0x1
enum BitOrder {
LSBFIRST = 0,
MSBFIRST = 1
};
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))

0
STM32F1XX/libraries/EEPROM/EEPROM.cpp Normal file → Executable file
View File

0
STM32F1XX/libraries/EEPROM/EEPROM.h Normal file → Executable file
View File

View File

@ -17,7 +17,9 @@ void setup()
{
// initialize the digital pin as an output:
pinMode(ledPin, OUTPUT);
SerialUSB.print(HELP_MSG);
Serial.begin(115200);
Serial.print(HELP_MSG);
}
void loop()
@ -25,10 +27,10 @@ void loop()
uint16 Status;
uint16 Data;
while (SerialUSB.available())
while (Serial.available())
{
char cmd = (char)SerialUSB.read();
SerialUSB.println(cmd);
char cmd = (char)Serial.read();
Serial.println(cmd);
if (cmd == '0')
{
DisplayConfig();
@ -50,20 +52,20 @@ void loop()
else if (cmd == '3')
{
Status = EEPROM.write(AddressWrite, DataWrite);
SerialUSB.print("EEPROM.write(0x");
SerialUSB.print(AddressWrite, HEX);
SerialUSB.print(", 0x");
SerialUSB.print(DataWrite, HEX);
SerialUSB.print(") : Status : ");
SerialUSB.println(Status, HEX);
Serial.print("EEPROM.write(0x");
Serial.print(AddressWrite, HEX);
Serial.print(", 0x");
Serial.print(DataWrite, HEX);
Serial.print(") : Status : ");
Serial.println(Status, HEX);
Status = EEPROM.read(AddressWrite, &Data);
SerialUSB.print("EEPROM.read(0x");
SerialUSB.print(AddressWrite, HEX);
SerialUSB.print(", &..) = 0x");
SerialUSB.print(Data, HEX);
SerialUSB.print(" : Status : ");
SerialUSB.println(Status, HEX);
Serial.print("EEPROM.read(0x");
Serial.print(AddressWrite, HEX);
Serial.print(", &..) = 0x");
Serial.print(Data, HEX);
Serial.print(" : Status : ");
Serial.println(Status, HEX);
++DataWrite;
}
@ -79,18 +81,18 @@ void loop()
else if (cmd == '6')
{
Status = EEPROM.init();
SerialUSB.print("EEPROM.init() : ");
SerialUSB.println(Status, HEX);
SerialUSB.println();
Serial.print("EEPROM.init() : ");
Serial.println(Status, HEX);
Serial.println();
}
else if (cmd == '7')
{
Status = EEPROM.format();
SerialUSB.print("EEPROM.format() : ");
SerialUSB.println(Status, HEX);
Serial.print("EEPROM.format() : ");
Serial.println(Status, HEX);
}
else
SerialUSB.print(HELP_MSG);
Serial.print(HELP_MSG);
}
digitalWrite(ledPin, HIGH);
delay(500);
@ -100,66 +102,66 @@ void loop()
void DisplayConfig(void)
{
SerialUSB.print ("EEPROM.PageBase0 : 0x");
SerialUSB.println(EEPROM.PageBase0, HEX);
SerialUSB.print ("EEPROM.PageBase1 : 0x");
SerialUSB.println(EEPROM.PageBase1, HEX);
SerialUSB.print ("EEPROM.PageSize : 0x");
SerialUSB.print (EEPROM.PageSize, HEX);
SerialUSB.print (" (");
SerialUSB.print (EEPROM.PageSize, DEC);
SerialUSB.println(")");
Serial.print ("EEPROM.PageBase0 : 0x");
Serial.println(EEPROM.PageBase0, HEX);
Serial.print ("EEPROM.PageBase1 : 0x");
Serial.println(EEPROM.PageBase1, HEX);
Serial.print ("EEPROM.PageSize : 0x");
Serial.print (EEPROM.PageSize, HEX);
Serial.print (" (");
Serial.print (EEPROM.PageSize, DEC);
Serial.println(")");
}
void DisplayHex(uint16 value)
{
if (value <= 0xF)
SerialUSB.print("000");
Serial.print("000");
else if (value <= 0xFF)
SerialUSB.print("00");
Serial.print("00");
else if (value <= 0xFFF)
SerialUSB.print("0");
SerialUSB.print(value, HEX);
Serial.print("0");
Serial.print(value, HEX);
}
void DisplayPages(uint32 endIndex)
{
SerialUSB.println("Page 0 Top Page 1");
Serial.println("Page 0 Top Page 1");
for (uint32 idx = 0; idx < endIndex; idx += 4)
{
SerialUSB.print (EEPROM.PageBase0 + idx, HEX);
SerialUSB.print (" : ");
Serial.print (EEPROM.PageBase0 + idx, HEX);
Serial.print (" : ");
DisplayHex(*(uint16*)(EEPROM.PageBase0 + idx));
SerialUSB.print (" ");
Serial.print (" ");
DisplayHex(*(uint16*)(EEPROM.PageBase0 + idx + 2));
SerialUSB.print (" ");
SerialUSB.print (EEPROM.PageBase1 + idx, HEX);
SerialUSB.print (" : ");
Serial.print (" ");
Serial.print (EEPROM.PageBase1 + idx, HEX);
Serial.print (" : ");
DisplayHex(*(uint16*)(EEPROM.PageBase1 + idx));
SerialUSB.print (" ");
Serial.print (" ");
DisplayHex(*(uint16*)(EEPROM.PageBase1 + idx + 2));
SerialUSB.println();
Serial.println();
}
}
void DisplayPagesEnd(uint32 endIndex)
{
SerialUSB.println("Page 0 Bottom Page 1");
Serial.println("Page 0 Bottom Page 1");
for (uint32 idx = EEPROM.PageSize - endIndex; idx < EEPROM.PageSize; idx += 4)
{
SerialUSB.print (EEPROM.PageBase0 + idx, HEX);
SerialUSB.print (" : ");
Serial.print (EEPROM.PageBase0 + idx, HEX);
Serial.print (" : ");
DisplayHex(*(uint16*)(EEPROM.PageBase0 + idx));
SerialUSB.print (" ");
Serial.print (" ");
DisplayHex(*(uint16*)(EEPROM.PageBase0 + idx + 2));
SerialUSB.print (" ");
SerialUSB.print (EEPROM.PageBase1 + idx, HEX);
SerialUSB.print (" : ");
Serial.print (" ");
Serial.print (EEPROM.PageBase1 + idx, HEX);
Serial.print (" : ");
DisplayHex(*(uint16*)(EEPROM.PageBase1 + idx));
SerialUSB.print (" ");
Serial.print (" ");
DisplayHex(*(uint16*)(EEPROM.PageBase1 + idx + 2));
SerialUSB.println();
Serial.println();
}
}
}

4
STM32F1XX/libraries/EEPROM/flash_stm32.c Normal file → Executable file
View File

@ -1,6 +1,6 @@
//#include "libmaple.h"
//#include "util.h"
#include "flash.h"
#include "libmaple/util.h"
#include "libmaple/flash.h"
#include "flash_stm32.h"
#define FLASH_KEY1 ((uint32)0x45670123)

0
STM32F1XX/libraries/EEPROM/flash_stm32.h Normal file → Executable file
View File

0
STM32F1XX/libraries/EEPROM/keywords.txt Normal file → Executable file
View File

29
STM32F1XX/libraries/LiquidCrystal/LiquidCrystal.cpp Normal file → Executable file
View File

@ -69,17 +69,7 @@ void LiquidCrystal::init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable,
_data_pins[5] = d5;
_data_pins[6] = d6;
_data_pins[7] = d7;
for (int i = 0; i < 8 - fourbitmode * 4; i++) {
pinMode(_data_pins[i], OUTPUT);
}
pinMode(_rs_pin, OUTPUT);
// we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
if (_rw_pin != 255) {
pinMode(_rw_pin, OUTPUT);
}
pinMode(_enable_pin, OUTPUT);
displaymode=fourbitmode;
if (fourbitmode)
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
@ -87,10 +77,22 @@ void LiquidCrystal::init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable,
_displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
// TODO: bnewbold, re-enable this?
begin(16, 1);
// begin(16, 1);
}
void LiquidCrystal::begin(uint8 cols, uint8 lines, uint8 dotsize) {
for (int i = 0; i < 8 - displaymode * 4; i++) {
//for (int i = 0; i <4; i++) {
pinMode(_data_pins[i], OUTPUT);
}
pinMode(_rs_pin, OUTPUT);
// we can save 1 pin by not using RW. Indicate by passing 255 instead of pin#
if (_rw_pin != 255) {
pinMode(_rw_pin, OUTPUT);
}
pinMode(_enable_pin, OUTPUT);
if (lines > 1) {
_displayfunction |= LCD_2LINE;
}
@ -275,8 +277,9 @@ inline void LiquidCrystal::command(uint8 value) {
send(value, LOW);
}
inline void LiquidCrystal::write(uint8 value) {
inline size_t LiquidCrystal::write(uint8 value) {
send(value, HIGH);
return 1;
}
/************ low level data pushing commands **********/

4
STM32F1XX/libraries/LiquidCrystal/LiquidCrystal.h Normal file → Executable file
View File

@ -80,14 +80,14 @@ public:
void createChar(uint8, uint8[]);
void setCursor(uint8, uint8);
virtual void write(uint8);
virtual size_t write(uint8);
void command(uint8);
private:
void send(uint8, uint8);
void write4bits(uint8);
void write8bits(uint8);
void pulseEnable();
uint8 displaymode;
uint8 _rs_pin; // LOW: command. HIGH: character.
uint8 _rw_pin; // LOW: write to LCD. HIGH: read from LCD.
uint8 _enable_pin; // activated by a HIGH pulse.

0
STM32F1XX/libraries/LiquidCrystal/rules.mk Normal file → Executable file
View File

View File

@ -0,0 +1,557 @@
/*
Copyright (c) 2007, Jim Studt (original old version - many contributors since)
The latest version of this library may be found at:
http://www.pjrc.com/teensy/td_libs_OneWire.html
OneWire has been maintained by Paul Stoffregen (paul@pjrc.com) since
January 2010. At the time, it was in need of many bug fixes, but had
been abandoned the original author (Jim Studt). None of the known
contributors were interested in maintaining OneWire. Paul typically
works on OneWire every 6 to 12 months. Patches usually wait that
long. If anyone is interested in more actively maintaining OneWire,
please contact Paul.
Version 2.2:
Teensy 3.0 compatibility, Paul Stoffregen, paul@pjrc.com
Arduino Due compatibility, http://arduino.cc/forum/index.php?topic=141030
Fix DS18B20 example negative temperature
Fix DS18B20 example's low res modes, Ken Butcher
Improve reset timing, Mark Tillotson
Add const qualifiers, Bertrik Sikken
Add initial value input to crc16, Bertrik Sikken
Add target_search() function, Scott Roberts
Version 2.1:
Arduino 1.0 compatibility, Paul Stoffregen
Improve temperature example, Paul Stoffregen
DS250x_PROM example, Guillermo Lovato
PIC32 (chipKit) compatibility, Jason Dangel, dangel.jason AT gmail.com
Improvements from Glenn Trewitt:
- crc16() now works
- check_crc16() does all of calculation/checking work.
- Added read_bytes() and write_bytes(), to reduce tedious loops.
- Added ds2408 example.
Delete very old, out-of-date readme file (info is here)
Version 2.0: Modifications by Paul Stoffregen, January 2010:
http://www.pjrc.com/teensy/td_libs_OneWire.html
Search fix from Robin James
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27
Use direct optimized I/O in all cases
Disable interrupts during timing critical sections
(this solves many random communication errors)
Disable interrupts during read-modify-write I/O
Reduce RAM consumption by eliminating unnecessary
variables and trimming many to 8 bits
Optimize both crc8 - table version moved to flash
Modified to work with larger numbers of devices - avoids loop.
Tested in Arduino 11 alpha with 12 sensors.
26 Sept 2008 -- Robin James
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1238032295/27#27
Updated to work with arduino-0008 and to include skip() as of
2007/07/06. --RJL20
Modified to calculate the 8-bit CRC directly, avoiding the need for
the 256-byte lookup table to be loaded in RAM. Tested in arduino-0010
-- Tom Pollard, Jan 23, 2008
Jim Studt's original library was modified by Josh Larios.
Tom Pollard, pollard@alum.mit.edu, contributed around May 20, 2008
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Much of the code was inspired by Derek Yerger's code, though I don't
think much of that remains. In any event that was..
(copyleft) 2006 by Derek Yerger - Free to distribute freely.
The CRC code was excerpted and inspired by the Dallas Semiconductor
sample code bearing this copyright.
//---------------------------------------------------------------------------
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included
// in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// Except as contained in this notice, the name of Dallas Semiconductor
// shall not be used except as stated in the Dallas Semiconductor
// Branding Policy.
//--------------------------------------------------------------------------
*/
#include "OneWire.h"
OneWire::OneWire(uint8_t pin)
{
pinMode(pin, INPUT);
bitmask = PIN_TO_BITMASK(pin);
baseReg = PIN_TO_BASEREG(pin);
#if ONEWIRE_SEARCH
reset_search();
#endif
}
// Perform the onewire reset function. We will wait up to 250uS for
// the bus to come high, if it doesn't then it is broken or shorted
// and we return a 0;
//
// Returns 1 if a device asserted a presence pulse, 0 otherwise.
//
uint8_t OneWire::reset(void)
{
IO_REG_TYPE mask = bitmask;
volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
uint8_t r;
uint8_t retries = 125;
noInterrupts();
DIRECT_MODE_INPUT(reg, mask);
interrupts();
// wait until the wire is high... just in case
do {
if (--retries == 0) return 0;
delayMicroseconds(2);
} while ( !DIRECT_READ(reg, mask));
noInterrupts();
DIRECT_WRITE_LOW(reg, mask);
DIRECT_MODE_OUTPUT(reg, mask); // drive output low
interrupts();
delayMicroseconds(480);
noInterrupts();
DIRECT_MODE_INPUT(reg, mask); // allow it to float
delayMicroseconds(70);
r = !DIRECT_READ(reg, mask);
interrupts();
delayMicroseconds(410);
return r;
}
//
// Write a bit. Port and bit is used to cut lookup time and provide
// more certain timing.
//
void OneWire::write_bit(uint8_t v)
{
IO_REG_TYPE mask=bitmask;
volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
if (v & 1) {
noInterrupts();
DIRECT_WRITE_LOW(reg, mask);
DIRECT_MODE_OUTPUT(reg, mask); // drive output low
delayMicroseconds(10);
DIRECT_WRITE_HIGH(reg, mask); // drive output high
interrupts();
delayMicroseconds(55);
} else {
noInterrupts();
DIRECT_WRITE_LOW(reg, mask);
DIRECT_MODE_OUTPUT(reg, mask); // drive output low
delayMicroseconds(65);
DIRECT_WRITE_HIGH(reg, mask); // drive output high
interrupts();
delayMicroseconds(5);
}
}
//
// Read a bit. Port and bit is used to cut lookup time and provide
// more certain timing.
//
uint8_t OneWire::read_bit(void)
{
IO_REG_TYPE mask=bitmask;
volatile IO_REG_TYPE *reg IO_REG_ASM = baseReg;
uint8_t r;
noInterrupts();
DIRECT_MODE_OUTPUT(reg, mask);
DIRECT_WRITE_LOW(reg, mask);
delayMicroseconds(3);
DIRECT_MODE_INPUT(reg, mask); // let pin float, pull up will raise
delayMicroseconds(10);
r = DIRECT_READ(reg, mask);
interrupts();
delayMicroseconds(53);
return r;
}
//
// Write a byte. The writing code uses the active drivers to raise the
// pin high, if you need power after the write (e.g. DS18S20 in
// parasite power mode) then set 'power' to 1, otherwise the pin will
// go tri-state at the end of the write to avoid heating in a short or
// other mishap.
//
void OneWire::write(uint8_t v, uint8_t power /* = 0 */) {
uint8_t bitMask;
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
OneWire::write_bit( (bitMask & v)?1:0);
}
if ( !power) {
noInterrupts();
DIRECT_MODE_INPUT(baseReg, bitmask);
DIRECT_WRITE_LOW(baseReg, bitmask);
interrupts();
}
}
void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) {
for (uint16_t i = 0 ; i < count ; i++)
write(buf[i]);
if (!power) {
noInterrupts();
DIRECT_MODE_INPUT(baseReg, bitmask);
DIRECT_WRITE_LOW(baseReg, bitmask);
interrupts();
}
}
//
// Read a byte
//
uint8_t OneWire::read() {
uint8_t bitMask;
uint8_t r = 0;
for (bitMask = 0x01; bitMask; bitMask <<= 1) {
if ( OneWire::read_bit()) r |= bitMask;
}
return r;
}
void OneWire::read_bytes(uint8_t *buf, uint16_t count) {
for (uint16_t i = 0 ; i < count ; i++)
buf[i] = read();
}
//
// Do a ROM select
//
void OneWire::select(const uint8_t rom[8])
{
uint8_t i;
write(0x55); // Choose ROM
for (i = 0; i < 8; i++) write(rom[i]);
}
//
// Do a ROM skip
//
void OneWire::skip()
{
write(0xCC); // Skip ROM
}
void OneWire::depower()
{
noInterrupts();
DIRECT_MODE_INPUT(baseReg, bitmask);
interrupts();
}
#if ONEWIRE_SEARCH
//
// You need to use this function to start a search again from the beginning.
// You do not need to do it for the first search, though you could.
//
void OneWire::reset_search()
{
// reset the search state
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
for(int i = 7; ; i--) {
ROM_NO[i] = 0;
if ( i == 0) break;
}
}
// Setup the search to find the device type 'family_code' on the next call
// to search(*newAddr) if it is present.
//
void OneWire::target_search(uint8_t family_code)
{
// set the search state to find SearchFamily type devices
ROM_NO[0] = family_code;
for (uint8_t i = 1; i < 8; i++)
ROM_NO[i] = 0;
LastDiscrepancy = 64;
LastFamilyDiscrepancy = 0;
LastDeviceFlag = FALSE;
}
//
// Perform a search. If this function returns a '1' then it has
// enumerated the next device and you may retrieve the ROM from the
// OneWire::address variable. If there are no devices, no further
// devices, or something horrible happens in the middle of the
// enumeration then a 0 is returned. If a new device is found then
// its address is copied to newAddr. Use OneWire::reset_search() to
// start over.
//
// --- Replaced by the one from the Dallas Semiconductor web site ---
//--------------------------------------------------------------------------
// Perform the 1-Wire Search Algorithm on the 1-Wire bus using the existing
// search state.
// Return TRUE : device found, ROM number in ROM_NO buffer
// FALSE : device not found, end of search
//
uint8_t OneWire::search(uint8_t *newAddr)
{
uint8_t id_bit_number;
uint8_t last_zero, rom_byte_number, search_result;
uint8_t id_bit, cmp_id_bit;
unsigned char rom_byte_mask, search_direction;
// initialize for search
id_bit_number = 1;
last_zero = 0;
rom_byte_number = 0;
rom_byte_mask = 1;
search_result = 0;
// if the last call was not the last one
if (!LastDeviceFlag)
{
// 1-Wire reset
if (!reset())
{
// reset the search
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
return FALSE;
}
// issue the search command
write(0xF0);
// loop to do the search
do
{
// read a bit and its complement
id_bit = read_bit();
cmp_id_bit = read_bit();
// check for no devices on 1-wire
if ((id_bit == 1) && (cmp_id_bit == 1))
break;
else
{
// all devices coupled have 0 or 1
if (id_bit != cmp_id_bit)
search_direction = id_bit; // bit write value for search
else
{
// if this discrepancy if before the Last Discrepancy
// on a previous next then pick the same as last time
if (id_bit_number < LastDiscrepancy)
search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0);
else
// if equal to last pick 1, if not then pick 0
search_direction = (id_bit_number == LastDiscrepancy);
// if 0 was picked then record its position in LastZero
if (search_direction == 0)
{
last_zero = id_bit_number;
// check for Last discrepancy in family
if (last_zero < 9)
LastFamilyDiscrepancy = last_zero;
}
}
// set or clear the bit in the ROM byte rom_byte_number
// with mask rom_byte_mask
if (search_direction == 1)
ROM_NO[rom_byte_number] |= rom_byte_mask;
else
ROM_NO[rom_byte_number] &= ~rom_byte_mask;
// serial number search direction write bit
write_bit(search_direction);
// increment the byte counter id_bit_number
// and shift the mask rom_byte_mask
id_bit_number++;
rom_byte_mask <<= 1;
// if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask
if (rom_byte_mask == 0)
{
rom_byte_number++;
rom_byte_mask = 1;
}
}
}
while(rom_byte_number < 8); // loop until through all ROM bytes 0-7
// if the search was successful then
if (!(id_bit_number < 65))
{
// search successful so set LastDiscrepancy,LastDeviceFlag,search_result
LastDiscrepancy = last_zero;
// check for last device
if (LastDiscrepancy == 0)
LastDeviceFlag = TRUE;
search_result = TRUE;
}
}
// if no device found then reset counters so next 'search' will be like a first
if (!search_result || !ROM_NO[0])
{
LastDiscrepancy = 0;
LastDeviceFlag = FALSE;
LastFamilyDiscrepancy = 0;
search_result = FALSE;
}
for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i];
return search_result;
}
#endif
#if ONEWIRE_CRC
// The 1-Wire CRC scheme is described in Maxim Application Note 27:
// "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products"
//
#if ONEWIRE_CRC8_TABLE
// This table comes from Dallas sample code where it is freely reusable,
// though Copyright (C) 2000 Dallas Semiconductor Corporation
static const uint8_t PROGMEM dscrc_table[] = {
0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53};
//
// Compute a Dallas Semiconductor 8 bit CRC. These show up in the ROM
// and the registers. (note: this might better be done without to
// table, it would probably be smaller and certainly fast enough
// compared to all those delayMicrosecond() calls. But I got
// confused, so I use this table from the examples.)
//
uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;
while (len--) {
crc = pgm_read_byte(dscrc_table + (crc ^ *addr++));
}
return crc;
}
#else
//
// Compute a Dallas Semiconductor 8 bit CRC directly.
// this is much slower, but much smaller, than the lookup table.
//
uint8_t OneWire::crc8(const uint8_t *addr, uint8_t len)
{
uint8_t crc = 0;
while (len--) {
uint8_t inbyte = *addr++;
for (uint8_t i = 8; i; i--) {
uint8_t mix = (crc ^ inbyte) & 0x01;
crc >>= 1;
if (mix) crc ^= 0x8C;
inbyte >>= 1;
}
}
return crc;
}
#endif
#if ONEWIRE_CRC16
bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc)
{
crc = ~crc16(input, len, crc);
return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1];
}
uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc)
{
static const uint8_t oddparity[16] =
{ 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
for (uint16_t i = 0 ; i < len ; i++) {
// Even though we're just copying a byte from the input,
// we'll be doing 16-bit computation with it.
uint16_t cdata = input[i];
cdata = (cdata ^ crc) & 0xff;
crc >>= 8;
if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4])
crc ^= 0xC001;
cdata <<= 6;
crc ^= cdata;
cdata <<= 1;
crc ^= cdata;
}
return crc;
}
#endif
#endif

View File

@ -0,0 +1,240 @@
#ifndef OneWire_h
#define OneWire_h
#include <inttypes.h>
#if ARDUINO >= 100
#include "Arduino.h" // for delayMicroseconds, digitalPinToBitMask, etc
#else
#include "WProgram.h" // for delayMicroseconds
#include "pins_arduino.h" // for digitalPinToBitMask, etc
#endif
// You can exclude certain features from OneWire. In theory, this
// might save some space. In practice, the compiler automatically
// removes unused code (technically, the linker, using -fdata-sections
// and -ffunction-sections when compiling, and Wl,--gc-sections
// when linking), so most of these will not result in any code size
// reduction. Well, unless you try to use the missing features
// and redesign your program to not need them! ONEWIRE_CRC8_TABLE
// is the exception, because it selects a fast but large algorithm
// or a small but slow algorithm.
// you can exclude onewire_search by defining that to 0
#ifndef ONEWIRE_SEARCH
#define ONEWIRE_SEARCH 1
#endif
// You can exclude CRC checks altogether by defining this to 0
#ifndef ONEWIRE_CRC
#define ONEWIRE_CRC 1
#endif
// Select the table-lookup method of computing the 8-bit CRC
// by setting this to 1. The lookup table enlarges code size by
// about 250 bytes. It does NOT consume RAM (but did in very
// old versions of OneWire). If you disable this, a slower
// but very compact algorithm is used.
#ifndef ONEWIRE_CRC8_TABLE
#define ONEWIRE_CRC8_TABLE 1
#endif
// You can allow 16-bit CRC checks by defining this to 1
// (Note that ONEWIRE_CRC must also be 1.)
#ifndef ONEWIRE_CRC16
#define ONEWIRE_CRC16 1
#endif
#define FALSE 0
#define TRUE 1
// Platform specific I/O definitions
#if defined(__AVR__)
#define PIN_TO_BASEREG(pin) (portInputRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint8_t
#define IO_REG_ASM asm("r30")
#define DIRECT_READ(base, mask) (((*(base)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base)+1)) &= ~(mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+1)) |= (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base)+2)) &= ~(mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+2)) |= (mask))
#elif defined(__MK20DX128__)
#define PIN_TO_BASEREG(pin) (portOutputRegister(pin))
#define PIN_TO_BITMASK(pin) (1)
#define IO_REG_TYPE uint8_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask) (*((base)+512))
#define DIRECT_MODE_INPUT(base, mask) (*((base)+640) = 0)
#define DIRECT_MODE_OUTPUT(base, mask) (*((base)+640) = 1)
#define DIRECT_WRITE_LOW(base, mask) (*((base)+256) = 1)
#define DIRECT_WRITE_HIGH(base, mask) (*((base)+128) = 1)
#elif defined(__SAM3X8E__)
// Arduino 1.5.1 may have a bug in delayMicroseconds() on Arduino Due.
// http://arduino.cc/forum/index.php/topic,141030.msg1076268.html#msg1076268
// If you have trouble with OneWire on Arduino Due, please check the
// status of delayMicroseconds() before reporting a bug in OneWire!
#define PIN_TO_BASEREG(pin) (&(digitalPinToPort(pin)->PIO_PER))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask) (((*((base)+15)) & (mask)) ? 1 : 0)
#define DIRECT_MODE_INPUT(base, mask) ((*((base)+5)) = (mask))
#define DIRECT_MODE_OUTPUT(base, mask) ((*((base)+4)) = (mask))
#define DIRECT_WRITE_LOW(base, mask) ((*((base)+13)) = (mask))
#define DIRECT_WRITE_HIGH(base, mask) ((*((base)+12)) = (mask))
#ifndef PROGMEM
#define PROGMEM
#endif
#ifndef pgm_read_byte
#define pgm_read_byte(addr) (*(const uint8_t *)(addr))
#endif
#elif defined(__PIC32MX__)
#define PIN_TO_BASEREG(pin) (portModeRegister(digitalPinToPort(pin)))
#define PIN_TO_BITMASK(pin) (digitalPinToBitMask(pin))
#define IO_REG_TYPE uint32_t
#define IO_REG_ASM
#define DIRECT_READ(base, mask) (((*(base+4)) & (mask)) ? 1 : 0) //PORTX + 0x10
#define DIRECT_MODE_INPUT(base, mask) ((*(base+2)) = (mask)) //TRISXSET + 0x08
#define DIRECT_MODE_OUTPUT(base, mask) ((*(base+1)) = (mask)) //TRISXCLR + 0x04
#define DIRECT_WRITE_LOW(base, mask) ((*(base+8+1)) = (mask)) //LATXCLR + 0x24
#define DIRECT_WRITE_HIGH(base, mask) ((*(base+8+2)) = (mask)) //LATXSET + 0x28
#elif defined(__STM32F1XX__)
#define PIN_TO_BASEREG(pin) ( portConfigRegister(pin) )
#define PIN_TO_BITMASK(pin) ( pin )
#define IO_REG_TYPE uint32
#define IO_REG_ASM
#define DIRECT_READ(base, pin) (( gpio_read_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit) ) ? HIGH : LOW)
#define DIRECT_WRITE_LOW(base, pin) ( gpio_write_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit,LOW) )
#define DIRECT_WRITE_HIGH(base, pin) ( gpio_write_bit(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit,HIGH) )
#define DIRECT_MODE_INPUT(base, pin) (gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_INPUT_FLOATING))
#define DIRECT_MODE_OUTPUT(base, pin) (gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_OUTPUT_PP))
#else
#error "Please define I/O register types here"
#endif
class OneWire
{
private:
IO_REG_TYPE bitmask;
volatile IO_REG_TYPE *baseReg;
#if ONEWIRE_SEARCH
// global search state
unsigned char ROM_NO[8];
uint8_t LastDiscrepancy;
uint8_t LastFamilyDiscrepancy;
uint8_t LastDeviceFlag;
#endif
public:
OneWire( uint8_t pin);
// Perform a 1-Wire reset cycle. Returns 1 if a device responds
// with a presence pulse. Returns 0 if there is no device or the
// bus is shorted or otherwise held low for more than 250uS
uint8_t reset(void);
// Issue a 1-Wire rom select command, you do the reset first.
void select(const uint8_t rom[8]);
// Issue a 1-Wire rom skip command, to address all on bus.
void skip(void);
// Write a byte. If 'power' is one then the wire is held high at
// the end for parasitically powered devices. You are responsible
// for eventually depowering it by calling depower() or doing
// another read or write.
void write(uint8_t v, uint8_t power = 0);
void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0);
// Read a byte.
uint8_t read(void);
void read_bytes(uint8_t *buf, uint16_t count);
// Write a bit. The bus is always left powered at the end, see
// note in write() about that.
void write_bit(uint8_t v);
// Read a bit.
uint8_t read_bit(void);
// Stop forcing power onto the bus. You only need to do this if
// you used the 'power' flag to write() or used a write_bit() call
// and aren't about to do another read or write. You would rather
// not leave this powered if you don't have to, just in case
// someone shorts your bus.
void depower(void);
#if ONEWIRE_SEARCH
// Clear the search state so that if will start from the beginning again.
void reset_search();
// Setup the search to find the device type 'family_code' on the next call
// to search(*newAddr) if it is present.
void target_search(uint8_t family_code);
// Look for the next device. Returns 1 if a new address has been
// returned. A zero might mean that the bus is shorted, there are
// no devices, or you have already retrieved all of them. It
// might be a good idea to check the CRC to make sure you didn't
// get garbage. The order is deterministic. You will always get
// the same devices in the same order.
uint8_t search(uint8_t *newAddr);
#endif
#if ONEWIRE_CRC
// Compute a Dallas Semiconductor 8 bit CRC, these are used in the
// ROM and scratchpad registers.
static uint8_t crc8(const uint8_t *addr, uint8_t len);
#if ONEWIRE_CRC16
// Compute the 1-Wire CRC16 and compare it against the received CRC.
// Example usage (reading a DS2408):
// // Put everything in a buffer so we can compute the CRC easily.
// uint8_t buf[13];
// buf[0] = 0xF0; // Read PIO Registers
// buf[1] = 0x88; // LSB address
// buf[2] = 0x00; // MSB address
// WriteBytes(net, buf, 3); // Write 3 cmd bytes
// ReadBytes(net, buf+3, 10); // Read 6 data bytes, 2 0xFF, 2 CRC16
// if (!CheckCRC16(buf, 11, &buf[11])) {
// // Handle error.
// }
//
// @param input - Array of bytes to checksum.
// @param len - How many bytes to use.
// @param inverted_crc - The two CRC16 bytes in the received data.
// This should just point into the received data,
// *not* at a 16-bit integer.
// @param crc - The crc starting value (optional)
// @return True, iff the CRC matches.
static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0);
// Compute a Dallas Semiconductor 16 bit CRC. This is required to check
// the integrity of data received from many 1-Wire devices. Note that the
// CRC computed here is *not* what you'll get from the 1-Wire network,
// for two reasons:
// 1) The CRC is transmitted bitwise inverted.
// 2) Depending on the endian-ness of your processor, the binary
// representation of the two-byte return value may have a different
// byte order than the two bytes you get from 1-Wire.
// @param input - Array of bytes to checksum.
// @param len - How many bytes to use.
// @param crc - The crc starting value (optional)
// @return The CRC16, as defined by Dallas Semiconductor.
static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0);
#endif
#endif
};
#endif

View File

@ -0,0 +1,112 @@
#include <OneWire.h>
// OneWire DS18S20, DS18B20, DS1822 Temperature Example
//
// http://www.pjrc.com/teensy/td_libs_OneWire.html
//
// The DallasTemperature library can do all this work for you!
// http://milesburton.com/Dallas_Temperature_Control_Library
OneWire ds(10); // on pin 10 (a 4.7K resistor is necessary)
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
byte i;
byte present = 0;
byte type_s;
byte data[12];
byte addr[8];
float celsius, fahrenheit;
if ( !ds.search(addr)) {
Serial.println("No more addresses.");
Serial.println();
ds.reset_search();
delay(250);
return;
}
Serial.print("ROM =");
for( i = 0; i < 8; i++) {
Serial.write(' ');
Serial.print(addr[i], HEX);
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
Serial.println();
// the first ROM byte indicates which chip
switch (addr[0]) {
case 0x10:
Serial.println(" Chip = DS18S20"); // or old DS1820
type_s = 1;
break;
case 0x28:
Serial.println(" Chip = DS18B20");
type_s = 0;
break;
case 0x22:
Serial.println(" Chip = DS1822");
type_s = 0;
break;
default:
Serial.println("Device is not a DS18x20 family device.");
return;
}
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
Serial.print(" Data = ");
Serial.print(present, HEX);
Serial.print(" ");
for ( i = 0; i < 9; i++) { // we need 9 bytes
data[i] = ds.read();
Serial.print(data[i], HEX);
Serial.print(" ");
}
Serial.print(" CRC=");
Serial.print(OneWire::crc8(data, 8), HEX);
Serial.println();
// Convert the data to actual temperature
// because the result is a 16 bit signed integer, it should
// be stored to an "int16_t" type, which is always 16 bits
// even when compiled on a 32 bit processor.
int16_t raw = (data[1] << 8) | data[0];
if (type_s) {
raw = raw << 3; // 9 bit resolution default
if (data[7] == 0x10) {
// "count remain" gives full 12 bit resolution
raw = (raw & 0xFFF0) + 12 - data[6];
}
} else {
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
}
celsius = (float)raw / 16.0;
fahrenheit = celsius * 1.8 + 32.0;
Serial.print(" Temperature = ");
Serial.print(celsius);
Serial.print(" Celsius, ");
Serial.print(fahrenheit);
Serial.println(" Fahrenheit");
}

View File

@ -0,0 +1,77 @@
#include <OneWire.h>
/*
* DS2408 8-Channel Addressable Switch
*
* Writte by Glenn Trewitt, glenn at trewitt dot org
*
* Some notes about the DS2408:
* - Unlike most input/output ports, the DS2408 doesn't have mode bits to
* set whether the pins are input or output. If you issue a read command,
* they're inputs. If you write to them, they're outputs.
* - For reading from a switch, you should use 10K pull-up resisters.
*/
void PrintBytes(uint8_t* addr, uint8_t count, bool newline=0) {
for (uint8_t i = 0; i < count; i++) {
Serial.print(addr[i]>>4, HEX);
Serial.print(addr[i]&0x0f, HEX);
}
if (newline)
Serial.println();
}
void ReadAndReport(OneWire* net, uint8_t* addr) {
Serial.print(" Reading DS2408 ");
PrintBytes(addr, 8);
Serial.println();
uint8_t buf[13]; // Put everything in the buffer so we can compute CRC easily.
buf[0] = 0xF0; // Read PIO Registers
buf[1] = 0x88; // LSB address
buf[2] = 0x00; // MSB address
net->write_bytes(buf, 3);
net->read_bytes(buf+3, 10); // 3 cmd bytes, 6 data bytes, 2 0xFF, 2 CRC16
net->reset();
if (!OneWire::check_crc16(buf, 11, &buf[11])) {
Serial.print("CRC failure in DS2408 at ");
PrintBytes(addr, 8, true);
return;
}
Serial.print(" DS2408 data = ");
// First 3 bytes contain command, register address.
Serial.println(buf[3], BIN);
}
OneWire net(10); // on pin 10
void setup(void) {
Serial.begin(9600);
}
void loop(void) {
byte i;
byte present = 0;
byte addr[8];
if (!net.search(addr)) {
Serial.print("No more addresses.\n");
net.reset_search();
delay(1000);
return;
}
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.print("CRC is not valid!\n");
return;
}
if (addr[0] != 0x29) {
PrintBytes(addr, 8);
Serial.print(" is not a DS2408.\n");
return;
}
ReadAndReport(&net, addr);
}

View File

@ -0,0 +1,90 @@
/*
DS250x add-only programmable memory reader w/SKIP ROM.
The DS250x is a 512/1024bit add-only PROM(you can add data but cannot change the old one) that's used mainly for device identification purposes
like serial number, mfgr data, unique identifiers, etc. It uses the Maxim 1-wire bus.
This sketch will use the SKIP ROM function that skips the 1-Wire search phase since we only have one device connected in the bus on digital pin 6.
If more than one device is connected to the bus, it will fail.
Sketch will not verify if device connected is from the DS250x family since the skip rom function effectively skips the family-id byte readout.
thus it is possible to run this sketch with any Maxim OneWire device in which case the command CRC will most likely fail.
Sketch will only read the first page of memory(32bits) starting from the lower address(0000h), if more than 1 device is present, then use the sketch with search functions.
Remember to put a 4.7K pullup resistor between pin 6 and +Vcc
To change the range or ammount of data to read, simply change the data array size, LSB/MSB addresses and for loop iterations
This example code is in the public domain and is provided AS-IS.
Built with Arduino 0022 and PJRC OneWire 2.0 library http://www.pjrc.com/teensy/td_libs_OneWire.html
created by Guillermo Lovato <glovato@gmail.com>
march/2011
*/
#include <OneWire.h>
OneWire ds(6); // OneWire bus on digital pin 6
void setup() {
Serial.begin (9600);
}
void loop() {
byte i; // This is for the for loops
boolean present; // device present var
byte data[32]; // container for the data from device
byte leemem[3] = { // array with the commands to initiate a read, DS250x devices expect 3 bytes to start a read: command,LSB&MSB adresses
0xF0 , 0x00 , 0x00 }; // 0xF0 is the Read Data command, followed by 00h 00h as starting address(the beginning, 0000h)
byte ccrc; // Variable to store the command CRC
byte ccrc_calc;
present = ds.reset(); // OneWire bus reset, always needed to start operation on the bus, returns a 1/TRUE if there's a device present.
ds.skip(); // Skip ROM search
if (present == TRUE){ // We only try to read the data if there's a device present
Serial.println("DS250x device present");
ds.write(leemem[0],1); // Read data command, leave ghost power on
ds.write(leemem[1],1); // LSB starting address, leave ghost power on
ds.write(leemem[2],1); // MSB starting address, leave ghost power on
ccrc = ds.read(); // DS250x generates a CRC for the command we sent, we assign a read slot and store it's value
ccrc_calc = OneWire::crc8(leemem, 3); // We calculate the CRC of the commands we sent using the library function and store it
if ( ccrc_calc != ccrc) { // Then we compare it to the value the ds250x calculated, if it fails, we print debug messages and abort
Serial.println("Invalid command CRC!");
Serial.print("Calculated CRC:");
Serial.println(ccrc_calc,HEX); // HEX makes it easier to observe and compare
Serial.print("DS250x readback CRC:");
Serial.println(ccrc,HEX);
return; // Since CRC failed, we abort the rest of the loop and start over
}
Serial.println("Data is: "); // For the printout of the data
for ( i = 0; i < 32; i++) { // Now it's time to read the PROM data itself, each page is 32 bytes so we need 32 read commands
data[i] = ds.read(); // we store each read byte to a different position in the data array
Serial.print(data[i]); // printout in ASCII
Serial.print(" "); // blank space
}
Serial.println();
delay(5000); // Delay so we don't saturate the serial output
}
else { // Nothing is connected in the bus
Serial.println("Nothing connected");
delay(3000);
}
}

View File

@ -0,0 +1,38 @@
#######################################
# Syntax Coloring Map For OneWire
#######################################
#######################################
# Datatypes (KEYWORD1)
#######################################
OneWire KEYWORD1
#######################################
# Methods and Functions (KEYWORD2)
#######################################
reset KEYWORD2
write_bit KEYWORD2
read_bit KEYWORD2
write KEYWORD2
write_bytes KEYWORD2
read KEYWORD2
read_bytes KEYWORD2
select KEYWORD2
skip KEYWORD2
depower KEYWORD2
reset_search KEYWORD2
search KEYWORD2
crc8 KEYWORD2
crc16 KEYWORD2
check_crc16 KEYWORD2
#######################################
# Instances (KEYWORD2)
#######################################
#######################################
# Constants (LITERAL1)
#######################################

View File

@ -31,6 +31,8 @@
#include "SPI.h"
//#define SPI_DEBUG
#include <libmaple/timer.h>
#include <libmaple/util.h>
#include <libmaple/rcc.h>
@ -54,11 +56,9 @@ struct spi_pins {
static const spi_pins* dev_to_spi_pins(spi_dev *dev);
static void enable_device(spi_dev *dev,
bool as_master,
SPIFrequency frequency,
spi_cfg_flag endianness,
spi_mode mode);
static void configure_gpios(spi_dev *dev, bool as_master);
static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq);
#if (BOARD_NR_SPI >= 3) && !defined(STM32_HIGH_DENSITY)
#error "The SPI library is misconfigured: 3 SPI ports only available on high density STM32 devices"
@ -118,37 +118,32 @@ SPIClass::SPIClass(uint32 spi_num) {
* Set up/tear down
*/
void SPIClass::begin(uint32_t frequency, uint8_t bitOrder, uint8_t mode) {
if (mode >= 4) {
ASSERT(0);
return;
}
//Serial.print(frequency);Serial.print(",");Serial.print(bitOrder);Serial.print(",");Serial.println(mode);// debugging
spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB;
spi_mode m = (spi_mode)mode;
enable_device(this->spi_d, true, (SPIFrequency)frequency, end, m);
}
void SPIClass::begin(void) {
this->begin(_clockDividerToFrequenyMap[_settings.clockDivider],_settings.bitOrder,_settings.dataMode);//originally SPI_1_125MHZ,MSBFIRST,0);
}
void SPIClass::beginSlave(uint32 bitOrder, uint32 mode) {
if (mode >= 4) {
if (dataMode >= 4) {
ASSERT(0);
return;
}
spi_cfg_flag end = bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB;
spi_mode m = (spi_mode)mode;
enable_device(this->spi_d, false, (SPIFrequency)0, end, m);
uint32 flags = ((bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE | SPI_SOFT_SS);
spi_init(spi_d);
configure_gpios(spi_d, 1);
#ifdef SPI_DEBUG
Serial.print("spi_master_enable("); Serial.print(clockDivider); Serial.print(","); Serial.print(dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
#endif
spi_master_enable(spi_d, (spi_baud_rate)clockDivider, (spi_mode)dataMode, flags);
}
void SPIClass::beginSlave(void) {
this->beginSlave(_settings.bitOrder, _settings.dataMode);
if (dataMode >= 4) {
ASSERT(0);
return;
}
uint32 flags = ((bitOrder == MSBFIRST ? SPI_FRAME_MSB : SPI_FRAME_LSB) | SPI_DFF_8_BIT | SPI_SW_SLAVE);
spi_init(spi_d);
configure_gpios(spi_d, 0);
#ifdef SPI_DEBUG
Serial.print("spi_slave_enable("); Serial.print(dataMode); Serial.print(","); Serial.print(flags); Serial.println(")");
#endif
spi_slave_enable(spi_d, (spi_mode)dataMode, flags);
}
void SPIClass::end(void) {
@ -172,15 +167,22 @@ void SPIClass::end(void) {
/* Roger Clark added 3 functions */
void SPIClass::setClockDivider(uint32_t clockDivider)
{
// Serial.print("Clock divider set to "); Serial.println(clockDivider);// debugging
_settings.clockDivider = clockDivider;
#ifdef SPI_DEBUG
Serial.print("Clock divider set to "); Serial.println(clockDivider);
#endif
this->clockDivider = clockDivider;
this->begin();
}
void SPIClass::setBitOrder(uint8_t bitOrder)
void SPIClass::setBitOrder(BitOrder bitOrder)
{
_settings.bitOrder = bitOrder;
#ifdef SPI_DEBUG
Serial.print("Bit order set to "); Serial.println(bitOrder);
#endif
this->bitOrder = bitOrder;
this->begin();
}
void SPIClass::setDataMode(uint8_t dataMode)
{
/* Notes. As far as I can tell, the AVR numbers for dataMode appear to match the numbers required by the STM32
@ -210,16 +212,26 @@ bit 0 - CPHA : Clock phase
If someone finds this is not the case or sees a logic error with this let me know ;-)
*/
_settings.dataMode = dataMode;
#ifdef SPI_DEBUG
Serial.print("Data mode set to "); Serial.println(dataMode);
#endif
this->dataMode = dataMode;
this->begin();
}
void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
{
_SSPin=pin;
pinMode(_SSPin,OUTPUT);
// digitalWrite(_SSPin,LOW);
#ifdef SPI_DEBUG
Serial.println("SPIClass::beginTransaction");
#endif
//_SSPin=pin;
//pinMode(_SSPin,OUTPUT);
//digitalWrite(_SSPin,LOW);
setBitOrder(settings.bitOrder);
setDataMode(settings.dataMode);
setClockDivider(determine_baud_rate(spi_d, settings.clock));
begin();
#if 0
// code from SAM core
uint8_t mode = interruptMode;
@ -245,7 +257,10 @@ void SPIClass::beginTransaction(uint8_t pin, SPISettings settings)
void SPIClass::endTransaction(void)
{
// digitalWrite(_SSPin,HIGH);
#ifdef SPI_DEBUG
Serial.println("SPIClass::endTransaction");
#endif
//digitalWrite(_SSPin,HIGH);
#if false
// code from SAM core
uint8_t mode = interruptMode;
@ -291,11 +306,18 @@ void SPIClass::write(const uint8 *data, uint32 length) {
while (txed < length) {
txed += spi_tx(this->spi_d, data + txed, length - txed);
}
while (spi_is_tx_empty(this->spi_d) == 0); // "4. After writing the last data item into the SPI_DR register, wait until TXE=1 ..."
while (spi_is_busy(this->spi_d) != 0); // "... then wait until BSY=0, this indicates that the transmission of the last data is complete."
}
uint8 SPIClass::transfer(uint8 byte) {
this->write(byte);
return this->read();
uint8 b;
spi_tx_reg(this->spi_d, byte); // "2. Write the first data item to be transmitted into the SPI_DR register (this clears the TXE flag)."
while (spi_is_rx_nonempty(this->spi_d) == 0); // "4. Wait until RXNE=1 ..."
b = spi_rx_reg(this->spi_d); // "... and read the last received data."
while (spi_is_tx_empty(this->spi_d) == 0); // "5. Wait until TXE=1 ..."
while (spi_is_busy(this->spi_d) != 0); // "... and then wait until BSY=0 before disabling the SPI."
return b;
}
void SPIClass::attachInterrupt(void) {
@ -354,9 +376,6 @@ uint8 SPIClass::recv(void) {
* Auxiliary functions
*/
static void configure_gpios(spi_dev *dev, bool as_master);
static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq);
static const spi_pins* dev_to_spi_pins(spi_dev *dev) {
switch (dev->clk_id) {
#if BOARD_NR_SPI >= 1
@ -372,27 +391,6 @@ static const spi_pins* dev_to_spi_pins(spi_dev *dev) {
}
}
/* Enables the device in master or slave full duplex mode. If you
* change this code, you must ensure that appropriate changes are made
* to SPIClass::end(). */
static void enable_device(spi_dev *dev,
bool as_master,
SPIFrequency freq,
spi_cfg_flag endianness,
spi_mode mode) {
spi_baud_rate baud = determine_baud_rate(dev, freq);
uint32 cfg_flags = (endianness | SPI_DFF_8_BIT | SPI_SW_SLAVE |
(as_master ? SPI_SOFT_SS : 0));
spi_init(dev);
configure_gpios(dev, as_master);
if (as_master) {
spi_master_enable(dev, baud, mode, cfg_flags);
} else {
spi_slave_enable(dev, mode, cfg_flags);
}
}
static void disable_pwm(const stm32_pin_info *i) {
if (i->timer_device) {
timer_set_mode(i->timer_device, i->timer_channel, TIMER_DISABLED);
@ -421,7 +419,7 @@ static void configure_gpios(spi_dev *dev, bool as_master) {
mosii->gpio_bit);
}
static const spi_baud_rate baud_rates[MAX_SPI_FREQS] __FLASH__ = {
static const spi_baud_rate baud_rates[8] __FLASH__ = {
SPI_BAUD_PCLK_DIV_2,
SPI_BAUD_PCLK_DIV_4,
SPI_BAUD_PCLK_DIV_8,
@ -436,15 +434,23 @@ static const spi_baud_rate baud_rates[MAX_SPI_FREQS] __FLASH__ = {
* Note: This assumes you're on a LeafLabs-style board
* (CYCLES_PER_MICROSECOND == 72, APB2 at 72MHz, APB1 at 36MHz).
*/
static spi_baud_rate determine_baud_rate(spi_dev *dev, SPIFrequency freq) {
if (rcc_dev_clk(dev->clk_id) == RCC_APB2 && freq == SPI_140_625KHZ) {
/* APB2 peripherals are too fast for 140.625 KHz */
ASSERT(0);
return (spi_baud_rate)~0;
static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq) {
uint32_t clock = 0, i;
#ifdef SPI_DEBUG
Serial.print("determine_baud_rate("); Serial.print(freq); Serial.println(")");
#endif
switch (rcc_dev_clk(dev->clk_id))
{
case RCC_APB2: clock = STM32_PCLK2; break; // 72 Mhz
case RCC_APB1: clock = STM32_PCLK1; break; // 36 Mhz
}
return (rcc_dev_clk(dev->clk_id) == RCC_APB2 ?
baud_rates[freq + 1] :
baud_rates[freq]);
clock /= 2;
i = 0;
while (i < 7 && freq < clock) {
clock /= 2;
i++;
}
return baud_rates[i];
}
SPIClass SPI(1);

View File

@ -45,39 +45,21 @@
#include <stdint.h>
#include <wirish.h>
// SPI_HAS_TRANSACTION means SPI has
// - beginTransaction()
// - endTransaction()
// - usingInterrupt()
// - SPISetting(clock, bitOrder, dataMode)
//#define SPI_HAS_TRANSACTION
/**
* @brief Defines the possible SPI communication speeds.
*/
typedef enum SPIFrequency {
SPI_18MHZ = 0, /**< 18 MHz */
SPI_9MHZ = 1, /**< 9 MHz */
SPI_4_5MHZ = 2, /**< 4.5 MHz */
SPI_2_25MHZ = 3, /**< 2.25 MHz */
SPI_1_125MHZ = 4, /**< 1.125 MHz */
SPI_562_500KHZ = 5, /**< 562.500 KHz */
SPI_281_250KHZ = 6, /**< 281.250 KHz */
SPI_140_625KHZ = 7, /**< 140.625 KHz */
} SPIFrequency;
#define MAX_SPI_FREQS 8
// defines from AVR SPI.h
#define SPI_CLOCK_DIV2 0x04
#define SPI_CLOCK_DIV4 0x00
#define SPI_CLOCK_DIV16 0x01
#define SPI_CLOCK_DIV8 0x05
#define SPI_CLOCK_DIV32 0x06
#define SPI_CLOCK_DIV64 0x02
#define SPI_CLOCK_DIV128 0x03
#define SPI_CLOCK_DIV1 0x07
#define SPI_MODE0 0x00
#define SPI_MODE1 0x02
#define SPI_MODE2 0x02
#define SPI_MODE3 0x03
#define SPI_CLOCK_DIV2 SPI_BAUD_PCLK_DIV_2
#define SPI_CLOCK_DIV4 SPI_BAUD_PCLK_DIV_4
#define SPI_CLOCK_DIV8 SPI_BAUD_PCLK_DIV_8
#define SPI_CLOCK_DIV16 SPI_BAUD_PCLK_DIV_16
#define SPI_CLOCK_DIV32 SPI_BAUD_PCLK_DIV_32
#define SPI_CLOCK_DIV64 SPI_BAUD_PCLK_DIV_64
#define SPI_CLOCK_DIV128 SPI_BAUD_PCLK_DIV_128
#define SPI_CLOCK_DIV256 SPI_BAUD_PCLK_DIV_256
/*
* Roger Clark. 20150106
@ -105,40 +87,37 @@ typedef enum SPIFrequency {
#endif
// PC13 or PA4
#define BOARD_SPI_DEFAULT_SS PA4
//#define BOARD_SPI_DEFAULT_SS PA4
#define BOARD_SPI_DEFAULT_SS PC13
#define SPI_MODE0 SPI_MODE_0
#define SPI_MODE1 SPI_MODE_1
#define SPI_MODE2 SPI_MODE_2
#define SPI_MODE3 SPI_MODE_3
class SPISettings {
public:
SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) {
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, dataMode);
} else {
init_MightInline(clock, bitOrder, dataMode);
}
}
SPISettings() {
init_AlwaysInline(SPI_CLOCK_DIV2, MSBFIRST, SPI_MODE0);
}
uint32_t clockDivider=SPI_CLOCK_DIV2;//belt and braces approach !
uint8_t bitOrder=MSBFIRST;//belt and braces approach !
uint8_t dataMode=SPI_MODE0; //belt and braces approach !
SPISettings(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
if (__builtin_constant_p(clock)) {
init_AlwaysInline(clock, bitOrder, dataMode);
} else {
init_MightInline(clock, bitOrder, dataMode);
}
}
SPISettings() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
private:
void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
{
init_AlwaysInline(clock, bitOrder, dataMode);
}
void init_AlwaysInline(uint32_t clock, uint8_t order, uint8_t mode)
__attribute__((__always_inline__))
{
this->clockDivider=clock;
this->bitOrder = order;
this->dataMode = mode;
}
friend class SPIClass;
void init_MightInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) {
init_AlwaysInline(clock, bitOrder, dataMode);
}
void init_AlwaysInline(uint32_t clock, BitOrder bitOrder, uint8_t dataMode) __attribute__((__always_inline__)) {
this->clock = clock;
this->bitOrder = bitOrder;
this->dataMode = dataMode;
}
uint32_t clock;
BitOrder bitOrder;
uint8_t dataMode;
friend class SPIClass;
};
@ -192,7 +171,7 @@ public:
void endTransaction(void);
void setClockDivider(uint32_t clockDivider);
void setBitOrder(uint8_t bitOrder);
void setBitOrder(BitOrder bitOrder);
void setDataMode(uint8_t dataMode);
// SPI Configuration methods
@ -308,23 +287,11 @@ public:
*/
uint8 recv(void);
private:
/**
* @brief Turn on a SPI port and set its GPIO pin modes for use as master.
*
* SPI port is enabled in full duplex mode, with software slave management.
*
* @param frequency Communication frequency
* @param bitOrder Either LSBFIRST (little-endian) or MSBFIRST (big-endian)
* @param mode SPI mode to use, one of SPI_MODE_0, SPI_MODE_1,
* SPI_MODE_2, and SPI_MODE_3.
*/
void begin(uint32_t frequency, uint8_t bitOrder, uint8_t mode);
SPISettings _settings;
spi_dev *spi_d;
spi_dev *spi_d;
uint8_t _SSPin;
const uint8_t _clockDividerToFrequenyMap[8]={SPI_4_5MHZ,SPI_1_125MHZ,SPI_1_125MHZ,SPI_1_125MHZ,SPI_9MHZ,SPI_2_25MHZ,SPI_1_125MHZ,SPI_18MHZ };// should really be //{SPI_4_5MHZ, SPI_1_125MHZ, SPI_281_250KHZ, SPI_140_625KHZ, SPI_9MHZ, SPI_2_25MHZ, SPI_562_500KHZ }; but the processor won't support the lower speeds so they have been set to 1.25 mhz
uint32_t clockDivider;
uint8_t dataMode;
BitOrder bitOrder;
};

View File

@ -80,7 +80,8 @@ recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compil
##recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--entry=Reset_Handler -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group "{build.path}/syscalls_sam3.c.o" {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group
#-Wl,--entry=__start__
#recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} "{build.variant.path}/{build.variant_system_lib}" "{build.path}/{archive_file}" -Wl,--end-group
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} -Wl,--whole-archive "{build.path}/{archive_file}" -Wl,--no-whole-archive -Wl,--end-group
#recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} -Wl,--whole-archive "{build.path}/{archive_file}" -Wl,--no-whole-archive -Wl,--end-group
recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mcpu={build.mcu} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" -lm -lgcc -mthumb -Wl,--cref -Wl,--check-sections -Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align -Wl,--warn-unresolved-symbols -Wl,--start-group {object_files} "{build.path}/{archive_file}" -Wl,--end-group
## Create eeprom
recipe.objcopy.eep.pattern=

View File

@ -33,13 +33,15 @@
#ifndef _LIBMAPLE_LIBMAPLE_TYPES_H_
#define _LIBMAPLE_LIBMAPLE_TYPES_H_
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint32;
typedef uint32_t uint32;
typedef unsigned long long uint64;
typedef signed char int8;

View File

@ -124,6 +124,7 @@ void usb_cdcacm_putc(char ch);
uint32 usb_cdcacm_tx(const uint8* buf, uint32 len);
uint32 usb_cdcacm_rx(uint8* buf, uint32 len);
uint32 usb_cdcacm_peek(uint8* buf, uint32 len);
uint32 usb_cdcacm_peek_ex(uint8* buf, uint32 offset, uint32 len);
uint32 usb_cdcacm_data_available(void); /* in RX buffer */
uint16 usb_cdcacm_get_pending(void);

View File

@ -353,6 +353,8 @@ typedef enum afio_remap_peripheral {
AFIO_REMAP_TIM2_PARTIAL_2 = AFIO_MAPR_TIM2_REMAP_PA0_PA1_PB10_PB11,
/** Timer 2 full remapping */
AFIO_REMAP_TIM2_FULL = AFIO_MAPR_TIM2_REMAP_FULL,
/** USART 3 part remapping */
AFIO_REMAP_USART3_PARTIAL = AFIO_MAPR_USART3_REMAP_PARTIAL,
/** USART 2 remapping */
AFIO_REMAP_USART2 = AFIO_MAPR_USART2_REMAP,
/** USART 1 remapping */

View File

@ -0,0 +1,13 @@
#ifndef _VARIANT_ARDUINO_STM32_
#define _VARIANT_ARDUINO_STM32_
#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device )
#define digitalPinToBitMask(P) ( BIT(PIN_MAP[P].gpio_bit) )
#define portOutputRegister(port) ( &(port->regs->ODR) )
#define portInputRegister(port) ( &(port->regs->IDR) )
#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) )
#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) )
#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) )
#endif /* _VARIANT_ARDUINO_STM32_ */

View File

@ -1,12 +1,14 @@
#ifndef _VARIANT_ARDUINO_STM32_
#define _VARIANT_ARDUINO_STM32_
// From SAM implementation #define digitalPinToBitMask(P) ( g_APinDescription[P].ulPin )
#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device )
#define digitalPinToBitMask(P) ( BIT(PIN_MAP[P].gpio_bit) )
#define portOutputRegister(port) ( &(port->regs->ODR) )
#define portInputRegister(port) ( &(port->regs->IDR) )
#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) )
#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) )
#warning "TO DO. IMPLEMENT digitalPinToBitMask in variant.h"
// Its likely that this function has no meaning with reference to the STM32 GPIO
// But its required by some libraries.
#define digitalPinToBitMask(P) ( 1 )
#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) )
#endif /* _VARIANT_ARDUINO_STM32_ */

View File

@ -1,12 +1,14 @@
#ifndef _VARIANT_ARDUINO_STM32_
#define _VARIANT_ARDUINO_STM32_
// From SAM implementation #define digitalPinToBitMask(P) ( g_APinDescription[P].ulPin )
#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device )
#define digitalPinToBitMask(P) ( BIT(PIN_MAP[P].gpio_bit) )
#define portOutputRegister(port) ( &(port->regs->ODR) )
#define portInputRegister(port) ( &(port->regs->IDR) )
#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) )
#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) )
#warning "TO DO. IMPLEMENT digitalPinToBitMask in variant.h"
// Its likely that this function has no meaning with reference to the STM32 GPIO
// But its required by some libraries.
#define digitalPinToBitMask(P) ( 1 )
#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) )
#endif /* _VARIANT_ARDUINO_STM32_ */

View File

@ -1,12 +1,14 @@
#ifndef _VARIANT_ARDUINO_STM32_
#define _VARIANT_ARDUINO_STM32_
// From SAM implementation #define digitalPinToBitMask(P) ( g_APinDescription[P].ulPin )
#define digitalPinToPort(P) ( PIN_MAP[P].gpio_device )
#define digitalPinToBitMask(P) ( BIT(PIN_MAP[P].gpio_bit) )
#define portOutputRegister(port) ( &(port->regs->ODR) )
#define portInputRegister(port) ( &(port->regs->IDR) )
#define portSetRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BSRR) )
#define portClearRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->BRR) )
#warning "TO DO. IMPLEMENT digitalPinToBitMask in variant.h"
// Its likely that this function has no meaning with reference to the STM32 GPIO
// But its required by some libraries.
#define digitalPinToBitMask(P) ( 1 )
#define portConfigRegister(pin) ( &(PIN_MAP[pin].gpio_device->regs->CRL) )
#endif /* _VARIANT_ARDUINO_STM32_ */

View File

@ -1,9 +1,11 @@
@echo off
echo Installing Maple DFU driver...
%~dp0wdi-simple --vid 0x1EAF --pid 0x0003 --type 1 --name "Maple DFU" --dest %~dp0maple-dfu
echo Installing Maple Serial driver...
%~dp0wdi-simple --vid 0x1EAF --pid 0x0004 --type 3 --name "Maple Serial" --dest %~dp0maple-serial
@echo off
echo Installing Maple DFU driver...
"%~dp0wdi-simple" --vid 0x1EAF --pid 0x0003 --type 1 --name "Maple DFU" --dest "%~dp0maple-dfu"
echo.
echo Installing Maple Serial driver...
"%~dp0wdi-simple" --vid 0x1EAF --pid 0x0004 --type 3 --name "Maple Serial" --dest "%~dp0maple-serial"
echo.
pause

View File

@ -0,0 +1,315 @@
diff -r -u -N libwdi-1.2.4 (original)/examples/wdi-simple.c libwdi-1.2.4 (modified)/examples/wdi-simple.c
--- libwdi-1.2.4 (original)/examples/wdi-simple.c 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/examples/wdi-simple.c 2015-01-19 11:22:49.026064300 +0100
@@ -57,7 +57,7 @@
printf("-p, --pid <id> set the product ID (PID, use 0x prefix for hex)\n");
printf("-i, --iid <id> set the interface ID (MI)\n");
printf("-t, --type <driver_type> set the driver to install\n");
- printf(" (0=WinUSB, 1=libusb-win32, 2=libusbK, 3=custom)\n");
+ printf(" (0=WinUSB, 1=libusb-win32, 2=libusbK, 3=usbser, 4=custom)\n");
printf("-w, --wcid use a WCID driver instead of a device-specific\n");
printf(" one (WinUSB, libusb-win32 or libusbK only)\n");
printf(" --filter use the libusb-win32 filter driver (requires -t1)\n");
@@ -223,7 +223,7 @@
if (wdi_create_list(&ldev, &ocl) == WDI_SUCCESS) {
r = WDI_SUCCESS;
for (; (ldev != NULL) && (r == WDI_SUCCESS); ldev = ldev->next) {
- if ( (ldev->vid == dev.vid) && (ldev->pid == dev.pid) && (ldev->mi == dev.mi) ) {
+ if ( (ldev->vid == dev.vid) && (ldev->pid == dev.pid) && (ldev->mi == dev.mi) && (ldev->is_composite == dev.is_composite)) {
dev.hardware_id = ldev->hardware_id;
dev.device_id = ldev->device_id;
matching_device_found = TRUE;
diff -r -u -N libwdi-1.2.4 (original)/examples/zadig.c libwdi-1.2.4 (modified)/examples/zadig.c
--- libwdi-1.2.4 (original)/examples/zadig.c 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/examples/zadig.c 2015-01-18 14:52:42.578606600 +0100
@@ -80,8 +80,8 @@
WORD application_version[4];
char app_dir[MAX_PATH], driver_text[64];
char extraction_path[MAX_PATH];
-const char* driver_display_name[WDI_NB_DRIVERS] = { "WinUSB", "libusb-win32", "libusbK", "Custom (extract only)" };
-const char* driver_name[WDI_NB_DRIVERS-1] = { "WinUSB", "libusb0", "libusbK" };
+const char* driver_display_name[WDI_NB_DRIVERS] = { "WinUSB", "libusb-win32", "libusbK", "USB Serial", "Custom (extract only)" };
+const char* driver_name[WDI_NB_DRIVERS-1] = { "WinUSB", "libusb0", "libusbK", "usbser" };
struct wdi_options_create_list cl_options = { 0 };
struct wdi_options_prepare_driver pd_options = { 0 };
struct wdi_options_install_cert ic_options = { 0 };
diff -r -u -N libwdi-1.2.4 (original)/libwdi/.msvc/libwdi_static.vcxproj libwdi-1.2.4 (modified)/libwdi/.msvc/libwdi_static.vcxproj
--- libwdi-1.2.4 (original)/libwdi/.msvc/libwdi_static.vcxproj 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/libwdi/.msvc/libwdi_static.vcxproj 2015-01-18 14:40:04.634370100 +0100
@@ -186,6 +186,8 @@
<None Include="..\libusb0.cat.in" />
<None Include="..\libusb0.inf.in" />
<None Include="..\libusbk.cat.in" />
+ <None Include="..\usbser.cat.in" />
+ <None Include="..\usbser.inf.in" />
<None Include="..\winusb.cat.in" />
<None Include="..\winusb.inf.in" />
<None Include="..\libusbk.inf.in" />
diff -r -u -N libwdi-1.2.4 (original)/libwdi/.msvc/libwdi_static.vcxproj.filters libwdi-1.2.4 (modified)/libwdi/.msvc/libwdi_static.vcxproj.filters
--- libwdi-1.2.4 (original)/libwdi/.msvc/libwdi_static.vcxproj.filters 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/libwdi/.msvc/libwdi_static.vcxproj.filters 2015-01-18 14:40:04.618745100 +0100
@@ -81,5 +81,11 @@
<None Include="..\libusbk.cat.in">
<Filter>Resource Files</Filter>
</None>
+ <None Include="..\usbser.cat.in">
+ <Filter>Resource Files</Filter>
+ </None>
+ <None Include="..\usbser.inf.in">
+ <Filter>Resource Files</Filter>
+ </None>
</ItemGroup>
</Project>
\ No newline at end of file
diff -r -u -N libwdi-1.2.4 (original)/libwdi/embedder.c libwdi-1.2.4 (modified)/libwdi/embedder.c
--- libwdi-1.2.4 (original)/libwdi/embedder.c 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/libwdi/embedder.c 2015-01-18 14:22:00.536945400 +0100
@@ -295,7 +295,7 @@
}
// Copy the fixed part of our table into our new array
for (i=0; i<nb_embeddables_fixed; i++) {
- embeddable[i].reuse_last = 0;
+ embeddable[i].reuse_last = embeddable_fixed[i].reuse_last;
embeddable[i].file_name = embeddable_fixed[i].file_name;
embeddable[i].extraction_subdir = embeddable_fixed[i].extraction_subdir;
}
diff -r -u -N libwdi-1.2.4 (original)/libwdi/embedder_files.h libwdi-1.2.4 (modified)/libwdi/embedder_files.h
--- libwdi-1.2.4 (original)/libwdi/embedder_files.h 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/libwdi/embedder_files.h 2015-01-18 15:02:29.980055000 +0100
@@ -90,7 +90,7 @@
# if defined(OPT_M32)
# if !defined(DDK_DIR)
- { 0, LIBUSBK_DIR "\\sys\\x86\\WdfCoInstaller" STR(WDF_VER) ".dll", "x86" },
+ { 0, LIBUSBK_DIR "\\sys\\x86\\WdfCoInstaller0" STR(WDF_VER) ".dll", "x86" },
# endif // DDK_DIR
{ 0, LIBUSBK_DIR "\\sys\\x86\\libusbK.sys", "x86" },
{ 0, LIBUSBK_DIR "\\dll\\x86\\libusbK.dll", "x86" },
@@ -107,7 +107,7 @@
# if defined(OPT_M64)
# if !defined(DDK_DIR)
- { 0, LIBUSBK_DIR "\\sys\\amd64\\WdfCoInstaller" STR(WDF_VER) ".dll", "amd64" },
+ { 0, LIBUSBK_DIR "\\sys\\amd64\\WdfCoInstaller0" STR(WDF_VER) ".dll", "amd64" },
# endif // DDK_DIR
{ 0, LIBUSBK_DIR "\\sys\\amd64\\libusbK.sys", "amd64" },
{ 0, LIBUSBK_DIR "\\dll\\amd64\\libusbK.dll", "amd64" },
@@ -127,7 +127,7 @@
# if defined(OPT_IA64)
# if !defined(DDK_DIR)
- { 0, LIBUSBK_DIR "\\sys\\ia64\\WdfCoInstaller" STR(WDF_VER) ".dll", "ia64" },
+ { 0, LIBUSBK_DIR "\\sys\\ia64\\WdfCoInstaller0" STR(WDF_VER) ".dll", "ia64" },
# endif // DDK_DIR
{ 0, LIBUSBK_DIR "\\sys\\ia64\\libusbK.sys", "ia64" },
{ 0, LIBUSBK_DIR "\\dll\\ia64\\libusbK.dll", "ia64" },
@@ -147,8 +147,10 @@
{ 0, "winusb.inf.in", "" },
{ 0, "libusb0.inf.in", "" },
{ 0, "libusbk.inf.in", "" },
+ { 0, "usbser.inf.in", "" },
// cat file lists for self signing
{ 0, "winusb.cat.in", "" },
{ 0, "libusb0.cat.in", "" },
{ 0, "libusbk.cat.in", "" },
+ { 0, "usbser.cat.in", "" },
};
diff -r -u -N libwdi-1.2.4 (original)/libwdi/libwdi.c libwdi-1.2.4 (modified)/libwdi/libwdi.c
--- libwdi-1.2.4 (original)/libwdi/libwdi.c 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/libwdi/libwdi.c 2015-01-19 11:47:51.098272300 +0100
@@ -54,11 +54,11 @@
static BOOL filter_driver = FALSE;
static DWORD timeout = DEFAULT_TIMEOUT;
static HANDLE pipe_handle = INVALID_HANDLE_VALUE;
-static VS_FIXEDFILEINFO driver_version[WDI_NB_DRIVERS-1] = { {0}, {0}, {0} };
-static const char* driver_name[WDI_NB_DRIVERS-1] = {"winusbcoinstaller2.dll", "libusb0.sys", "libusbK.sys"};
-static const char* inf_template[WDI_NB_DRIVERS-1] = {"winusb.inf.in", "libusb0.inf.in", "libusbk.inf.in"};
-static const char* cat_template[WDI_NB_DRIVERS-1] = {"winusb.cat.in", "libusb0.cat.in", "libusbk.cat.in"};
-static const char* ms_compat_id[WDI_NB_DRIVERS-1] = {"MS_COMP_WINUSB", "MS_COMP_LIBUSB0", "MS_COMP_LIBUSBK"};
+static VS_FIXEDFILEINFO driver_version[WDI_NB_DRIVERS-1] = { {0}, {0}, {0}, {0} };
+static const char* driver_name[WDI_NB_DRIVERS-1] = {"winusbcoinstaller2.dll", "libusb0.sys", "libusbK.sys", "usbser.sys"};
+static const char* inf_template[WDI_NB_DRIVERS-1] = {"winusb.inf.in", "libusb0.inf.in", "libusbk.inf.in", "usbser.inf.in"};
+static const char* cat_template[WDI_NB_DRIVERS-1] = {"winusb.cat.in", "libusb0.cat.in", "libusbk.cat.in", "usbser.cat.in"};
+static const char* ms_compat_id[WDI_NB_DRIVERS-1] = {"MS_COMP_WINUSB", "MS_COMP_LIBUSB0", "MS_COMP_LIBUSBK", "MS_COMP_USBSER"};
// for 64 bit platforms detection
static BOOL (__stdcall *pIsWow64Process)(HANDLE, PBOOL) = NULL;
static int windows_version = WINDOWS_UNDEFINED;
@@ -397,6 +397,32 @@
return WDI_ERROR_RESOURCE;
}
+ if (driver_type == WDI_USBSER) {
+ SYSTEMTIME LocalTime;
+ FILETIME FileTime;
+ file_info = &driver_version[driver_type];
+ ZeroMemory(file_info, sizeof(VS_FIXEDFILEINFO));
+ file_info->dwSignature = 0xFEEF04BD;
+ file_info->dwStrucVersion = 0x10000; // not used
+ file_info->dwFileVersionMS = (1 << 16) | (0 << 0);
+ file_info->dwFileVersionLS = (0 << 16) | (0 << 0);
+ file_info->dwProductVersionMS = 0x60003; // not used
+ file_info->dwProductVersionLS = 0x25804000; // not used
+ file_info->dwFileFlagsMask = 0x3F; // not used
+ file_info->dwFileFlags = 0; // not used
+ file_info->dwFileOS = 0x40004; // not used
+ file_info->dwFileType = 2; // not used
+ file_info->dwFileSubtype = 0; // not used
+ GetLocalTime(&LocalTime);
+ if (SystemTimeToFileTime(&LocalTime, &FileTime))
+ {
+ file_info->dwFileDateMS = FileTime.dwHighDateTime;
+ file_info->dwFileDateLS = FileTime.dwLowDateTime;
+ }
+ memcpy(driver_info, file_info, sizeof(VS_FIXEDFILEINFO));
+ return WDI_SUCCESS;
+ }
+
for (res=0; res<nb_resources; res++) {
// Identify the WinUSB and libusb0 files we'll pick the date & version of
if (safe_strcmp(resource[res].name, driver_name[driver_type]) == 0) {
@@ -489,6 +515,12 @@
#else
return FALSE;
#endif
+ case WDI_USBSER:
+#if defined(USBSER_DIR)
+ return TRUE;
+#else
+ return FALSE;
+#endif
case WDI_USER:
#if defined(USER_DIR)
return TRUE;
@@ -978,7 +1010,7 @@
{
const wchar_t bom = 0xFEFF;
#if defined(ENABLE_DEBUG_LOGGING) || defined(INCLUDE_DEBUG_LOGGING)
- const char* driver_display_name[WDI_NB_DRIVERS] = { "WinUSB", "libusb0.sys", "libusbK.sys", "user driver" };
+ const char* driver_display_name[WDI_NB_DRIVERS] = { "WinUSB", "libusb0.sys", "libusbK.sys", "usbser.sys", "user driver" };
#endif
const char* inf_ext = ".inf";
const char* vendor_name = NULL;
diff -r -u -N libwdi-1.2.4 (original)/libwdi/libwdi.h libwdi-1.2.4 (modified)/libwdi/libwdi.h
--- libwdi-1.2.4 (original)/libwdi/libwdi.h 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/libwdi/libwdi.h 2015-01-18 14:40:04.603120300 +0100
@@ -49,6 +49,7 @@
WDI_WINUSB,
WDI_LIBUSB0,
WDI_LIBUSBK,
+ WDI_USBSER,
WDI_USER,
WDI_NB_DRIVERS // Total number of drivers in the enum
};
diff -r -u -N libwdi-1.2.4 (original)/libwdi/usbser.cat.in libwdi-1.2.4 (modified)/libwdi/usbser.cat.in
--- libwdi-1.2.4 (original)/libwdi/usbser.cat.in 1970-01-01 01:00:00.000000000 +0100
+++ libwdi-1.2.4 (modified)/libwdi/usbser.cat.in 2015-01-18 17:51:34.298706900 +0100
@@ -0,0 +1,2 @@
+# List of the binaries referenced by the USBSER inf
+# These are used to generate and self-sign a .cat file
diff -r -u -N libwdi-1.2.4 (original)/libwdi/usbser.inf.in libwdi-1.2.4 (modified)/libwdi/usbser.inf.in
--- libwdi-1.2.4 (original)/libwdi/usbser.inf.in 1970-01-01 01:00:00.000000000 +0100
+++ libwdi-1.2.4 (modified)/libwdi/usbser.inf.in 2015-01-18 15:41:06.984656000 +0100
@@ -0,0 +1,54 @@
+; #INF_FILENAME#
+
+[Strings]
+DeviceName = "#DEVICE_DESCRIPTION#"
+VendorName = "#DEVICE_MANUFACTURER#"
+SourceName = "#DEVICE_DESCRIPTION# Install Disk"
+DeviceID = "#DEVICE_HARDWARE_ID#"
+DeviceGUID = "#DEVICE_INTERFACE_GUID#"
+
+[Version]
+Signature = "$Windows NT$"
+Class = Ports
+ClassGuid = {4D36E978-E325-11CE-BFC1-08002BE10318}
+Provider = %VendorName%
+CatalogFile = #CAT_FILENAME#
+DriverVer = #DRIVER_DATE#, #DRIVER_VERSION#
+
+[Manufacturer]
+%VendorName%=DeviceList, NTamd64, NTia64
+
+[DestinationDirs]
+FakeModemCopyFileSection=12
+DefaultDestDir=12
+
+[DeviceList]
+%DeviceName% = DriverInstall, USB\%DeviceID%
+
+[DeviceList.NTamd64]
+%DeviceName% = DriverInstall, USB\%DeviceID%
+
+[DeviceList.NTia64]
+%DeviceName% = DriverInstall, USB\%DeviceID%
+
+[DriverInstall]
+include=mdmcpq.inf,usb.inf
+CopyFiles = FakeModemCopyFileSection
+AddReg=DriverAddReg
+
+[DriverAddReg]
+HKR,,DevLoader,,*ntkern
+HKR,,NTMPDriver,,usbser.sys
+HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
+
+[DriverInstall.Services]
+include=mdmcpq.inf
+AddService=usbser, 0x00000002, DriverService
+
+[DriverService]
+DisplayName=%ServiceName%
+ServiceType=1
+StartType=3
+ErrorControl=1
+ServiceBinary=%12%\usbser.sys
+LoadOrderGroup=Base
diff -r -u -N libwdi-1.2.4 (original)/libwdi/vid_data.c libwdi-1.2.4 (modified)/libwdi/vid_data.c
--- libwdi-1.2.4 (original)/libwdi/vid_data.c 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/libwdi/vid_data.c 2015-01-18 17:24:32.080058800 +0100
@@ -2914,6 +2914,7 @@
{ 0xeb2a, "KWorld" },
{ 0xf003, "Hewlett Packard" },
{ 0xf4ec, "Atten Electronics / Siglent Technologies" },
+ { 0x1eaf, "LeafLabs, LLC" },
};
const char* LIBWDI_API wdi_get_vendor_name(unsigned short vid)
diff -r -u -N libwdi-1.2.4 (original)/msvc/config.h libwdi-1.2.4 (modified)/msvc/config.h
--- libwdi-1.2.4 (original)/msvc/config.h 2014-12-01 00:01:08.000000000 +0100
+++ libwdi-1.2.4 (modified)/msvc/config.h 2015-01-18 15:32:43.809858300 +0100
@@ -21,7 +21,7 @@
* match your WinUSB redist directrories
*/
#ifndef DDK_DIR
-#define DDK_DIR "C:/Program Files (x86)/Windows Kits/8.1"
+ #define DDK_DIR "C:/temp/libwdi/ddk"
#endif
/* DDK WDF coinstaller version */
@@ -35,17 +35,22 @@
/* embed libusb0 driver files from the following location */
#ifndef LIBUSB0_DIR
-#define LIBUSB0_DIR "D:/libusb-win32"
+ #define LIBUSB0_DIR "C:/temp/libwdi/libusb0"
#endif
/* embed libusbK driver files from the following location */
#ifndef LIBUSBK_DIR
-#define LIBUSBK_DIR "D:/libusbK/bin"
+ #define LIBUSBK_DIR "C:/temp/libwdi/libusbk"
+#endif
+
+/* embed usbser driver files from the following location */
+#ifndef USBSER_DIR
+ #define USBSER_DIR "C:/temp/libwdi/usbser"
#endif
/* embed user defined driver files from the following location */
#ifndef USER_DIR
-// #define USER_DIR "C:/signed-driver"
+// #define USER_DIR "C:/temp/libwdi/user"
#endif
/* 32 bit support */

View File

@ -0,0 +1,851 @@
Copyright (c) 2002-2004 Stephan Meyer, <ste_meyer@web.de>
Copyright (c) 2000-2004 Johannes Erdfelt, <johannes@erdfelt.com>
Copyright (c) 2000-2004 Thomas Sailer, <sailer@ife.ee.ethz.ch>
Copyright (c) 2010 Travis Robinson, <libusbdotnet@gmail.com>
This software is distributed under the following licenses:
Driver: GNU General Public License (GPL)
Library, Test Files, Installer: GNU Lesser General Public License (LGPL)
***********************************************************************
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@ -0,0 +1,147 @@
; Copyright 2012 Blacklabel Development, Inc.
[Strings]
DriverPackageDisplayName="Arduino USB Driver"
ManufacturerName="Arduino LLC (www.arduino.cc)"
ServiceName="USB RS-232 Emulation Driver"
due.bossa.name="Bossa Program Port"
due.programming_port.name="Arduino Due Programming Port"
due.sketch.name="Arduino Due"
esplora.bootloader.name="Arduino Esplora bootloader"
esplora.sketch.name="Arduino Esplora"
leonardo.bootloader.name="Arduino Leonardo bootloader"
leonardo.sketch.name="Arduino Leonardo"
lilypadUSB.bootloader.name="Arduino LilyPad USB bootloader"
lilypadUSB.sketch.name="Arduino LilyPad USB"
mega2560.name="Arduino Mega 2560"
mega2560rev3.name="Arduino Mega 2560"
megaADK.name="Arduino Mega ADK"
megaADKrev3.name="Arduino Mega ADK"
micro.bootloader.name="Arduino Micro bootloader"
micro.sketch.name="Arduino Micro"
uno.name="Arduino Uno"
unoR3.name="Arduino Uno"
usbserial.name="Arduino USB Serial Light Adapter"
robotControl.bootloader.name="Arduino Robot Control bootloader"
robotControl.sketch.name="Arduino Robot"
robotMotor.bootloader.name="Arduino Robot Motor bootloader"
robotMotor.sketch.name="Arduino Robot"
yun.bootloader.name="Arduino Yun bootloader"
yun.sketch.name="Arduino Yun"
[DefaultInstall]
CopyINF=arduino.inf
[Version]
Class=Ports
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
Signature="$Windows NT$"
Provider=%ManufacturerName%
DriverPackageDisplayName=%DriverPackageDisplayName%
CatalogFile=arduino.cat
DriverVer=01/04/2013,1.0.0.0
[Manufacturer]
%ManufacturerName%=DeviceList, NTamd64, NTia64
[DestinationDirs]
FakeModemCopyFileSection=12
DefaultDestDir=12
[DeviceList]
%due.bossa.name%=DriverInstall, USB\VID_03EB&PID_6124
%due.programming_port.name%=DriverInstall, USB\VID_2341&PID_003D
%due.sketch.name%=DriverInstall, USB\VID_2341&PID_003E&MI_00
%esplora.bootloader.name%=DriverInstall, USB\VID_2341&PID_003C
%esplora.sketch.name%=DriverInstall, USB\VID_2341&PID_803C&MI_00
%leonardo.bootloader.name%=DriverInstall, USB\VID_2341&PID_0036
%leonardo.sketch.name%=DriverInstall, USB\VID_2341&PID_8036&MI_00
%lilypadUSB.bootloader.name%=DriverInstall, USB\VID_1B4F&PID_9207
%lilypadUSB.sketch.name%=DriverInstall, USB\VID_1B4F&PID_9208&MI_00
%mega2560rev3.name%=DriverInstall, USB\VID_2341&PID_0042
%mega2560.name%=DriverInstall, USB\VID_2341&PID_0010
%megaADK.name%=DriverInstall, USB\VID_2341&PID_003F
%megaADKrev3.name%=DriverInstall, USB\VID_2341&PID_0044
%micro.bootloader.name%=DriverInstall, USB\VID_2341&PID_0037
%micro.sketch.name%=DriverInstall, USB\VID_2341&PID_8037&MI_00
%uno.name%=DriverInstall, USB\VID_2341&PID_0001
%unoR3.name%=DriverInstall, USB\VID_2341&PID_0043
%usbserial.name%=DriverInstall, USB\VID_2341&PID_003B
%robotControl.bootloader.name%=DriverInstall, USB\VID_2341&PID_0038
%robotControl.sketch.name%=DriverInstall, USB\VID_2341&PID_8038&MI_00
%robotMotor.bootloader.name%=DriverInstall, USB\VID_2341&PID_0039
%robotMotor.sketch.name%=DriverInstall, USB\VID_2341&PID_8039&MI_00
%yun.bootloader.name%=DriverInstall, USB\VID_2341&PID_0041
%yun.sketch.name%=DriverInstall, USB\VID_2341&PID_8041&MI_00
[DeviceList.NTamd64]
%due.bossa.name%=DriverInstall, USB\VID_03EB&PID_6124
%due.programming_port.name%=DriverInstall, USB\VID_2341&PID_003D
%due.sketch.name%=DriverInstall, USB\VID_2341&PID_003E&MI_00
%esplora.bootloader.name%=DriverInstall, USB\VID_2341&PID_003C
%esplora.sketch.name%=DriverInstall, USB\VID_2341&PID_803C&MI_00
%leonardo.bootloader.name%=DriverInstall, USB\VID_2341&PID_0036
%leonardo.sketch.name%=DriverInstall, USB\VID_2341&PID_8036&MI_00
%lilypadUSB.bootloader.name%=DriverInstall, USB\VID_1B4F&PID_9207
%lilypadUSB.sketch.name%=DriverInstall, USB\VID_1B4F&PID_9208&MI_00
%mega2560rev3.name%=DriverInstall, USB\VID_2341&PID_0042
%mega2560.name%=DriverInstall, USB\VID_2341&PID_0010
%megaADK.name%=DriverInstall, USB\VID_2341&PID_003F
%megaADKrev3.name%=DriverInstall, USB\VID_2341&PID_0044
%micro.bootloader.name%=DriverInstall, USB\VID_2341&PID_0037
%micro.sketch.name%=DriverInstall, USB\VID_2341&PID_8037&MI_00
%uno.name%=DriverInstall, USB\VID_2341&PID_0001
%unoR3.name%=DriverInstall, USB\VID_2341&PID_0043
%usbserial.name%=DriverInstall, USB\VID_2341&PID_003B
%robotControl.bootloader.name%=DriverInstall, USB\VID_2341&PID_0038
%robotControl.sketch.name%=DriverInstall, USB\VID_2341&PID_8038&MI_00
%robotMotor.bootloader.name%=DriverInstall, USB\VID_2341&PID_0039
%robotMotor.sketch.name%=DriverInstall, USB\VID_2341&PID_8039&MI_00
%yun.bootloader.name%=DriverInstall, USB\VID_2341&PID_0041
%yun.sketch.name%=DriverInstall, USB\VID_2341&PID_8041&MI_00
[DeviceList.NTia64]
%esplora.bootloader.name%=DriverInstall, USB\VID_2341&PID_003C
%esplora.sketch.name%=DriverInstall, USB\VID_2341&PID_803C&MI_00
%leonardo.bootloader.name%=DriverInstall, USB\VID_2341&PID_0036
%leonardo.sketch.name%=DriverInstall, USB\VID_2341&PID_8036&MI_00
%lilypadUSB.bootloader.name%=DriverInstall, USB\VID_1B4F&PID_9207
%lilypadUSB.sketch.name%=DriverInstall, USB\VID_1B4F&PID_9208&MI_00
%mega2560rev3.name%=DriverInstall, USB\VID_2341&PID_0042
%mega2560.name%=DriverInstall, USB\VID_2341&PID_0010
%megaADK.name%=DriverInstall, USB\VID_2341&PID_003F
%megaADKrev3.name%=DriverInstall, USB\VID_2341&PID_0044
%micro.bootloader.name%=DriverInstall, USB\VID_2341&PID_0037
%micro.sketch.name%=DriverInstall, USB\VID_2341&PID_8037&MI_00
%uno.name%=DriverInstall, USB\VID_2341&PID_0001
%unoR3.name%=DriverInstall, USB\VID_2341&PID_0043
%usbserial.name%=DriverInstall, USB\VID_2341&PID_003B
%robotControl.bootloader.name%=DriverInstall, USB\VID_2341&PID_0038
%robotControl.sketch.name%=DriverInstall, USB\VID_2341&PID_8038&MI_00
%robotMotor.bootloader.name%=DriverInstall, USB\VID_2341&PID_0039
%robotMotor.sketch.name%=DriverInstall, USB\VID_2341&PID_8039&MI_00
%yun.bootloader.name%=DriverInstall, USB\VID_2341&PID_0041
%yun.sketch.name%=DriverInstall, USB\VID_2341&PID_8041&MI_00
[DriverInstall]
include=mdmcpq.inf,usb.inf
CopyFiles = FakeModemCopyFileSection
AddReg=DriverAddReg
[DriverAddReg]
HKR,,DevLoader,,*ntkern
HKR,,NTMPDriver,,usbser.sys
HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
[DriverInstall.Services]
include=mdmcpq.inf
AddService=usbser, 0x00000002, DriverService
[DriverService]
DisplayName=%ServiceName%
ServiceType=1
StartType=3
ErrorControl=1
ServiceBinary=%12%\usbser.sys
LoadOrderGroup=Base

@ -0,0 +1 @@
Subproject commit 4f925b447669d3c4968c6f5679390a8abffb9654

10
drivers/win/src/readme.md Normal file
View File

@ -0,0 +1,10 @@
It doesn't seem to be possible to have a patched version of a submodule within a repo.
Thanks to Tim Schuerewegen for his work to produce the modified code
To rebuild libdwi simple example to include the USB VID/PID's for the Maple USB devices, apply the diff file as a patch to the sources in the pbatard_libwdi folder
See also the libwdi-extra-files folder supplied by Tim Schuerewegen, required to build in Visial Studio on Windows

View File

@ -0,0 +1,12 @@
This is at least a partial credits-file of people that have
contributed to the Maple bootloader. It is formatted the same way the
Linux kernel CREDITS file is structured: sorted by name and formatted
for easy processing.
The fields are: name (N), email (E), web-address (W), description (D).
----------
N: Tormod Volden
E: debian.tormod@gmail.com
D: Fixes for DFU compliance

View File

@ -0,0 +1,249 @@
# Makefile skeleton adapted from Peter Harrison's - www.micromouse.com
# MCU name and submodel
MCU = cortex-m3
SUBMDL = stm32f103
# toolchain (using code sourcery now)
TCHAIN = arm-none-eabi
THUMB = -mthumb
THUMB_IW = -mthumb-interwork
# Target file name (without extension).
BUILDDIR = build
TARGET = $(BUILDDIR)/maple_boot
ST_LIB = stm32_lib
ST_USB = usb_lib
# Optimization level [0,1,2,3,s]
OPT ?= 0
DEBUG =
#DEBUG = dwarf-2
INCDIRS = ./$(ST_LIB) ./$(ST_USB)
CFLAGS = $(DEBUG)
CFLAGS += -O$(OPT)
CFLAGS += -ffunction-sections -fdata-sections
CFLAGS += -Wall -Wimplicit
CFLAGS += -Wcast-align
CFLAGS += -Wpointer-arith -Wswitch
CFLAGS += -Wredundant-decls -Wreturn-type -Wshadow -Wunused
CFLAGS += -Wa,-adhlns=$(BUILDDIR)/$(subst $(suffix $<),.lst,$<)
CFLAGS += $(patsubst %,-I%,$(INCDIRS))
# Aeembler Flags
ASFLAGS = -Wa,-adhlns=$(BUILDDIR)/$(<:.s=.lst)#,--g$(DEBUG)
LDFLAGS = -nostartfiles -Wl,-Map=$(TARGET).map,--cref,--gc-sections
LDFLAGS += -lc -lgcc
# Set the linker script
LDFLAGS +=-T$(ST_LIB)/c_only_md.ld
# Define programs and commands.
SHELL = sh
CC = $(TCHAIN)-gcc
CPP = $(TCHAIN)-g++
AR = $(TCHAIN)-ar
OBJCOPY = $(TCHAIN)-objcopy
OBJDUMP = $(TCHAIN)-objdump
SIZE = $(TCHAIN)-size
NM = $(TCHAIN)-nm
REMOVE = rm -f
REMOVEDIR = rm -r
COPY = cp
# Define Messages
# English
MSG_ERRORS_NONE = Errors: none
MSG_BEGIN = "-------- begin --------"
MSG_ETAGS = Created TAGS File
MSG_END = -------- end --------
MSG_SIZE_BEFORE = Size before:
MSG_SIZE_AFTER = Size after:
MSG_FLASH = Creating load file for Flash:
MSG_EXTENDED_LISTING = Creating Extended Listing:
MSG_SYMBOL_TABLE = Creating Symbol Table:
MSG_LINKING = Linking:
MSG_COMPILING = Compiling C:
MSG_ASSEMBLING = Assembling:
MSG_CLEANING = Cleaning project:
# Combine all necessary flags and optional flags.
# Add target processor to flags.
GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d
ALL_CFLAGS = -mcpu=$(MCU) $(THUMB_IW) -I. $(CFLAGS) $(GENDEPFLAGS)
ALL_ASFLAGS = -mcpu=$(MCU) $(THUMB_IW) -I. -x assembler-with-cpp $(ASFLAGS)
# --------------------------------------------- #
# file management
ASRC = $(ST_LIB)/c_only_startup.s $(ST_LIB)/cortexm3_macro.s
STM32SRCS =
_STM32USBSRCS = usb_regs.c \
usb_int.c \
usb_init.c \
usb_core.c \
usb_mem.c
STM32USBSRCS = $(patsubst %, $(ST_USB)/%,$(_STM32USBSRCS))
SRCS = usb.c usb_callbacks.c usb_descriptor.c main.c hardware.c dfu.c
SRC = $(SRCS) $(STM32SRCS) $(STM32USBSRCS)
# Define all object files.
_COBJ = $(SRC:.c=.o)
_AOBJ = $(ASRC:.s=.o)
COBJ = $(patsubst %, $(BUILDDIR)/%,$(_COBJ))
AOBJ = $(patsubst %, $(BUILDDIR)/%,$(_AOBJ))
# Define all listing files.
_LST = $(ASRC:.s=.lst)
_LST += $(SRC:.c=.lst)
LST = $(patsubst %, $(BUILDDIR)/%,$(_LST))
# Display size of file.
HEXSIZE = $(SIZE) --target=binary $(TARGET).hex
ELFSIZE = $(SIZE) -A $(TARGET).elf
# go!
all: begin gccversion build sizeafter finished end
build: elf bin lss sym
bin: $(TARGET).bin
elf: $(TARGET).elf
lss: $(TARGET).lss
sym: $(TARGET).sym
dfu: $(TARGET).bin
sudo dfu-util -d 0110:1001 -a 0 -D $(TARGET).bin
begin:
mkdir -p build/stm32_lib
mkdir -p build/usb_lib
@echo --
@echo $(MSG_BEGIN)
@echo $(COBJ)
finished:
@echo $(MSG_ERRORS_NONE)
tags:
etags `find . -name "*.c" -o -name "*.cpp" -o -name "*.h"`
@echo $(MSG_ETAGS)
end:
@echo $(MSG_END)
@echo
sizeafter:
@if [ -f $(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); echo; fi
gccversion:
@$(CC) --version
program:
@echo "Flash-programming with OpenOCD"
cp $(TARGET).bin flash/tmpflash.bin
cd flash && openocd -f flash.cfg
program_serial:
@echo "Flash-programming with stm32loader.py"
./flash/stm32loader.py -p /dev/ttyUSB0 -evw build/maple_boot.bin
debug: $(TARGET).bin
@echo "Flash-programming with OpenOCD - DEBUG"
cp $(TARGET).bin flash/tmpflash.bin
cd flash && openocd -f debug.cfg
install: $(TARGET).bin
cp $(TARGET).bin build/main.bin
openocd -f flash/perry_flash.cfg
run: $(TARGET).bin
openocd -f flash/run.cfg
# Create final output file (.hex) from ELF output file.
%.hex: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O binary $< $@
# Create final output file (.bin) from ELF output file.
%.bin: %.elf
@echo
@echo $(MSG_FLASH) $@
$(OBJCOPY) -O binary $< $@
# Create extended listing file from ELF output file.
# testing: option -C
%.lss: %.elf
@echo
@echo $(MSG_EXTENDED_LISTING) $@
$(OBJDUMP) -h -S -D $< > $@
# Create a symbol table from ELF output file.
%.sym: %.elf
@echo
@echo $(MSG_SYMBOL_TABLE) $@
$(NM) -n $< > $@
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(COBJ) $(AOBJ)
%.elf: $(COBJ) $(AOBJ)
@echo
@echo $(MSG_LINKING) $@
$(CC) $(THUMB) $(ALL_CFLAGS) $(AOBJ) $(COBJ) --output $@ $(LDFLAGS)
# Compile: create object files from C source files. ARM/Thumb
$(COBJ) : $(BUILDDIR)/%.o : %.c
@echo
@echo $(MSG_COMPILING) $<
$(CC) -c $(THUMB) $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files. ARM/Thumb
$(AOBJ) : $(BUILDDIR)/%.o : %.s
@echo
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(THUMB) $(ALL_ASFLAGS) $< -o $@
clean: begin clean_list finished end
clean_list :
@echo
@echo $(MSG_CLEANING)
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).bin
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).a90
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lnk
$(REMOVE) $(TARGET).lss
$(REMOVE) $(COBJ)
$(REMOVE) $(AOBJ)
$(REMOVE) $(LST)
$(REMOVE) flash/tmpflash.bin
# $(REMOVE) $(SRC:.c=.s)
# $(REMOVE) $(SRC:.c=.d)
$(REMOVE) .dep/*
# Include the dependency files.
-include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*)
# Listing of phony targets.
.PHONY : all begin finish tags end sizeafter gccversion \
build elf hex bin lss sym clean clean_list program cscope
cscope:
rm -rf *.cscope
find . -iname "*.[hcs]" | grep -v examples | xargs cscope -R -b

View File

@ -0,0 +1,35 @@
FILES -------------------------------------------------------------------------
stm32lib/*
- all the (possibly consolidated) stm32 lib and usb example code
usb.c
- USB-specific hardware setup. Interrupts, clocks, etc. handling USB when
not "Attached". some low-level callbacks (low power mode, init, reset,
resume, etc).
usb_callbacks.c
- aka endpoints: handling data transfer when "Configured". calls out to
application specific callbacks (i.e. DFU).
usb_descriptor.c
- aka application descriptor; big static struct and callbacks for sending
the descriptor.
main.c
- main loop and calling any hardware init stuff. timing hacks for EEPROM
writes not to block usb interrupts. logic to handle 2 second timeout then
jump to user code.
hardware.c
- init routines to setup clocks, interrupts, also destructor functions.
does not include USB stuff. EEPROM read/write functions.
dfu.c
- mostly the giant FSM case switch, also some USB endpoint callbacks
TODO --------------------------------------------------------------------------
* pack the structs
* use sizeof() for usb application descriptor once structs are packed

View File

@ -0,0 +1,44 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
/**
* @file common.h
*
* @brief toplevel include for bootloader source files
*
*
*/
#ifndef __COMMON_H
#define __COMMON_H
#include "config.h"
#include "hardware.h"
#include "stm32f10x_type.h"
#include "cortexm3_macro.h"
#include "usb.h"
typedef void (*FuncPtr)(void);
#endif

View File

@ -0,0 +1,59 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
/**
* @file config.h
*
* @brief bootloader settings and macro defines
*
*
*/
#ifndef __CONFIG_H
#define __CONFIG_H
#include "common.h"
#define LED_BANK GPIOB
#define LED 1
#define BLINK_FAST 0x50000
#define BLINK_SLOW 0x100000
#define BUTTON_BANK GPIOB
#define BUTTON 8
#define STARTUP_BLINKS 5
#define BOOTLOADER_WAIT 6
#define USER_CODE_RAM ((u32)0x20000C00)
#define RAM_END ((u32)0x20005000)
#define USER_CODE_FLASH ((u32)0x08005000)
#define FLASH_END ((u32)0x08020000)
#define VEND_ID0 0xAF
#define VEND_ID1 0x1E
#define PROD_ID0 0x03
#define PROD_ID1 0x00
#endif

View File

@ -0,0 +1,409 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
/**
* @file dfu.c
*
* @brief The principle dfu state machine as well as the data
* transfer callbacks accessed by the usb library
*
*
*/
#include "dfu.h"
#include "usb.h"
/* DFU globals */
static volatile u32 userAppAddr = USER_CODE_RAM; /* default RAM user code location */
static volatile u32 userAppEnd = RAM_END;
static volatile DFUStatus dfuAppStatus; /* includes state */
static volatile bool userFlash = FALSE;
volatile bool dfuBusy = FALSE;
static volatile u8 recvBuffer[wTransferSize] __attribute__((aligned(4)));
static volatile u32 userFirmwareLen = 0;
static volatile u16 thisBlockLen = 0;
static volatile u16 uploadBlockLen = 0;
volatile PLOT code_copy_lock;
/* todo: force dfu globals to be singleton to avoid re-inits? */
void dfuInit(void) {
dfuAppStatus.bStatus = OK;
dfuAppStatus.bwPollTimeout0 = 0x00;
dfuAppStatus.bwPollTimeout1 = 0x00;
dfuAppStatus.bwPollTimeout2 = 0x00;
dfuAppStatus.bState = dfuIDLE;
dfuAppStatus.iString = 0x00; /* all strings must be 0x00 until we make them! */
userFirmwareLen = 0;
thisBlockLen = 0;;
userAppAddr = USER_CODE_RAM; /* default RAM user code location */
userAppEnd = RAM_END;
userFlash = FALSE;
code_copy_lock = WAIT;
dfuBusy = FALSE;
}
bool dfuUpdateByRequest(void) {
/* were using the global pInformation struct from usb_lib here,
see comment in maple_dfu.h around DFUEvent struct */
dfuBusy = TRUE;
u8 startState = dfuAppStatus.bState;
dfuAppStatus.bStatus = OK;
/* often leaner to nest if's then embed a switch/case */
if (startState == dfuIDLE) {
/* device running inside DFU mode */
dfuBusy = TRUE; // signals the main loop to defer to the dfu write-loop
if (pInformation->USBbRequest == DFU_DNLOAD) {
if (pInformation->USBwLengths.w > 0) {
userFirmwareLen = 0;
dfuAppStatus.bState = dfuDNLOAD_SYNC;
if (pInformation->Current_AlternateSetting == 1) {
userAppAddr = USER_CODE_FLASH;
userFlash = TRUE;
/* make sure the flash is setup properly, unlock it */
setupFLASH();
flashUnlock();
} else {
userAppAddr = USER_CODE_RAM;
userFlash = FALSE;
}
} else {
dfuAppStatus.bState = dfuERROR;
dfuAppStatus.bStatus = errNOTDONE;
}
} else if (pInformation->USBbRequest == DFU_UPLOAD) {
dfuAppStatus.bState = dfuUPLOAD_IDLE;
/* record length of first block for calculating target
address from wValue in consecutive blocks */
uploadBlockLen = pInformation->USBwLengths.w;
thisBlockLen = uploadBlockLen; /* for this first block as well */
/* calculate where the data should be copied from */
userFirmwareLen = uploadBlockLen * pInformation->USBwValue;
if (pInformation->Current_AlternateSetting == 1) {
userAppAddr = USER_CODE_FLASH;
userAppEnd = FLASH_END;
} else {
userAppAddr = USER_CODE_RAM;
userAppEnd = RAM_END;
}
} else if (pInformation->USBbRequest == DFU_ABORT) {
dfuAppStatus.bState = dfuIDLE;
dfuAppStatus.bStatus = OK; /* are we really ok? we were just aborted */
} else if (pInformation->USBbRequest == DFU_GETSTATUS) {
dfuAppStatus.bState = dfuIDLE;
} else if (pInformation->USBbRequest == DFU_GETSTATE) {
dfuAppStatus.bState = dfuIDLE;
} else {
dfuAppStatus.bState = dfuERROR;
dfuAppStatus.bStatus = errSTALLEDPKT;
}
} else if (startState == dfuDNLOAD_SYNC) {
/* device received block, waiting for DFU_GETSTATUS request */
if (pInformation->USBbRequest == DFU_GETSTATUS) {
/* todo, add routine to wait for last block write to finish */
if (userFlash) {
if (code_copy_lock == WAIT) {
code_copy_lock = BEGINNING;
dfuAppStatus.bwPollTimeout0 = 0x20; /* 32 ms */
dfuAppStatus.bwPollTimeout1 = 0x00;
dfuAppStatus.bState = dfuDNBUSY;
} else if (code_copy_lock == BEGINNING) {
dfuAppStatus.bState = dfuDNLOAD_SYNC;
} else if (code_copy_lock == MIDDLE) {
dfuAppStatus.bState = dfuDNLOAD_SYNC;
} else if (code_copy_lock == END) {
dfuAppStatus.bwPollTimeout0 = 0x00;
code_copy_lock = WAIT;
dfuAppStatus.bState = dfuDNLOAD_IDLE;
}
} else {
dfuAppStatus.bState = dfuDNLOAD_IDLE;
dfuCopyBufferToExec();
}
} else if (pInformation->USBbRequest == DFU_GETSTATE) {
dfuAppStatus.bState = dfuDNLOAD_SYNC;
} else {
dfuAppStatus.bState = dfuERROR;
dfuAppStatus.bStatus = errSTALLEDPKT;
}
} else if (startState == dfuDNBUSY) {
/* if were actually done writing, goto sync, else stay busy */
if (code_copy_lock == END) {
dfuAppStatus.bwPollTimeout0 = 0x00;
code_copy_lock = WAIT;
dfuAppStatus.bState = dfuDNLOAD_IDLE;
} else {
dfuAppStatus.bState = dfuDNBUSY;
}
} else if (startState == dfuDNLOAD_IDLE) {
/* device is expecting dfu_dnload requests */
if (pInformation->USBbRequest == DFU_DNLOAD) {
if (pInformation->USBwLengths.w > 0) {
dfuAppStatus.bState = dfuDNLOAD_SYNC;
} else {
/* todo, support "disagreement" if device expects more data than this */
dfuAppStatus.bState = dfuMANIFEST_SYNC;
/* relock the flash */
flashLock();
}
} else if (pInformation->USBbRequest == DFU_ABORT) {
dfuAppStatus.bState = dfuIDLE;
} else if (pInformation->USBbRequest == DFU_GETSTATUS) {
dfuAppStatus.bState = dfuIDLE;
} else if (pInformation->USBbRequest == DFU_GETSTATE) {
dfuAppStatus.bState = dfuIDLE;
} else {
dfuAppStatus.bState = dfuERROR;
dfuAppStatus.bStatus = errSTALLEDPKT;
}
} else if (startState == dfuMANIFEST_SYNC) {
/* device has received last block, waiting DFU_GETSTATUS request */
if (pInformation->USBbRequest == DFU_GETSTATUS) {
dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET;
dfuAppStatus.bStatus = OK;
} else if (pInformation->USBbRequest == DFU_GETSTATE) {
dfuAppStatus.bState = dfuMANIFEST_SYNC;
} else {
dfuAppStatus.bState = dfuERROR;
dfuAppStatus.bStatus = errSTALLEDPKT;
}
} else if (startState == dfuMANIFEST) {
/* device is in manifestation phase */
/* should never receive request while in manifest! */
dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET;
dfuAppStatus.bStatus = OK;
} else if (startState == dfuMANIFEST_WAIT_RESET) {
/* device has programmed new firmware but needs external
usb reset or power on reset to run the new code */
/* consider timing out and self-resetting */
dfuAppStatus.bState = dfuMANIFEST_WAIT_RESET;
} else if (startState == dfuUPLOAD_IDLE) {
/* device expecting further dfu_upload requests */
if (pInformation->USBbRequest == DFU_UPLOAD) {
if (pInformation->USBwLengths.w > 0) {
/* check that this is not the last possible block */
userFirmwareLen = uploadBlockLen * pInformation->USBwValue;
if (userAppAddr + userFirmwareLen + uploadBlockLen <= userAppEnd) {
thisBlockLen = uploadBlockLen;
dfuAppStatus.bState = dfuUPLOAD_IDLE;
} else {
/* if above comparison was just equal, thisBlockLen becomes zero
next time when USBWValue has been increased by one */
thisBlockLen = userAppEnd - userAppAddr - userFirmwareLen;
/* check for overflow due to USBwValue out of range */
if (thisBlockLen >= pInformation->USBwLengths.w) {
thisBlockLen = 0;
}
dfuAppStatus.bState = dfuIDLE;
}
} else {
dfuAppStatus.bState = dfuERROR;
dfuAppStatus.bStatus = errNOTDONE;
}
} else if (pInformation->USBbRequest == DFU_ABORT) {
dfuAppStatus.bState = dfuIDLE;
} else if (pInformation->USBbRequest == DFU_GETSTATUS) {
dfuAppStatus.bState = dfuUPLOAD_IDLE;
} else if (pInformation->USBbRequest == DFU_GETSTATE) {
dfuAppStatus.bState = dfuUPLOAD_IDLE;
} else {
dfuAppStatus.bState = dfuERROR;
dfuAppStatus.bStatus = errSTALLEDPKT;
}
} else if (startState == dfuERROR) {
/* status is in error, awaiting DFU_CLRSTATUS request */
if (pInformation->USBbRequest == DFU_GETSTATUS) {
/* todo, add routine to wait for last block write to finish */
dfuAppStatus.bState = dfuERROR;
} else if (pInformation->USBbRequest == DFU_GETSTATE) {
dfuAppStatus.bState = dfuERROR;
} else if (pInformation->USBbRequest == DFU_CLRSTATUS) {
/* todo handle any cleanup we need here */
dfuAppStatus.bState = dfuIDLE;
dfuAppStatus.bStatus = OK;
} else {
dfuAppStatus.bState = dfuERROR;
dfuAppStatus.bStatus = errSTALLEDPKT;
}
} else {
/* some kind of error... */
dfuAppStatus.bState = dfuERROR;
dfuAppStatus.bStatus = errSTALLEDPKT;
}
if (dfuAppStatus.bStatus == OK) {
return TRUE;
} else {
return FALSE;
}
}
void dfuUpdateByReset(void) {
u8 startState = dfuAppStatus.bState;
userFirmwareLen = 0;
if (startState == appDETACH) {
dfuAppStatus.bState = dfuIDLE;
dfuAppStatus.bStatus = OK;
nvicDisableInterrupts();
usbEnbISR();
} else if (startState == appIDLE || startState == dfuIDLE) {
/* do nothing...might be normal usb bus activity */
} else {
/* we reset from the dfu, reset everything and startover,
which is the correct operation if this is an erroneous
event or properly following a MANIFEST */
dfuAppStatus.bState = dfuIDLE;
dfuAppStatus.bStatus = OK;
systemHardReset();
}
}
void dfuUpdateByTimeout(void) {
}
u8 *dfuCopyState(u16 length) {
if (length == 0) {
pInformation->Ctrl_Info.Usb_wLength = 1;
return NULL;
} else {
return (&(dfuAppStatus.bState));
}
}
u8 *dfuCopyStatus(u16 length) {
if (length == 0) {
pInformation->Ctrl_Info.Usb_wLength = 6;
return NULL;
} else {
return (u8*)(&dfuAppStatus);
}
}
u8 *dfuCopyDNLOAD(u16 length) {
if (length == 0) {
pInformation->Ctrl_Info.Usb_wLength = pInformation->USBwLengths.w - pInformation->Ctrl_Info.Usb_wOffset;
thisBlockLen = pInformation->USBwLengths.w;
return NULL;
} else {
return ((u8 *)recvBuffer + pInformation->Ctrl_Info.Usb_wOffset);
}
}
u8 *dfuCopyUPLOAD(u16 length) {
if (length == 0) {
pInformation->Ctrl_Info.Usb_wLength = thisBlockLen - pInformation->Ctrl_Info.Usb_wOffset;
return NULL;
} else {
return((u8*) userAppAddr + userFirmwareLen + pInformation->Ctrl_Info.Usb_wOffset);
}
}
void dfuCopyBufferToExec() {
int i;
u32 *userSpace;
if (!userFlash) {
userSpace = (u32 *)(USER_CODE_RAM + userFirmwareLen);
/* we dont need to handle when thisBlock len is not divisible by 4,
since the linker will align everything to 4B anyway */
for (i = 0; i < thisBlockLen; i = i + 4) {
*userSpace++ = *(u32 *)(recvBuffer + i);
}
} else {
userSpace = (u32 *)(USER_CODE_FLASH + userFirmwareLen);
flashErasePage((u32)(userSpace));
for (i = 0; i < thisBlockLen; i = i + 4) {
flashWriteWord((u32)(userSpace++), *(u32 *)(recvBuffer +i));
}
}
userFirmwareLen += thisBlockLen;
thisBlockLen = 0;
}
u8 dfuGetState(void) {
return dfuAppStatus.bState;
}
void dfuSetState(u8 newState) {
dfuAppStatus.bState = newState;
}
bool dfuUploadStarted() {
return dfuBusy;
}
void dfuFinishUpload() {
while (1) {
if (userFlash) {
if (code_copy_lock == BEGINNING) {
code_copy_lock = MIDDLE;
strobePin(LED_BANK, LED, 2, 0x1000);
dfuCopyBufferToExec();
strobePin(LED_BANK, LED, 2, 0x500);
code_copy_lock = END;
}
}
/* otherwise do nothing, dfu state machine resets itself */
}
}

View File

@ -0,0 +1,121 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
#ifndef __DFU_H
#define __DFU_H
#include "common.h"
/* exposed types */
typedef u8 *(*ClassReqCB)(u16);
/* exposed structs */
typedef struct _DFUStatus {
u8 bStatus;
u8 bwPollTimeout0;
u8 bwPollTimeout1;
u8 bwPollTimeout2;
u8 bState; /* state of device at the time the host receives the message! */
u8 iString;
} DFUStatus;
typedef enum _PLOT {
BEGINNING,
MIDDLE,
END,
WAIT
} PLOT;
/*** DFU bRequest Values ******/
/* bmRequestType, wValue, wIndex, wLength, Data */
#define DFU_DETACH 0x00 /* 0x21, wTimeout, Interface, Zero, None */
#define DFU_DNLOAD 0x01 /* 0x21, wBlockNum, Interface, Length, Firmware */
#define DFU_UPLOAD 0x02 /* 0xA1, Zero, Interface, Length, Firmware */
#define DFU_GETSTATUS 0x03 /* 0xA1, Zero, Interface, 6, Status */
#define DFU_CLRSTATUS 0x04 /* 0x21, Zero, Interface, Zero, None */
#define DFU_GETSTATE 0x05 /* 0xA1, Zero, Interface, 1, State */
#define DFU_ABORT 0x06 /* 0x21, Zero, Interface, Zero, None */
/*** DFU Status Values ******/
#define OK 0x00 /* No error */
#define errTARGET 0x01 /* File is not appropriate for this device */
#define errFILE 0x02 /* File fails some vendor tests */
#define errWRITE 0x03 /* Device is unable to write memory */
#define errERASE 0x04 /* Memory erase failed */
#define errCHECK_ERASED 0x05 /* Memory erase check failed */
#define errPROG 0x06 /* Program memory function failed */
#define errVERIFY 0x07 /* Written program failed verification */
#define errADDRESS 0x08 /* address out of range */
#define errNOTDONE 0x09 /* received DNLOAD with wLength=0, but firmware seems incomplete */
#define errFIRMWARE 0x0A /* Runtime firmware corrupt, cannot return to non-dfu operations! */
#define errVENDOR 0x0B /* vendor specific error */
#define errUSBR 0x0C /* Unexpected usb reset! */
#define errPOR 0x0D /* Unexpected power on reset */
#define errUNKNOWN 0x0E /* Unknown error */
#define errSTALLEDPKT 0x0F /* device stalled unexpected request */
/***************************/
/*** DFU State Values **************/
#define appIDLE 0x00
#define appDETACH 0x01
#define dfuIDLE 0x02
#define dfuDNLOAD_SYNC 0x03
#define dfuDNBUSY 0x04
#define dfuDNLOAD_IDLE 0x05
#define dfuMANIFEST_SYNC 0x06
#define dfuMANIFEST 0x07
#define dfuMANIFEST_WAIT_RESET 0x08
#define dfuUPLOAD_IDLE 0x09
#define dfuERROR 0x0A
/***********************************/
extern volatile bool dfuBusy;
/* exposed functions */
void dfuInit(void); /* singleton dfu initializer */
/* should consume dfuEvent type, but for now we can use pInfo (see comment above) */
bool dfuUpdateByRequest(void); /* returns if new status is OK */
void dfuUpdateByReset(void);
void dfuUpdateByTimeout(void);
/* usb callbacks */
u8 *dfuCopyState(u16);
u8 *dfuCopyStatus(u16);
u8 *dfuCopyDNLOAD(u16);
u8 *dfuCopyUPLOAD(u16);
void dfuCopyBufferToExec(void);
bool checkTestFile(void);
u8 dfuGetState(void);
void dfuSetState(u8);
bool dfuUploadStarted();
void dfuFinishUpload();
#endif

View File

@ -0,0 +1,83 @@
# script for stm32
interface ft2232
ft2232_device_desc "Olimex OpenOCD JTAG"
ft2232_layout olimex-jtag
ft2232_vid_pid 0x15ba 0x0003
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
# jtag speed
jtag_khz 600
#use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst
#jtag scan chain
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
# See STM Document RM0008
# Section 26.6.3
set _CPUTAPID 0x3ba00477
}
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
if { [info exists BSTAPID ] } {
set _BSTAPID $BSTAPID
} else {
# See STM Document RM0008
# Section 26.6.2
# Medium Density RevA
set _BSTAPID 0x06410041
# Rev B and Rev Z
set _BSTAPID 0x16410041
# High Density Devices, Rev A
#set _BSTAPID 0x06414041
}
jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID
set _TARGETNAME [format "%s.cpu" $_CHIPNAME]
target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0
#$_TARGETNAME configure -event halted halt_handle
#flash bank stm32x 0 0 0 0 0
#target create cortex_m3 -endian little
#run_and_halt_time 0 30
#working_area 0 0x20000000 0x4000 nobackup
flash bank stm32x 0x08000000 0x00010000 0 0 0
# For more information about the configuration files, take a look at:
# openocd.texi
#script flash.script
proc halt_handle {} {
resume
}
proc flash_test {} {
puts "Entering DEBUG wait"
sleep 100
# reset run
# sleep 500
}
init
flash_test

View File

@ -0,0 +1,91 @@
# script for stm32
interface ft2232
ft2232_device_desc "Olimex OpenOCD JTAG"
ft2232_layout olimex-jtag
ft2232_vid_pid 0x15ba 0x0003
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
# jtag speed
jtag_khz 600
#use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst
#jtag scan chain
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
# See STM Document RM0008
# Section 26.6.3
set _CPUTAPID 0x3ba00477
}
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
if { [info exists BSTAPID ] } {
set _BSTAPID $BSTAPID
} else {
# See STM Document RM0008
# Section 26.6.2
# Medium Density RevA
set _BSTAPID 0x06410041
# Rev B and Rev Z
set _BSTAPID 0x16410041
# High Density Devices, Rev A
#set _BSTAPID 0x06414041
}
jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID
set _TARGETNAME [format "%s.cpu" $_CHIPNAME]
target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0
#$_TARGETNAME configure -event halted halt_handle
#flash bank stm32x 0 0 0 0 0
#target create cortex_m3 -endian little
#run_and_halt_time 0 30
#working_area 0 0x20000000 0x4000 nobackup
flash bank stm32x 0x08000000 0x00010000 0 0 0
# For more information about the configuration files, take a look at:
# openocd.texi
#script flash.script
proc halt_handle {} {
resume
}
proc flash_test {} {
puts "Trying to flash"
sleep 100
halt
sleep 300
stm32x mass_erase 0
sleep 20
flash write_bank 0 tmpflash.bin 0
sleep 50
# reset run
# sleep 500
reset run
shutdown
}
init
flash_test

View File

@ -0,0 +1,73 @@
# script for stm32
interface ft2232
ft2232_device_desc "Olimex OpenOCD JTAG"
ft2232_layout olimex-jtag
ft2232_vid_pid 0x15ba 0x0003
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
# jtag speed
jtag_khz 500
jtag_nsrst_delay 200
jtag_ntrst_delay 200
#use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst
#jtag scan chain
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
# See STM Document RM0008
# Section 26.6.3
set _CPUTAPID 0x3ba00477
}
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
if { [info exists BSTAPID ] } {
set _BSTAPID $BSTAPID
} else {
# See STM Document RM0008
# Section 26.6.2
# Medium Density RevA
set _BSTAPID 0x06410041
# Rev B and Rev Z
set _BSTAPID 0x16410041
# High Density Devices, Rev A
#set _BSTAPID 0x06414041
}
jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID
set _TARGETNAME [format "%s.cpu" $_CHIPNAME]
target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 0x5000 -work-area-backup 0
flash bank stm32x 0x08000000 0x00010000 0 0 0
init
halt
sleep 1000
stm32x unlock 0
flash erase_sector 0 0 0
sleep 1000
flash write_bank 0 tmpflash.bin 0
sleep 3000
reset
sleep 3000
shutdown

View File

@ -0,0 +1,72 @@
# script for stm32
interface ft2232
ft2232_device_desc "Olimex OpenOCD JTAG"
ft2232_layout olimex-jtag
ft2232_vid_pid 0x15ba 0x0003
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME stm32
}
if { [info exists ENDIAN] } {
set _ENDIAN $ENDIAN
} else {
set _ENDIAN little
}
# jtag speed
jtag_khz 500
jtag_nsrst_delay 100
jtag_ntrst_delay 100
#use combined on interfaces or targets that can't set TRST/SRST separately
reset_config trst_and_srst
#jtag scan chain
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
# See STM Document RM0008
# Section 26.6.3
set _CPUTAPID 0x3ba00477
}
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_CPUTAPID
if { [info exists BSTAPID ] } {
set _BSTAPID $BSTAPID
} else {
# See STM Document RM0008
# Section 26.6.2
# Medium Density RevA
set _BSTAPID 0x06410041
# Rev B and Rev Z
set _BSTAPID 0x16410041
# High Density Devices, Rev A
#set _BSTAPID 0x06414041
}
jtag newtap $_CHIPNAME bs -irlen 5 -ircapture 0x1 -irmask 0x1 -expected-id $_BSTAPID
set _TARGETNAME [format "%s.cpu" $_CHIPNAME]
target create $_TARGETNAME cortex_m3 -endian $_ENDIAN -chain-position $_TARGETNAME
$_TARGETNAME configure -work-area-virt 0 -work-area-phys 0x20000000 -work-area-size 16384 -work-area-backup 0
#flash bank stm32x 0 0 0 0 0
target create cortex_m3 -endian little
#run_and_halt_time 0 30
#working_area 0 0x20000000 0x4000 nobackup
#flash bank stm32x 0x08000000 0x00010000 0 0 0
reset
sleep 3000
shutdown
# For more information about the configuration files, take a look at:
# openocd.texi

View File

@ -0,0 +1,435 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# vim: sw=4:ts=4:si:et:enc=utf-8
# Author: Ivan A-R <ivan@tuxotronic.org>
# Project page: http://tuxotronic.org/wiki/projects/stm32loader
#
# This file is part of stm32loader.
#
# stm32loader 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 3, or (at your option) any later
# version.
#
# stm32loader is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
# for more details.
#
# You should have received a copy of the GNU General Public License
# along with stm32loader; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
import sys, getopt
import serial
import time
try:
from progressbar import *
usepbar = 1
except:
usepbar = 0
# Verbose level
QUIET = 20
def mdebug(level, message):
if(QUIET >= level):
print >> sys.stderr , message
class CmdException(Exception):
pass
class CommandInterface:
def open(self, aport='/dev/tty.usbserial-FTD3TMCH', abaudrate=115200) :
self.sp = serial.Serial(
port=aport,
baudrate=abaudrate, # baudrate
bytesize=8, # number of databits
parity=serial.PARITY_EVEN,
stopbits=1,
xonxoff=0, # enable software flow control
rtscts=0, # disable RTS/CTS flow control
timeout=5 # set a timeout value, None for waiting forever
)
def _wait_for_ask(self, info = ""):
# wait for ask
try:
ask = ord(self.sp.read())
except:
raise CmdException("Can't read port or timeout")
else:
if ask == 0x79:
# ACK
return 1
else:
if ask == 0x1F:
# NACK
raise CmdException("NACK "+info)
else:
# Unknow responce
raise CmdException("Unknow response. "+info+": "+hex(ask))
def reset(self):
self.sp.setDTR(0)
time.sleep(0.1)
self.sp.setDTR(1)
time.sleep(0.5)
def initChip(self):
# Set boot
self.sp.setRTS(0)
self.reset()
self.sp.write("\x7F") # Syncro
return self._wait_for_ask("Syncro")
def releaseChip(self):
self.sp.setRTS(1)
self.reset()
def cmdGeneric(self, cmd):
self.sp.write(chr(cmd))
self.sp.write(chr(cmd ^ 0xFF)) # Control byte
return self._wait_for_ask(hex(cmd))
def cmdGet(self):
if self.cmdGeneric(0x00):
mdebug(10, "*** Get command");
len = ord(self.sp.read())
version = ord(self.sp.read())
mdebug(10, " Bootloader version: "+hex(version))
dat = map(lambda c: hex(ord(c)), self.sp.read(len))
mdebug(10, " Available commands: "+str(dat))
self._wait_for_ask("0x00 end")
return version
else:
raise CmdException("Get (0x00) failed")
def cmdGetVersion(self):
if self.cmdGeneric(0x01):
mdebug(10, "*** GetVersion command")
version = ord(self.sp.read())
self.sp.read(2)
self._wait_for_ask("0x01 end")
mdebug(10, " Bootloader version: "+hex(version))
return version
else:
raise CmdException("GetVersion (0x01) failed")
def cmdGetID(self):
if self.cmdGeneric(0x02):
mdebug(10, "*** GetID command")
len = ord(self.sp.read())
id = self.sp.read(len+1)
self._wait_for_ask("0x02 end")
return id
else:
raise CmdException("GetID (0x02) failed")
def _encode_addr(self, addr):
byte3 = (addr >> 0) & 0xFF
byte2 = (addr >> 8) & 0xFF
byte1 = (addr >> 16) & 0xFF
byte0 = (addr >> 24) & 0xFF
crc = byte0 ^ byte1 ^ byte2 ^ byte3
return (chr(byte0) + chr(byte1) + chr(byte2) + chr(byte3) + chr(crc))
def cmdReadMemory(self, addr, lng):
assert(lng <= 256)
if self.cmdGeneric(0x11):
mdebug(10, "*** ReadMemory command")
self.sp.write(self._encode_addr(addr))
self._wait_for_ask("0x11 address failed")
N = (lng - 1) & 0xFF
crc = N ^ 0xFF
self.sp.write(chr(N) + chr(crc))
self._wait_for_ask("0x11 length failed")
return map(lambda c: ord(c), self.sp.read(lng))
else:
raise CmdException("ReadMemory (0x11) failed")
def cmdGo(self, addr):
if self.cmdGeneric(0x21):
mdebug(10, "*** Go command")
self.sp.write(self._encode_addr(addr))
self._wait_for_ask("0x21 go failed")
else:
raise CmdException("Go (0x21) failed")
def cmdWriteMemory(self, addr, data):
assert(len(data) <= 256)
if self.cmdGeneric(0x31):
mdebug(10, "*** Write memory command")
self.sp.write(self._encode_addr(addr))
self._wait_for_ask("0x31 address failed")
#map(lambda c: hex(ord(c)), data)
lng = (len(data)-1) & 0xFF
mdebug(10, " %s bytes to write" % [lng+1]);
self.sp.write(chr(lng)) # len really
crc = 0xFF
for c in data:
crc = crc ^ c
self.sp.write(chr(c))
self.sp.write(chr(crc))
self._wait_for_ask("0x31 programming failed")
mdebug(10, " Write memory done")
else:
raise CmdException("Write memory (0x31) failed")
def cmdEraseMemory(self, sectors = None):
if self.cmdGeneric(0x43):
mdebug(10, "*** Erase memory command")
if sectors is None:
# Global erase
self.sp.write(chr(0xFF))
self.sp.write(chr(0x00))
else:
# Sectors erase
self.sp.write(chr((len(sectors)-1) & 0xFF))
crc = 0xFF
for c in sectors:
crc = crc ^ c
self.sp.write(chr(c))
self.sp.write(chr(crc))
self._wait_for_ask("0x43 erasing failed")
mdebug(10, " Erase memory done")
else:
raise CmdException("Erase memory (0x43) failed")
def cmdWriteProtect(self, sectors):
if self.cmdGeneric(0x63):
mdebug(10, "*** Write protect command")
self.sp.write(chr((len(sectors)-1) & 0xFF))
crc = 0xFF
for c in sectors:
crc = crc ^ c
self.sp.write(chr(c))
self.sp.write(chr(crc))
self._wait_for_ask("0x63 write protect failed")
mdebug(10, " Write protect done")
else:
raise CmdException("Write Protect memory (0x63) failed")
def cmdWriteUnprotect(self):
if self.cmdGeneric(0x73):
mdebug(10, "*** Write Unprotect command")
self._wait_for_ask("0x73 write unprotect failed")
self._wait_for_ask("0x73 write unprotect 2 failed")
mdebug(10, " Write Unprotect done")
else:
raise CmdException("Write Unprotect (0x73) failed")
def cmdReadoutProtect(self):
if self.cmdGeneric(0x82):
mdebug(10, "*** Readout protect command")
self._wait_for_ask("0x82 readout protect failed")
self._wait_for_ask("0x82 readout protect 2 failed")
mdebug(10, " Read protect done")
else:
raise CmdException("Readout protect (0x82) failed")
def cmdReadoutUnprotect(self):
if self.cmdGeneric(0x92):
mdebug(10, "*** Readout Unprotect command")
self._wait_for_ask("0x92 readout unprotect failed")
self._wait_for_ask("0x92 readout unprotect 2 failed")
mdebug(10, " Read Unprotect done")
else:
raise CmdException("Readout unprotect (0x92) failed")
# Complex commands section
def readMemory(self, addr, lng):
data = []
if usepbar:
widgets = ['Reading: ', Percentage(),', ', ETA(), ' ', Bar()]
pbar = ProgressBar(widgets=widgets,maxval=lng, term_width=79).start()
while lng > 256:
if usepbar:
pbar.update(pbar.maxval-lng)
else:
mdebug(5, "Read %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256})
data = data + self.cmdReadMemory(addr, 256)
addr = addr + 256
lng = lng - 256
if usepbar:
pbar.update(pbar.maxval-lng)
pbar.finish()
else:
mdebug(5, "Read %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256})
data = data + self.cmdReadMemory(addr, lng)
return data
def writeMemory(self, addr, data):
lng = len(data)
if usepbar:
widgets = ['Writing: ', Percentage(),' ', ETA(), ' ', Bar()]
pbar = ProgressBar(widgets=widgets, maxval=lng, term_width=79).start()
offs = 0
while lng > 256:
if usepbar:
pbar.update(pbar.maxval-lng)
else:
mdebug(5, "Write %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256})
self.cmdWriteMemory(addr, data[offs:offs+256])
offs = offs + 256
addr = addr + 256
lng = lng - 256
if usepbar:
pbar.update(pbar.maxval-lng)
pbar.finish()
else:
mdebug(5, "Write %(len)d bytes at 0x%(addr)X" % {'addr': addr, 'len': 256})
self.cmdWriteMemory(addr, data[offs:offs+lng] + ([0xFF] * (256-lng)) )
def __init__(self) :
pass
def usage():
print """Usage: %s [-hqVewvr] [-l length] [-p port] [-b baud] [-a addr] [file.bin]
-h This help
-q Quiet
-V Verbose
-e Erase
-w Write
-v Verify
-r Read
-l length Length of read
-p port Serial port (default: /dev/tty.usbserial-ftCYPMYJ)
-b baud Baud speed (default: 115200)
-a addr Target address
./stm32loader.py -e -w -v example/main.bin
""" % sys.argv[0]
if __name__ == "__main__":
# Import Psyco if available
try:
import psyco
psyco.full()
print "Using Psyco..."
except ImportError:
pass
conf = {
'port': '/dev/tty.usbserial-FTD3TMCH',
'baud': 115200,
'address': 0x08000000,
'erase': 0,
'write': 0,
'verify': 0,
'read': 0,
'len': 1000,
'fname':'',
}
# http://www.python.org/doc/2.5.2/lib/module-getopt.html
try:
opts, args = getopt.getopt(sys.argv[1:], "hqVewvrp:b:a:l:")
except getopt.GetoptError, err:
# print help information and exit:
print str(err) # will print something like "option -a not recognized"
usage()
sys.exit(2)
QUIET = 5
for o, a in opts:
if o == '-V':
QUIET = 10
elif o == '-q':
QUIET = 0
elif o == '-h':
usage()
sys.exit(0)
elif o == '-e':
conf['erase'] = 1
elif o == '-w':
conf['write'] = 1
elif o == '-v':
conf['verify'] = 1
elif o == '-r':
conf['read'] = 1
elif o == '-p':
conf['port'] = a
elif o == '-b':
conf['baud'] = eval(a)
elif o == '-a':
conf['address'] = eval(a)
elif o == '-l':
conf['len'] = eval(a)
# elif o == '-f':
# conf['fname'] = a
else:
assert False, "unhandled option"
cmd = CommandInterface()
cmd.open(conf['port'], conf['baud'])
mdebug(10, "Open port %(port)s, baud %(baud)d" % {'port':conf['port'], 'baud':conf['baud']})
try:
try:
cmd.initChip()
except:
print "Can't init. Ensure that BOOT0 is enabled and reset device"
bootversion = cmd.cmdGet()
mdebug(0, "Bootloader version %X" % bootversion)
mdebug(0, "Chip id `%s'" % str(map(lambda c: hex(ord(c)), cmd.cmdGetID())))
# cmd.cmdGetVersion()
# cmd.cmdGetID()
# cmd.cmdReadoutUnprotect()
# cmd.cmdWriteUnprotect()
# cmd.cmdWriteProtect([0, 1])
if (conf['write'] or conf['verify']):
data = map(lambda c: ord(c), file(args[0]).read())
if conf['erase']:
cmd.cmdEraseMemory()
if conf['write']:
cmd.writeMemory(conf['address'], data)
if conf['verify']:
verify = cmd.readMemory(conf['address'], len(data))
if(data == verify):
print "Verification OK"
else:
print "Verification FAILED"
print str(len(data)) + ' vs ' + str(len(verify))
for i in xrange(0, len(data)):
if data[i] != verify[i]:
print hex(i) + ': ' + hex(data[i]) + ' vs ' + hex(verify[i])
if not conf['write'] and conf['read']:
rdata = cmd.readMemory(conf['address'], conf['len'])
# file(conf['fname'], 'wb').write(rdata)
file(args[0], 'wb').write(''.join(map(chr,rdata)))
# cmd.cmdGo(addr + 0x04)
finally:
cmd.releaseChip()

View File

@ -0,0 +1,304 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
/**
* @file hardware.c
*
* @brief init routines to setup clocks, interrupts, also destructor functions.
* does not include USB stuff. EEPROM read/write functions.
*
*/
#include "hardware.h"
void setPin(u32 bank, u8 pin) {
u32 pinMask = 0x1 << (pin);
SET_REG(GPIO_BSRR(bank), pinMask);
}
void resetPin(u32 bank, u8 pin) {
u32 pinMask = 0x1 << (16 + pin);
SET_REG(GPIO_BSRR(bank), pinMask);
}
bool readPin(u32 bank, u8 pin) {
// todo, implement read
if (GET_REG(GPIO_IDR(bank)) & (0x01 << pin)) {
return TRUE;
} else {
return FALSE;
}
}
void strobePin(u32 bank, u8 pin, u8 count, u32 rate) {
resetPin(bank, pin);
u32 c;
while (count-- > 0) {
for (c = rate; c > 0; c--) {
asm volatile("nop");
}
setPin(bank, pin);
for (c = rate; c > 0; c--) {
asm volatile("nop");
}
resetPin(bank, pin);
}
}
void systemReset(void) {
SET_REG(RCC_CR, GET_REG(RCC_CR) | 0x00000001);
SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xF8FF0000);
SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFEF6FFFF);
SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFFFBFFFF);
SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xFF80FFFF);
SET_REG(RCC_CIR, 0x00000000); /* disable all RCC interrupts */
}
void setupCLK(void) {
/* enable HSE */
SET_REG(RCC_CR, GET_REG(RCC_CR) | 0x00010001);
while ((GET_REG(RCC_CR) & 0x00020000) == 0); /* for it to come on */
/* enable flash prefetch buffer */
SET_REG(FLASH_ACR, 0x00000012);
/* Configure PLL */
SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) | 0x001D0400); /* pll=72Mhz,APB1=36Mhz,AHB=72Mhz */
SET_REG(RCC_CR, GET_REG(RCC_CR) | 0x01000000); /* enable the pll */
while ((GET_REG(RCC_CR) & 0x03000000) == 0); /* wait for it to come on */
/* Set SYSCLK as PLL */
SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) | 0x00000002);
while ((GET_REG(RCC_CFGR) & 0x00000008) == 0); /* wait for it to come on */
}
void setupLED(void) {
// todo, swap out hardcoded pin/bank with macro
u32 rwmVal; /* read-write-modify place holder var */
/* Setup APB2 (GPIOB) */
rwmVal = GET_REG(RCC_APB2ENR);
rwmVal |= 0x00000008;
SET_REG(RCC_APB2ENR, rwmVal);
/* Setup GPIOB Pin 1 as PP Out */
SET_REG(GPIO_CRL(GPIOB), 0x00000010);
rwmVal = GET_REG(GPIO_CRL(GPIOB));
rwmVal &= 0xFFFFFF0F;
rwmVal |= 0x00000010;
SET_REG(GPIO_CRL(GPIOB), rwmVal);
setPin(GPIOB, 1);
}
void setupBUTTON(void) {
// todo, swap out hardcoded pin/bank with macro
u32 rwmVal; /* read-write-modify place holder var */
/* Setup APB2 (GPIOB) */
rwmVal = GET_REG(RCC_APB2ENR);
rwmVal |= 0x00000008;
SET_REG(RCC_APB2ENR, rwmVal);
/* Setup GPIOB Pin 8 as PP Out */
rwmVal = GET_REG(GPIO_CRH(GPIOB));
rwmVal &= 0xFFFFFFF0;
rwmVal |= 0x00000004;
SET_REG(GPIO_CRH(GPIOB), rwmVal);
}
void setupFLASH() {
/* configure the HSI oscillator */
if ((pRCC->CR & 0x01) == 0x00) {
u32 rwmVal = pRCC->CR;
rwmVal |= 0x01;
pRCC->CR = rwmVal;
}
/* wait for it to come on */
while ((pRCC->CR & 0x02) == 0x00) {}
}
bool checkUserCode(u32 usrAddr) {
u32 sp = *(vu32 *) usrAddr;
if ((sp & 0x2FFE0000) == 0x20000000) {
return (TRUE);
} else {
return (FALSE);
}
}
void jumpToUser(u32 usrAddr) {
typedef void (*funcPtr)(void);
u32 jumpAddr = *(vu32 *)(usrAddr + 0x04); /* reset ptr in vector table */
funcPtr usrMain = (funcPtr) jumpAddr;
/* tear down all the dfu related setup */
// disable usb interrupts, clear them, turn off usb, set the disc pin
// todo pick exactly what we want to do here, now its just a conservative
flashLock();
usbDsbISR();
nvicDisableInterrupts();
setPin(GPIOB, 9); // disconnect usb from host. todo, macroize pin
systemReset(); // resets clocks and periphs, not core regs
__MSR_MSP(*(vu32 *) usrAddr); /* set the users stack ptr */
usrMain(); /* go! */
}
void nvicInit(NVIC_InitTypeDef *NVIC_InitStruct) {
u32 tmppriority = 0x00;
u32 tmpreg = 0x00;
u32 tmpmask = 0x00;
u32 tmppre = 0;
u32 tmpsub = 0x0F;
SCB_TypeDef *rSCB = (SCB_TypeDef *) SCB_BASE;
NVIC_TypeDef *rNVIC = (NVIC_TypeDef *) NVIC_BASE;
/* Compute the Corresponding IRQ Priority --------------------------------*/
tmppriority = (0x700 - (rSCB->AIRCR & (u32)0x700)) >> 0x08;
tmppre = (0x4 - tmppriority);
tmpsub = tmpsub >> tmppriority;
tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
tmppriority |= NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;
tmppriority = tmppriority << 0x04;
tmppriority = ((u32)tmppriority) << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);
tmpreg = rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)];
tmpmask = (u32)0xFF << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);
tmpreg &= ~tmpmask;
tmppriority &= tmpmask;
tmpreg |= tmppriority;
rNVIC->IPR[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg;
/* Enable the Selected IRQ Channels --------------------------------------*/
rNVIC->ISER[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] =
(u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F);
}
void nvicDisableInterrupts() {
NVIC_TypeDef *rNVIC = (NVIC_TypeDef *) NVIC_BASE;
rNVIC->ICER[0] = 0xFFFFFFFF;
rNVIC->ICER[1] = 0xFFFFFFFF;
rNVIC->ICPR[0] = 0xFFFFFFFF;
rNVIC->ICPR[1] = 0xFFFFFFFF;
SET_REG(STK_CTRL, 0x04); /* disable the systick, which operates separately from nvic */
}
void systemHardReset(void) {
SCB_TypeDef *rSCB = (SCB_TypeDef *) SCB_BASE;
/* Reset */
rSCB->AIRCR = (u32)AIRCR_RESET_REQ;
/* should never get here */
while (1) {
asm volatile("nop");
}
}
bool flashErasePage(u32 pageAddr) {
u32 rwmVal = GET_REG(FLASH_CR);
rwmVal = FLASH_CR_PER;
SET_REG(FLASH_CR, rwmVal);
while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}
SET_REG(FLASH_AR, pageAddr);
SET_REG(FLASH_CR, FLASH_CR_START | FLASH_CR_PER);
while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}
/* todo: verify the page was erased */
rwmVal = 0x00;
SET_REG(FLASH_CR, rwmVal);
return TRUE;
}
bool flashErasePages(u32 pageAddr, u16 n) {
while (n-- > 0) {
if (!flashErasePage(pageAddr + 0x400 * n)) {
return FALSE;
}
}
return TRUE;
}
bool flashWriteWord(u32 addr, u32 word) {
vu16 *flashAddr = (vu16 *)addr;
vu32 lhWord = (vu32)word & 0x0000FFFF;
vu32 hhWord = ((vu32)word & 0xFFFF0000) >> 16;
u32 rwmVal = GET_REG(FLASH_CR);
SET_REG(FLASH_CR, FLASH_CR_PG);
/* apparently we need not write to FLASH_AR and can
simply do a native write of a half word */
while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}
*(flashAddr + 0x01) = (vu16)hhWord;
while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}
*(flashAddr) = (vu16)lhWord;
while (GET_REG(FLASH_SR) & FLASH_SR_BSY) {}
rwmVal &= 0xFFFFFFFE;
SET_REG(FLASH_CR, rwmVal);
/* verify the write */
if (*(vu32 *)addr != word) {
return FALSE;
}
return TRUE;
}
void flashLock() {
/* take down the HSI oscillator? it may be in use elsewhere */
/* ensure all FPEC functions disabled and lock the FPEC */
SET_REG(FLASH_CR, 0x00000080);
}
void flashUnlock() {
/* unlock the flash */
SET_REG(FLASH_KEYR, FLASH_KEY1);
SET_REG(FLASH_KEYR, FLASH_KEY2);
}

View File

@ -0,0 +1,190 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
#ifndef __HARDWARE_H
#define __HARDWARE_H
#include "stm32f10x_type.h"
#include "cortexm3_macro.h"
#include "common.h"
/* macro'd register and peripheral definitions */
#define RCC ((u32)0x40021000)
#define FLASH ((u32)0x40022000)
#define GPIOA ((u32)0x40010800)
#define GPIOB ((u32)0x40010C00)
#define GPIOC ((u32)0x40011000)
#define RCC_CR RCC
#define RCC_CFGR (RCC + 0x04)
#define RCC_CIR (RCC + 0x08)
#define RCC_AHBENR (RCC + 0x14)
#define RCC_APB2ENR (RCC + 0x18)
#define RCC_APB1ENR (RCC + 0x1C)
#define FLASH_ACR (FLASH + 0x00)
#define FLASH_KEYR (FLASH + 0x04)
#define FLASH_OPTKEYR (FLASH + 0x08)
#define FLASH_SR (FLASH + 0x0C)
#define FLASH_CR (FLASH + 0x10)
#define FLASH_AR (FLASH + 0x14)
#define FLASH_OBR (FLASH + 0x1C)
#define FLASH_WRPR (FLASH + 0x20)
#define FLASH_KEY1 0x45670123
#define FLASH_KEY2 0xCDEF89AB
#define FLASH_RDPRT 0x00A5
#define FLASH_SR_BSY 0x01
#define FLASH_CR_PER 0x02
#define FLASH_CR_PG 0x01
#define FLASH_CR_START 0x40
#define GPIO_CRL(port) port
#define GPIO_CRH(port) (port+0x04)
#define GPIO_IDR(port) (port+0x08)
#define GPIO_ODR(port) (port+0x0c)
#define GPIO_BSRR(port) (port+0x10)
#define SCS_BASE ((u32)0xE000E000)
#define NVIC_BASE (SCS_BASE + 0x0100)
#define SCB_BASE (SCS_BASE + 0x0D00)
#define SCS 0xE000E000
#define NVIC (SCS+0x100)
#define SCB (SCS+0xD00)
#define STK (SCS+0x10)
#define SCB_VTOR (SCB+0x08)
#define STK_CTRL (STK+0x00)
#define TIM1_APB2_ENB ((u32)0x00000800)
#define TIM1 ((u32)0x40012C00)
#define TIM1_PSC (TIM1+0x28)
#define TIM1_ARR (TIM1+0x2C)
#define TIM1_RCR (TIM1+0x30)
#define TIM1_CR1 (TIM1+0x00)
#define TIM1_CR2 (TIM1+0x04)
#define TIM1_DIER (TIM1+0x0C)
#define TIM1_UP_IRQ_Channel ((u8)0x19)
#define USB_HP_IRQ ((u8)0x13)
#define USB_LP_IRQ ((u8)0x14)
#define TIM2_IRQ ((u8)0x1C)
/* AIRCR */
#define AIRCR_RESET 0x05FA0000
#define AIRCR_RESET_REQ (AIRCR_RESET | (u32)0x04);
/* temporary copyage of example from kiel */
#define __VAL(__TIMCLK, __PERIOD) ((__TIMCLK/1000000UL)*__PERIOD)
#define __PSC(__TIMCLK, __PERIOD) (((__VAL(__TIMCLK, __PERIOD)+49999UL)/50000UL) - 1)
#define __ARR(__TIMCLK, __PERIOD) ((__VAL(__TIMCLK, __PERIOD)/(__PSC(__TIMCLK, __PERIOD)+1)) - 1)
#define SET_REG(addr,val) do { *(vu32*)(addr)=val; } while(0)
#define GET_REG(addr) (*(vu32*)(addr))
/* todo: there must be some major misunderstanding in how we access
regs. The direct access approach (GET_REG) causes the usb init to
fail upon trying to activate RCC_APB1 |= 0x00800000. However, using
the struct approach from ST, it works fine...temporarily switching
to that approach */
typedef struct {
vu32 CR;
vu32 CFGR;
vu32 CIR;
vu32 APB2RSTR;
vu32 APB1RSTR;
vu32 AHBENR;
vu32 APB2ENR;
vu32 APB1ENR;
vu32 BDCR;
vu32 CSR;
} RCC_RegStruct;
#define pRCC ((RCC_RegStruct *) RCC)
typedef struct {
vu32 ISER[2];
u32 RESERVED0[30];
vu32 ICER[2];
u32 RSERVED1[30];
vu32 ISPR[2];
u32 RESERVED2[30];
vu32 ICPR[2];
u32 RESERVED3[30];
vu32 IABR[2];
u32 RESERVED4[62];
vu32 IPR[15];
} NVIC_TypeDef;
typedef struct {
u8 NVIC_IRQChannel;
u8 NVIC_IRQChannelPreemptionPriority;
u8 NVIC_IRQChannelSubPriority;
bool NVIC_IRQChannelCmd; /* TRUE for enable */
} NVIC_InitTypeDef;
typedef struct {
vuc32 CPUID;
vu32 ICSR;
vu32 VTOR;
vu32 AIRCR;
vu32 SCR;
vu32 CCR;
vu32 SHPR[3];
vu32 SHCSR;
vu32 CFSR;
vu32 HFSR;
vu32 DFSR;
vu32 MMFAR;
vu32 BFAR;
vu32 AFSR;
} SCB_TypeDef;
void setPin(u32 bank, u8 pin);
void resetPin(u32 bank, u8 pin);
bool readPin(u32 bank, u8 pin);
void strobePin(u32 bank, u8 pin, u8 count, u32 rate);
void systemHardReset(void);
void systemReset(void);
void setupCLK(void);
void setupLED(void);
void setupFLASH(void);
void setupBUTTON(void);
bool checkUserCode(u32 usrAddr);
void jumpToUser(u32 usrAddr);
bool flashWriteWord(u32 addr, u32 word);
bool flashErasePage(u32 addr);
bool flashErasePages(u32 addr, u16 n);
void flashLock(void);
void flashUnlock(void);
void nvicInit(NVIC_InitTypeDef *);
void nvicDisableInterrupts(void);
#endif

View File

@ -0,0 +1,70 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
/**
* @file main.c
*
* @brief main loop and calling any hardware init stuff. timing hacks for EEPROM
* writes not to block usb interrupts. logic to handle 2 second timeout then
* jump to user code.
*
*/
#include "common.h"
int main() {
systemReset(); // peripherals but not PC
setupCLK();
setupLED();
setupUSB();
setupBUTTON();
setupFLASH();
strobePin(LED_BANK, LED, STARTUP_BLINKS, BLINK_FAST);
/* wait for host to upload program or halt bootloader */
bool no_user_jump = !checkUserCode(USER_CODE_FLASH) && !checkUserCode(USER_CODE_RAM) || readPin(BUTTON_BANK, BUTTON);
int delay_count = 0;
while ((delay_count++ < BOOTLOADER_WAIT)
|| no_user_jump) {
strobePin(LED_BANK, LED, 1, BLINK_SLOW);
if (dfuUploadStarted()) {
dfuFinishUpload(); // systemHardReset from DFU once done
}
}
if (checkUserCode(USER_CODE_RAM)) {
jumpToUser(USER_CODE_RAM);
} else if (checkUserCode(USER_CODE_FLASH)) {
jumpToUser(USER_CODE_FLASH);
} else {
// some sort of fault occurred, hard reset
strobePin(LED_BANK, LED, 5, BLINK_FAST);
systemHardReset();
}
}

View File

@ -0,0 +1,5 @@
Modified version of maple bootloader which includes DFU read functionality
Modifications were made by Tim Schuerewegen

View File

@ -0,0 +1,172 @@
/*
Default linker script for STM32F10x_128K_20K
Original Copyright RAISONANCE S.A.S. 2008
Modified P Harrison May 2009
*/
/*
* Default stack sizes.
*
* These are used by the startup in order to allocate stacks for the different modes.
* PROVIDE" allows to easily override these values from an object file or the commmand line.
*/
__Stack_Size = 1024 ;
PROVIDE ( _Stack_Size = __Stack_Size ) ;
__Stack_Init = _estack - __Stack_Size ;
PROVIDE ( _Stack_Init = __Stack_Init ) ;
/*
*There will be a link error if there is not this amount of RAM free at the end.
*/
_Minimum_Stack_Size = 0x100 ;
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 20K
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K
}
/* higher address of the user mode stack */
_estack = 0x20005000;
SECTIONS
{
/*
* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section,
* which goes to FLASH
*/
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >FLASH
/*
* for some STRx devices, the beginning of the startup code is stored in the .flashtext section,
* which goes to FLASH
*/
.flashtext :
{
. = ALIGN(4);
KEEP (*(.flashtext)) /* Startup code */
. = ALIGN(4);
} >FLASH
/*
* the program code is stored in the .text section, which goes to Flash
*/
.text :
{
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
_etext = .;
_sidata = _etext;
} >FLASH
/*
* This is the initialized data section. It is stored in RAM but the initial values
* are held in flash and copied to RAM by the startup code
*/
/* we copy the important program globals vector in RAM as well, so that users can fool with it */
.data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */
{
. = ALIGN(4);
_sdata = . ; /* Used by the startup in order to initialize the .data section */
KEEP( *(.data) )
KEEP( *(.data.*) )
. = ALIGN(4);
_edata = . ; /* Used by the startup in order to initialize the .data section */
} >RAM
/*
* This is the uninitialized data section. Date here is stored in RAM and will be
* set to zero by the startup code.
*/
.bss :
{
. = ALIGN(4);
_sbss = .; /* Used by the startup in order to initialize the .bss section */
*(.bss)
*(COMMON)
. = ALIGN(4);
_ebss = . ; /* Used by the startup in order to initialize the .bss section */
} >RAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
/*
* This is the user stack section
* This is just to check that there is enough RAM left for the User mode stack
* It should generate an error if it's full.
*/
._usrstack :
{
. = ALIGN(4);
_susrstack = . ;
. = . + _Minimum_Stack_Size ;
. = ALIGN(4);
_eusrstack = . ;
} >RAM
/*
* after that it's only debugging information.
*/
/* remove the debugging information from the standard libraries */
DISCARD :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/*
* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0.
*/
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View File

@ -0,0 +1,169 @@
/*
Default linker script for STM32F10x_128K_20K
Original Copyright RAISONANCE S.A.S. 2008
Modified P Harrison May 2009
*/
/*
* Default stack sizes.
*
* These are used by the startup in order to allocate stacks for the different modes.
* PROVIDE" allows to easily override these values from an object file or the commmand line.
*/
__Stack_Size = 1024 ;
PROVIDE ( _Stack_Size = __Stack_Size ) ;
__Stack_Init = _estack - __Stack_Size ;
PROVIDE ( _Stack_Init = __Stack_Init ) ;
/*
*There will be a link error if there is not this amount of RAM free at the end.
*/
_Minimum_Stack_Size = 0x100 ;
MEMORY
{
RAM (xrw) : ORIGIN = 0x20000C00, LENGTH = 17K
}
/* higher address of the user mode stack */
_estack = 0x20005000;
_magicRate = 0x5000;
SECTIONS
{
/*
* for Cortex devices, the beginning of the startup code is stored in the .isr_vector section,
* which goes to FLASH
*/
.isr_vector :
{
. = ALIGN(4);
KEEP(*(.isr_vector)) /* Startup code */
. = ALIGN(4);
} >RAM
/*
* for some STRx devices, the beginning of the startup code is stored in the .flashtext section,
* which goes to FLASH
*/
.flashtext :
{
. = ALIGN(4);
KEEP (*(.flashtext)) /* Startup code */
. = ALIGN(4);
} >RAM
/*
* the program code is stored in the .text section, which goes to Flash
*/
.text :
{
. = ALIGN(4);
*(.text) /* remaining code */
*(.text.*) /* remaining code */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4);
_etext = .;
_sidata = _etext; /* Uused by the startup in order to initialize the .data secion */
} >RAM
/*
* This is the initialized data section. It is stored in RAM but the initial values
* are held in flash and copied to RAM by the startup code
*/
.data : AT ( _sidata ) /* AT makes the LMA follow on in the binary image */
{
. = ALIGN(4);
_sdata = . ; /* Used by the startup in order to initialize the .data section */
KEEP( *(.data) )
KEEP( *(.data.*) )
. = ALIGN(4);
_edata = . ; /* Used by the startup in order to initialize the .data section */
} >RAM
/*
* This is the uninitialized data section. Date here is stored in RAM and will be
* set to zero by the startup code.
*/
.bss :
{
. = ALIGN(4);
_sbss = .; /* Used by the startup in order to initialize the .bss section */
*(.bss)
*(COMMON)
. = ALIGN(4);
_ebss = . ; /* Used by the startup in order to initialize the .bss section */
} >RAM
PROVIDE ( end = _ebss );
PROVIDE ( _end = _ebss );
/*
* This is the user stack section
* This is just to check that there is enough RAM left for the User mode stack
* It should generate an error if it's full.
*/
._usrstack :
{
. = ALIGN(4);
_susrstack = . ;
. = . + _Minimum_Stack_Size ;
. = ALIGN(4);
_eusrstack = . ;
} >RAM
/*
* after that it's only debugging information.
*/
/* remove the debugging information from the standard libraries */
DISCARD :
{
libc.a ( * )
libm.a ( * )
libgcc.a ( * )
}
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
/*
* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0.
*/
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
}

View File

@ -0,0 +1,367 @@
/**
******************************************************************************
* @file startup_stm32f10x_md.s
* @author MCD Application Team
* @version V3.1.0
* @date 06/19/2009
* @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M3 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
*******************************************************************************
* @copy
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
*/
.syntax unified
.cpu cortex-m3
.fpu softvfp
.thumb
.global g_pfnVectors
.global SystemInit_ExtMemCtl_Dummy
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.equ BootRAM, 0xF108F85F
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2], #4
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word MemManage_Handler
.word BusFault_Handler
.word UsageFault_Handler
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word DebugMon_Handler
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler
.word PVD_IRQHandler
.word TAMPER_IRQHandler
.word RTC_IRQHandler
.word FLASH_IRQHandler
.word RCC_IRQHandler
.word EXTI0_IRQHandler
.word EXTI1_IRQHandler
.word EXTI2_IRQHandler
.word EXTI3_IRQHandler
.word EXTI4_IRQHandler
.word DMA1_Channel1_IRQHandler
.word DMA1_Channel2_IRQHandler
.word DMA1_Channel3_IRQHandler
.word DMA1_Channel4_IRQHandler
.word DMA1_Channel5_IRQHandler
.word DMA1_Channel6_IRQHandler
.word DMA1_Channel7_IRQHandler
.word ADC1_2_IRQHandler
.word USB_HP_CAN1_TX_IRQHandler
.word USB_LP_CAN1_RX0_IRQHandler
.word CAN1_RX1_IRQHandler
.word CAN1_SCE_IRQHandler
.word EXTI9_5_IRQHandler
.word TIM1_BRK_IRQHandler
.word TIM1_UP_IRQHandler
.word TIM1_TRG_COM_IRQHandler
.word TIM1_CC_IRQHandler
.word TIM2_IRQHandler
.word TIM3_IRQHandler
.word TIM4_IRQHandler
.word I2C1_EV_IRQHandler
.word I2C1_ER_IRQHandler
.word I2C2_EV_IRQHandler
.word I2C2_ER_IRQHandler
.word SPI1_IRQHandler
.word SPI2_IRQHandler
.word USART1_IRQHandler
.word USART2_IRQHandler
.word USART3_IRQHandler
.word EXTI15_10_IRQHandler
.word RTCAlarm_IRQHandler
.word USBWakeUp_IRQHandler
/*
.word TIM8_BRK
.word TIM8_UP
.word TIM8_TRG_COM
.word TIM8_CC
.word ADC3
.word FSMC
.word SDIO
.word TIM5
.word SPI3
.word UART4
.word UART5
.word TIM6
.word TIM7
.word DMA2_Channel1
.word DMA2_Channel2
.word DMA2_Channel3
.word DMA2_Channel5
*/
.word BootRAM /* @0x108. This is for boot in RAM mode for
STM32F10x Medium Density devices. */
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak MemManage_Handler
.thumb_set MemManage_Handler,Default_Handler
.weak BusFault_Handler
.thumb_set BusFault_Handler,Default_Handler
.weak UsageFault_Handler
.thumb_set UsageFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak DebugMon_Handler
.thumb_set DebugMon_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak PVD_IRQHandler
.thumb_set PVD_IRQHandler,Default_Handler
.weak TAMPER_IRQHandler
.thumb_set TAMPER_IRQHandler,Default_Handler
.weak RTC_IRQHandler
.thumb_set RTC_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_IRQHandler
.thumb_set RCC_IRQHandler,Default_Handler
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak DMA1_Channel1_IRQHandler
.thumb_set DMA1_Channel1_IRQHandler,Default_Handler
.weak DMA1_Channel2_IRQHandler
.thumb_set DMA1_Channel2_IRQHandler,Default_Handler
.weak DMA1_Channel3_IRQHandler
.thumb_set DMA1_Channel3_IRQHandler,Default_Handler
.weak DMA1_Channel4_IRQHandler
.thumb_set DMA1_Channel4_IRQHandler,Default_Handler
.weak DMA1_Channel5_IRQHandler
.thumb_set DMA1_Channel5_IRQHandler,Default_Handler
.weak DMA1_Channel6_IRQHandler
.thumb_set DMA1_Channel6_IRQHandler,Default_Handler
.weak DMA1_Channel7_IRQHandler
.thumb_set DMA1_Channel7_IRQHandler,Default_Handler
.weak ADC1_2_IRQHandler
.thumb_set ADC1_2_IRQHandler,Default_Handler
.weak USB_HP_CAN1_TX_IRQHandler
.thumb_set USB_HP_CAN1_TX_IRQHandler,Default_Handler
.weak USB_LP_CAN1_RX0_IRQHandler
.thumb_set USB_LP_CAN1_RX0_IRQHandler,Default_Handler
.weak CAN1_RX1_IRQHandler
.thumb_set CAN1_RX1_IRQHandler,Default_Handler
.weak CAN1_SCE_IRQHandler
.thumb_set CAN1_SCE_IRQHandler,Default_Handler
.weak EXTI9_5_IRQHandler
.thumb_set EXTI9_5_IRQHandler,Default_Handler
.weak TIM1_BRK_IRQHandler
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
.weak TIM1_UP_IRQHandler
.thumb_set TIM1_UP_IRQHandler,Default_Handler
.weak TIM1_TRG_COM_IRQHandler
.thumb_set TIM1_TRG_COM_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM3_IRQHandler
.thumb_set TIM3_IRQHandler,Default_Handler
.weak TIM4_IRQHandler
.thumb_set TIM4_IRQHandler,Default_Handler
.weak I2C1_EV_IRQHandler
.thumb_set I2C1_EV_IRQHandler,Default_Handler
.weak I2C1_ER_IRQHandler
.thumb_set I2C1_ER_IRQHandler,Default_Handler
.weak I2C2_EV_IRQHandler
.thumb_set I2C2_EV_IRQHandler,Default_Handler
.weak I2C2_ER_IRQHandler
.thumb_set I2C2_ER_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak SPI2_IRQHandler
.thumb_set SPI2_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler
.weak USART2_IRQHandler
.thumb_set USART2_IRQHandler,Default_Handler
.weak USART3_IRQHandler
.thumb_set USART3_IRQHandler,Default_Handler
.weak EXTI15_10_IRQHandler
.thumb_set EXTI15_10_IRQHandler,Default_Handler
.weak RTCAlarm_IRQHandler
.thumb_set RTCAlarm_IRQHandler,Default_Handler
.weak USBWakeUp_IRQHandler
.thumb_set USBWakeUp_IRQHandler,Default_Handler

View File

@ -0,0 +1,128 @@
/**
******************************************************************************
* @file startup_stm32f10x_md.s
* @author MCD Application Team
* @version V3.1.0
* @date 06/19/2009
* @brief STM32F10x Medium Density Devices vector table for RIDE7 toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Branches to main in the C library (which eventually
* calls main()).
* After Reset the Cortex-M3 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
*******************************************************************************
* @copy
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* <h2><center>&copy; COPYRIGHT 2009 STMicroelectronics</center></h2>
*/
.syntax unified
.cpu cortex-m3
.fpu softvfp
.thumb
.global g_pfnVectors
.global SystemInit_ExtMemCtl_Dummy
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.word _magicRate
.equ BootRAM, 0xF108F85F
/**
* @brief This is the code that gets called when the processor first
* starts execution following a reset event. Only the absolutely
* necessary set is performed, after which the application
* supplied main() routine is called.
* @param None
* @retval : None
*/
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Copy the data segment initializers from flash to SRAM */
movs r1, #0
b LoopCopyDataInit
CopyDataInit:
ldr r3, =_sidata
ldr r3, [r3, r1]
str r3, [r0, r1]
adds r1, r1, #4
LoopCopyDataInit:
ldr r0, =_sdata
ldr r3, =_edata
adds r2, r0, r1
cmp r2, r3
bcc CopyDataInit
ldr r2, =_sbss
b LoopFillZerobss
/* Zero fill the bss segment. */
FillZerobss:
movs r3, #0
str r3, [r2], #4
LoopFillZerobss:
ldr r3, = _ebss
cmp r2, r3
bcc FillZerobss
/* Call the application's entry point.*/
bl main
bx lr
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M3. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word _magicRate

View File

@ -0,0 +1,53 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : cortexm3_macro.h
* Author : MCD Application Team
* Version : V2.0.3
* Date : 09/22/2008
* Description : Header file for cortexm3_macro.s.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CORTEXM3_MACRO_H
#define __CORTEXM3_MACRO_H
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_type.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void __WFI(void);
void __WFE(void);
void __SEV(void);
void __ISB(void);
void __DSB(void);
void __DMB(void);
void __SVC(void);
u32 __MRS_CONTROL(void);
void __MSR_CONTROL(u32 Control);
u32 __MRS_PSP(void);
void __MSR_PSP(u32 TopOfProcessStack);
u32 __MRS_MSP(void);
void __MSR_MSP(u32 TopOfMainStack);
void __RESETPRIMASK(void);
void __SETPRIMASK(void);
u32 __READ_PRIMASK(void);
void __RESETFAULTMASK(void);
void __SETFAULTMASK(void);
u32 __READ_FAULTMASK(void);
void __BASEPRICONFIG(u32 NewPriority);
u32 __GetBASEPRI(void);
u16 __REV_HalfWord(u16 Data);
u32 __REV_Word(u32 Data);
#endif /* __CORTEXM3_MACRO_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,312 @@
# 1 "./stm32_lib/cortexm3_macro.S"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "./stm32_lib/cortexm3_macro.S"
# 16 "./stm32_lib/cortexm3_macro.S"
.cpu cortex-m3
.fpu softvfp
.syntax unified
.thumb
.text
.globl __WFI
.globl __WFE
.globl __SEV
.globl __ISB
.globl __DSB
.globl __DMB
.globl __SVC
.globl __MRS_CONTROL
.globl __MSR_CONTROL
.globl __MRS_PSP
.globl __MSR_PSP
.globl __MRS_MSP
.globl __MSR_MSP
.globl __RESETPRIMASK
.globl __SETPRIMASK
.globl __READ_PRIMASK
.globl __RESETFAULTMASK
.globl __SETFAULTMASK
.globl __READ_FAULTMASK
.globl __BASEPRICONFIG
.globl __GetBASEPRI
.globl __REV_HalfWord
.globl __REV_Word
.thumb_func
__WFI:
WFI
BX r14
.thumb_func
__WFE:
WFE
BX r14
.thumb_func
__SEV:
SEV
BX r14
.thumb_func
__ISB:
ISB
BX r14
.thumb_func
__DSB:
DSB
BX r14
.thumb_func
__DMB:
DMB
BX r14
.thumb_func
__SVC:
SVC 0x01
BX r14
.thumb_func
__MRS_CONTROL:
MRS r0,control
BX r14
.thumb_func
__MSR_CONTROL:
MSR control, r0
ISB
BX r14
.thumb_func
__MRS_PSP:
MRS r0, psp
BX r14
.thumb_func
__MSR_PSP:
MSR psp, r0
BX r14
.thumb_func
__MRS_MSP:
MRS r0, msp
BX r14
.thumb_func
__MSR_MSP:
MSR msp, r0
BX r14
.thumb_func
__RESETPRIMASK:
CPSIE i
BX r14
.thumb_func
__SETPRIMASK:
CPSID i
BX r14
.thumb_func
__READ_PRIMASK:
MRS r0, PRIMASK
BX r14
.thumb_func
__RESETFAULTMASK:
CPSIE f
BX r14
.thumb_func
__SETFAULTMASK:
CPSID f
BX r14
.thumb_func
__READ_FAULTMASK:
MRS r0, FAULTMASK
BX r14
.thumb_func
__BASEPRICONFIG:
MSR basepri, r0
BX r14
.thumb_func
__GetBASEPRI:
MRS r0, basepri_max
BX r14
.thumb_func
__REV_HalfWord:
REV16 r0, r0
BX r14
.thumb_func
__REV_Word:
REV r0, r0
BX r14
.end

View File

@ -0,0 +1,80 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : stm32f10x_type.h
* Author : MCD Application Team
* Version : V2.0.3
* Date : 09/22/2008
* Description : This file contains all the common data types used for the
* STM32F10x firmware library.
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F10x_TYPE_H
#define __STM32F10x_TYPE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef signed long s32;
typedef signed short s16;
typedef signed char s8;
typedef signed long const sc32; /* Read Only */
typedef signed short const sc16; /* Read Only */
typedef signed char const sc8; /* Read Only */
typedef volatile signed long vs32;
typedef volatile signed short vs16;
typedef volatile signed char vs8;
typedef volatile signed long const vsc32; /* Read Only */
typedef volatile signed short const vsc16; /* Read Only */
typedef volatile signed char const vsc8; /* Read Only */
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned long const uc32; /* Read Only */
typedef unsigned short const uc16; /* Read Only */
typedef unsigned char const uc8; /* Read Only */
typedef volatile unsigned long vu32;
typedef volatile unsigned short vu16;
typedef volatile unsigned char vu8;
typedef volatile unsigned long const vuc32; /* Read Only */
typedef volatile unsigned short const vuc16; /* Read Only */
typedef volatile unsigned char const vuc8; /* Read Only */
typedef enum {FALSE = 0, TRUE = !FALSE} bool;
typedef enum {RESET = 0, SET = !RESET} FlagStatus, ITStatus;
typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
#define IS_FUNCTIONAL_STATE(STATE) (((STATE) == DISABLE) || ((STATE) == ENABLE))
typedef enum {ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
#define U8_MAX ((u8)255)
#define S8_MAX ((s8)127)
#define S8_MIN ((s8)-128)
#define U16_MAX ((u16)65535u)
#define S16_MAX ((s16)32767)
#define S16_MIN ((s16)-32768)
#define U32_MAX ((u32)4294967295uL)
#define S32_MAX ((s32)2147483647)
#define S32_MIN ((s32)-2147483648)
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __STM32F10x_TYPE_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,503 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
/**
* @file usb.c
*
* @brief usb-specific hardware setup, NVIC, clocks, and usb activities
* in the pre-attached state. includes some of the lower level callbacks
* needed by the usb library, like suspend,resume,init,etc
*/
#include "usb.h"
#include "dfu.h"
void setupUSB(void) {
u32 rwmVal; /* read-write-modify place holder var */
/* Setup the USB DISC Pin */
rwmVal = GET_REG(RCC_APB2ENR);
rwmVal |= 0x00000008;
SET_REG(RCC_APB2ENR, rwmVal);
// todo, macroize usb_disc pin
/* Setup GPIOB Pin 9 as OD out */
rwmVal = GET_REG(GPIO_CRH(GPIOB));
rwmVal &= 0xFFFFFF0F;
rwmVal |= 0x00000050;
setPin(GPIOB, 9);
SET_REG(GPIO_CRH(GPIOB), rwmVal);
pRCC->APB1ENR |= 0x00800000;
/* initialize the usb application */
resetPin(GPIOB, 9); /* present ourselves to the host */
usbAppInit();
}
vu32 bDeviceState = UNCONNECTED;
/* tracks sequential behavior of the ISTR */
vu16 wIstr;
vu8 bIntPackSOF = 0;
DEVICE Device_Table = {
NUM_ENDPTS,
1
};
DEVICE_PROP Device_Property = {
usbInit,
usbReset,
usbStatusIn,
usbStatusOut,
usbDataSetup,
usbNoDataSetup,
usbGetInterfaceSetting,
usbGetDeviceDescriptor,
usbGetConfigDescriptor,
usbGetStringDescriptor,
usbGetFunctionalDescriptor,
0,
bMaxPacketSize
};
USER_STANDARD_REQUESTS User_Standard_Requests = {
usbGetConfiguration,
usbSetConfiguration,
usbGetInterface,
usbSetInterface,
usbGetStatus,
usbClearFeature,
usbSetEndpointFeature,
usbSetDeviceFeature,
usbSetDeviceAddress
};
void (*pEpInt_IN[7])(void) = {
nothingProc,
nothingProc,
nothingProc,
nothingProc,
nothingProc,
nothingProc,
nothingProc,
};
void (*pEpInt_OUT[7])(void) = {
nothingProc,
nothingProc,
nothingProc,
nothingProc,
nothingProc,
nothingProc,
nothingProc,
};
struct {
volatile RESUME_STATE eState;
volatile u8 bESOFcnt;
} ResumeS;
/* dummy proc */
void nothingProc(void) {
}
/* Function Definitions */
void usbAppInit(void) {
/* hook in to usb_core, depends on all those damn
non encapsulated externs! */
USB_Init();
}
void usbSuspend(void) {
u16 wCNTR;
wCNTR = _GetCNTR();
wCNTR |= CNTR_FSUSP | CNTR_LPMODE;
_SetCNTR(wCNTR);
/* run any power reduction handlers */
bDeviceState = SUSPENDED;
}
void usbResumeInit(void) {
u16 wCNTR;
/* restart any clocks that had been stopped */
wCNTR = _GetCNTR();
wCNTR &= (~CNTR_LPMODE);
_SetCNTR(wCNTR);
/* undo power reduction handlers here */
_SetCNTR(ISR_MSK);
}
void usbResume(RESUME_STATE eResumeSetVal) {
u16 wCNTR;
if (eResumeSetVal != RESUME_ESOF)
ResumeS.eState = eResumeSetVal;
switch (ResumeS.eState) {
case RESUME_EXTERNAL:
usbResumeInit();
ResumeS.eState = RESUME_OFF;
break;
case RESUME_INTERNAL:
usbResumeInit();
ResumeS.eState = RESUME_START;
break;
case RESUME_LATER:
ResumeS.bESOFcnt = 2;
ResumeS.eState = RESUME_WAIT;
break;
case RESUME_WAIT:
ResumeS.bESOFcnt--;
if (ResumeS.bESOFcnt == 0)
ResumeS.eState = RESUME_START;
break;
case RESUME_START:
wCNTR = _GetCNTR();
wCNTR |= CNTR_RESUME;
_SetCNTR(wCNTR);
ResumeS.eState = RESUME_ON;
ResumeS.bESOFcnt = 10;
break;
case RESUME_ON:
ResumeS.bESOFcnt--;
if (ResumeS.bESOFcnt == 0) {
wCNTR = _GetCNTR();
wCNTR &= (~CNTR_RESUME);
_SetCNTR(wCNTR);
ResumeS.eState = RESUME_OFF;
}
break;
case RESUME_OFF:
case RESUME_ESOF:
default:
ResumeS.eState = RESUME_OFF;
break;
}
}
RESULT usbPowerOn(void) {
u16 wRegVal;
wRegVal = CNTR_FRES;
_SetCNTR(wRegVal);
wInterrupt_Mask = 0;
_SetCNTR(wInterrupt_Mask);
_SetISTR(0);
wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM; /* the bare minimum */
_SetCNTR(wInterrupt_Mask);
return USB_SUCCESS;
}
RESULT usbPowerOff(void) {
_SetCNTR(CNTR_FRES);
_SetISTR(0);
_SetCNTR(CNTR_FRES + CNTR_PDWN);
/* note that all weve done here is powerdown the
usb peripheral. we have no disabled the clocks,
pulled the usb_disc pin back up, or reset the
application state machines */
return USB_SUCCESS;
}
void usbInit(void) {
dfuInit();
pInformation->Current_Configuration = 0;
usbPowerOn();
_SetISTR(0);
wInterrupt_Mask = ISR_MSK;
_SetCNTR(wInterrupt_Mask);
usbEnbISR(); /* configure the cortex M3 private peripheral NVIC */
bDeviceState = UNCONNECTED;
}
void usbReset(void) {
dfuUpdateByReset();
pInformation->Current_Configuration = 0;
pInformation->Current_Feature = usbConfigDescriptorDFU.Descriptor[7];
_SetBTABLE(BTABLE_ADDRESS);
/* setup the ctrl endpoint */
_SetEPType(ENDP0, EP_CONTROL);
_SetEPTxStatus(ENDP0, EP_TX_STALL);
_SetEPRxAddr(ENDP0, ENDP0_RXADDR);
_SetEPTxAddr(ENDP0, ENDP0_TXADDR);
Clear_Status_Out(ENDP0);
SetEPRxCount(ENDP0, pProperty->MaxPacketSize);
// SetEPTxCount(ENDP0, pProperty->MaxPacketSize);
SetEPRxValid(ENDP0);
bDeviceState = ATTACHED;
SetDeviceAddress(0); /* different than usbSetDeviceAddr! comes from usb_core */
}
void usbStatusIn(void) {
}
void usbStatusOut(void) {
}
RESULT usbDataSetup(u8 request) {
u8 *(*CopyRoutine)(u16);
CopyRoutine = NULL;
/* handle dfu class requests */
if ((pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
if (dfuUpdateByRequest()) {
/* successfull state transition, handle the request */
switch (request) {
case(DFU_GETSTATUS):
CopyRoutine = dfuCopyStatus;
break;
case(DFU_GETSTATE):
CopyRoutine = dfuCopyState;
break;
case(DFU_DNLOAD):
CopyRoutine = dfuCopyDNLOAD;
break;
case(DFU_UPLOAD):
CopyRoutine = dfuCopyUPLOAD;
break;
default:
/* leave copy routine null */
break;
}
}
}
if (CopyRoutine != NULL) {
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine)(0);
return USB_SUCCESS;
}
return USB_UNSUPPORT;
}
RESULT usbNoDataSetup(u8 request) {
if ((pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT)) == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
/* todo, keep track of the destination interface, often stored in wIndex */
if (dfuUpdateByRequest()) {
return USB_SUCCESS;
}
}
return USB_UNSUPPORT;
}
RESULT usbGetInterfaceSetting(u8 interface, u8 altSetting) {
/* alt setting 0 -> program RAM, alt setting 1 -> FLASH */
if (interface > NUM_ALT_SETTINGS) {
return USB_UNSUPPORT;
} else {
return USB_SUCCESS;
}
}
u8 *usbGetDeviceDescriptor(u16 len) {
return Standard_GetDescriptorData(len, &usbDeviceDescriptorDFU);
}
u8 *usbGetConfigDescriptor(u16 len) {
return Standard_GetDescriptorData(len, &usbConfigDescriptorDFU);
}
u8 *usbGetStringDescriptor(u16 len) {
u8 strIndex = pInformation->USBwValue0;
if (strIndex > STR_DESC_LEN) {
return NULL;
} else {
return Standard_GetDescriptorData(len, &usbStringDescriptor[strIndex]);
}
}
u8 *usbGetFunctionalDescriptor(u16 len) {
return Standard_GetDescriptorData(len, &usbFunctionalDescriptor);
}
/***** start of USER STANDARD REQUESTS ******
*
* These are the USER STANDARD REQUESTS, they are handled
* in the core but we are given these callbacks at the
* application level
*******************************************/
void usbGetConfiguration(void) {
/* nothing process */
}
void usbSetConfiguration(void) {
if (pInformation->Current_Configuration != 0) {
bDeviceState = CONFIGURED;
}
}
void usbGetInterface(void) {
/* nothing process */
}
void usbSetInterface(void) {
/* nothing process */
}
void usbGetStatus(void) {
/* nothing process */
}
void usbClearFeature(void) {
/* nothing process */
}
void usbSetEndpointFeature(void) {
/* nothing process */
}
void usbSetDeviceFeature(void) {
/* nothing process */
}
void usbSetDeviceAddress(void) {
bDeviceState = ADDRESSED;
}
/***** end of USER STANDARD REQUESTS *****/
void usbEnbISR(void) {
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE;
nvicInit(&NVIC_InitStructure);
}
void usbDsbISR(void) {
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE;
nvicInit(&NVIC_InitStructure);
}
void USB_LP_CAN1_RX0_IRQHandler(void) {
wIstr = _GetISTR();
/* go nuts with the preproc switches since this is an ISTR and must be FAST */
#if (ISR_MSK & ISTR_RESET)
if (wIstr & ISTR_RESET & wInterrupt_Mask) {
_SetISTR((u16)CLR_RESET);
Device_Property.Reset();
}
#endif
#if (ISR_MSK & ISTR_DOVR)
if (wIstr & ISTR_DOVR & wInterrupt_Mask) {
_SetISTR((u16)CLR_DOVR);
}
#endif
#if (ISR_MSK & ISTR_ERR)
if (wIstr & ISTR_ERR & wInterrupt_Mask) {
_SetISTR((u16)CLR_ERR);
}
#endif
#if (ISR_MSK & ISTR_WKUP)
if (wIstr & ISTR_WKUP & wInterrupt_Mask) {
_SetISTR((u16)CLR_WKUP);
usbResume(RESUME_EXTERNAL);
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (ISR_MSK & ISTR_SUSP)
if (wIstr & ISTR_SUSP & wInterrupt_Mask) {
/* check if SUSPEND is possible */
if (F_SUSPEND_ENABLED) {
usbSuspend();
} else {
/* if not possible then resume after xx ms */
usbResume(RESUME_LATER);
}
/* clear of the ISTR bit must be done after setting of CNTR_FSUSP */
_SetISTR((u16)CLR_SUSP);
}
#endif
#if (ISR_MSK & ISTR_SOF)
if (wIstr & ISTR_SOF & wInterrupt_Mask) {
_SetISTR((u16)CLR_SOF);
bIntPackSOF++;
}
#endif
#if (ISR_MSK & ISTR_ESOF)
if (wIstr & ISTR_ESOF & wInterrupt_Mask) {
_SetISTR((u16)CLR_ESOF);
/* resume handling timing is made with ESOFs */
usbResume(RESUME_ESOF); /* request without change of the machine state */
}
#endif
/*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*/
#if (ISR_MSK & ISTR_CTR)
if (wIstr & ISTR_CTR & wInterrupt_Mask) {
/* servicing of the endpoint correct transfer interrupt */
/* clear of the CTR flag into the sub */
CTR_LP(); /* low priority ISR defined in the usb core lib */
}
#endif
}

View File

@ -0,0 +1,132 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
#ifndef __USB_H
#define __USB_H
#include "common.h"
#include "usb_lib.h"
#include "usb_descriptor.h"
/* USB configuration params */
#define BTABLE_ADDRESS 0x00
#define ENDP0_RXADDR 0x40
#define ENDP0_TXADDR 0x80 /* gives 64 bytes i/o buflen */
#define ENDP1_TXADDR 0xC0
#define ENDP2_TXADDR 0x100
#define ENDP3_RXADDR 0x110
#define bMaxPacketSize 0x40 /* 64B, maximum for usb FS devices */
#define wTransferSize 0x0400 /* 1024B, want: maxpacket < wtransfer < 10KB (to ensure everything can live in ram */
#define NUM_ENDPTS 0x01
/* do we gracefully implement usb suspend? */
#define F_SUSPEND_ENABLED 1
/* defines which interrupts are handled */
#define ISR_MSK (CNTR_CTRM | \
CNTR_WKUPM | \
CNTR_SUSPM | \
CNTR_ERRM | \
CNTR_SOFM | \
CNTR_ESOFM | \
CNTR_RESETM \
)
typedef enum _RESUME_STATE {
RESUME_EXTERNAL,
RESUME_INTERNAL,
RESUME_LATER,
RESUME_WAIT,
RESUME_START,
RESUME_ON,
RESUME_OFF,
RESUME_ESOF
} RESUME_STATE;
typedef enum _DEVICE_STATE {
UNCONNECTED,
ATTACHED,
POWERED,
SUSPENDED,
ADDRESSED,
CONFIGURED
} DEVICE_STATE;
void setupUSB(void);
void usbAppInit(void); /* singleton usb initializer */
void usbSuspend(void);
void usbResumeInit(void);
void usbResume(RESUME_STATE state);
RESULT usbPowerOn(void);
RESULT usbPowerOff(void);
/* internal functions (as per the usb_core pProperty structure) */
void usbInit(void);
void usbReset(void);
void usbStatusIn(void);
void usbStatusOut(void);
RESULT usbDataSetup(u8 request);
RESULT usbNoDataSetup(u8 request);
RESULT usbGetInterfaceSetting(u8, u8);
u8 *usbGetDeviceDescriptor(u16 length);
u8 *usbGetConfigDescriptor(u16 length);
u8 *usbGetStringDescriptor(u16 length);
u8 *usbGetFunctionalDescriptor(u16 length);
/* internal callbacks to respond to standard requests */
void usbGetConfiguration(void);
void usbSetConfiguration(void);
void usbGetInterface(void);
void usbSetInterface(void);
void usbGetStatus(void);
void usbClearFeature(void);
void usbSetEndpointFeature(void);
void usbSetDeviceFeature(void);
void usbSetDeviceAddress(void);
/* the small number of comm emulator functions to
eventually be migrated into their own usart sources
*/
u8 *vcomGetLineCoding(u16 length);
u8 *vcomSetLineCoding(u16 length);
void vcomEp1In(void);
void vcomEp3Out(void);
/* Interrupt setup/handling exposed only so that
its obvious from main what interrupts are overloaded
from c_only_startup.s (see the top of main.c) */
void usbDsbISR(void);
void usbEnbISR(void);
/* override the weakly defined isr in linker */
void USB_LP_CAN1_RX0_IRQHandler(void);
void nothingProc(void);
#endif

View File

@ -0,0 +1,31 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
/**
* @file usb_callbacks.c
*
* @brief aka endpoints: handling data transfer when "Configured". calls out to
* application specific callbacks (eg DFU)
*
*/

View File

@ -0,0 +1,193 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
/**
* @file usb_descriptor.c
*
* @brief aka application descriptor; big static struct and callbacks for sending
* the descriptor.
*
*/
#include "usb_descriptor.h"
u8 u8_usbDeviceDescriptorDFU[18] = {
0x12, /* bLength */
0x01, /* bDescriptorType */
0x00, /* bcdUSB, version 1.00 */
0x01,
0x00, /* bDeviceClass : See interface */
0x00, /* bDeviceSubClass : See interface*/
0x00, /* bDeviceProtocol : See interface */
bMaxPacketSize, /* bMaxPacketSize0 0x40 = 64 */
VEND_ID0, /* idVendor (0110) */
VEND_ID1,
PROD_ID0, /* idProduct (0x1001 or 1002) */
PROD_ID1,
0x01, /* bcdDevice*/
0x02,
0x01, /* iManufacturer : index of string Manufacturer */
0x02, /* iProduct : index of string descriptor of product*/
0x03, /* iSerialNumber : index of string serial number*/
0x01 /*bNumConfigurations */
};
ONE_DESCRIPTOR usbDeviceDescriptorDFU = {
u8_usbDeviceDescriptorDFU,
0x12
};
u8 u8_usbFunctionalDescriptor[9] = {
/******************** DFU Functional Descriptor********************/
0x09, /*blength = 7 Bytes*/
0x21, /* DFU Functional Descriptor*/
0x03, /*bmAttributes, bitCanDnload | bitCanUpload */
0xFF, /*DetachTimeOut= 255 ms*/
0x00,
(wTransferSize & 0x00FF),
(wTransferSize & 0xFF00) >> 8, /* TransferSize = 1024 Byte*/
0x10, /* bcdDFUVersion = 1.1 */
0x01
};
ONE_DESCRIPTOR usbFunctionalDescriptor = {
u8_usbFunctionalDescriptor,
0x09
};
u8 u8_usbConfigDescriptorDFU[36] = {
0x09, /* bLength: Configuation Descriptor size */
0x02, /* bDescriptorType: Configuration */
0x24, /* wTotalLength: Bytes returned */
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: */
0x00, /* iConfiguration: */
0x80, /* bmAttributes: */
0x32, /* MaxPower 100 mA */
/* 09 */
/************ Descriptor of DFU interface 0 Alternate setting 0 *********/
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x00, /* bNumEndpoints*/
0xFE, /* bInterfaceClass: DFU */
0x01, /* bInterfaceSubClass */
0x02, /* nInterfaceProtocol, switched to 0x02 while in dfu_mode */
0x04, /* iInterface: */
/************ Descriptor of DFU interface 0 Alternate setting 1 *********/
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: */
0x00, /* bInterfaceNumber: Number of Interface */
0x01, /* bAlternateSetting: Alternate setting */
0x00, /* bNumEndpoints*/
0xFE, /* bInterfaceClass: DFU */
0x01, /* bInterfaceSubClass */
0x02, /* nInterfaceProtocol, switched to 0x02 while in dfu_mode */
0x05, /* iInterface: */
/******************** DFU Functional Descriptor********************/
0x09, /*blength = 7 Bytes*/
0x21, /* DFU Functional Descriptor*/
0x03, /*bmAttributes, bitCanDnload | bitCanUpload */
0xFF, /*DetachTimeOut= 255 ms*/
0x00,
(wTransferSize & 0x00FF),
(wTransferSize & 0xFF00) >> 8, /* TransferSize = 1024 Byte*/
0x10, /* bcdDFUVersion = 1.1 */
0x01
/***********************************************************/
/*36*/
};
ONE_DESCRIPTOR usbConfigDescriptorDFU = {
u8_usbConfigDescriptorDFU,
0x24
};
u8 u8_usbStringLangId[0x04] = {
0x04,
0x03,
0x09,
0x04 /* LangID = 0x0409: U.S. English */
};
u8 u8_usbStringVendor[0x12] = {
0x12,
0x03,
'L', 0, 'e', 0, 'a', 0, 'f', 0, 'L', 0, 'a', 0, 'b', 0, 's', 0
};
u8 u8_usbStringProduct[0x14] = {
0x14,
0x03,
'M', 0, 'a', 0, 'p', 0, 'l', 0, 'e', 0, ' ', 0, '0', 0, '0', 0, '3', 0
};
u8 u8_usbStringSerial[0x10] = {
0x10,
0x03,
'L', 0, 'L', 0, 'M', 0, ' ', 0, '0', 0, '0', 0, '3', 0
};
u8 u8_usbStringAlt0[0x36] = {
0x36,
0x03,
'D', 0, 'F', 0, 'U', 0, ' ', 0, 'P', 0, 'r', 0, 'o', 0, 'g', 0, 'r', 0,
'a', 0, 'm', 0, ' ', 0, 'R', 0, 'A', 0, 'M', 0, ' ', 0, '0', 0, 'x', 0,
'2', 0, '0', 0, '0', 0, '0', 0, '0', 0, 'C', 0, '0', 0, '0', 0
};
u8 u8_usbStringAlt1[0x3A] = {
0x3A,
0x03,
'D', 0, 'F', 0, 'U', 0, ' ', 0, 'P', 0, 'r', 0, 'o', 0, 'g', 0, 'r', 0,
'a', 0, 'm', 0, ' ', 0, 'F', 0, 'L', 0, 'A', 0, 'S', 0, 'H', 0, ' ', 0,
'0', 0, 'x', 0, '0', 0, '8', 0, '0', 0, '0', 0, '5', 0, '0', 0, '0', 0,
'0', 0
};
u8 u8_usbStringInterface = NULL;
ONE_DESCRIPTOR usbStringDescriptor[STR_DESC_LEN] = {
{ (u8 *)u8_usbStringLangId, 0x04 },
{ (u8 *)u8_usbStringVendor, 0x12 },
{ (u8 *)u8_usbStringProduct, 0x20 },
{ (u8 *)u8_usbStringSerial, 0x10 },
{ (u8 *)u8_usbStringAlt0, 0x36 },
{ (u8 *)u8_usbStringAlt1, 0x3A }
};

View File

@ -0,0 +1,40 @@
/* *****************************************************************************
* The MIT License
*
* Copyright (c) 2010 LeafLabs LLC.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
* ****************************************************************************/
#ifndef __MAPLE_USB_DESC_H
#define __MAPLE_USB_DESC_H
#include "common.h"
#include "usb_lib.h"
#include "usb.h"
#define NUM_ALT_SETTINGS 2
#define STR_DESC_LEN 6
extern ONE_DESCRIPTOR usbDeviceDescriptorDFU;
extern ONE_DESCRIPTOR usbConfigDescriptorDFU;
extern ONE_DESCRIPTOR usbStringDescriptor[6];
extern ONE_DESCRIPTOR usbFunctionalDescriptor;
#endif

View File

@ -0,0 +1,86 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_conf.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Device Firmware Upgrade (DFU) configuration file
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CONF_H
#define __USB_CONF_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
/*-------------------------------------------------------------*/
/* EP_NUM */
/* defines how many endpoints are used by the device */
/*-------------------------------------------------------------*/
#define EP_NUM (1)
/*-------------------------------------------------------------*/
/* -------------- Buffer Description Table -----------------*/
/*-------------------------------------------------------------*/
/* buffer table base address */
/* buffer table base address */
#define BTABLE_ADDRESS (0x00)
/* EP0 */
/* rx/tx buffer base address */
#define ENDP0_RXADDR (0x10)
#define ENDP0_TXADDR (0x50)
/*-------------------------------------------------------------*/
/* ------------------- ISTR events -------------------------*/
/*-------------------------------------------------------------*/
/* IMR_MSK */
/* mask defining which events has to be handled */
/* by the device application software */
#define IMR_MSK (CNTR_CTRM | \
CNTR_WKUPM | \
CNTR_SUSPM | \
CNTR_ERRM | \
CNTR_SOFM | \
CNTR_ESOFM | \
CNTR_RESETM \
)
/* CTR service routines */
/* associated to defined endpoints */
#define EP1_IN_Callback NOP_Process
#define EP2_IN_Callback NOP_Process
#define EP3_IN_Callback NOP_Process
#define EP4_IN_Callback NOP_Process
#define EP5_IN_Callback NOP_Process
#define EP6_IN_Callback NOP_Process
#define EP7_IN_Callback NOP_Process
#define EP1_OUT_Callback NOP_Process
#define EP2_OUT_Callback NOP_Process
#define EP3_OUT_Callback NOP_Process
#define EP4_OUT_Callback NOP_Process
#define EP5_OUT_Callback NOP_Process
#define EP6_OUT_Callback NOP_Process
#define EP7_OUT_Callback NOP_Process
#endif /*__USB_CONF_H*/
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,247 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_core.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Standard protocol processing functions prototypes
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_CORE_H
#define __USB_CORE_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _CONTROL_STATE
{
WAIT_SETUP, /* 0 */
SETTING_UP, /* 1 */
IN_DATA, /* 2 */
OUT_DATA, /* 3 */
LAST_IN_DATA, /* 4 */
LAST_OUT_DATA, /* 5 */
WAIT_STATUS_IN, /* 7 */
WAIT_STATUS_OUT, /* 8 */
STALLED, /* 9 */
PAUSE /* 10 */
} CONTROL_STATE; /* The state machine states of a control pipe */
typedef struct OneDescriptor
{
u8 *Descriptor;
u16 Descriptor_Size;
}
ONE_DESCRIPTOR, *PONE_DESCRIPTOR;
/* All the request process routines return a value of this type
If the return value is not SUCCESS or NOT_READY,
the software will STALL the correspond endpoint */
typedef enum _RESULT
{
USB_SUCCESS = 0, /* Process sucessfully */
USB_ERROR,
USB_UNSUPPORT,
USB_NOT_READY /* The process has not been finished, endpoint will be
NAK to further rquest */
} RESULT;
/*-*-*-*-*-*-*-*-*-*-* Definitions for endpoint level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _ENDPOINT_INFO
{
/* When send data out of the device,
CopyData() is used to get data buffer 'Length' bytes data
if Length is 0,
CopyData() returns the total length of the data
if the request is not supported, returns 0
(NEW Feature )
if CopyData() returns -1, the calling routine should not proceed
further and will resume the SETUP process by the class device
if Length is not 0,
CopyData() returns a pointer to indicate the data location
Usb_wLength is the data remain to be sent,
Usb_wOffset is the Offset of original data
When receive data from the host,
CopyData() is used to get user data buffer which is capable
of Length bytes data to copy data from the endpoint buffer.
if Length is 0,
CopyData() returns the available data length,
if Length is not 0,
CopyData() returns user buffer address
Usb_rLength is the data remain to be received,
Usb_rPointer is the Offset of data buffer
*/
u16 Usb_wLength;
u16 Usb_wOffset;
u16 PacketSize;
u8 *(*CopyData)(u16 Length);
}ENDPOINT_INFO;
/*-*-*-*-*-*-*-*-*-*-*-* Definitions for device level -*-*-*-*-*-*-*-*-*-*-*-*/
typedef struct _DEVICE
{
u8 Total_Endpoint; /* Number of endpoints that are used */
u8 Total_Configuration;/* Number of configuration available */
}
DEVICE;
typedef union
{
u16 w;
struct BW
{
/* Little Endian */
u8 bb0;
u8 bb1;
}
bw;
} u16_u8;
typedef struct _DEVICE_INFO
{
u8 USBbmRequestType; /* bmRequestType */
u8 USBbRequest; /* bRequest */
u16_u8 USBwValues; /* wValue */
u16_u8 USBwIndexs; /* wIndex */
u16_u8 USBwLengths; /* wLength */
u8 ControlState; /* of type CONTROL_STATE */
u8 Current_Feature;
u8 Current_Configuration; /* Selected configuration */
u8 Current_Interface; /* Selected interface of current configuration */
u8 Current_AlternateSetting;/* Selected Alternate Setting of current
interface*/
ENDPOINT_INFO Ctrl_Info;
}DEVICE_INFO;
typedef struct _DEVICE_PROP
{
void (*Init)(void); /* Initialize the device */
void (*Reset)(void); /* Reset routine of this device */
/* Device dependent process after the status stage */
void (*Process_Status_IN)(void);
void (*Process_Status_OUT)(void);
/* Procedure of process on setup stage of a class specified request with data stage */
/* All class specified requests with data stage are processed in Class_Data_Setup
Class_Data_Setup()
responses to check all special requests and fills ENDPOINT_INFO
according to the request
If IN tokens are expected, then wLength & wOffset will be filled
with the total transferring bytes and the starting position
If OUT tokens are expected, then rLength & rOffset will be filled
with the total expected bytes and the starting position in the buffer
If the request is valid, Class_Data_Setup returns SUCCESS, else UNSUPPORT
CAUTION:
Since GET_CONFIGURATION & GET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_Data_Setup)(u8 RequestNo);
/* Procedure of process on setup stage of a class specified request without data stage */
/* All class specified requests without data stage are processed in Class_NoData_Setup
Class_NoData_Setup
responses to check all special requests and perform the request
CAUTION:
Since SET_CONFIGURATION & SET_INTERFACE are highly related to
the individual classes, they will be checked and processed here.
*/
RESULT (*Class_NoData_Setup)(u8 RequestNo);
/*Class_Get_Interface_Setting
This function is used by the file usb_core.c to test if the selected Interface
and Alternate Setting (u8 Interface, u8 AlternateSetting) are supported by
the application.
This function is writing by user. It should return "SUCCESS" if the Interface
and Alternate Setting are supported by the application or "UNSUPPORT" if they
are not supported. */
RESULT (*Class_Get_Interface_Setting)(u8 Interface, u8 AlternateSetting);
u8* (*GetDeviceDescriptor)(u16 Length);
u8* (*GetConfigDescriptor)(u16 Length);
u8* (*GetStringDescriptor)(u16 Length);
u8* (*GetFunctionalDescriptor)(u16 Length);
u8* RxEP_buffer;
u8 MaxPacketSize;
}DEVICE_PROP;
typedef struct _USER_STANDARD_REQUESTS
{
void (*User_GetConfiguration)(void); /* Get Configuration */
void (*User_SetConfiguration)(void); /* Set Configuration */
void (*User_GetInterface)(void); /* Get Interface */
void (*User_SetInterface)(void); /* Set Interface */
void (*User_GetStatus)(void); /* Get Status */
void (*User_ClearFeature)(void); /* Clear Feature */
void (*User_SetEndPointFeature)(void); /* Set Endpoint Feature */
void (*User_SetDeviceFeature)(void); /* Set Device Feature */
void (*User_SetDeviceAddress)(void); /* Set Device Address */
}
USER_STANDARD_REQUESTS;
/* Exported constants --------------------------------------------------------*/
#define Type_Recipient (pInformation->USBbmRequestType & (REQUEST_TYPE | RECIPIENT))
#define Usb_rLength Usb_wLength
#define Usb_rOffset Usb_wOffset
#define USBwValue USBwValues.w
#define USBwValue0 USBwValues.bw.bb0
#define USBwValue1 USBwValues.bw.bb1
#define USBwIndex USBwIndexs.w
#define USBwIndex0 USBwIndexs.bw.bb0
#define USBwIndex1 USBwIndexs.bw.bb1
#define USBwLength USBwLengths.w
#define USBwLength0 USBwLengths.bw.bb0
#define USBwLength1 USBwLengths.bw.bb1
#define StatusInfo0 StatusInfo.bw.bb0
#define StatusInfo1 StatusInfo.bw.bb1
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
u8 Setup0_Process(void);
u8 Post0_Process(void);
u8 Out0_Process(void);
u8 In0_Process(void);
RESULT Standard_SetEndPointFeature(void);
RESULT Standard_SetDeviceFeature(void);
u8 *Standard_GetConfiguration(u16 Length);
RESULT Standard_SetConfiguration(void);
u8 *Standard_GetInterface(u16 Length);
RESULT Standard_SetInterface(void);
u8 *Standard_GetDescriptorData(u16 Length, PONE_DESCRIPTOR pDesc);
u8 *Standard_GetStatus(u16 Length);
RESULT Standard_ClearFeature(void);
void SetDeviceAddress(u8);
void NOP_Process(void);
extern DEVICE_PROP Device_Property;
extern USER_STANDARD_REQUESTS User_Standard_Requests;
extern DEVICE Device_Table;
extern DEVICE_INFO Device_Info;
/* cells saving status during interrupt servicing */
extern u16 SaveRState;
extern u16 SaveTState;
#endif /* __USB_CORE_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,80 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_def.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Definitions related to USB Core
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_DEF_H
#define __USB_DEF_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _RECIPIENT_TYPE
{
DEVICE_RECIPIENT, /* Recipient device */
INTERFACE_RECIPIENT, /* Recipient interface */
ENDPOINT_RECIPIENT, /* Recipient endpoint */
OTHER_RECIPIENT
} RECIPIENT_TYPE;
typedef enum _STANDARD_REQUESTS
{
GET_STATUS = 0,
CLEAR_FEATURE,
RESERVED1,
SET_FEATURE,
RESERVED2,
SET_ADDRESS,
GET_DESCRIPTOR,
SET_DESCRIPTOR,
GET_CONFIGURATION,
SET_CONFIGURATION,
GET_INTERFACE,
SET_INTERFACE,
TOTAL_sREQUEST, /* Total number of Standard request */
SYNCH_FRAME = 12
} STANDARD_REQUESTS;
/* Definition of "USBwValue" */
typedef enum _DESCRIPTOR_TYPE
{
DEVICE_DESCRIPTOR = 1,
CONFIG_DESCRIPTOR,
STRING_DESCRIPTOR,
INTERFACE_DESCRIPTOR,
ENDPOINT_DESCRIPTOR
} DESCRIPTOR_TYPE;
/* Feature selector of a SET_FEATURE or CLEAR_FEATURE */
typedef enum _FEATURE_SELECTOR
{
ENDPOINT_STALL,
DEVICE_REMOTE_WAKEUP
} FEATURE_SELECTOR;
/* Exported constants --------------------------------------------------------*/
/* Definition of "USBbmRequestType" */
#define REQUEST_TYPE 0x60 /* Mask to get request type */
#define STANDARD_REQUEST 0x00 /* Standard request */
#define CLASS_REQUEST 0x20 /* Class request */
#define VENDOR_REQUEST 0x40 /* Vendor request */
#define RECIPIENT 0x1F /* Mask to get recipient */
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
#endif /* __USB_DEF_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,64 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_init.c
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Initialization routines & global variables
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* The number of current endpoint, it will be used to specify an endpoint */
u8 EPindex;
/* The number of current device, it is an index to the Device_Table */
/* u8 Device_no; */
/* Points to the DEVICE_INFO structure of current device */
/* The purpose of this register is to speed up the execution */
DEVICE_INFO *pInformation;
/* Points to the DEVICE_PROP structure of current device */
/* The purpose of this register is to speed up the execution */
DEVICE_PROP *pProperty;
/* Temporary save the state of Rx & Tx status. */
/* Whenever the Rx or Tx state is changed, its value is saved */
/* in this variable first and will be set to the EPRB or EPRA */
/* at the end of interrupt process */
u16 SaveState ;
u16 wInterrupt_Mask;
DEVICE_INFO Device_Info;
USER_STANDARD_REQUESTS *pUser_Standard_Requests;
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : USB_Init
* Description : USB system initialization
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void USB_Init(void)
{
pInformation = &Device_Info;
pInformation->ControlState = 2;
pProperty = &Device_Property;
pUser_Standard_Requests = &User_Standard_Requests;
/* Initialize devices one by one */
pProperty->Init();
}
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,49 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_init.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Initialization routines & global variables
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INIT_H
#define __USB_INIT_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void USB_Init(void);
/* External variables --------------------------------------------------------*/
/* The number of current endpoint, it will be used to specify an endpoint */
extern u8 EPindex;
/* The number of current device, it is an index to the Device_Table */
/*extern u8 Device_no; */
/* Points to the DEVICE_INFO structure of current device */
/* The purpose of this register is to speed up the execution */
extern DEVICE_INFO* pInformation;
/* Points to the DEVICE_PROP structure of current device */
/* The purpose of this register is to speed up the execution */
extern DEVICE_PROP* pProperty;
/* Temporary save the state of Rx & Tx status. */
/* Whenever the Rx or Tx state is changed, its value is saved */
/* in this variable first and will be set to the EPRB or EPRA */
/* at the end of interrupt process */
extern USER_STANDARD_REQUESTS *pUser_Standard_Requests;
extern u16 SaveState ;
extern u16 wInterrupt_Mask;
#endif /* __USB_INIT_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,192 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_int.c
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Endpoint CTR (Low and High) interrupt's service routines
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
u16 SaveRState;
u16 SaveTState;
/* Extern variables ----------------------------------------------------------*/
extern void (*pEpInt_IN[7])(void); /* Handles IN interrupts */
extern void (*pEpInt_OUT[7])(void); /* Handles OUT interrupts */
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : CTR_LP.
* Description : Low priority Endpoint Correct Transfer interrupt's service
* routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void CTR_LP(void)
{
u32 wEPVal = 0;
/* stay in loop while pending ints */
while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
{
_SetISTR((u16)CLR_CTR); /* clear CTR flag */
/* extract highest priority endpoint number */
EPindex = (u8)(wIstr & ISTR_EP_ID);
if (EPindex == 0)
{
/* Decode and service control endpoint interrupt */
/* calling related service routine */
/* (Setup0_Process, In0_Process, Out0_Process) */
/* save RX & TX status */
/* and set both to NAK */
SaveRState = _GetEPRxStatus(ENDP0);
SaveTState = _GetEPTxStatus(ENDP0);
_SetEPRxStatus(ENDP0, EP_RX_NAK);
_SetEPTxStatus(ENDP0, EP_TX_NAK);
/* DIR bit = origin of the interrupt */
if ((wIstr & ISTR_DIR) == 0)
{
/* DIR = 0 */
/* DIR = 0 => IN int */
/* DIR = 0 implies that (EP_CTR_TX = 1) always */
_ClearEP_CTR_TX(ENDP0);
In0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxStatus(ENDP0, SaveRState);
_SetEPTxStatus(ENDP0, SaveTState);
return;
}
else
{
/* DIR = 1 */
/* DIR = 1 & CTR_RX => SETUP or OUT int */
/* DIR = 1 & (CTR_TX | CTR_RX) => 2 int pending */
wEPVal = _GetENDPOINT(ENDP0);
if ((wEPVal & EP_CTR_TX) != 0)
{
_ClearEP_CTR_TX(ENDP0);
In0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxStatus(ENDP0, SaveRState);
_SetEPTxStatus(ENDP0, SaveTState);
return;
}
else if ((wEPVal &EP_SETUP) != 0)
{
_ClearEP_CTR_RX(ENDP0); /* SETUP bit kept frozen while CTR_RX = 1 */
Setup0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxStatus(ENDP0, SaveRState);
_SetEPTxStatus(ENDP0, SaveTState);
return;
}
else if ((wEPVal & EP_CTR_RX) != 0)
{
_ClearEP_CTR_RX(ENDP0);
Out0_Process();
/* before terminate set Tx & Rx status */
_SetEPRxStatus(ENDP0, SaveRState);
_SetEPTxStatus(ENDP0, SaveTState);
return;
}
}
}/* if(EPindex == 0) */
else
{
/* Decode and service non control endpoints interrupt */
/* process related endpoint register */
wEPVal = _GetENDPOINT(EPindex);
if ((wEPVal & EP_CTR_RX) != 0)
{
/* clear int flag */
_ClearEP_CTR_RX(EPindex);
/* call OUT service function */
(*pEpInt_OUT[EPindex-1])();
} /* if((wEPVal & EP_CTR_RX) */
if ((wEPVal & EP_CTR_TX) != 0)
{
/* clear int flag */
_ClearEP_CTR_TX(EPindex);
/* call IN service function */
(*pEpInt_IN[EPindex-1])();
} /* if((wEPVal & EP_CTR_TX) != 0) */
}/* if(EPindex == 0) else */
}/* while(...) */
}
/*******************************************************************************
* Function Name : CTR_HP.
* Description : High Priority Endpoint Correct Transfer interrupt's service
* routine.
* Input : None.
* Output : None.
* Return : None.
*******************************************************************************/
void CTR_HP(void)
{
u32 wEPVal = 0;
while (((wIstr = _GetISTR()) & ISTR_CTR) != 0)
{
_SetISTR((u16)CLR_CTR); /* clear CTR flag */
/* extract highest priority endpoint number */
EPindex = (u8)(wIstr & ISTR_EP_ID);
/* process related endpoint register */
wEPVal = _GetENDPOINT(EPindex);
if ((wEPVal & EP_CTR_RX) != 0)
{
/* clear int flag */
_ClearEP_CTR_RX(EPindex);
/* call OUT service function */
(*pEpInt_OUT[EPindex-1])();
} /* if((wEPVal & EP_CTR_RX) */
else if ((wEPVal & EP_CTR_TX) != 0)
{
/* clear int flag */
_ClearEP_CTR_TX(EPindex);
/* call IN service function */
(*pEpInt_IN[EPindex-1])();
} /* if((wEPVal & EP_CTR_TX) != 0) */
}/* while(...) */
}
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,33 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_int.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Endpoint CTR (Low and High) interrupt's service routines
* prototypes
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_INT_H
#define __USB_INT_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void CTR_LP(void);
void CTR_HP(void);
/* External variables --------------------------------------------------------*/
#endif /* __USB_INT_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,37 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_lib.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : USB library include files
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_LIB_H
#define __USB_LIB_H
/* Includes ------------------------------------------------------------------*/
#include "usb_type.h"
#include "usb_regs.h"
#include "usb_def.h"
#include "usb_core.h"
#include "usb_init.h"
#include "usb_mem.h"
#include "usb_int.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#endif /* __USB_LIB_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,73 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_mem.c
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Utility functions for memory transfers to/from PMA
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : UserToPMABufferCopy
* Description : Copy a buffer from user memory area to packet memory area (PMA)
* Input : - pbUsrBuf: pointer to user memory area.
* - wPMABufAddr: address into PMA.
* - wNBytes: no. of bytes to be copied.
* Output : None.
* Return : None .
*******************************************************************************/
void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes)
{
u32 n = (wNBytes + 1) >> 1; /* n = (wNBytes + 1) / 2 */
u32 i, temp1, temp2;
u16 *pdwVal;
pdwVal = (u16 *)(wPMABufAddr * 2 + PMAAddr);
for (i = n; i != 0; i--)
{
temp1 = (u16) * pbUsrBuf;
pbUsrBuf++;
temp2 = temp1 | (u16) * pbUsrBuf << 8;
*pdwVal++ = temp2;
pdwVal++;
pbUsrBuf++;
}
}
/*******************************************************************************
* Function Name : PMAToUserBufferCopy
* Description : Copy a buffer from user memory area to packet memory area (PMA)
* Input : - pbUsrBuf = pointer to user memory area.
* - wPMABufAddr = address into PMA.
* - wNBytes = no. of bytes to be copied.
* Output : None.
* Return : None.
*******************************************************************************/
void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes)
{
u32 n = (wNBytes + 1) >> 1;/* /2*/
u32 i;
u32 *pdwVal;
pdwVal = (u32 *)(wPMABufAddr * 2 + PMAAddr);
for (i = n; i != 0; i--)
{
*(u16*)pbUsrBuf++ = *pdwVal++;
pbUsrBuf++;
}
}
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,32 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_mem.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Utility prototypes functions for memory/PMA transfers
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_MEM_H
#define __USB_MEM_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
void UserToPMABufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes);
void PMAToUserBufferCopy(u8 *pbUsrBuf, u16 wPMABufAddr, u16 wNBytes);
/* External variables --------------------------------------------------------*/
#endif /*__USB_MEM_H*/
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,748 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_regs.c
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Interface functions to USB cell registers
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "usb_lib.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Extern variables ----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/*******************************************************************************
* Function Name : SetCNTR.
* Description : Set the CNTR register value.
* Input : wRegValue: new register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetCNTR(u16 wRegValue)
{
_SetCNTR(wRegValue);
}
/*******************************************************************************
* Function Name : GetCNTR.
* Description : returns the CNTR register value.
* Input : None.
* Output : None.
* Return : CNTR register Value.
*******************************************************************************/
u16 GetCNTR(void)
{
return(_GetCNTR());
}
/*******************************************************************************
* Function Name : SetISTR.
* Description : Set the ISTR register value.
* Input : wRegValue: new register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetISTR(u16 wRegValue)
{
_SetISTR(wRegValue);
}
/*******************************************************************************
* Function Name : GetISTR
* Description : Returns the ISTR register value.
* Input : None.
* Output : None.
* Return : ISTR register Value
*******************************************************************************/
u16 GetISTR(void)
{
return(_GetISTR());
}
/*******************************************************************************
* Function Name : GetFNR
* Description : Returns the FNR register value.
* Input : None.
* Output : None.
* Return : FNR register Value
*******************************************************************************/
u16 GetFNR(void)
{
return(_GetFNR());
}
/*******************************************************************************
* Function Name : SetDADDR
* Description : Set the DADDR register value.
* Input : wRegValue: new register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetDADDR(u16 wRegValue)
{
_SetDADDR(wRegValue);
}
/*******************************************************************************
* Function Name : GetDADDR
* Description : Returns the DADDR register value.
* Input : None.
* Output : None.
* Return : DADDR register Value
*******************************************************************************/
u16 GetDADDR(void)
{
return(_GetDADDR());
}
/*******************************************************************************
* Function Name : SetBTABLE
* Description : Set the BTABLE.
* Input : wRegValue: New register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetBTABLE(u16 wRegValue)
{
_SetBTABLE(wRegValue);
}
/*******************************************************************************
* Function Name : GetBTABLE.
* Description : Returns the BTABLE register value.
* Input : None.
* Output : None.
* Return : BTABLE address.
*******************************************************************************/
u16 GetBTABLE(void)
{
return(_GetBTABLE());
}
/*******************************************************************************
* Function Name : SetENDPOINT
* Description : Setthe Endpoint register value.
* Input : bEpNum: Endpoint Number.
* wRegValue.
* Output : None.
* Return : None.
*******************************************************************************/
void SetENDPOINT(u8 bEpNum, u16 wRegValue)
{
_SetENDPOINT(bEpNum, wRegValue);
}
/*******************************************************************************
* Function Name : GetENDPOINT
* Description : Return the Endpoint register value.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint register value.
*******************************************************************************/
u16 GetENDPOINT(u8 bEpNum)
{
return(_GetENDPOINT(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPType
* Description : sets the type in the endpoint register.
* Input : bEpNum: Endpoint Number.
* wType: type definition.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPType(u8 bEpNum, u16 wType)
{
_SetEPType(bEpNum, wType);
}
/*******************************************************************************
* Function Name : GetEPType
* Description : Returns the endpoint type.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Type
*******************************************************************************/
u16 GetEPType(u8 bEpNum)
{
return(_GetEPType(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxStatus
* Description : Set the status of Tx endpoint.
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxStatus(u8 bEpNum, u16 wState)
{
_SetEPTxStatus(bEpNum, wState);
}
/*******************************************************************************
* Function Name : SetEPRxStatus
* Description : Set the status of Rx endpoint.
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxStatus(u8 bEpNum, u16 wState)
{
_SetEPRxStatus(bEpNum, wState);
}
/*******************************************************************************
* Function Name : SetDouBleBuffEPStall
* Description : sets the status for Double Buffer Endpoint to STALL
* Input : bEpNum: Endpoint Number.
* bDir: Endpoint direction.
* Output : None.
* Return : None.
*******************************************************************************/
void SetDouBleBuffEPStall(u8 bEpNum, u8 bDir)
{
u16 Endpoint_DTOG_Status;
Endpoint_DTOG_Status = GetENDPOINT(bEpNum);
if (bDir == EP_DBUF_OUT)
{ /* OUT double buffered endpoint */
_SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPRX_DTOG1);
}
else if (bDir == EP_DBUF_IN)
{ /* IN double buffered endpoint */
_SetENDPOINT(bEpNum, Endpoint_DTOG_Status & ~EPTX_DTOG1);
}
}
/*******************************************************************************
* Function Name : GetEPTxStatus
* Description : Returns the endpoint Tx status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint TX Status
*******************************************************************************/
u16 GetEPTxStatus(u8 bEpNum)
{
return(_GetEPTxStatus(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPRxStatus
* Description : Returns the endpoint Rx status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint RX Status
*******************************************************************************/
u16 GetEPRxStatus(u8 bEpNum)
{
return(_GetEPRxStatus(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxValid
* Description : Valid the endpoint Tx Status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxValid(u8 bEpNum)
{
_SetEPTxStatus(bEpNum, EP_TX_VALID);
}
/*******************************************************************************
* Function Name : SetEPRxValid
* Description : Valid the endpoint Rx Status.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxValid(u8 bEpNum)
{
_SetEPRxStatus(bEpNum, EP_RX_VALID);
}
/*******************************************************************************
* Function Name : SetEP_KIND
* Description : Clear the EP_KIND bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEP_KIND(u8 bEpNum)
{
_SetEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : ClearEP_KIND
* Description : set the EP_KIND bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearEP_KIND(u8 bEpNum)
{
_ClearEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : Clear_Status_Out
* Description : Clear the Status Out of the related Endpoint
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void Clear_Status_Out(u8 bEpNum)
{
_ClearEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : Set_Status_Out
* Description : Set the Status Out of the related Endpoint
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void Set_Status_Out(u8 bEpNum)
{
_SetEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : SetEPDoubleBuff
* Description : Enable the double buffer feature for the endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDoubleBuff(u8 bEpNum)
{
_SetEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : ClearEPDoubleBuff
* Description : Disable the double buffer feature for the endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearEPDoubleBuff(u8 bEpNum)
{
_ClearEP_KIND(bEpNum);
}
/*******************************************************************************
* Function Name : GetTxStallStatus
* Description : Returns the Stall status of the Tx endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Tx Stall status.
*******************************************************************************/
u16 GetTxStallStatus(u8 bEpNum)
{
return(_GetTxStallStatus(bEpNum));
}
/*******************************************************************************
* Function Name : GetRxStallStatus
* Description : Returns the Stall status of the Rx endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Rx Stall status.
*******************************************************************************/
u16 GetRxStallStatus(u8 bEpNum)
{
return(_GetRxStallStatus(bEpNum));
}
/*******************************************************************************
* Function Name : ClearEP_CTR_RX
* Description : Clear the CTR_RX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearEP_CTR_RX(u8 bEpNum)
{
_ClearEP_CTR_RX(bEpNum);
}
/*******************************************************************************
* Function Name : ClearEP_CTR_TX
* Description : Clear the CTR_TX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearEP_CTR_TX(u8 bEpNum)
{
_ClearEP_CTR_TX(bEpNum);
}
/*******************************************************************************
* Function Name : ToggleDTOG_RX
* Description : Toggle the DTOG_RX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ToggleDTOG_RX(u8 bEpNum)
{
_ToggleDTOG_RX(bEpNum);
}
/*******************************************************************************
* Function Name : ToggleDTOG_TX
* Description : Toggle the DTOG_TX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ToggleDTOG_TX(u8 bEpNum)
{
_ToggleDTOG_TX(bEpNum);
}
/*******************************************************************************
* Function Name : ClearDTOG_RX.
* Description : Clear the DTOG_RX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearDTOG_RX(u8 bEpNum)
{
_ClearDTOG_RX(bEpNum);
}
/*******************************************************************************
* Function Name : ClearDTOG_TX.
* Description : Clear the DTOG_TX bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
void ClearDTOG_TX(u8 bEpNum)
{
_ClearDTOG_TX(bEpNum);
}
/*******************************************************************************
* Function Name : SetEPAddress
* Description : Set the endpoint address.
* Input : bEpNum: Endpoint Number.
* bAddr: New endpoint address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPAddress(u8 bEpNum, u8 bAddr)
{
_SetEPAddress(bEpNum, bAddr);
}
/*******************************************************************************
* Function Name : GetEPAddress
* Description : Get the endpoint address.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint address.
*******************************************************************************/
u8 GetEPAddress(u8 bEpNum)
{
return(_GetEPAddress(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxAddr
* Description : Set the endpoint Tx buffer address.
* Input : bEpNum: Endpoint Number.
* wAddr: new address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxAddr(u8 bEpNum, u16 wAddr)
{
_SetEPTxAddr(bEpNum, wAddr);
}
/*******************************************************************************
* Function Name : SetEPRxAddr
* Description : Set the endpoint Rx buffer address.
* Input : bEpNum: Endpoint Number.
* wAddr: new address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxAddr(u8 bEpNum, u16 wAddr)
{
_SetEPRxAddr(bEpNum, wAddr);
}
/*******************************************************************************
* Function Name : GetEPTxAddr
* Description : Returns the endpoint Tx buffer address.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Rx buffer address.
*******************************************************************************/
u16 GetEPTxAddr(u8 bEpNum)
{
return(_GetEPTxAddr(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPRxAddr.
* Description : Returns the endpoint Rx buffer address.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Rx buffer address.
*******************************************************************************/
u16 GetEPRxAddr(u8 bEpNum)
{
return(_GetEPRxAddr(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPTxCount.
* Description : Set the Tx count.
* Input : bEpNum: Endpoint Number.
* wCount: new count value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPTxCount(u8 bEpNum, u16 wCount)
{
_SetEPTxCount(bEpNum, wCount);
}
/*******************************************************************************
* Function Name : SetEPCountRxReg.
* Description : Set the Count Rx Register value.
* Input : *pdwReg: point to the register.
* wCount: the new register value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPCountRxReg(u32 *pdwReg, u16 wCount)
{
_SetEPCountRxReg(dwReg, wCount);
}
/*******************************************************************************
* Function Name : SetEPRxCount
* Description : Set the Rx count.
* Input : bEpNum: Endpoint Number.
* wCount: the new count value.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPRxCount(u8 bEpNum, u16 wCount)
{
_SetEPRxCount(bEpNum, wCount);
}
/*******************************************************************************
* Function Name : GetEPTxCount
* Description : Get the Tx count.
* Input : bEpNum: Endpoint Number.
* Output : None
* Return : Tx count value.
*******************************************************************************/
u16 GetEPTxCount(u8 bEpNum)
{
return(_GetEPTxCount(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPRxCount
* Description : Get the Rx count.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Rx count value.
*******************************************************************************/
u16 GetEPRxCount(u8 bEpNum)
{
return(_GetEPRxCount(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPDblBuffAddr
* Description : Set the addresses of the buffer 0 and 1.
* Input : bEpNum: Endpoint Number.
* wBuf0Addr: new address of buffer 0.
* wBuf1Addr: new address of buffer 1.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuffAddr(u8 bEpNum, u16 wBuf0Addr, u16 wBuf1Addr)
{
_SetEPDblBuffAddr(bEpNum, wBuf0Addr, wBuf1Addr);
}
/*******************************************************************************
* Function Name : SetEPDblBuf0Addr
* Description : Set the Buffer 1 address.
* Input : bEpNum: Endpoint Number
* wBuf0Addr: new address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuf0Addr(u8 bEpNum, u16 wBuf0Addr)
{
_SetEPDblBuf0Addr(bEpNum, wBuf0Addr);
}
/*******************************************************************************
* Function Name : SetEPDblBuf1Addr
* Description : Set the Buffer 1 address.
* Input : bEpNum: Endpoint Number
* wBuf1Addr: new address.
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuf1Addr(u8 bEpNum, u16 wBuf1Addr)
{
_SetEPDblBuf1Addr(bEpNum, wBuf1Addr);
}
/*******************************************************************************
* Function Name : GetEPDblBuf0Addr
* Description : Returns the address of the Buffer 0.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
u16 GetEPDblBuf0Addr(u8 bEpNum)
{
return(_GetEPDblBuf0Addr(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPDblBuf1Addr
* Description : Returns the address of the Buffer 1.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Address of the Buffer 1.
*******************************************************************************/
u16 GetEPDblBuf1Addr(u8 bEpNum)
{
return(_GetEPDblBuf1Addr(bEpNum));
}
/*******************************************************************************
* Function Name : SetEPDblBuffCount
* Description : Set the number of bytes for a double Buffer
* endpoint.
* Input : bEpNum,bDir, wCount
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuffCount(u8 bEpNum, u8 bDir, u16 wCount)
{
_SetEPDblBuffCount(bEpNum, bDir, wCount);
}
/*******************************************************************************
* Function Name : SetEPDblBuf0Count
* Description : Set the number of bytes in the buffer 0 of a double Buffer
* endpoint.
* Input : bEpNum, bDir, wCount
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuf0Count(u8 bEpNum, u8 bDir, u16 wCount)
{
_SetEPDblBuf0Count(bEpNum, bDir, wCount);
}
/*******************************************************************************
* Function Name : SetEPDblBuf1Count
* Description : Set the number of bytes in the buffer 0 of a double Buffer
* endpoint.
* Input : bEpNum, bDir, wCount
* Output : None.
* Return : None.
*******************************************************************************/
void SetEPDblBuf1Count(u8 bEpNum, u8 bDir, u16 wCount)
{
_SetEPDblBuf1Count(bEpNum, bDir, wCount);
}
/*******************************************************************************
* Function Name : GetEPDblBuf0Count
* Description : Returns the number of byte received in the buffer 0 of a double
* Buffer endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Buffer 0 count
*******************************************************************************/
u16 GetEPDblBuf0Count(u8 bEpNum)
{
return(_GetEPDblBuf0Count(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPDblBuf1Count
* Description : Returns the number of data received in the buffer 1 of a double
* Buffer endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Buffer 1 count.
*******************************************************************************/
u16 GetEPDblBuf1Count(u8 bEpNum)
{
return(_GetEPDblBuf1Count(bEpNum));
}
/*******************************************************************************
* Function Name : GetEPDblBufDir
* Description : gets direction of the double buffered endpoint
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : EP_DBUF_OUT, EP_DBUF_IN,
* EP_DBUF_ERR if the endpoint counter not yet programmed.
*******************************************************************************/
EP_DBUF_DIR GetEPDblBufDir(u8 bEpNum)
{
if ((u16)(*_pEPRxCount(bEpNum) & 0xFC00) != 0)
return(EP_DBUF_OUT);
else if (((u16)(*_pEPTxCount(bEpNum)) & 0x03FF) != 0)
return(EP_DBUF_IN);
else
return(EP_DBUF_ERR);
}
/*******************************************************************************
* Function Name : FreeUserBuffer
* Description : free buffer used from the application realizing it to the line
toggles bit SW_BUF in the double buffered endpoint register
* Input : bEpNum, bDir
* Output : None.
* Return : None.
*******************************************************************************/
void FreeUserBuffer(u8 bEpNum, u8 bDir)
{
if (bDir == EP_DBUF_OUT)
{ /* OUT double buffered endpoint */
_ToggleDTOG_TX(bEpNum);
}
else if (bDir == EP_DBUF_IN)
{ /* IN double buffered endpoint */
_ToggleDTOG_RX(bEpNum);
}
}
/*******************************************************************************
* Function Name : ToWord
* Description : merge two byte in a word.
* Input : bh: byte high, bl: bytes low.
* Output : None.
* Return : resulted word.
*******************************************************************************/
u16 ToWord(u8 bh, u8 bl)
{
u16 wRet;
wRet = (u16)bl | ((u16)bh << 8);
return(wRet);
}
/*******************************************************************************
* Function Name : ByteSwap
* Description : Swap two byte in a word.
* Input : wSwW: word to Swap.
* Output : None.
* Return : resulted word.
*******************************************************************************/
u16 ByteSwap(u16 wSwW)
{
u8 bTemp;
u16 wRet;
bTemp = (u8)(wSwW & 0xff);
wRet = (wSwW >> 8) | ((u16)bTemp << 8);
return(wRet);
}
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,619 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_regs.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Interface prototype functions to USB cell registers
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_REGS_H
#define __USB_REGS_H
/* Includes ------------------------------------------------------------------*/
/* Exported types ------------------------------------------------------------*/
typedef enum _EP_DBUF_DIR
{
/* double buffered endpoint direction */
EP_DBUF_ERR,
EP_DBUF_OUT,
EP_DBUF_IN
}EP_DBUF_DIR;
/* endpoint buffer number */
enum EP_BUF_NUM
{
EP_NOBUF,
EP_BUF0,
EP_BUF1
};
/* Exported constants --------------------------------------------------------*/
#define RegBase (0x40005C00L) /* USB_IP Peripheral Registers base address */
#define PMAAddr (0x40006000L) /* USB_IP Packet Memory Area base address */
/******************************************************************************/
/* General registers */
/******************************************************************************/
/* Control register */
#define CNTR ((volatile unsigned *)(RegBase + 0x40))
/* Interrupt status register */
#define ISTR ((volatile unsigned *)(RegBase + 0x44))
/* Frame number register */
#define FNR ((volatile unsigned *)(RegBase + 0x48))
/* Device address register */
#define DADDR ((volatile unsigned *)(RegBase + 0x4C))
/* Buffer Table address register */
#define BTABLE ((volatile unsigned *)(RegBase + 0x50))
/******************************************************************************/
/* Endpoint registers */
/******************************************************************************/
#define EP0REG ((volatile unsigned *)(RegBase)) /* endpoint 0 register address */
/* endpoints enumeration */
#define ENDP0 ((u8)0)
#define ENDP1 ((u8)1)
#define ENDP2 ((u8)2)
#define ENDP3 ((u8)3)
#define ENDP4 ((u8)4)
#define ENDP5 ((u8)5)
#define ENDP6 ((u8)6)
#define ENDP7 ((u8)7)
/******************************************************************************/
/* ISTR interrupt events */
/******************************************************************************/
#define ISTR_CTR (0x8000) /* Correct TRansfer (clear-only bit) */
#define ISTR_DOVR (0x4000) /* DMA OVeR/underrun (clear-only bit) */
#define ISTR_ERR (0x2000) /* ERRor (clear-only bit) */
#define ISTR_WKUP (0x1000) /* WaKe UP (clear-only bit) */
#define ISTR_SUSP (0x0800) /* SUSPend (clear-only bit) */
#define ISTR_RESET (0x0400) /* RESET (clear-only bit) */
#define ISTR_SOF (0x0200) /* Start Of Frame (clear-only bit) */
#define ISTR_ESOF (0x0100) /* Expected Start Of Frame (clear-only bit) */
#define ISTR_DIR (0x0010) /* DIRection of transaction (read-only bit) */
#define ISTR_EP_ID (0x000F) /* EndPoint IDentifier (read-only bit) */
#define CLR_CTR (~ISTR_CTR) /* clear Correct TRansfer bit */
#define CLR_DOVR (~ISTR_DOVR) /* clear DMA OVeR/underrun bit*/
#define CLR_ERR (~ISTR_ERR) /* clear ERRor bit */
#define CLR_WKUP (~ISTR_WKUP) /* clear WaKe UP bit */
#define CLR_SUSP (~ISTR_SUSP) /* clear SUSPend bit */
#define CLR_RESET (~ISTR_RESET) /* clear RESET bit */
#define CLR_SOF (~ISTR_SOF) /* clear Start Of Frame bit */
#define CLR_ESOF (~ISTR_ESOF) /* clear Expected Start Of Frame bit */
/******************************************************************************/
/* CNTR control register bits definitions */
/******************************************************************************/
#define CNTR_CTRM (0x8000) /* Correct TRansfer Mask */
#define CNTR_DOVRM (0x4000) /* DMA OVeR/underrun Mask */
#define CNTR_ERRM (0x2000) /* ERRor Mask */
#define CNTR_WKUPM (0x1000) /* WaKe UP Mask */
#define CNTR_SUSPM (0x0800) /* SUSPend Mask */
#define CNTR_RESETM (0x0400) /* RESET Mask */
#define CNTR_SOFM (0x0200) /* Start Of Frame Mask */
#define CNTR_ESOFM (0x0100) /* Expected Start Of Frame Mask */
#define CNTR_RESUME (0x0010) /* RESUME request */
#define CNTR_FSUSP (0x0008) /* Force SUSPend */
#define CNTR_LPMODE (0x0004) /* Low-power MODE */
#define CNTR_PDWN (0x0002) /* Power DoWN */
#define CNTR_FRES (0x0001) /* Force USB RESet */
/******************************************************************************/
/* FNR Frame Number Register bit definitions */
/******************************************************************************/
#define FNR_RXDP (0x8000) /* status of D+ data line */
#define FNR_RXDM (0x4000) /* status of D- data line */
#define FNR_LCK (0x2000) /* LoCKed */
#define FNR_LSOF (0x1800) /* Lost SOF */
#define FNR_FN (0x07FF) /* Frame Number */
/******************************************************************************/
/* DADDR Device ADDRess bit definitions */
/******************************************************************************/
#define DADDR_EF (0x80)
#define DADDR_ADD (0x7F)
/******************************************************************************/
/* Endpoint register */
/******************************************************************************/
/* bit positions */
#define EP_CTR_RX (0x8000) /* EndPoint Correct TRansfer RX */
#define EP_DTOG_RX (0x4000) /* EndPoint Data TOGGLE RX */
#define EPRX_STAT (0x3000) /* EndPoint RX STATus bit field */
#define EP_SETUP (0x0800) /* EndPoint SETUP */
#define EP_T_FIELD (0x0600) /* EndPoint TYPE */
#define EP_KIND (0x0100) /* EndPoint KIND */
#define EP_CTR_TX (0x0080) /* EndPoint Correct TRansfer TX */
#define EP_DTOG_TX (0x0040) /* EndPoint Data TOGGLE TX */
#define EPTX_STAT (0x0030) /* EndPoint TX STATus bit field */
#define EPADDR_FIELD (0x000F) /* EndPoint ADDRess FIELD */
/* EndPoint REGister MASK (no toggle fields) */
#define EPREG_MASK (EP_CTR_RX|EP_SETUP|EP_T_FIELD|EP_KIND|EP_CTR_TX|EPADDR_FIELD)
/* EP_TYPE[1:0] EndPoint TYPE */
#define EP_TYPE_MASK (0x0600) /* EndPoint TYPE Mask */
#define EP_BULK (0x0000) /* EndPoint BULK */
#define EP_CONTROL (0x0200) /* EndPoint CONTROL */
#define EP_ISOCHRONOUS (0x0400) /* EndPoint ISOCHRONOUS */
#define EP_INTERRUPT (0x0600) /* EndPoint INTERRUPT */
#define EP_T_MASK (~EP_T_FIELD & EPREG_MASK)
/* EP_KIND EndPoint KIND */
#define EPKIND_MASK (~EP_KIND & EPREG_MASK)
/* STAT_TX[1:0] STATus for TX transfer */
#define EP_TX_DIS (0x0000) /* EndPoint TX DISabled */
#define EP_TX_STALL (0x0010) /* EndPoint TX STALLed */
#define EP_TX_NAK (0x0020) /* EndPoint TX NAKed */
#define EP_TX_VALID (0x0030) /* EndPoint TX VALID */
#define EPTX_DTOG1 (0x0010) /* EndPoint TX Data TOGgle bit1 */
#define EPTX_DTOG2 (0x0020) /* EndPoint TX Data TOGgle bit2 */
#define EPTX_DTOGMASK (EPTX_STAT|EPREG_MASK)
/* STAT_RX[1:0] STATus for RX transfer */
#define EP_RX_DIS (0x0000) /* EndPoint RX DISabled */
#define EP_RX_STALL (0x1000) /* EndPoint RX STALLed */
#define EP_RX_NAK (0x2000) /* EndPoint RX NAKed */
#define EP_RX_VALID (0x3000) /* EndPoint RX VALID */
#define EPRX_DTOG1 (0x1000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOG2 (0x2000) /* EndPoint RX Data TOGgle bit1 */
#define EPRX_DTOGMASK (EPRX_STAT|EPREG_MASK)
/* Exported macro ------------------------------------------------------------*/
/* SetCNTR */
#define _SetCNTR(wRegValue) (*CNTR = (u16)wRegValue)
/* SetISTR */
#define _SetISTR(wRegValue) (*ISTR = (u16)wRegValue)
/* SetDADDR */
#define _SetDADDR(wRegValue) (*DADDR = (u16)wRegValue)
/* SetBTABLE */
#define _SetBTABLE(wRegValue)(*BTABLE = (u16)(wRegValue & 0xFFF8))
/* GetCNTR */
#define _GetCNTR() ((u16) *CNTR)
/* GetISTR */
#define _GetISTR() ((u16) *ISTR)
/* GetFNR */
#define _GetFNR() ((u16) *FNR)
/* GetDADDR */
#define _GetDADDR() ((u16) *DADDR)
/* GetBTABLE */
#define _GetBTABLE() ((u16) *BTABLE)
/* SetENDPOINT */
#define _SetENDPOINT(bEpNum,wRegValue) (*(EP0REG + bEpNum)= \
(u16)wRegValue)
/* GetENDPOINT */
#define _GetENDPOINT(bEpNum) ((u16)(*(EP0REG + bEpNum)))
/*******************************************************************************
* Macro Name : SetEPType
* Description : sets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* wType
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPType(bEpNum,wType) (_SetENDPOINT(bEpNum,\
((_GetENDPOINT(bEpNum) & EP_T_MASK) | wType)))
/*******************************************************************************
* Macro Name : GetEPType
* Description : gets the type in the endpoint register(bits EP_TYPE[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : Endpoint Type
*******************************************************************************/
#define _GetEPType(bEpNum) (_GetENDPOINT(bEpNum) & EP_T_FIELD)
/*******************************************************************************
* Macro Name : SetEPTxStatus
* Description : sets the status for tx transfer (bits STAT_TX[1:0]).
* Input : bEpNum: Endpoint Number.
* wState: new state
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxStatus(bEpNum,wState) {\
register u16 _wRegVal; \
_wRegVal = _GetENDPOINT(bEpNum) & EPTX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPTX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG1; \
/* toggle second bit ? */ \
if((EPTX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPTX_DTOG2; \
_SetENDPOINT(bEpNum, _wRegVal); \
} /* _SetEPTxStatus */
/*******************************************************************************
* Macro Name : SetEPRxStatus
* Description : sets the status for rx transfer (bits STAT_TX[1:0])
* Input : bEpNum: Endpoint Number.
* wState: new state.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPRxStatus(bEpNum,wState) {\
register u16 _wRegVal; \
\
_wRegVal = _GetENDPOINT(bEpNum) & EPRX_DTOGMASK;\
/* toggle first bit ? */ \
if((EPRX_DTOG1 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG1; \
/* toggle second bit ? */ \
if((EPRX_DTOG2 & wState)!= 0) \
_wRegVal ^= EPRX_DTOG2; \
_SetENDPOINT(bEpNum, _wRegVal); \
} /* _SetEPRxStatus */
/*******************************************************************************
* Macro Name : GetEPTxStatus / GetEPRxStatus
* Description : gets the status for tx/rx transfer (bits STAT_TX[1:0]
* /STAT_RX[1:0])
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : status .
*******************************************************************************/
#define _GetEPTxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPTX_STAT)
#define _GetEPRxStatus(bEpNum) ((u16)_GetENDPOINT(bEpNum) & EPRX_STAT)
/*******************************************************************************
* Macro Name : SetEPTxValid / SetEPRxValid
* Description : sets directly the VALID tx/rx-status into the enpoint register
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxValid(bEpNum) (_SetEPTxStatus(bEpNum, EP_TX_VALID))
#define _SetEPRxValid(bEpNum) (_SetEPRxStatus(bEpNum, EP_RX_VALID))
/*******************************************************************************
* Macro Name : GetTxStallStatus / GetRxStallStatus.
* Description : checks stall condition in an endpoint.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : TRUE = endpoint in stall condition.
*******************************************************************************/
#define _GetTxStallStatus(bEpNum) (_GetEPTxStatus(bEpNum) \
== EP_TX_STALL)
#define _GetRxStallStatus(bEpNum) (_GetEPRxStatus(bEpNum) \
== EP_RX_STALL)
/*******************************************************************************
* Macro Name : SetEP_KIND / ClearEP_KIND.
* Description : set & clear EP_KIND bit.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \
(_GetENDPOINT(bEpNum) | EP_KIND) & EPREG_MASK))
#define _ClearEP_KIND(bEpNum) (_SetENDPOINT(bEpNum, \
(_GetENDPOINT(bEpNum) & EPKIND_MASK)))
/*******************************************************************************
* Macro Name : Set_Status_Out / Clear_Status_Out.
* Description : Sets/clears directly STATUS_OUT bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _Set_Status_Out(bEpNum) _SetEP_KIND(bEpNum)
#define _Clear_Status_Out(bEpNum) _ClearEP_KIND(bEpNum)
/*******************************************************************************
* Macro Name : SetEPDoubleBuff / ClearEPDoubleBuff.
* Description : Sets/clears directly EP_KIND bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDoubleBuff(bEpNum) _SetEP_KIND(bEpNum)
#define _ClearEPDoubleBuff(bEpNum) _ClearEP_KIND(bEpNum)
/*******************************************************************************
* Macro Name : ClearEP_CTR_RX / ClearEP_CTR_TX.
* Description : Clears bit CTR_RX / CTR_TX in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearEP_CTR_RX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0x7FFF & EPREG_MASK))
#define _ClearEP_CTR_TX(bEpNum) (_SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & 0xFF7F & EPREG_MASK))
/*******************************************************************************
* Macro Name : ToggleDTOG_RX / ToggleDTOG_TX .
* Description : Toggles DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ToggleDTOG_RX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_DTOG_RX | _GetENDPOINT(bEpNum) & EPREG_MASK))
#define _ToggleDTOG_TX(bEpNum) (_SetENDPOINT(bEpNum, \
EP_DTOG_TX | _GetENDPOINT(bEpNum) & EPREG_MASK))
/*******************************************************************************
* Macro Name : ClearDTOG_RX / ClearDTOG_TX.
* Description : Clears DTOG_RX / DTOG_TX bit in the endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _ClearDTOG_RX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_RX) != 0)\
_ToggleDTOG_RX(bEpNum)
#define _ClearDTOG_TX(bEpNum) if((_GetENDPOINT(bEpNum) & EP_DTOG_TX) != 0)\
_ToggleDTOG_TX(bEpNum)
/*******************************************************************************
* Macro Name : SetEPAddress.
* Description : Sets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* bAddr: Address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPAddress(bEpNum,bAddr) _SetENDPOINT(bEpNum,\
_GetENDPOINT(bEpNum) & EPREG_MASK | bAddr)
/*******************************************************************************
* Macro Name : GetEPAddress.
* Description : Gets address in an endpoint register.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPAddress(bEpNum) ((u8)(_GetENDPOINT(bEpNum) & EPADDR_FIELD))
#define _pEPTxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8 )*2 + PMAAddr))
#define _pEPTxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+2)*2 + PMAAddr))
#define _pEPRxAddr(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+4)*2 + PMAAddr))
#define _pEPRxCount(bEpNum) ((u32 *)((_GetBTABLE()+bEpNum*8+6)*2 + PMAAddr))
/*******************************************************************************
* Macro Name : SetEPTxAddr / SetEPRxAddr.
* Description : sets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* wAddr: address to be set (must be word aligned).
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxAddr(bEpNum,wAddr) (*_pEPTxAddr(bEpNum) = ((wAddr >> 1) << 1))
#define _SetEPRxAddr(bEpNum,wAddr) (*_pEPRxAddr(bEpNum) = ((wAddr >> 1) << 1))
/*******************************************************************************
* Macro Name : GetEPTxAddr / GetEPRxAddr.
* Description : Gets address of the tx/rx buffer.
* Input : bEpNum: Endpoint Number.
* Output : None.
* Return : address of the buffer.
*******************************************************************************/
#define _GetEPTxAddr(bEpNum) ((u16)*_pEPTxAddr(bEpNum))
#define _GetEPRxAddr(bEpNum) ((u16)*_pEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPCountRxReg.
* Description : Sets counter of rx buffer with no. of blocks.
* Input : pdwReg: pointer to counter.
* wCount: Counter.
* Output : None.
* Return : None.
*******************************************************************************/
#define _BlocksOf32(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 5;\
if((wCount & 0x1f) == 0)\
wNBlocks--;\
*pdwReg = (u32)((wNBlocks << 10) | 0x8000);\
}/* _BlocksOf32 */
#define _BlocksOf2(dwReg,wCount,wNBlocks) {\
wNBlocks = wCount >> 1;\
if((wCount & 0x1) != 0)\
wNBlocks++;\
*pdwReg = (u32)(wNBlocks << 10);\
}/* _BlocksOf2 */
#define _SetEPCountRxReg(dwReg,wCount) {\
u16 wNBlocks;\
if(wCount > 62){_BlocksOf32(dwReg,wCount,wNBlocks);}\
else {_BlocksOf2(dwReg,wCount,wNBlocks);}\
}/* _SetEPCountRxReg */
#define _SetEPRxDblBuf0Count(bEpNum,wCount) {\
u32 *pdwReg = _pEPTxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : SetEPTxCount / SetEPRxCount.
* Description : sets counter for the tx/rx buffer.
* Input : bEpNum: endpoint number.
* wCount: Counter value.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPTxCount(bEpNum,wCount) (*_pEPTxCount(bEpNum) = wCount)
#define _SetEPRxCount(bEpNum,wCount) {\
u32 *pdwReg = _pEPRxCount(bEpNum); \
_SetEPCountRxReg(pdwReg, wCount);\
}
/*******************************************************************************
* Macro Name : GetEPTxCount / GetEPRxCount.
* Description : gets counter of the tx buffer.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : Counter value.
*******************************************************************************/
#define _GetEPTxCount(bEpNum)((u16)(*_pEPTxCount(bEpNum)) & 0x3ff)
#define _GetEPRxCount(bEpNum)((u16)(*_pEPRxCount(bEpNum)) & 0x3ff)
/*******************************************************************************
* Macro Name : SetEPDblBuf0Addr / SetEPDblBuf1Addr.
* Description : Sets buffer 0/1 address in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Addr(bEpNum,wBuf0Addr) {_SetEPTxAddr(bEpNum, wBuf0Addr);}
#define _SetEPDblBuf1Addr(bEpNum,wBuf1Addr) {_SetEPRxAddr(bEpNum, wBuf1Addr);}
/*******************************************************************************
* Macro Name : SetEPDblBuffAddr.
* Description : Sets addresses in a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : wBuf0Addr: buffer 0 address.
* : wBuf1Addr = buffer 1 address.
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuffAddr(bEpNum,wBuf0Addr,wBuf1Addr) { \
_SetEPDblBuf0Addr(bEpNum, wBuf0Addr);\
_SetEPDblBuf1Addr(bEpNum, wBuf1Addr);\
} /* _SetEPDblBuffAddr */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Addr / GetEPDblBuf1Addr.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Addr(bEpNum) (_GetEPTxAddr(bEpNum))
#define _GetEPDblBuf1Addr(bEpNum) (_GetEPRxAddr(bEpNum))
/*******************************************************************************
* Macro Name : SetEPDblBuffCount / SetEPDblBuf0Count / SetEPDblBuf1Count.
* Description : Gets buffer 0/1 address of a double buffer endpoint.
* Input : bEpNum: endpoint number.
* : bDir: endpoint dir EP_DBUF_OUT = OUT
* EP_DBUF_IN = IN
* : wCount: Counter value
* Output : None.
* Return : None.
*******************************************************************************/
#define _SetEPDblBuf0Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxDblBuf0Count(bEpNum,wCount);} \
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */ \
*_pEPTxCount(bEpNum) = (u32)wCount; \
} /* SetEPDblBuf0Count*/
#define _SetEPDblBuf1Count(bEpNum, bDir, wCount) { \
if(bDir == EP_DBUF_OUT)\
/* OUT endpoint */ \
{_SetEPRxCount(bEpNum,wCount);}\
else if(bDir == EP_DBUF_IN)\
/* IN endpoint */\
*_pEPRxCount(bEpNum) = (u32)wCount; \
} /* SetEPDblBuf1Count */
#define _SetEPDblBuffCount(bEpNum, bDir, wCount) {\
_SetEPDblBuf0Count(bEpNum, bDir, wCount); \
_SetEPDblBuf1Count(bEpNum, bDir, wCount); \
} /* _SetEPDblBuffCount */
/*******************************************************************************
* Macro Name : GetEPDblBuf0Count / GetEPDblBuf1Count.
* Description : Gets buffer 0/1 rx/tx counter for double buffering.
* Input : bEpNum: endpoint number.
* Output : None.
* Return : None.
*******************************************************************************/
#define _GetEPDblBuf0Count(bEpNum) (_GetEPTxCount(bEpNum))
#define _GetEPDblBuf1Count(bEpNum) (_GetEPRxCount(bEpNum))
/* External variables --------------------------------------------------------*/
extern volatile u16 wIstr; /* ISTR register last read value */
/* Exported functions ------------------------------------------------------- */
void SetCNTR(u16 /*wRegValue*/);
void SetISTR(u16 /*wRegValue*/);
void SetDADDR(u16 /*wRegValue*/);
void SetBTABLE(u16 /*wRegValue*/);
u16 GetCNTR(void);
u16 GetISTR(void);
u16 GetFNR(void);
u16 GetDADDR(void);
u16 GetBTABLE(void);
void SetENDPOINT(u8 /*bEpNum*/, u16 /*wRegValue*/);
u16 GetENDPOINT(u8 /*bEpNum*/);
void SetEPType(u8 /*bEpNum*/, u16 /*wType*/);
u16 GetEPType(u8 /*bEpNum*/);
void SetEPTxStatus(u8 /*bEpNum*/, u16 /*wState*/);
void SetEPRxStatus(u8 /*bEpNum*/, u16 /*wState*/);
void SetDouBleBuffEPStall(u8 /*bEpNum*/, u8 bDir);
u16 GetEPTxStatus(u8 /*bEpNum*/);
u16 GetEPRxStatus(u8 /*bEpNum*/);
void SetEPTxValid(u8 /*bEpNum*/);
void SetEPRxValid(u8 /*bEpNum*/);
u16 GetTxStallStatus(u8 /*bEpNum*/);
u16 GetRxStallStatus(u8 /*bEpNum*/);
void SetEP_KIND(u8 /*bEpNum*/);
void ClearEP_KIND(u8 /*bEpNum*/);
void Set_Status_Out(u8 /*bEpNum*/);
void Clear_Status_Out(u8 /*bEpNum*/);
void SetEPDoubleBuff(u8 /*bEpNum*/);
void ClearEPDoubleBuff(u8 /*bEpNum*/);
void ClearEP_CTR_RX(u8 /*bEpNum*/);
void ClearEP_CTR_TX(u8 /*bEpNum*/);
void ToggleDTOG_RX(u8 /*bEpNum*/);
void ToggleDTOG_TX(u8 /*bEpNum*/);
void ClearDTOG_RX(u8 /*bEpNum*/);
void ClearDTOG_TX(u8 /*bEpNum*/);
void SetEPAddress(u8 /*bEpNum*/, u8 /*bAddr*/);
u8 GetEPAddress(u8 /*bEpNum*/);
void SetEPTxAddr(u8 /*bEpNum*/, u16 /*wAddr*/);
void SetEPRxAddr(u8 /*bEpNum*/, u16 /*wAddr*/);
u16 GetEPTxAddr(u8 /*bEpNum*/);
u16 GetEPRxAddr(u8 /*bEpNum*/);
void SetEPCountRxReg(u32 * /*pdwReg*/, u16 /*wCount*/);
void SetEPTxCount(u8 /*bEpNum*/, u16 /*wCount*/);
void SetEPRxCount(u8 /*bEpNum*/, u16 /*wCount*/);
u16 GetEPTxCount(u8 /*bEpNum*/);
u16 GetEPRxCount(u8 /*bEpNum*/);
void SetEPDblBuf0Addr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/);
void SetEPDblBuf1Addr(u8 /*bEpNum*/, u16 /*wBuf1Addr*/);
void SetEPDblBuffAddr(u8 /*bEpNum*/, u16 /*wBuf0Addr*/, u16 /*wBuf1Addr*/);
u16 GetEPDblBuf0Addr(u8 /*bEpNum*/);
u16 GetEPDblBuf1Addr(u8 /*bEpNum*/);
void SetEPDblBuffCount(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/);
void SetEPDblBuf0Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/);
void SetEPDblBuf1Count(u8 /*bEpNum*/, u8 /*bDir*/, u16 /*wCount*/);
u16 GetEPDblBuf0Count(u8 /*bEpNum*/);
u16 GetEPDblBuf1Count(u8 /*bEpNum*/);
EP_DBUF_DIR GetEPDblBufDir(u8 /*bEpNum*/);
void FreeUserBuffer(u8 bEpNum/*bEpNum*/, u8 bDir);
u16 ToWord(u8, u8);
u16 ByteSwap(u16);
#endif /* __USB_REGS_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -0,0 +1,72 @@
/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
* File Name : usb_type.h
* Author : MCD Application Team
* Version : V2.2.1
* Date : 09/22/2008
* Description : Type definitions used by the USB Library
********************************************************************************
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
* CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USB_TYPE_H
#define __USB_TYPE_H
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
#ifndef NULL
#define NULL ((void *)0)
#endif
#ifndef __STM32F10x_TYPE_H
typedef signed long s32;
typedef signed short s16;
typedef signed char s8;
typedef volatile signed long vs32;
typedef volatile signed short vs16;
typedef volatile signed char vs8;
typedef unsigned long u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned long const uc32; /* Read Only */
typedef unsigned short const uc16; /* Read Only */
typedef unsigned char const uc8; /* Read Only */
typedef volatile unsigned long vu32;
typedef volatile unsigned short vu16;
typedef volatile unsigned char vu8;
typedef volatile unsigned long const vuc32; /* Read Only */
typedef volatile unsigned short const vuc16; /* Read Only */
typedef volatile unsigned char const vuc8; /* Read Only */
typedef enum
{
FALSE = 0, TRUE = !FALSE
}
bool;
typedef enum { RESET = 0, SET = !RESET } FlagStatus, ITStatus;
typedef enum { DISABLE = 0, ENABLE = !DISABLE} FunctionalState;
typedef enum { ERROR = 0, SUCCESS = !ERROR} ErrorStatus;
#endif
/* Exported macro ------------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
/* External variables --------------------------------------------------------*/
#endif /* __USB_TYPE_H */
/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

View File

@ -6,7 +6,18 @@ if [ $# -lt 4 ]; then
echo "Usage: $0 $# <dummy_port> <altID> <usbID> <binfile>" >&2
exit 1
fi
dummy_port=$1; altID=$2; usbID=$3; binfile=$4
dummy_port=$1; altID=$2; usbID=$3; binfile=$4;dummy_port_fullpath="/dev/$1"
#if we can find the Serial device try resetting it and then sleeping for 1 sec while the board reboots
if [ -e $dummy_port_fullpath ]; then
echo "resetting " $dummy_port_fullpath
stty -f $dummy_port_fullpath 1200
sleep 1
# stty -f $dummy_port_fullpath 1200
# sleep 1
fi
DFU_UTIL=/usr/local/bin/dfu-util
if [ ! -x ${DFU_UTIL} ]; then
@ -18,4 +29,4 @@ if [ ! -x ${DFU_UTIL} ]; then
exit 2
fi
${DFU_UTIL} -d ${usbID} -a ${altID} -D ${binfile}
${DFU_UTIL} -d ${usbID} -a ${altID} -D ${binfile} -R

View File

@ -17,7 +17,9 @@ set str1=%7
set str1=%str1:/=\%
set gcc=%str1: =%
if %6 == 1 (goto debug) else (if %5 == maple_serial (goto Serial) else (goto maple_loader))
if %6 == 1 (goto debug) else (if %5 == maple_serial (goto Serial) else (if %5 == maple_dfu (goto maple_loader) else (goto STLink)))
exit
:debug
debugging.bat %gcc% %elf%
@ -47,3 +49,8 @@ rem: "%ProgramFiles(x86)%\STMicroelectronics\Software\Flash Loader Demonstrator\
rem: -- 32 bit version
rem: "%ProgramFiles%\STMicroelectronics\Software\Flash Loader Demonstrator\STMFlashLoader.exe" -c --pn %commportnum% --br 230400 -i STM32_Med-density_64K -e --all -d --fn %str% --a 0x8000000 -r --a 0x8000000
exit
:STLink
stlink\ST-LINK_CLI.exe -c SWD -P %str% 0x8000000 -Rst -Run
exit