Merge branch 'master' of https://github.com/rogerclarkmelbourne/Arduino_STM32
This commit is contained in:
commit
4e808480ca
|
@ -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/*~
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -39,4 +39,6 @@ void yield(void);
|
|||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#include "variant.h"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
|
@ -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))
|
||||
|
|
108
STM32F1XX/libraries/EEPROM/examples/EEPROM_example/EEPROM_example.ino
Normal file → Executable file
108
STM32F1XX/libraries/EEPROM/examples/EEPROM_example/EEPROM_example.ino
Normal file → Executable 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();
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -69,8 +69,21 @@ void LiquidCrystal::init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable,
|
|||
_data_pins[5] = d5;
|
||||
_data_pins[6] = d6;
|
||||
_data_pins[7] = d7;
|
||||
displaymode=fourbitmode;
|
||||
|
||||
for (int i = 0; i < 8 - fourbitmode * 4; i++) {
|
||||
if (fourbitmode)
|
||||
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
||||
else
|
||||
_displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
||||
|
||||
// TODO: bnewbold, re-enable this?
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
@ -80,17 +93,6 @@ void LiquidCrystal::init(uint8 fourbitmode, uint8 rs, uint8 rw, uint8 enable,
|
|||
pinMode(_rw_pin, OUTPUT);
|
||||
}
|
||||
pinMode(_enable_pin, OUTPUT);
|
||||
|
||||
if (fourbitmode)
|
||||
_displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
||||
else
|
||||
_displayfunction = LCD_8BITMODE | LCD_1LINE | LCD_5x8DOTS;
|
||||
|
||||
// TODO: bnewbold, re-enable this?
|
||||
begin(16, 1);
|
||||
}
|
||||
|
||||
void LiquidCrystal::begin(uint8 cols, uint8 lines, uint8 dotsize) {
|
||||
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 **********/
|
||||
|
|
|
@ -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,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
|
|
@ -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
|
|
@ -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");
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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)
|
||||
#######################################
|
|
@ -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);
|
||||
|
|
|
@ -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,39 +87,36 @@ 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) {
|
||||
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(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() { init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0); }
|
||||
private:
|
||||
void init_MightInline(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
|
||||
{
|
||||
void init_MightInline(uint32_t clock, BitOrder 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;
|
||||
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;
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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=
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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_ */
|
|
@ -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
|
||||
"%~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
|
||||
"%~dp0wdi-simple" --vid 0x1EAF --pid 0x0004 --type 3 --name "Maple Serial" --dest "%~dp0maple-serial"
|
||||
echo.
|
||||
|
||||
pause
|
||||
|
|
|
@ -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 */
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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.
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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()
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
Modified version of maple bootloader which includes DFU read functionality
|
||||
|
||||
Modifications were made by Tim Schuerewegen
|
||||
|
||||
|
|
@ -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) }
|
||||
}
|
|
@ -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) }
|
||||
}
|
|
@ -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>© 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
|
||||
|
|
@ -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>© 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
|
||||
|
||||
|
|
@ -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****/
|
|
@ -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
|
|
@ -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****/
|
|
@ -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
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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)
|
||||
*
|
||||
*/
|
|
@ -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 }
|
||||
};
|
||||
|
|
@ -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
|
|
@ -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
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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****/
|
|
@ -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
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue