merging tmk
This commit is contained in:
commit
547da78335
6120 changed files with 2442332 additions and 64463 deletions
478
tmk_core/protocol/adb.c
Normal file
478
tmk_core/protocol/adb.c
Normal file
|
@ -0,0 +1,478 @@
|
|||
/*
|
||||
Copyright 2011 Jun WAKO <wakojun@gmail.com>
|
||||
Copyright 2013 Shay Green <gblargg@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
|
||||
GPL-compatible, and OK to use in both free and proprietary applications.
|
||||
Additions and corrections to this file are welcome.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "adb.h"
|
||||
|
||||
|
||||
// GCC doesn't inline functions normally
|
||||
#define data_lo() (ADB_DDR |= (1<<ADB_DATA_BIT))
|
||||
#define data_hi() (ADB_DDR &= ~(1<<ADB_DATA_BIT))
|
||||
#define data_in() (ADB_PIN & (1<<ADB_DATA_BIT))
|
||||
|
||||
#ifdef ADB_PSW_BIT
|
||||
static inline void psw_lo(void);
|
||||
static inline void psw_hi(void);
|
||||
static inline bool psw_in(void);
|
||||
#endif
|
||||
|
||||
static inline void attention(void);
|
||||
static inline void place_bit0(void);
|
||||
static inline void place_bit1(void);
|
||||
static inline void send_byte(uint8_t data);
|
||||
static inline uint16_t wait_data_lo(uint16_t us);
|
||||
static inline uint16_t wait_data_hi(uint16_t us);
|
||||
static inline uint16_t adb_host_dev_recv(uint8_t device);
|
||||
|
||||
|
||||
void adb_host_init(void)
|
||||
{
|
||||
ADB_PORT &= ~(1<<ADB_DATA_BIT);
|
||||
data_hi();
|
||||
#ifdef ADB_PSW_BIT
|
||||
psw_hi();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ADB_PSW_BIT
|
||||
bool adb_host_psw(void)
|
||||
{
|
||||
return psw_in();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Don't call this in a row without the delay, otherwise it makes some of poor controllers
|
||||
* overloaded and misses strokes. Recommended interval is 12ms.
|
||||
*
|
||||
* Thanks a lot, blargg!
|
||||
* <http://geekhack.org/index.php?topic=14290.msg1068919#msg1068919>
|
||||
* <http://geekhack.org/index.php?topic=14290.msg1070139#msg1070139>
|
||||
*/
|
||||
|
||||
// ADB Bit Cells
|
||||
//
|
||||
// bit cell time: 70-130us
|
||||
// low part of bit0: 60-70% of bit cell
|
||||
// low part of bit1: 30-40% of bit cell
|
||||
//
|
||||
// bit cell time 70us 130us
|
||||
// --------------------------------------------
|
||||
// low part of bit0 42-49 78-91
|
||||
// high part of bit0 21-28 39-52
|
||||
// low part of bit1 21-28 39-52
|
||||
// high part of bit1 42-49 78-91
|
||||
//
|
||||
//
|
||||
// bit0:
|
||||
// 70us bit cell:
|
||||
// ____________~~~~~~
|
||||
// 42-49 21-28
|
||||
//
|
||||
// 130us bit cell:
|
||||
// ____________~~~~~~
|
||||
// 78-91 39-52
|
||||
//
|
||||
// bit1:
|
||||
// 70us bit cell:
|
||||
// ______~~~~~~~~~~~~
|
||||
// 21-28 42-49
|
||||
//
|
||||
// 130us bit cell:
|
||||
// ______~~~~~~~~~~~~
|
||||
// 39-52 78-91
|
||||
//
|
||||
// [from Apple IIgs Hardware Reference Second Edition]
|
||||
|
||||
enum {
|
||||
ADDR_KEYB = 0x20,
|
||||
ADDR_MOUSE = 0x30
|
||||
};
|
||||
|
||||
uint16_t adb_host_kbd_recv(void)
|
||||
{
|
||||
return adb_host_dev_recv(ADDR_KEYB);
|
||||
}
|
||||
|
||||
#ifdef ADB_MOUSE_ENABLE
|
||||
void adb_mouse_init(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint16_t adb_host_mouse_recv(void)
|
||||
{
|
||||
return adb_host_dev_recv(ADDR_MOUSE);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline uint16_t adb_host_dev_recv(uint8_t device)
|
||||
{
|
||||
uint16_t data = 0;
|
||||
cli();
|
||||
attention();
|
||||
send_byte(device|0x0C); // Addr:Keyboard(0010)/Mouse(0011), Cmd:Talk(11), Register0(00)
|
||||
place_bit0(); // Stopbit(0)
|
||||
if (!wait_data_hi(500)) { // Service Request(310us Adjustable Keyboard): just ignored
|
||||
sei();
|
||||
return -30; // something wrong
|
||||
}
|
||||
if (!wait_data_lo(500)) { // Tlt/Stop to Start(140-260us)
|
||||
sei();
|
||||
return 0; // No data to send
|
||||
}
|
||||
|
||||
uint8_t n = 17; // start bit + 16 data bits
|
||||
do {
|
||||
uint8_t lo = (uint8_t) wait_data_hi(130);
|
||||
if (!lo)
|
||||
goto error;
|
||||
|
||||
uint8_t hi = (uint8_t) wait_data_lo(lo);
|
||||
if (!hi)
|
||||
goto error;
|
||||
|
||||
hi = lo - hi;
|
||||
lo = 130 - lo;
|
||||
|
||||
data <<= 1;
|
||||
if (lo < hi) {
|
||||
data |= 1;
|
||||
}
|
||||
else if (n == 17) {
|
||||
sei();
|
||||
return -20;
|
||||
}
|
||||
}
|
||||
while ( --n );
|
||||
|
||||
// Stop bit can't be checked normally since it could have service request lenghtening
|
||||
// and its high state never goes low.
|
||||
if (!wait_data_hi(351) || wait_data_lo(91)) {
|
||||
sei();
|
||||
return -21;
|
||||
}
|
||||
sei();
|
||||
return data;
|
||||
|
||||
error:
|
||||
sei();
|
||||
return -n;
|
||||
}
|
||||
|
||||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l)
|
||||
{
|
||||
cli();
|
||||
attention();
|
||||
send_byte(cmd);
|
||||
place_bit0(); // Stopbit(0)
|
||||
_delay_us(200); // Tlt/Stop to Start
|
||||
place_bit1(); // Startbit(1)
|
||||
send_byte(data_h);
|
||||
send_byte(data_l);
|
||||
place_bit0(); // Stopbit(0);
|
||||
sei();
|
||||
}
|
||||
|
||||
// send state of LEDs
|
||||
void adb_host_kbd_led(uint8_t led)
|
||||
{
|
||||
// Addr:Keyboard(0010), Cmd:Listen(10), Register2(10)
|
||||
// send upper byte (not used)
|
||||
// send lower byte (bit2: ScrollLock, bit1: CapsLock, bit0:
|
||||
adb_host_listen(0x2A,0,led&0x07);
|
||||
}
|
||||
|
||||
|
||||
#ifdef ADB_PSW_BIT
|
||||
static inline void psw_lo()
|
||||
{
|
||||
ADB_DDR |= (1<<ADB_PSW_BIT);
|
||||
ADB_PORT &= ~(1<<ADB_PSW_BIT);
|
||||
}
|
||||
static inline void psw_hi()
|
||||
{
|
||||
ADB_PORT |= (1<<ADB_PSW_BIT);
|
||||
ADB_DDR &= ~(1<<ADB_PSW_BIT);
|
||||
}
|
||||
static inline bool psw_in()
|
||||
{
|
||||
ADB_PORT |= (1<<ADB_PSW_BIT);
|
||||
ADB_DDR &= ~(1<<ADB_PSW_BIT);
|
||||
return ADB_PIN&(1<<ADB_PSW_BIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void attention(void)
|
||||
{
|
||||
data_lo();
|
||||
_delay_us(800-35); // bit1 holds lo for 35 more
|
||||
place_bit1();
|
||||
}
|
||||
|
||||
static inline void place_bit0(void)
|
||||
{
|
||||
data_lo();
|
||||
_delay_us(65);
|
||||
data_hi();
|
||||
_delay_us(35);
|
||||
}
|
||||
|
||||
static inline void place_bit1(void)
|
||||
{
|
||||
data_lo();
|
||||
_delay_us(35);
|
||||
data_hi();
|
||||
_delay_us(65);
|
||||
}
|
||||
|
||||
static inline void send_byte(uint8_t data)
|
||||
{
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (data&(0x80>>i))
|
||||
place_bit1();
|
||||
else
|
||||
place_bit0();
|
||||
}
|
||||
}
|
||||
|
||||
// These are carefully coded to take 6 cycles of overhead.
|
||||
// inline asm approach became too convoluted
|
||||
static inline uint16_t wait_data_lo(uint16_t us)
|
||||
{
|
||||
do {
|
||||
if ( !data_in() )
|
||||
break;
|
||||
_delay_us(1 - (6 * 1000000.0 / F_CPU));
|
||||
}
|
||||
while ( --us );
|
||||
return us;
|
||||
}
|
||||
|
||||
static inline uint16_t wait_data_hi(uint16_t us)
|
||||
{
|
||||
do {
|
||||
if ( data_in() )
|
||||
break;
|
||||
_delay_us(1 - (6 * 1000000.0 / F_CPU));
|
||||
}
|
||||
while ( --us );
|
||||
return us;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
ADB Protocol
|
||||
============
|
||||
|
||||
Resources
|
||||
---------
|
||||
ADB - The Untold Story: Space Aliens Ate My Mouse
|
||||
http://developer.apple.com/legacy/mac/library/#technotes/hw/hw_01.html
|
||||
ADB Manager
|
||||
http://developer.apple.com/legacy/mac/library/documentation/mac/pdf/Devices/ADB_Manager.pdf
|
||||
Service request(5-17)
|
||||
Apple IIgs Hardware Reference Second Edition [Chapter6 p121]
|
||||
ftp://ftp.apple.asimov.net/pub/apple_II/documentation/Apple%20IIgs%20Hardware%20Reference.pdf
|
||||
ADB Keycode
|
||||
http://72.0.193.250/Documentation/macppc/adbkeycodes/
|
||||
http://m0115.web.fc2.com/m0115.jpg
|
||||
[Inside Macintosh volume V, pages 191-192]
|
||||
http://www.opensource.apple.com/source/IOHIDFamily/IOHIDFamily-421.18.3/IOHIDFamily/Cosmo_USB2ADB.c
|
||||
ADB Signaling
|
||||
http://kbdbabel.sourceforge.net/doc/kbd_signaling_pcxt_ps2_adb.pdf
|
||||
ADB Overview & History
|
||||
http://en.wikipedia.org/wiki/Apple_Desktop_Bus
|
||||
Microchip Application Note: ADB device(with code for PIC16C)
|
||||
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en011062
|
||||
AVR ATtiny2131 ADB to PS/2 converter(Japanese)
|
||||
http://hp.vector.co.jp/authors/VA000177/html/KeyBoardA5DEA5CBA5A2II.html
|
||||
|
||||
|
||||
Pinouts
|
||||
-------
|
||||
ADB female socket from the front:
|
||||
__________
|
||||
| | <--- top
|
||||
| 4o o3 |
|
||||
|2o o1|
|
||||
| == |
|
||||
|________| <--- bottom
|
||||
| | <--- 4pins
|
||||
|
||||
|
||||
ADB female socket from bottom:
|
||||
|
||||
========== <--- front
|
||||
| |
|
||||
| |
|
||||
|2o o1|
|
||||
|4o o3|
|
||||
---------- <--- back
|
||||
|
||||
1: Data
|
||||
2: Power SW(low when press Power key)
|
||||
3: Vcc(5V)
|
||||
4: GND
|
||||
|
||||
|
||||
Commands
|
||||
--------
|
||||
ADB command is 1byte and consists of 4bit-address, 2bit-command
|
||||
type and 2bit-register. The commands are always sent by Host.
|
||||
|
||||
Command format:
|
||||
7 6 5 4 3 2 1 0
|
||||
| | | |------------ address
|
||||
| |-------- command type
|
||||
| |---- register
|
||||
|
||||
bits commands
|
||||
------------------------------------------------------
|
||||
- - - - 0 0 0 0 Send Request(reset all devices)
|
||||
A A A A 0 0 0 1 Flush(reset a device)
|
||||
- - - - 0 0 1 0 Reserved
|
||||
- - - - 0 0 1 1 Reserved
|
||||
- - - - 0 1 - - Reserved
|
||||
A A A A 1 0 R R Listen(write to a device)
|
||||
A A A A 1 1 R R Talk(read from a device)
|
||||
|
||||
The command to read keycodes from keyboard is 0x2C which
|
||||
consist of keyboard address 2 and Talk against register 0.
|
||||
|
||||
Address:
|
||||
2: keyboard
|
||||
3: mice
|
||||
|
||||
Registers:
|
||||
0: application(keyboard uses this to store its data.)
|
||||
1: application
|
||||
2: application(keyboard uses this for LEDs and state of modifiers)
|
||||
3: status and command
|
||||
|
||||
|
||||
Communication
|
||||
-------------
|
||||
This is a minimum information for keyboard communication.
|
||||
See "Resources" for detail.
|
||||
|
||||
Signaling:
|
||||
|
||||
~~~~____________~~||||||||||||__~~~~~_~~|||||||||||||||__~~~~
|
||||
|
||||
|800us | |7 Command 0| | | |15-64 Data 0|Stopbit(0)
|
||||
+Attention | | | +Startbit(1)
|
||||
+Startbit(1) | +Tlt(140-260us)
|
||||
+stopbit(0)
|
||||
|
||||
Bit cells:
|
||||
|
||||
bit0: ______~~~
|
||||
65 :35us
|
||||
|
||||
bit1: ___~~~~~~
|
||||
35 :65us
|
||||
|
||||
bit0 low time: 60-70% of bit cell(42-91us)
|
||||
bit1 low time: 30-40% of bit cell(21-52us)
|
||||
bit cell time: 70-130us
|
||||
[from Apple IIgs Hardware Reference Second Edition]
|
||||
|
||||
Criterion for bit0/1:
|
||||
After 55us if line is low/high then bit is 0/1.
|
||||
|
||||
Attention & start bit:
|
||||
Host asserts low in 560-1040us then places start bit(1).
|
||||
|
||||
Tlt(Stop to Start):
|
||||
Bus stays high in 140-260us then device places start bit(1).
|
||||
|
||||
Global reset:
|
||||
Host asserts low in 2.8-5.2ms. All devices are forced to reset.
|
||||
|
||||
Service request from device(Srq):
|
||||
Device can request to send at commad(Global only?) stop bit.
|
||||
Requesting device keeps low for 140-260us at stop bit of command.
|
||||
|
||||
|
||||
Keyboard Data(Register0)
|
||||
This 16bit data can contains two keycodes and two released flags.
|
||||
First keycode is palced in upper byte. When one keyocode is sent,
|
||||
lower byte is 0xFF.
|
||||
Release flag is 1 when key is released.
|
||||
|
||||
1514 . . . . . 8 7 6 . . . . . 0
|
||||
| | | | | | | | | +-+-+-+-+-+-+- Keycode2
|
||||
| | | | | | | | +--------------- Released2(1 when the key is released)
|
||||
| +-+-+-+-+-+-+----------------- Keycode1
|
||||
+------------------------------- Released1(1 when the key is released)
|
||||
|
||||
Keycodes:
|
||||
Scancode consists of 7bit keycode and 1bit release flag.
|
||||
Device can send two keycodes at once. If just one keycode is sent
|
||||
keycode1 contains it and keyocode2 is 0xFF.
|
||||
|
||||
Power switch:
|
||||
You can read the state from PSW line(active low) however
|
||||
the switch has a special scancode 0x7F7F, so you can
|
||||
also read from Data line. It uses 0xFFFF for release scancode.
|
||||
|
||||
Keyboard LEDs & state of keys(Register2)
|
||||
This register hold current state of three LEDs and nine keys.
|
||||
The state of LEDs can be changed by sending Listen command.
|
||||
|
||||
1514 . . . . . . 7 6 5 . 3 2 1 0
|
||||
| | | | | | | | | | | | | | | +- LED1(NumLock)
|
||||
| | | | | | | | | | | | | | +--- LED2(CapsLock)
|
||||
| | | | | | | | | | | | | +----- LED3(ScrollLock)
|
||||
| | | | | | | | | | +-+-+------- Reserved
|
||||
| | | | | | | | | +------------- ScrollLock
|
||||
| | | | | | | | +--------------- NumLock
|
||||
| | | | | | | +----------------- Apple/Command
|
||||
| | | | | | +------------------- Option
|
||||
| | | | | +--------------------- Shift
|
||||
| | | | +----------------------- Control
|
||||
| | | +------------------------- Reset/Power
|
||||
| | +--------------------------- CapsLock
|
||||
| +----------------------------- Delete
|
||||
+------------------------------- Reserved
|
||||
|
||||
END_OF_ADB
|
||||
*/
|
66
tmk_core/protocol/adb.h
Normal file
66
tmk_core/protocol/adb.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
Copyright 2011 Jun WAKO <wakojun@gmail.com>
|
||||
|
||||
This software is licensed with a Modified BSD License.
|
||||
All of this is supposed to be Free Software, Open Source, DFSG-free,
|
||||
GPL-compatible, and OK to use in both free and proprietary applications.
|
||||
Additions and corrections to this file are welcome.
|
||||
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef ADB_H
|
||||
#define ADB_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if !(defined(ADB_PORT) && \
|
||||
defined(ADB_PIN) && \
|
||||
defined(ADB_DDR) && \
|
||||
defined(ADB_DATA_BIT))
|
||||
# error "ADB port setting is required in config.h"
|
||||
#endif
|
||||
|
||||
#define ADB_POWER 0x7F
|
||||
#define ADB_CAPS 0x39
|
||||
|
||||
|
||||
// ADB host
|
||||
void adb_host_init(void);
|
||||
bool adb_host_psw(void);
|
||||
uint16_t adb_host_kbd_recv(void);
|
||||
uint16_t adb_host_mouse_recv(void);
|
||||
void adb_host_listen(uint8_t cmd, uint8_t data_h, uint8_t data_l);
|
||||
void adb_host_kbd_led(uint8_t led);
|
||||
void adb_mouse_task(void);
|
||||
void adb_mouse_init(void);
|
||||
|
||||
|
||||
#endif
|
27
tmk_core/protocol/bluefruit.mk
Normal file
27
tmk_core/protocol/bluefruit.mk
Normal file
|
@ -0,0 +1,27 @@
|
|||
BLUEFRUIT_DIR = protocol/bluefruit
|
||||
PJRC_DIR = protocol/pjrc
|
||||
|
||||
SRC += $(BLUEFRUIT_DIR)/main.c \
|
||||
$(BLUEFRUIT_DIR)/bluefruit.c \
|
||||
serial_uart.c \
|
||||
$(PJRC_DIR)/pjrc.c \
|
||||
$(PJRC_DIR)/usb_keyboard.c \
|
||||
$(PJRC_DIR)/usb_debug.c \
|
||||
$(PJRC_DIR)/usb.c
|
||||
|
||||
# Option modules
|
||||
ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
|
||||
SRC += $(PJRC_DIR)/usb_mouse.c
|
||||
endif
|
||||
|
||||
ifdef EXTRAKEY_ENABLE
|
||||
SRC += $(PJRC_DIR)/usb_extra.c
|
||||
endif
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TMK_DIR)/$(BLUEFRUIT_DIR)
|
||||
#VPATH += $(TMK_DIR)/$(BLUEFRUIT_DIR)/usb_debug_only
|
||||
VPATH += $(TMK_DIR)/$(PJRC_DIR)
|
||||
|
||||
OPT_DEFS += -DPROTOCOL_BLUEFRUIT
|
||||
OPT_DEFS += -DPROTOCOL_PJRC
|
205
tmk_core/protocol/bluefruit/bluefruit.c
Normal file
205
tmk_core/protocol/bluefruit/bluefruit.c
Normal file
|
@ -0,0 +1,205 @@
|
|||
/*
|
||||
Bluefruit Protocol for TMK firmware
|
||||
Author: Benjamin Gould, 2013
|
||||
Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "host.h"
|
||||
#include "report.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "host_driver.h"
|
||||
#include "serial.h"
|
||||
#include "bluefruit.h"
|
||||
|
||||
#define BLUEFRUIT_TRACE_SERIAL 1
|
||||
|
||||
static uint8_t bluefruit_keyboard_leds = 0;
|
||||
|
||||
static void bluefruit_serial_send(uint8_t);
|
||||
|
||||
void bluefruit_keyboard_print_report(report_keyboard_t *report)
|
||||
{
|
||||
if (!debug_keyboard) return;
|
||||
dprintf("keys: "); for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) { debug_hex8(report->keys[i]); dprintf(" "); }
|
||||
dprintf(" mods: "); debug_hex8(report->mods);
|
||||
dprintf(" reserved: "); debug_hex8(report->reserved);
|
||||
dprintf("\n");
|
||||
}
|
||||
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
static void bluefruit_trace_header()
|
||||
{
|
||||
dprintf("+------------------------------------+\n");
|
||||
dprintf("| HID report to Bluefruit via serial |\n");
|
||||
dprintf("+------------------------------------+\n|");
|
||||
}
|
||||
|
||||
static void bluefruit_trace_footer()
|
||||
{
|
||||
dprintf("|\n+------------------------------------+\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void bluefruit_serial_send(uint8_t data)
|
||||
{
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
dprintf(" ");
|
||||
debug_hex8(data);
|
||||
dprintf(" ");
|
||||
#endif
|
||||
serial_send(data);
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Host driver
|
||||
*------------------------------------------------------------------*/
|
||||
|
||||
static uint8_t keyboard_leds(void);
|
||||
static void send_keyboard(report_keyboard_t *report);
|
||||
static void send_mouse(report_mouse_t *report);
|
||||
static void send_system(uint16_t data);
|
||||
static void send_consumer(uint16_t data);
|
||||
|
||||
|
||||
void sendString(char string[], int length) {
|
||||
for(int i = 0; i < length; i++) {
|
||||
serial_send(string[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static host_driver_t driver = {
|
||||
keyboard_leds,
|
||||
send_keyboard,
|
||||
send_mouse,
|
||||
send_system,
|
||||
send_consumer
|
||||
};
|
||||
|
||||
host_driver_t *bluefruit_driver(void)
|
||||
{
|
||||
return &driver;
|
||||
}
|
||||
|
||||
static uint8_t keyboard_leds(void) {
|
||||
return bluefruit_keyboard_leds;
|
||||
}
|
||||
|
||||
static void send_keyboard(report_keyboard_t *report)
|
||||
{
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
bluefruit_trace_header();
|
||||
#endif
|
||||
bluefruit_serial_send(0xFD);
|
||||
for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
|
||||
|
||||
bluefruit_serial_send(report->raw[i]);
|
||||
}
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
bluefruit_trace_footer();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void send_mouse(report_mouse_t *report)
|
||||
{
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
bluefruit_trace_header();
|
||||
#endif
|
||||
bluefruit_serial_send(0xFD);
|
||||
bluefruit_serial_send(0x00);
|
||||
bluefruit_serial_send(0x03);
|
||||
bluefruit_serial_send(report->buttons);
|
||||
bluefruit_serial_send(report->x);
|
||||
bluefruit_serial_send(report->y);
|
||||
bluefruit_serial_send(report->v); // should try sending the wheel v here
|
||||
bluefruit_serial_send(report->h); // should try sending the wheel h here
|
||||
bluefruit_serial_send(0x00);
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
bluefruit_trace_footer();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void send_system(uint16_t data)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
+-----------------+-------------------+-------+
|
||||
| Consumer Key | Bit Map | Hex |
|
||||
+-----------------+-------------------+-------+
|
||||
| Home | 00000001 00000000 | 01 00 |
|
||||
| KeyboardLayout | 00000010 00000000 | 02 00 |
|
||||
| Search | 00000100 00000000 | 04 00 |
|
||||
| Snapshot | 00001000 00000000 | 08 00 |
|
||||
| VolumeUp | 00010000 00000000 | 10 00 |
|
||||
| VolumeDown | 00100000 00000000 | 20 00 |
|
||||
| Play/Pause | 01000000 00000000 | 40 00 |
|
||||
| Fast Forward | 10000000 00000000 | 80 00 |
|
||||
| Rewind | 00000000 00000001 | 00 01 |
|
||||
| Scan Next Track | 00000000 00000010 | 00 02 |
|
||||
| Scan Prev Track | 00000000 00000100 | 00 04 |
|
||||
| Random Play | 00000000 00001000 | 00 08 |
|
||||
| Stop | 00000000 00010000 | 00 10 |
|
||||
+-------------------------------------+-------+
|
||||
*/
|
||||
#define CONSUMER2BLUEFRUIT(usage) \
|
||||
(usage == AUDIO_MUTE ? 0x0000 : \
|
||||
(usage == AUDIO_VOL_UP ? 0x1000 : \
|
||||
(usage == AUDIO_VOL_DOWN ? 0x2000 : \
|
||||
(usage == TRANSPORT_NEXT_TRACK ? 0x0002 : \
|
||||
(usage == TRANSPORT_PREV_TRACK ? 0x0004 : \
|
||||
(usage == TRANSPORT_STOP ? 0x0010 : \
|
||||
(usage == TRANSPORT_STOP_EJECT ? 0x0000 : \
|
||||
(usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : \
|
||||
(usage == AL_CC_CONFIG ? 0x0000 : \
|
||||
(usage == AL_EMAIL ? 0x0000 : \
|
||||
(usage == AL_CALCULATOR ? 0x0000 : \
|
||||
(usage == AL_LOCAL_BROWSER ? 0x0000 : \
|
||||
(usage == AC_SEARCH ? 0x0400 : \
|
||||
(usage == AC_HOME ? 0x0100 : \
|
||||
(usage == AC_BACK ? 0x0000 : \
|
||||
(usage == AC_FORWARD ? 0x0000 : \
|
||||
(usage == AC_STOP ? 0x0000 : \
|
||||
(usage == AC_REFRESH ? 0x0000 : \
|
||||
(usage == AC_BOOKMARKS ? 0x0000 : 0)))))))))))))))))))
|
||||
|
||||
static void send_consumer(uint16_t data)
|
||||
{
|
||||
static uint16_t last_data = 0;
|
||||
if (data == last_data) return;
|
||||
last_data = data;
|
||||
|
||||
uint16_t bitmap = CONSUMER2BLUEFRUIT(data);
|
||||
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
dprintf("\nData: ");
|
||||
debug_hex16(data);
|
||||
dprintf("; bitmap: ");
|
||||
debug_hex16(bitmap);
|
||||
dprintf("\n");
|
||||
bluefruit_trace_header();
|
||||
#endif
|
||||
bluefruit_serial_send(0xFD);
|
||||
bluefruit_serial_send(0x00);
|
||||
bluefruit_serial_send(0x02);
|
||||
bluefruit_serial_send((bitmap>>8)&0xFF);
|
||||
bluefruit_serial_send(bitmap&0xFF);
|
||||
bluefruit_serial_send(0x00);
|
||||
bluefruit_serial_send(0x00);
|
||||
bluefruit_serial_send(0x00);
|
||||
bluefruit_serial_send(0x00);
|
||||
#ifdef BLUEFRUIT_TRACE_SERIAL
|
||||
bluefruit_trace_footer();
|
||||
#endif
|
||||
}
|
25
tmk_core/protocol/bluefruit/bluefruit.h
Normal file
25
tmk_core/protocol/bluefruit/bluefruit.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
Bluefruit Protocol for TMK firmware
|
||||
Author: Benjamin Gould, 2013
|
||||
Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef VUSB_H
|
||||
#define VUSB_H
|
||||
|
||||
#include "host_driver.h"
|
||||
|
||||
|
||||
host_driver_t *bluefruit_driver(void);
|
||||
|
||||
#endif
|
138
tmk_core/protocol/bluefruit/main.c
Normal file
138
tmk_core/protocol/bluefruit/main.c
Normal file
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
Bluefruit Protocol for TMK firmware
|
||||
Author: Benjamin Gould, 2013
|
||||
Based on code Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <util/delay.h>
|
||||
#include "../serial.h"
|
||||
#include "keyboard.h"
|
||||
#include "usb.h"
|
||||
#include "host.h"
|
||||
#include "timer.h"
|
||||
#include "print.h"
|
||||
#include "debug.h"
|
||||
#include "sendchar.h"
|
||||
#include "suspend.h"
|
||||
#include "bluefruit.h"
|
||||
#include "pjrc.h"
|
||||
|
||||
#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
|
||||
|
||||
#define HOST_DRIVER_NOT_SET 0
|
||||
#define BLUEFRUIT_HOST_DRIVER 1
|
||||
#define PJRC_HOST_DRIVER 2
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
CPU_PRESCALE(0);
|
||||
|
||||
// DDRD = _BV(PD5);
|
||||
// DDRB = _BV(PB0);
|
||||
|
||||
// PORTD = _BV(PD5);
|
||||
// PORTB = _BV(PB0);
|
||||
|
||||
print_set_sendchar(sendchar);
|
||||
|
||||
// usb_init();
|
||||
// _delay_ms(2000);
|
||||
// while (!usb_configured()) /* wait */
|
||||
|
||||
|
||||
|
||||
dprintf("Initializing keyboard...\n");
|
||||
keyboard_init();
|
||||
|
||||
// This implementation is pretty simplistic... if the USB connection
|
||||
// is not configured, choose the Bluefruit, otherwise use USB
|
||||
// Definitely would prefer to have this driven by an input pin and make
|
||||
// it switch dynamically - BCG
|
||||
// if (!usb_configured()) {
|
||||
|
||||
// // Send power to Bluefruit... Adafruit says it takes 27 mA, I think
|
||||
// // the pins should provide 40 mA, but just in case I switch the
|
||||
// // Bluefruit using a transistor - BCG
|
||||
// DDRB = _BV(PB6);
|
||||
// PORTB |= _BV(PB6);
|
||||
|
||||
dprintf("Setting host driver to bluefruit...\n");
|
||||
host_set_driver(bluefruit_driver());
|
||||
|
||||
dprintf("Initializing serial...\n");
|
||||
serial_init();
|
||||
|
||||
// char swpa[] = "+++\r\n";
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// serial_send(swpa[i]);
|
||||
// }
|
||||
|
||||
// char ble_enable[] = "AT+BLEKEYBOARDEN=1\r\n";
|
||||
// for (int i = 0; i < 20; i++) {
|
||||
// serial_send(ble_enable[i]);
|
||||
// }
|
||||
|
||||
// char reset[] = "ATZ\r\n";
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// serial_send(reset[i]);
|
||||
// }
|
||||
|
||||
// for (int i = 0; i < 5; i++) {
|
||||
// serial_send(swpa[i]);
|
||||
// }
|
||||
|
||||
// wait an extra second for the PC's operating system
|
||||
// to load drivers and do whatever it does to actually
|
||||
// be ready for input
|
||||
_delay_ms(1000);
|
||||
// PORTD = ~_BV(PD5);
|
||||
dprintf("Starting main loop");
|
||||
while (1) {
|
||||
keyboard_task();
|
||||
}
|
||||
|
||||
// } else {
|
||||
|
||||
// // I'm not smart enough to get this done with LUFA - BCG
|
||||
// dprintf("Setting host driver to PJRC...\n");
|
||||
// host_set_driver(pjrc_driver());
|
||||
// #ifdef SLEEP_LED_ENABLE
|
||||
// sleep_led_init();
|
||||
// #endif
|
||||
// // wait an extra second for the PC's operating system
|
||||
// // to load drivers and do whatever it does to actually
|
||||
// // be ready for input
|
||||
// _delay_ms(1000);
|
||||
// PORTB = ~_BV(PB0);
|
||||
// dprintf("Starting main loop");
|
||||
// while (1) {
|
||||
// while (suspend) {
|
||||
// suspend_power_down();
|
||||
// if (remote_wakeup && suspend_wakeup_condition()) {
|
||||
// usb_remote_wakeup();
|
||||
// }
|
||||
// }
|
||||
// keyboard_task();
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
189
tmk_core/protocol/ibm4704.c
Normal file
189
tmk_core/protocol/ibm4704.c
Normal file
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
Copyright 2010,2011,2012,2013 Jun WAKO <wakojun@gmail.com>
|
||||
*/
|
||||
#include <stdbool.h>
|
||||
#include <util/delay.h>
|
||||
#include "debug.h"
|
||||
#include "ring_buffer.h"
|
||||
#include "ibm4704.h"
|
||||
|
||||
|
||||
#define WAIT(stat, us, err) do { \
|
||||
if (!wait_##stat(us)) { \
|
||||
ibm4704_error = err; \
|
||||
goto ERROR; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
uint8_t ibm4704_error = 0;
|
||||
|
||||
|
||||
void ibm4704_init(void)
|
||||
{
|
||||
inhibit(); // keep keyboard from sending
|
||||
IBM4704_INT_INIT();
|
||||
IBM4704_INT_ON();
|
||||
idle(); // allow keyboard sending
|
||||
}
|
||||
|
||||
/*
|
||||
Host to Keyboard
|
||||
----------------
|
||||
Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
|
||||
|
||||
____ __ __ __ __ __ __ __ __ __ ________
|
||||
Clock \______/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
|
||||
^ ____ ____ ____ ____ ____ ____ ____ ____ ____ ____ ___
|
||||
Data ____|__/ X____X____X____X____X____X____X____X____X____X \___
|
||||
| Start 0 1 2 3 4 5 6 7 P Stop
|
||||
Request by host
|
||||
|
||||
Start bit: can be long as 300-350us.
|
||||
Request: Host pulls Clock line down to request to send a command.
|
||||
Timing: After Request keyboard pull up Data and down Clock line to low for start bit.
|
||||
After request host release Clock line once Data line becomes hi.
|
||||
Host writes a bit while Clock is hi and Keyboard reads while low.
|
||||
Stop bit: Host releases or pulls up Data line to hi after 9th clock and waits for keyboard pull down the line to lo.
|
||||
*/
|
||||
uint8_t ibm4704_send(uint8_t data)
|
||||
{
|
||||
bool parity = true; // odd parity
|
||||
ibm4704_error = 0;
|
||||
|
||||
IBM4704_INT_OFF();
|
||||
|
||||
/* Request to send */
|
||||
idle();
|
||||
clock_lo();
|
||||
|
||||
/* wait for Start bit(Clock:lo/Data:hi) */
|
||||
WAIT(data_hi, 300, 0x30);
|
||||
|
||||
/* Data bit */
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
WAIT(clock_hi, 100, 0x40+i);
|
||||
if (data&(1<<i)) {
|
||||
parity = !parity;
|
||||
data_hi();
|
||||
} else {
|
||||
data_lo();
|
||||
}
|
||||
WAIT(clock_lo, 100, 0x48+i);
|
||||
}
|
||||
|
||||
/* Parity bit */
|
||||
WAIT(clock_hi, 100, 0x34);
|
||||
if (parity) { data_hi(); } else { data_lo(); }
|
||||
WAIT(clock_lo, 100, 0x35);
|
||||
|
||||
/* Stop bit */
|
||||
WAIT(clock_hi, 100, 0x34);
|
||||
data_hi();
|
||||
|
||||
/* End */
|
||||
WAIT(data_lo, 100, 0x36);
|
||||
|
||||
idle();
|
||||
IBM4704_INT_ON();
|
||||
return 0;
|
||||
ERROR:
|
||||
idle();
|
||||
if (ibm4704_error > 0x30) {
|
||||
xprintf("S:%02X ", ibm4704_error);
|
||||
}
|
||||
IBM4704_INT_ON();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* wait forever to receive data */
|
||||
uint8_t ibm4704_recv_response(void)
|
||||
{
|
||||
while (!rbuf_has_data()) {
|
||||
_delay_ms(1);
|
||||
}
|
||||
return rbuf_dequeue();
|
||||
}
|
||||
|
||||
uint8_t ibm4704_recv(void)
|
||||
{
|
||||
if (rbuf_has_data()) {
|
||||
return rbuf_dequeue();
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Keyboard to Host
|
||||
----------------
|
||||
Data bits are LSB first and Parity is odd. Clock has around 60us high and 30us low part.
|
||||
|
||||
____ __ __ __ __ __ __ __ __ __ _______
|
||||
Clock \_____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/
|
||||
____ ____ ____ ____ ____ ____ ____ ____ ____ ____
|
||||
Data ____/ X____X____X____X____X____X____X____X____X____X________
|
||||
Start 0 1 2 3 4 5 6 7 P Stop
|
||||
|
||||
Start bit: can be long as 300-350us.
|
||||
Inhibit: Pull Data line down to inhibit keyboard to send.
|
||||
Timing: Host reads bit while Clock is hi.(rising edge)
|
||||
Stop bit: Keyboard pulls down Data line to lo after 9th clock.
|
||||
*/
|
||||
ISR(IBM4704_INT_VECT)
|
||||
{
|
||||
static enum {
|
||||
BIT0, BIT1, BIT2, BIT3, BIT4, BIT5, BIT6, BIT7, PARITY, STOP
|
||||
} state = BIT0;
|
||||
// LSB first
|
||||
static uint8_t data = 0;
|
||||
// Odd parity
|
||||
static uint8_t parity = false;
|
||||
|
||||
ibm4704_error = 0;
|
||||
|
||||
switch (state) {
|
||||
case BIT0:
|
||||
case BIT1:
|
||||
case BIT2:
|
||||
case BIT3:
|
||||
case BIT4:
|
||||
case BIT5:
|
||||
case BIT6:
|
||||
case BIT7:
|
||||
data >>= 1;
|
||||
if (data_in()) {
|
||||
data |= 0x80;
|
||||
parity = !parity;
|
||||
}
|
||||
break;
|
||||
case PARITY:
|
||||
if (data_in()) {
|
||||
parity = !parity;
|
||||
}
|
||||
if (!parity)
|
||||
goto ERROR;
|
||||
break;
|
||||
case STOP:
|
||||
// Data:Low
|
||||
WAIT(data_lo, 100, state);
|
||||
rbuf_enqueue(data);
|
||||
ibm4704_error = IBM4704_ERR_NONE;
|
||||
goto DONE;
|
||||
break;
|
||||
default:
|
||||
goto ERROR;
|
||||
}
|
||||
state++;
|
||||
goto RETURN;
|
||||
ERROR:
|
||||
ibm4704_error = state;
|
||||
while (ibm4704_send(0xFE)) _delay_ms(1); // resend
|
||||
xprintf("R:%02X%02X\n", state, data);
|
||||
DONE:
|
||||
state = BIT0;
|
||||
data = 0;
|
||||
parity = false;
|
||||
RETURN:
|
||||
return;
|
||||
}
|
110
tmk_core/protocol/ibm4704.h
Normal file
110
tmk_core/protocol/ibm4704.h
Normal file
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
Copyright 2014 Jun WAKO <wakojun@gmail.com>
|
||||
*/
|
||||
#ifndef IBM4704_H
|
||||
#define IBM4704_H
|
||||
|
||||
#define IBM4704_ERR_NONE 0
|
||||
#define IBM4704_ERR_PARITY 0x70
|
||||
|
||||
|
||||
void ibm4704_init(void);
|
||||
uint8_t ibm4704_send(uint8_t data);
|
||||
uint8_t ibm4704_recv_response(void);
|
||||
uint8_t ibm4704_recv(void);
|
||||
|
||||
|
||||
/* Check pin configuration */
|
||||
#if !(defined(IBM4704_CLOCK_PORT) && \
|
||||
defined(IBM4704_CLOCK_PIN) && \
|
||||
defined(IBM4704_CLOCK_DDR) && \
|
||||
defined(IBM4704_CLOCK_BIT))
|
||||
# error "ibm4704 clock pin configuration is required in config.h"
|
||||
#endif
|
||||
|
||||
#if !(defined(IBM4704_DATA_PORT) && \
|
||||
defined(IBM4704_DATA_PIN) && \
|
||||
defined(IBM4704_DATA_DDR) && \
|
||||
defined(IBM4704_DATA_BIT))
|
||||
# error "ibm4704 data pin configuration is required in config.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* static functions
|
||||
*------------------------------------------------------------------*/
|
||||
static inline void clock_lo(void)
|
||||
{
|
||||
IBM4704_CLOCK_PORT &= ~(1<<IBM4704_CLOCK_BIT);
|
||||
IBM4704_CLOCK_DDR |= (1<<IBM4704_CLOCK_BIT);
|
||||
}
|
||||
static inline void clock_hi(void)
|
||||
{
|
||||
/* input with pull up */
|
||||
IBM4704_CLOCK_DDR &= ~(1<<IBM4704_CLOCK_BIT);
|
||||
IBM4704_CLOCK_PORT |= (1<<IBM4704_CLOCK_BIT);
|
||||
}
|
||||
static inline bool clock_in(void)
|
||||
{
|
||||
IBM4704_CLOCK_DDR &= ~(1<<IBM4704_CLOCK_BIT);
|
||||
IBM4704_CLOCK_PORT |= (1<<IBM4704_CLOCK_BIT);
|
||||
_delay_us(1);
|
||||
return IBM4704_CLOCK_PIN&(1<<IBM4704_CLOCK_BIT);
|
||||
}
|
||||
static inline void data_lo(void)
|
||||
{
|
||||
IBM4704_DATA_PORT &= ~(1<<IBM4704_DATA_BIT);
|
||||
IBM4704_DATA_DDR |= (1<<IBM4704_DATA_BIT);
|
||||
}
|
||||
static inline void data_hi(void)
|
||||
{
|
||||
/* input with pull up */
|
||||
IBM4704_DATA_DDR &= ~(1<<IBM4704_DATA_BIT);
|
||||
IBM4704_DATA_PORT |= (1<<IBM4704_DATA_BIT);
|
||||
}
|
||||
static inline bool data_in(void)
|
||||
{
|
||||
IBM4704_DATA_DDR &= ~(1<<IBM4704_DATA_BIT);
|
||||
IBM4704_DATA_PORT |= (1<<IBM4704_DATA_BIT);
|
||||
_delay_us(1);
|
||||
return IBM4704_DATA_PIN&(1<<IBM4704_DATA_BIT);
|
||||
}
|
||||
|
||||
static inline uint16_t wait_clock_lo(uint16_t us)
|
||||
{
|
||||
while (clock_in() && us) { asm(""); _delay_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
static inline uint16_t wait_clock_hi(uint16_t us)
|
||||
{
|
||||
while (!clock_in() && us) { asm(""); _delay_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
static inline uint16_t wait_data_lo(uint16_t us)
|
||||
{
|
||||
while (data_in() && us) { asm(""); _delay_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
static inline uint16_t wait_data_hi(uint16_t us)
|
||||
{
|
||||
while (!data_in() && us) { asm(""); _delay_us(1); us--; }
|
||||
return us;
|
||||
}
|
||||
|
||||
/* idle state that device can send */
|
||||
static inline void idle(void)
|
||||
{
|
||||
clock_hi();
|
||||
data_hi();
|
||||
}
|
||||
|
||||
/* inhibit device to send
|
||||
* keyboard checks Data line on start bit(Data:hi) and it stops sending if Data line is low.
|
||||
*/
|
||||
static inline void inhibit(void)
|
||||
{
|
||||
clock_hi();
|
||||
data_lo();
|
||||
}
|
||||
|
||||
#endif
|
26
tmk_core/protocol/iwrap.mk
Normal file
26
tmk_core/protocol/iwrap.mk
Normal file
|
@ -0,0 +1,26 @@
|
|||
IWRAP_DIR = protocol/iwrap
|
||||
|
||||
OPT_DEFS += -DPROTOCOL_IWRAP
|
||||
|
||||
SRC += $(IWRAP_DIR)/main.c \
|
||||
$(IWRAP_DIR)/iwrap.c \
|
||||
$(IWRAP_DIR)/suart.S \
|
||||
$(COMMON_DIR)/sendchar_uart.c \
|
||||
$(COMMON_DIR)/uart.c
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TMK_DIR)/protocol/iwrap
|
||||
|
||||
|
||||
# TODO: compatible with LUFA and PJRC
|
||||
# V-USB
|
||||
#
|
||||
VUSB_DIR = protocol/vusb
|
||||
OPT_DEFS += -DPROTOCOL_VUSB
|
||||
SRC += $(VUSB_DIR)/vusb.c \
|
||||
$(VUSB_DIR)/usbdrv/usbdrv.c \
|
||||
$(VUSB_DIR)/usbdrv/usbdrvasm.S \
|
||||
$(VUSB_DIR)/usbdrv/oddebug.c
|
||||
VPATH += $(TMK_DIR)/protocol/vusb:$(TMK_DIR)/protocol/vusb/usbdrv
|
||||
|
||||
|
376
tmk_core/protocol/iwrap/iWRAP4.txt
Normal file
376
tmk_core/protocol/iwrap/iWRAP4.txt
Normal file
|
@ -0,0 +1,376 @@
|
|||
Bulegiga WT12
|
||||
=============
|
||||
WT12 is a bluetooth module from Bluegiga. http://www.bluegiga.com/
|
||||
|
||||
iWRAP
|
||||
higher layer interface for bluetooth firmware
|
||||
communicate with UART
|
||||
|
||||
iWRAP HID
|
||||
default setting
|
||||
115200 8bit/n/1/n
|
||||
|
||||
|
||||
TODO
|
||||
----
|
||||
KiCAD circuit/PCB design
|
||||
power saving
|
||||
AVR sleep(15ms by watch dog timer)
|
||||
WT12 sleep
|
||||
measuring current consumption
|
||||
measuring battery life of normal usage/idle/intensive usage
|
||||
software reset/bootloarder
|
||||
LED indicator(chaging/paring/connecting)
|
||||
license confirmation of suart.c
|
||||
consumer page is not working
|
||||
authenticate method/SSP
|
||||
SPP keyboard support
|
||||
SPP debug console support
|
||||
mouse wheel feature request to Bluegiga
|
||||
|
||||
|
||||
Problems
|
||||
--------
|
||||
power consumption
|
||||
no consumer page support(bug?)
|
||||
no mouse wheel support
|
||||
no paring management
|
||||
no interactive auth method
|
||||
|
||||
|
||||
UART hardware flow control
|
||||
--------------------------
|
||||
(iWRAP4 User Guide 9.5)
|
||||
Hardware flow control is enabled by default and it should not be disabled unless mandatory, because without the hardware flow control the data transmission may not be reliable.
|
||||
If the hardware flow control is enabled from PS-keys, but no flow control is used, the following steps should be implemented in the hardware design:
|
||||
- CTS pin must be grounded
|
||||
- RTS pin must be left floating
|
||||
|
||||
|
||||
Power Saving
|
||||
------------
|
||||
power consume
|
||||
without opimization: 4hr to shutdown(310mAh)
|
||||
2011/08/25: 9hr(310mAh) SNIFF MASTER sleep/WDTO_120MS
|
||||
|
||||
measure current consumption
|
||||
HHKB keyswitch matrix board
|
||||
idle
|
||||
scanning
|
||||
Bluegiga WT12 module
|
||||
SLEEP command
|
||||
deep sleep on/off in config bits
|
||||
|
||||
HHKB keyswich
|
||||
how to power off
|
||||
I/O pin configuration when sleeping
|
||||
FET switch for 5V regulator
|
||||
|
||||
Bluetooth module
|
||||
power off when in USB mode
|
||||
power off by FET switch
|
||||
|
||||
AVR configuration
|
||||
unused pins
|
||||
ADC
|
||||
|
||||
|
||||
|
||||
SET CONTROL CONFIG
|
||||
------------------
|
||||
SET CONTROL CONFIG 4810
|
||||
SET CONTROL CONFIG LIST
|
||||
SET CONTROL CONFIG 0000 0000 4910 DEEP_SLEEP KLUDGE INTERACTIVE_PIN UART_LATENCY
|
||||
|
||||
Bit14 UART low latency
|
||||
Bit11 Interactive pairing mode
|
||||
Bit04 Deep sleep
|
||||
|
||||
|
||||
Reconnection
|
||||
------------
|
||||
SET CONTROL AUTOCALL 1124 5000 HID
|
||||
1124 HID service class
|
||||
5000 interval ms
|
||||
|
||||
HID profile
|
||||
-----------
|
||||
This is needed to configure only once.
|
||||
SET PROFILE HID ON
|
||||
RESET
|
||||
|
||||
HID class
|
||||
---------
|
||||
SET BT CLASS 005C0 // keyboard/mouse combined devie
|
||||
|
||||
Pairing Security
|
||||
----------------
|
||||
Secure Simple Pairing(SSP)
|
||||
SET BT SSP 2 0 // Enables SSP for keyboard and Man-in-the-middle protection
|
||||
SET BT SSP 3 0 // Enables SSP just works mode
|
||||
|
||||
for keyboard with SSP
|
||||
SET BT AUTH * 0000
|
||||
SET BT SSP 2 0
|
||||
SET CONTROL CONFIG 800
|
||||
RESET
|
||||
|
||||
for keyboard without SSP
|
||||
SET BT AUTH * 0000
|
||||
SET CONTROL CONFIG 800
|
||||
RESET
|
||||
|
||||
AUTH
|
||||
AUTH xx:xx:xx:xx:xx:xx? // Pairing request event
|
||||
AUTH xx:xx:xx:xx:xx:xx 0000
|
||||
|
||||
SSP PASSKEY 78:dd:08:b7:e4:a2 ?
|
||||
SSP PASSKEY 78:dd:08:b7:e4:a2 xxxxx
|
||||
(SSP COMPLETE 78:dd:08:b7:e4:a2 HCI_ERROR_AUTH_FAIL // failed)
|
||||
RING 0 78:dd:08:b7:e4:a2 11 HID
|
||||
|
||||
Connecton
|
||||
RING xx:xx:xx:xx:xx:xx xx HID // connection event
|
||||
|
||||
KILL xx:xx:xx:xx:xx:xx
|
||||
|
||||
Mode
|
||||
----
|
||||
Command mode
|
||||
Data mode
|
||||
Raw mode
|
||||
(Simple mode not for a real keyboard)
|
||||
|
||||
Raw mode
|
||||
Keyboard:
|
||||
0x9f, length(10), 0xa1, 0x01, mods, 0x00, key1, key2, key3, key4, key5, key6
|
||||
|
||||
Mouse:
|
||||
0x9f, length(5), 0xa1, 0x02, buttons, X, Y
|
||||
|
||||
Consumer page:
|
||||
0x9f, length(5), 0xa1, 0x03, bitfield1, bitfield2, bitfield3
|
||||
|
||||
consumer page suage
|
||||
Bitfield 1:
|
||||
0x01 Volume Increment
|
||||
0x02 Volume Decrement
|
||||
0x04 Mute
|
||||
0x08 Play/Pause
|
||||
0x10 Scan Next Track
|
||||
0x20 Scan Previous Track
|
||||
0x40 Stop
|
||||
0x80 Eject
|
||||
Bitfield 2:
|
||||
0x01 Email Reader
|
||||
0x02 Application Control Search
|
||||
0x04 AC Bookmarks
|
||||
0x08 AC Home
|
||||
0x10 AC Back
|
||||
0x20 AC Forward
|
||||
0x40 AC Stop
|
||||
0x80 AC Refresh
|
||||
Bitfield 3:
|
||||
0x01 Application Launch Generic Consumer Control
|
||||
0x02 AL Internet Browser
|
||||
0x04 AL Calculator
|
||||
0x08 AL Terminal Lock / Screensaver
|
||||
0x10 AL Local Machine Browser
|
||||
0x20 AC Minimize
|
||||
0x40 Record
|
||||
0x80 Rewind
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
2011/07/13
|
||||
set
|
||||
SET BT BDADDR 00:07:80:47:22:14
|
||||
SET BT NAME HHKB pro BT
|
||||
SET BT CLASS 0005c0
|
||||
SET BT AUTH * 0000
|
||||
SET BT IDENT BT:47 f000 4.1.0 Bluegiga iWRAP
|
||||
SET BT LAP 9e8b33
|
||||
SET BT PAGEMODE 4 2000 1
|
||||
SET BT PAIR 78:dd:08:b7:e4:a2 a191189cd7e51030ad6a07848ce879bb
|
||||
SET BT POWER 3 3 3
|
||||
SET BT ROLE 0 f 7d00
|
||||
SET BT SNIFF 0 20 1 8
|
||||
SET BT SSP 2 1
|
||||
SET BT MTU 667
|
||||
SET CONTROL AUTOCALL 1124 3000 HID
|
||||
SET CONTROL BAUD 38400,8n1
|
||||
SET CONTROL CD 00 0
|
||||
SET CONTROL ECHO 7
|
||||
SET CONTROL ESCAPE 43 00 1
|
||||
SET CONTROL GAIN 0 5
|
||||
SET CONTROL INIT SET CONTROL MUX 0
|
||||
SET CONTROL MSC DTE 00 00 00 00 00 00
|
||||
SET CONTROL MUX 1
|
||||
SET CONTROL PIO 00 00
|
||||
SET CONTROL READY 00
|
||||
SET PROFILE HID f HID
|
||||
SET
|
||||
|
||||
info config
|
||||
|
||||
!!! THIS IS BETA RELEASE AND MAY BE USED FOR EVALUATION PURPOSES ONLY !!!
|
||||
|
||||
WRAP THOR AI (4.1.0 build 435)
|
||||
Copyright (c) 2003-2011 Bluegiga Technologies Inc.
|
||||
Compiled on Jun 28 2011 17:19:51, running on WT12-A module, psr v31
|
||||
AVRCP BGIO FTP HFP HFP_AG HID HID_CONSUMER_PAGE HSP LEDS MAP OTA PBAP PIO=0x00fc SSP SUBRATE TEST VOLUME
|
||||
- BOCK3 version 435 (Jun 28 2011 17:19:37) (max acl/sco 7/1)
|
||||
- Bluetooth version 2.1, Power class 2
|
||||
- Loader 4279, firmware 6297 (56-bit encryption), native execution mode
|
||||
- up 0 days, 06:23, 2 connections (pool 2)
|
||||
- User configuration:
|
||||
&028a = 0001 0000 0000 0011 0024 0000 0000 0010 0000 0080 0000 0000 0080 005f 009b 0034 00fb 0006
|
||||
&028b = 0000 0bb8
|
||||
&028d = 0001
|
||||
&0295 = 0000 0005 000b 0000 0003 0000 0000 0000 0000 0000 0000
|
||||
&0298 = a006
|
||||
&0299 = 0000 0000
|
||||
&02a3 = 0030 0030 0030 0030
|
||||
&02a4 = 009d 0000
|
||||
&02a5 = 0053 0045 0054 0020 0043 004f 004e 0054 0052 004f 004c 0020 004d 0055 0058 0020 0030
|
||||
&02a7 = 0000 05c0
|
||||
&02a8 = 4910 0000 0000
|
||||
&02aa = 0004 2000 0001 0033 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
|
||||
&02ac = 0000 0000 002b 0000 0000 0000 0000 0000 0000 0000 0002 0000 0000 0000 0010 0000 0000 0000 0000 029b 0000 0000 0000 0000
|
||||
&02ad = 4848 424b 7020 6f72 4220 0054
|
||||
&02b3 = 0005 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003
|
||||
&02b7 = 000f 4948 0044
|
||||
&02bb = 8000
|
||||
READY.
|
||||
|
||||
|
||||
|
||||
|
||||
2011/07/07 settings:
|
||||
set
|
||||
SET BT BDADDR 00:07:80:47:22:14
|
||||
SET BT NAME HHKB Pro BT
|
||||
SET BT CLASS 0005c0
|
||||
SET BT AUTH * 000
|
||||
SET BT IDENT BT:47 f000 4.0.0 Bluegiga iWRAP
|
||||
SET BT LAP 9e8b33
|
||||
SET BT PAGEMODE 4 2000 1
|
||||
SET BT PAIR 78:dd:08:b7:e4:a2 9e54d0aabb1b4d73cfccddb1ea4ef2d6
|
||||
SET BT POWER 3 3 3
|
||||
SET BT ROLE 0 f 7d00
|
||||
SET BT SNIFF 0 20 1 8
|
||||
SET BT SSP 3 0
|
||||
SET BT MTU 667
|
||||
SET CONTROL BAUD 38400,8n1
|
||||
SET CONTROL CD 00 0
|
||||
SET CONTROL ECHO 7
|
||||
SET CONTROL ESCAPE 255 00 1
|
||||
SET CONTROL GAIN 0 5
|
||||
SET CONTROL INIT set control mux 0
|
||||
SET CONTROL MSC DTE 00 00 00 00 00 00
|
||||
SET CONTROL PREAMP 1 1
|
||||
SET CONTROL READY 00
|
||||
SET PROFILE HID HID
|
||||
SET PROFILE SPP Bluetooth Serial Port
|
||||
SET
|
||||
|
||||
info config
|
||||
WRAP THOR AI (4.0.0 build 317)
|
||||
Copyright (c) 2003-2010 Bluegiga Technologies Inc.
|
||||
Compiled on Apr 20 2010 16:44:28, running on WT12-A module, psr v31
|
||||
AVRCP FTP PBAP PIO=0x00fc SSP SUBRATE VOLUME
|
||||
- BOCK3 version 317 (Apr 20 2010 16:44:21) (max acl/sco 7/1)
|
||||
- Bluetooth version 2.1, Power class 2
|
||||
- Loader 4279, firmware 6297 (56-bit encryption), native execution mode
|
||||
- up 0 days, 00:00, 0 connections (pool 1)
|
||||
- User configuration:
|
||||
&028c = 0001 0020 0000 0001 0008 0000
|
||||
&028d = 0000
|
||||
&0296 = 0047 0001 f000 0400 6c42 6575 6967 6167 6920 5257 5041
|
||||
&0298 = c006
|
||||
&02a3 = 0030 0030 0030
|
||||
&02a4 = 009d 0000
|
||||
&02a5 = 0073 0065 0074 0020 0063 006f 006e 0074 0072 006f 006c 0020 006d 0075 0078 0020 0030
|
||||
&02a7 = 0000 05c0
|
||||
&02a8 = 0800 0000 0000
|
||||
&02ac = 0000 0000 00ff 0000 0000 0000 0000 0000 0000 0000 0002 0000 0000 0000 0010 0000 0000 0000 0000 029b 0000 0000 0000 0000
|
||||
&02ad = 4848 424b 5020 6f72 4220 0054
|
||||
&02b3 = 0004 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003
|
||||
&02b7 = 0000
|
||||
&02bb = 6c42 6575 6f74 746f 2068 6553 6972 6c61 5020 726f 0074
|
||||
READY.
|
||||
|
||||
|
||||
|
||||
2011/08/23:
|
||||
SET BT BDADDR 00:07:80:47:22:14
|
||||
SET BT NAME HHKB pro BT
|
||||
SET BT CLASS 0005c0
|
||||
SET BT AUTH * 0000
|
||||
SET BT IDENT BT:47 f000 4.1.0 Bluegiga iWRAP
|
||||
SET BT LAP 9e8b33
|
||||
SET BT PAGEMODE 4 2000 1
|
||||
SET BT PAIRCOUNT 4
|
||||
SET BT POWER 3 3 3
|
||||
SET BT ROLE 1 f 12c0
|
||||
SET BT SNIFF 10 2 1 8
|
||||
SET BT SSP 3 0
|
||||
SET BT MTU 667
|
||||
SET CONTROL BAUD 38400,8n1
|
||||
SET CONTROL CD 00 0
|
||||
SET CONTROL ECHO 7
|
||||
SET CONTROL ESCAPE 43 00 1
|
||||
SET CONTROL GAIN 0 5
|
||||
SET CONTROL INIT SET CONTROL MUX 0
|
||||
SET CONTROL MSC DTE 00 00 00 00 00 00
|
||||
SET CONTROL MUX 1
|
||||
SET CONTROL PIO 00 00
|
||||
SET CONTROL READY 00
|
||||
SET PROFILE HID 7 HIDKeyboardMouse
|
||||
SET
|
||||
|
||||
SET CONTROL CONFIG 0000 0004 481e CLOCK_CACHE INTERLACED_INQ INTERLACED_PAGE DEEP_SLEEP INTERACTIVE_PIN UART_LATENCY 23D_NOKLUDGE
|
||||
|
||||
|
||||
|
||||
2011/08/25:
|
||||
SET BT BDADDR 00:07:80:47:22:14
|
||||
SET BT NAME HHKB pro BT
|
||||
SET BT CLASS 0005c0
|
||||
|
||||
SET BT IDENT BT:47 f000 4.1.0 Bluegiga iWRAP
|
||||
SET BT LAP 9e8b33
|
||||
SET BT PAGEMODE 4 2000 1
|
||||
SET BT PAIRCOUNT 4
|
||||
SET BT PAIR 78:dd:08:b7:e4:a2 0be83335a03fed8ededae42e99554e28
|
||||
SET BT POWER 3 3 3
|
||||
SET BT ROLE 1 f 12c0
|
||||
SET BT SNIFF 100 20 1 8
|
||||
SET BT SSP 3 0
|
||||
SET BT MTU 667
|
||||
SET CONTROL BAUD 38400,8n1
|
||||
SET CONTROL CD 00 0
|
||||
SET CONTROL ECHO 7
|
||||
SET CONTROL ESCAPE - 20 1
|
||||
SET CONTROL GAIN 0 5
|
||||
SET CONTROL INIT SET CONTROL MUX 0
|
||||
SET CONTROL MSC DTE 00 00 00 00 00 00
|
||||
SET CONTROL MUX 1
|
||||
SET CONTROL PIO 00 00
|
||||
SET CONTROL READY 00
|
||||
SET PROFILE HID f HIDKeyboardMouse
|
||||
SET
|
||||
|
||||
|
||||
SET CONTROL CONFIG 0000 0000 490e CLOCK_CACHE INTERLACED_INQ INTERLACED_PAGE KLUDGE INTERACTIVE_PIN UART_LATENCY
|
||||
|
||||
|
||||
2011/09/08:
|
||||
SET CONTROL CONFIG 0000 0000 410e CLOCK_CACHE INTERLACED_INQ INTERLACED_PAGE KLUDGE UART_LATENCY
|
||||
|
||||
Removed INTERACTIVE_PIN to avoid interactive auth and use SET BT AUTH pin(0000).
|
||||
|
||||
|
||||
EOF
|
356
tmk_core/protocol/iwrap/iWRAP5.txt
Normal file
356
tmk_core/protocol/iwrap/iWRAP5.txt
Normal file
|
@ -0,0 +1,356 @@
|
|||
Terminology
|
||||
===========
|
||||
PSM
|
||||
HIDP HID Protocol
|
||||
L2CAP Logical Link Control Adaptation Protocol
|
||||
MTU Maximum Transmission Unit
|
||||
|
||||
|
||||
|
||||
HID Protocol
|
||||
============
|
||||
3 of HID_SPEC_V11.pdf
|
||||
|
||||
Channel
|
||||
-------
|
||||
Control channel PSM=0x0011
|
||||
Interrupt channel PSM=0x0013
|
||||
|
||||
Message
|
||||
-------
|
||||
HANDSHAKE(0)
|
||||
HID_CONTROL(1)
|
||||
|
||||
GET_REPORT(4)
|
||||
Host requests report(DATA payload on Control channel) from Device
|
||||
Size Desc
|
||||
------------------------------------------------------------------------------
|
||||
HIDP-Hdr 1 7..4: HIDP Message TYpe(4: GET_REPORT)
|
||||
3: Size(1:2-octed buffer size, 0:size of the report)
|
||||
2: 0
|
||||
1..0: Report Type(1:input, 2:output, 3: feature)
|
||||
ReportID 1 Optional
|
||||
BufferSize 2 Optional(specified when Size=1)
|
||||
|
||||
SET_REPORT(5)
|
||||
GET_PROTOCOL(6)
|
||||
SET_PROTOCOL(7)
|
||||
|
||||
DATA(A)
|
||||
Input/Output Report: All DATA payloads flow on Interrupt channel.
|
||||
Other: flows on Control channel.
|
||||
Size Desc
|
||||
------------------------------------------------------------------------------
|
||||
HIDP-Hdr 1 7..4 0xA
|
||||
3..2 Reserved(0)
|
||||
1..0 Report Type(0:Other, 1:Input, 2:Output, 3:Feature)
|
||||
Payload N Data
|
||||
|
||||
|
||||
|
||||
|
||||
Boot Protocol
|
||||
=============
|
||||
3.3.2
|
||||
No report descriptor, fixed report descriptors defined.
|
||||
|
||||
Device ReportID Size
|
||||
---------------------------------
|
||||
Reserved 0
|
||||
Keyboard 1 9octets
|
||||
Mouse 2 4octets
|
||||
Reserved 3-255
|
||||
|
||||
Report descriptor
|
||||
-----------------
|
||||
Report ID is added to USB HID boot protocol descriptor.
|
||||
Boot Protocol device doesn't need to supply descriptors. and can send extra data on end of boot report this data will be ignored unless host supports report descriptor.
|
||||
|
||||
Report Protocol devices can have specific descriptors. Using Boot protocol descriptor followed by extra data may be useful for compatibility to Boot protocol only supported host.
|
||||
|
||||
NOTE:
|
||||
Bluegiga HID sample say report ID of mouse is 1 but 2?
|
||||
Bluegiga HID sample say report ID of consumer page is 2 but 3?
|
||||
** mouse.desc and consumer.desc were fixed.
|
||||
size
|
||||
keyboard.desc 67 0x43
|
||||
mouse.desc 60 0x3c
|
||||
consumer.desc 82 0x52
|
||||
combo.desc 209 0xd1
|
||||
|
||||
|
||||
|
||||
SDP
|
||||
===
|
||||
attributes(3.3.2)
|
||||
----------
|
||||
HIDDeviceSubclass
|
||||
which type is supported in Boot Protocol Mode
|
||||
7 6
|
||||
---
|
||||
0 1 Keyboard
|
||||
1 0 Pointing device
|
||||
1 1 Combo keyboard/pointing device
|
||||
|
||||
HIDBootDevice
|
||||
TRUE
|
||||
HIDReconnectInitiate
|
||||
TRUE
|
||||
|
||||
|
||||
Class of Device/Service
|
||||
=======================
|
||||
http://phys.sci.hokudai.ac.jp/LABS/yts/pic/GB002/Bluetooth_assigned_numbers_baseband.pdf
|
||||
|
||||
0x0005C0 Keyboard and Pointing deivce(combo)
|
||||
|
||||
|
||||
23 16 15 8 7 0
|
||||
---------------------------------
|
||||
Service |Major |Minor |Format
|
||||
|
||||
Format type
|
||||
1 0
|
||||
---
|
||||
0 0
|
||||
|
||||
Minor Device Class of Peripheral Major
|
||||
7 6
|
||||
---
|
||||
0 1 Keyboard
|
||||
1 0 Pointing device
|
||||
1 1 Combo keyboard/pointing device
|
||||
|
||||
|
||||
Major device classes
|
||||
12 11 10 9 8
|
||||
--------------
|
||||
0 0 0 0 0 Miscellaneous
|
||||
0 0 0 0 1 Computer
|
||||
0 0 0 1 0 Phone
|
||||
0 0 0 1 1 LAN /Network Access point
|
||||
0 0 1 0 0 Audio/Video (headset,speaker,stereo, video display, vcr.....
|
||||
0 0 1 0 1 *Peripheral (mouse, joystick, keyboards, ..... )
|
||||
0 0 1 1 0 Imaging (printing, scanner, camera, display, ...)
|
||||
1 1 1 1 1 Uncategorized, specific device code not specified
|
||||
X X X X X All other values reserved
|
||||
|
||||
|
||||
Major service classes
|
||||
bit
|
||||
--------------------------------------
|
||||
13 Limited Discoverable Mode [Ref #1]
|
||||
14 (reserved)
|
||||
15 (reserved)
|
||||
16 Positioning (Location identification)
|
||||
17 Networking (LAN, Ad hoc, ...)
|
||||
18 Rendering (Printing, Speaker, ...)
|
||||
19 Capturing (Scanner, Microphone, ...)
|
||||
20 Object Transfer (v-Inbox, v-Folder, ...)
|
||||
21 Audio (Speaker, Microphone, Headset service, ...)
|
||||
22 Telephony (Cordless telephony, Modem, Headset service, ...)
|
||||
23 Information (WEB-server, WAP-server, ...)
|
||||
|
||||
|
||||
|
||||
|
||||
Authentication SSP
|
||||
-------------------
|
||||
SET BT SSP 2 0 PASS KEY entering
|
||||
SET BT SSP 3 0 NO PASS KEY entering
|
||||
SET BT SSP <capabilities> <mitm>
|
||||
<capabilities>: 0:display only 1:display+yes/no button 2:keyboard only 3:none
|
||||
SET BT SSP 2 1 # 2:keyboard only 1:Man-in-the-middle protection is needed
|
||||
SET BT SSP 2 0 # 2:keyboard only 0:Man-in-the-middle protection is not needed
|
||||
|
||||
|
||||
SET BT SSP 2 1
|
||||
bond only if MITM protection is supported by host
|
||||
SET BT SSP 2 0
|
||||
bond even if MITM protection is not supported by host
|
||||
|
||||
On Windows 'Add device' causes SSP PASSKEY event on iWRAP
|
||||
SSP PASSKEY 78:dd:08:b7:e4:a2 ?
|
||||
|
||||
If device has display(0 or 1) this event occurs. User should be shown this code on the device.
|
||||
SSP CONFIRM 78:dd:08:b7:e4:a2 517572
|
||||
|
||||
|
||||
SET BT SSP 3 0
|
||||
No input/output, No MITM protection.
|
||||
Without procedure of authentication the divice is bond to host.
|
||||
|
||||
|
||||
Connect
|
||||
=======
|
||||
CALL 78:dd:08:b7:e4:a2 11 HID
|
||||
|
||||
|
||||
Setting
|
||||
========
|
||||
Following settings need to be done before wiring into keyboard.
|
||||
- UART speed: 38400bps(115200bps didn't work with software serial)
|
||||
- No SSP procedure(without MITM protection)
|
||||
- No Power Saving
|
||||
|
||||
# clear pairing record and set default
|
||||
SET BT PAIR *
|
||||
SET RESET
|
||||
|
||||
SET CONTROL INIT SET CONTROL MUX 0
|
||||
SET CONTROL BAUD 38400,8n1
|
||||
SET BT NAME TMK Blootooth WT12
|
||||
SET BT CLASS 0005c0
|
||||
SET BT AUTH * 0000
|
||||
SET BT SSP 3 0
|
||||
SET CONTROL CONFIG 4800
|
||||
SET PROFILE HID 0f c0 0100 00 en 0409 TMK Bluetooth keyboard(WT12)
|
||||
SET PROFILE SPP
|
||||
|
||||
# power saving?
|
||||
SET BT SNIFF 100 20 1 8
|
||||
|
||||
|
||||
# Report Descriptor
|
||||
# combo keyboard + mouse + consumer
|
||||
HID SET d2 05010906a1010507850119e029e715002501750195088102950175088101950575010508850119012905910295017503910395067508150025650507190029658100c005010902a1010901a1008502050919012908150025017501950881020501093009311581257f750895028106093895018106050c0a380295018106c0c0050c0901a1018503050c1500250109e909ea09e209cd19b529b87501950881020a8a010a21020a2a021a23022a27027501950881020a83010a96010a92010a9e010a94010a060209b209b4750195088102c0
|
||||
|
||||
|
||||
|
||||
SET PROFILE HID
|
||||
---------------
|
||||
SET PROFILE HID 0d c0 100 0 en 0409 HHKB pro Bluetooth keyboard
|
||||
{function bit} uint8
|
||||
{subclass} uint8
|
||||
{version} uint16
|
||||
{country} uint8
|
||||
{BTlang} char[2]
|
||||
{USBlang} uint16
|
||||
{name} string
|
||||
|
||||
|
||||
SET BT CLASS
|
||||
------------
|
||||
See Class of Device
|
||||
composite device: keyboard and mouse
|
||||
SET BT CLASS 005c0
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
----------
|
||||
after setting
|
||||
----------
|
||||
set
|
||||
SET BT BDADDR 00:07:80:47:22:14
|
||||
SET BT NAME TMK Blootooth WT12
|
||||
SET BT CLASS 0005c0
|
||||
SET BT AUTH * 0000
|
||||
SET BT IDENT BT:47 f000 5.0.1 Bluegiga iWRAP
|
||||
SET BT LAP 9e8b33
|
||||
SET BT PAGEMODE 4 2000 1
|
||||
SET BT PAIR 78:dd:08:b7:e4:a2 9e3d85c91bcae73fef8cc10bec18b42f
|
||||
SET BT POWER 3 3 3
|
||||
SET BT ROLE 0 f 7d00
|
||||
SET BT SNIFF 0 20 1 8
|
||||
SET BT SSP 3 0
|
||||
SET BT MTU 667
|
||||
SET CONTROL BAUD 38400,8n1
|
||||
SET CONTROL CD 00 0
|
||||
SET CONTROL ECHO 7
|
||||
SET CONTROL ESCAPE 43 00 1
|
||||
SET CONTROL GAIN 0 5
|
||||
SET CONTROL INIT SET CONTROL MUX 0
|
||||
SET CONTROL MSC DTE 00 00 00 00 00 00
|
||||
SET CONTROL MUX 1
|
||||
SET CONTROL PIO 00 00
|
||||
SET CONTROL READY 00
|
||||
SET PROFILE HID 0f c0 0100 00 en 0409 TMK Bluetooth keyboard(WT12)
|
||||
SET
|
||||
|
||||
set control config list
|
||||
SET CONTROL CONFIG 0000 0000 0000 4900 KLUDGE INTERACTIVE_PIN UART_LATENCY
|
||||
|
||||
|
||||
info config
|
||||
WRAP THOR AI (5.0.1 build 620)
|
||||
Copyright (c) 2003-2012 Bluegiga Technologies Inc.
|
||||
Compiled on Oct 1 2012 10:56:21, running on WT12-A module, psr v31
|
||||
BGIO FTP HFP HFP_AG HID HID_CONSUMER_PAGE HSP MAP MDP OTA PBAP PIO=0x00fc SSP SUBRATE TEST VOLUME
|
||||
- BOCK4 version 620 (Oct 1 2012 10:56:03) (max acl/sco 7/1)
|
||||
- Bluetooth version 3.0, Power class 2
|
||||
- Loader 8615, firmware 8825 (56-bit encryption), native execution mode
|
||||
- up 0 days, 01:50, 2 connections (pool 2)
|
||||
- User configuration:
|
||||
&028d = 0001
|
||||
&0295 = 0000 0005 000b 0000 0003 0000 0000 0000 0000 0000 0000
|
||||
&0298 = c053
|
||||
&0299 = 0000 0000
|
||||
&02a3 = 0030 0030 0030 0030
|
||||
&02a4 = 009d 0000
|
||||
&02a5 = 0053 0045 0054 0020 0043 004f 004e 0054 0052 004f 004c 0020 004d 0055 0058 0020 0030
|
||||
&02a7 = 0000 05c0
|
||||
&02a8 = 0800 0000 0000 0000
|
||||
&02aa = 0004 2000 0001 0033 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
|
||||
&02ac = 0000 0000 002b 0000 0000 0000 0000 0000 0000 0000 0002 0000 0000 0000 0010 0000 0000 0000 0000 029b 0000 0000 0000 0000
|
||||
&02ad = 4d54 204b 6c42 6f6f 6f74 746f 2068 5457 3231
|
||||
&02b0 = fa65 b0aa 934a 077b a600 d1cc fe58 8dd5
|
||||
&02b3 = 0004 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0003 0005 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0005
|
||||
&02b7 = 000f 00c0 0100 0000 0065 006e 0409 4d54 204b 6c42 6575 6f74 746f &02bb = 8000
|
||||
READY.
|
||||
----------
|
||||
|
||||
|
||||
|
||||
-----
|
||||
After 5.0.1 Firmware update
|
||||
Firmware: ai-5.0.1-620-25b.bc4.dfu
|
||||
PSR: wt12-a.ai-5.0.1-620-25b.psrf
|
||||
-----
|
||||
info config
|
||||
WRAP THOR AI (5.0.1 build 620)
|
||||
Copyright (c) 2003-2012 Bluegiga Technologies Inc.
|
||||
Compiled on Oct 1 2012 10:56:21, running on WT12-A module, psr v31
|
||||
BGIO FTP HFP HFP_AG HID HID_CONSUMER_PAGE HSP MAP MDP OTA PBAP PIO=0x00fc SSP SUBRATE TEST VOLUME
|
||||
- BOCK4 version 620 (Oct 1 2012 10:56:03) (max acl/sco 7/1)
|
||||
- Bluetooth version 3.0, Power class 2
|
||||
- Loader 8615, firmware 8825 (56-bit encryption), native execution mode
|
||||
- up 0 days, 00:03, 0 connections (pool 1)
|
||||
- User configuration:
|
||||
&0295 = 0000 0005 000b 0000 0003 0000 0000 0000 0000 0000 0000
|
||||
&0299 = 0000 0000
|
||||
&02aa = 0004 2000 0001 0033 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000
|
||||
&02ac = 0000 0000 002b 0000 0000 0000 0000 0000 0000 0000 0002 0000 0000 0000 0010 0000 0000 0000 0000 029b 0000 0000 0000 0000
|
||||
&02ad = 5457 3231 412d
|
||||
&02b0 = fa65 b0aa 934a 077b a600 d1cc fe58 8dd5
|
||||
READY.
|
||||
|
||||
set
|
||||
SET BT BDADDR 00:07:80:47:22:14
|
||||
SET BT NAME WT12-A
|
||||
SET BT CLASS 001f00
|
||||
SET BT IDENT BT:47 f000 5.0.1 Bluegiga iWRAP
|
||||
SET BT LAP 9e8b33
|
||||
SET BT PAGEMODE 4 2000 1
|
||||
SET BT PAIR 78:dd:08:b7:e4:a2 af18f81faa107e6dd068762ef921f48b
|
||||
SET BT POWER 3 3 3
|
||||
SET BT ROLE 0 f 7d00
|
||||
SET BT SNIFF 0 20 1 8
|
||||
SET BT SSP 3 0
|
||||
SET BT MTU 667
|
||||
SET CONTROL BAUD 115200,8n1
|
||||
SET CONTROL CD 00 0
|
||||
SET CONTROL ECHO 7
|
||||
SET CONTROL ESCAPE 43 00 1
|
||||
SET CONTROL GAIN 0 5
|
||||
SET CONTROL MSC DTE 00 00 00 00 00 00
|
||||
SET CONTROL PIO 00 00
|
||||
SET CONTROL READY 00
|
||||
SET PROFILE SPP Bluetooth Serial Port
|
||||
SET
|
||||
|
||||
set control config list
|
||||
SET CONTROL CONFIG 0000 0000 0000 0100 KLUDGE
|
||||
---------
|
469
tmk_core/protocol/iwrap/iwrap.c
Normal file
469
tmk_core/protocol/iwrap/iwrap.c
Normal file
|
@ -0,0 +1,469 @@
|
|||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
/* host driver for Bulegiga iWRAP */
|
||||
/* Bluegiga BT12
|
||||
* Connections
|
||||
* Hardware UART Software UART BlueTooth
|
||||
* PC=====UART=======AVR=====SUART====iWRAP(BT12)-----------PC
|
||||
*
|
||||
* - Hardware UART for Debug Console to communicate iWRAP
|
||||
* - Software UART for iWRAP control to send keyboard/mouse data
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include "keycode.h"
|
||||
#include "suart.h"
|
||||
#include "uart.h"
|
||||
#include "report.h"
|
||||
#include "host_driver.h"
|
||||
#include "iwrap.h"
|
||||
#include "print.h"
|
||||
|
||||
|
||||
/* iWRAP MUX mode utils. 3.10 HID raw mode(iWRAP_HID_Application_Note.pdf) */
|
||||
#define MUX_HEADER(LINK, LENGTH) do { \
|
||||
xmit(0xbf); /* SOF */ \
|
||||
xmit(LINK); /* Link */ \
|
||||
xmit(0x00); /* Flags */ \
|
||||
xmit(LENGTH); /* Length */ \
|
||||
} while (0)
|
||||
#define MUX_FOOTER(LINK) xmit(LINK^0xff)
|
||||
|
||||
|
||||
static uint8_t connected = 0;
|
||||
//static uint8_t channel = 1;
|
||||
|
||||
/* iWRAP buffer */
|
||||
#define MUX_BUF_SIZE 64
|
||||
static char buf[MUX_BUF_SIZE];
|
||||
static uint8_t snd_pos = 0;
|
||||
|
||||
#define MUX_RCV_BUF_SIZE 256
|
||||
static char rcv_buf[MUX_RCV_BUF_SIZE];
|
||||
static uint8_t rcv_head = 0;
|
||||
static uint8_t rcv_tail = 0;
|
||||
|
||||
|
||||
/* receive buffer */
|
||||
static void rcv_enq(char c)
|
||||
{
|
||||
uint8_t next = (rcv_head + 1) % MUX_RCV_BUF_SIZE;
|
||||
if (next != rcv_tail) {
|
||||
rcv_buf[rcv_head] = c;
|
||||
rcv_head = next;
|
||||
}
|
||||
}
|
||||
|
||||
static char rcv_deq(void)
|
||||
{
|
||||
char c = 0;
|
||||
if (rcv_head != rcv_tail) {
|
||||
c = rcv_buf[rcv_tail++];
|
||||
rcv_tail %= MUX_RCV_BUF_SIZE;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
static char rcv_peek(void)
|
||||
{
|
||||
if (rcv_head == rcv_tail)
|
||||
return 0;
|
||||
return rcv_buf[rcv_tail];
|
||||
}
|
||||
*/
|
||||
|
||||
static void rcv_clear(void)
|
||||
{
|
||||
rcv_tail = rcv_head = 0;
|
||||
}
|
||||
|
||||
/* iWRAP response */
|
||||
ISR(PCINT1_vect, ISR_BLOCK) // recv() runs away in case of ISR_NOBLOCK
|
||||
{
|
||||
if ((SUART_IN_PIN & (1<<SUART_IN_BIT)))
|
||||
return;
|
||||
|
||||
static volatile uint8_t mux_state = 0xff;
|
||||
static volatile uint8_t mux_link = 0xff;
|
||||
uint8_t c = recv();
|
||||
switch (mux_state) {
|
||||
case 0xff: // SOF
|
||||
if (c == 0xbf)
|
||||
mux_state--;
|
||||
break;
|
||||
case 0xfe: // Link
|
||||
mux_state--;
|
||||
mux_link = c;
|
||||
break;
|
||||
case 0xfd: // Flags
|
||||
mux_state--;
|
||||
break;
|
||||
case 0xfc: // Length
|
||||
mux_state = c;
|
||||
break;
|
||||
case 0x00:
|
||||
mux_state = 0xff;
|
||||
mux_link = 0xff;
|
||||
break;
|
||||
default:
|
||||
if (mux_state--) {
|
||||
uart_putchar(c);
|
||||
rcv_enq(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* iWRAP communication
|
||||
*------------------------------------------------------------------*/
|
||||
void iwrap_init(void)
|
||||
{
|
||||
// reset iWRAP if in already MUX mode after AVR software-reset
|
||||
iwrap_send("RESET");
|
||||
iwrap_mux_send("RESET");
|
||||
_delay_ms(3000);
|
||||
iwrap_send("\r\nSET CONTROL MUX 1\r\n");
|
||||
_delay_ms(500);
|
||||
iwrap_check_connection();
|
||||
}
|
||||
|
||||
void iwrap_mux_send(const char *s)
|
||||
{
|
||||
rcv_clear();
|
||||
MUX_HEADER(0xff, strlen((char *)s));
|
||||
iwrap_send(s);
|
||||
MUX_FOOTER(0xff);
|
||||
}
|
||||
|
||||
void iwrap_send(const char *s)
|
||||
{
|
||||
while (*s)
|
||||
xmit(*s++);
|
||||
}
|
||||
|
||||
/* send buffer */
|
||||
void iwrap_buf_add(uint8_t c)
|
||||
{
|
||||
// need space for '\0'
|
||||
if (snd_pos < MUX_BUF_SIZE-1)
|
||||
buf[snd_pos++] = c;
|
||||
}
|
||||
|
||||
void iwrap_buf_del(void)
|
||||
{
|
||||
if (snd_pos)
|
||||
snd_pos--;
|
||||
}
|
||||
|
||||
void iwrap_buf_send(void)
|
||||
{
|
||||
buf[snd_pos] = '\0';
|
||||
snd_pos = 0;
|
||||
iwrap_mux_send(buf);
|
||||
}
|
||||
|
||||
void iwrap_call(void)
|
||||
{
|
||||
char *p;
|
||||
|
||||
iwrap_mux_send("SET BT PAIR");
|
||||
_delay_ms(500);
|
||||
|
||||
p = rcv_buf + rcv_tail;
|
||||
while (!strncmp(p, "SET BT PAIR", 11)) {
|
||||
p += 7;
|
||||
strncpy(p, "CALL", 4);
|
||||
strncpy(p+22, " 11 HID\n\0", 9);
|
||||
print_S(p);
|
||||
iwrap_mux_send(p);
|
||||
// TODO: skip to next line
|
||||
p += 57;
|
||||
|
||||
DEBUG_LED_CONFIG;
|
||||
DEBUG_LED_ON;
|
||||
_delay_ms(500);
|
||||
DEBUG_LED_OFF;
|
||||
_delay_ms(500);
|
||||
DEBUG_LED_ON;
|
||||
_delay_ms(500);
|
||||
DEBUG_LED_OFF;
|
||||
_delay_ms(500);
|
||||
DEBUG_LED_ON;
|
||||
_delay_ms(500);
|
||||
DEBUG_LED_OFF;
|
||||
_delay_ms(500);
|
||||
DEBUG_LED_ON;
|
||||
_delay_ms(500);
|
||||
DEBUG_LED_OFF;
|
||||
_delay_ms(500);
|
||||
DEBUG_LED_ON;
|
||||
_delay_ms(500);
|
||||
DEBUG_LED_OFF;
|
||||
_delay_ms(500);
|
||||
}
|
||||
iwrap_check_connection();
|
||||
}
|
||||
|
||||
void iwrap_kill(void)
|
||||
{
|
||||
char c;
|
||||
iwrap_mux_send("LIST");
|
||||
_delay_ms(500);
|
||||
|
||||
while ((c = rcv_deq()) && c != '\n') ;
|
||||
if (strncmp(rcv_buf + rcv_tail, "LIST ", 5)) {
|
||||
print("no connection to kill.\n");
|
||||
return;
|
||||
}
|
||||
// skip 10 'space' chars
|
||||
for (uint8_t i = 10; i; i--)
|
||||
while ((c = rcv_deq()) && c != ' ') ;
|
||||
|
||||
char *p = rcv_buf + rcv_tail - 5;
|
||||
strncpy(p, "KILL ", 5);
|
||||
strncpy(p + 22, "\n\0", 2);
|
||||
print_S(p);
|
||||
iwrap_mux_send(p);
|
||||
_delay_ms(500);
|
||||
|
||||
iwrap_check_connection();
|
||||
}
|
||||
|
||||
void iwrap_unpair(void)
|
||||
{
|
||||
iwrap_mux_send("SET BT PAIR");
|
||||
_delay_ms(500);
|
||||
|
||||
char *p = rcv_buf + rcv_tail;
|
||||
if (!strncmp(p, "SET BT PAIR", 11)) {
|
||||
strncpy(p+29, "\n\0", 2);
|
||||
print_S(p);
|
||||
iwrap_mux_send(p);
|
||||
}
|
||||
}
|
||||
|
||||
void iwrap_sleep(void)
|
||||
{
|
||||
iwrap_mux_send("SLEEP");
|
||||
}
|
||||
|
||||
void iwrap_sniff(void)
|
||||
{
|
||||
}
|
||||
|
||||
void iwrap_subrate(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool iwrap_failed(void)
|
||||
{
|
||||
if (strncmp(rcv_buf, "SYNTAX ERROR", 12))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t iwrap_connected(void)
|
||||
{
|
||||
return connected;
|
||||
}
|
||||
|
||||
uint8_t iwrap_check_connection(void)
|
||||
{
|
||||
iwrap_mux_send("LIST");
|
||||
_delay_ms(100);
|
||||
|
||||
if (strncmp(rcv_buf, "LIST ", 5) || !strncmp(rcv_buf, "LIST 0", 6))
|
||||
connected = 0;
|
||||
else
|
||||
connected = 1;
|
||||
return connected;
|
||||
}
|
||||
|
||||
|
||||
/*------------------------------------------------------------------*
|
||||
* Host driver
|
||||
*------------------------------------------------------------------*/
|
||||
static uint8_t keyboard_leds(void);
|
||||
static void send_keyboard(report_keyboard_t *report);
|
||||
static void send_mouse(report_mouse_t *report);
|
||||
static void send_system(uint16_t data);
|
||||
static void send_consumer(uint16_t data);
|
||||
|
||||
static host_driver_t driver = {
|
||||
keyboard_leds,
|
||||
send_keyboard,
|
||||
send_mouse,
|
||||
send_system,
|
||||
send_consumer
|
||||
};
|
||||
|
||||
host_driver_t *iwrap_driver(void)
|
||||
{
|
||||
return &driver;
|
||||
}
|
||||
|
||||
static uint8_t keyboard_leds(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void send_keyboard(report_keyboard_t *report)
|
||||
{
|
||||
if (!iwrap_connected() && !iwrap_check_connection()) return;
|
||||
MUX_HEADER(0x01, 0x0c);
|
||||
// HID raw mode header
|
||||
xmit(0x9f);
|
||||
xmit(0x0a); // Length
|
||||
xmit(0xa1); // DATA(Input)
|
||||
xmit(0x01); // Report ID
|
||||
xmit(report->mods);
|
||||
xmit(0x00); // reserved byte(always 0)
|
||||
xmit(report->keys[0]);
|
||||
xmit(report->keys[1]);
|
||||
xmit(report->keys[2]);
|
||||
xmit(report->keys[3]);
|
||||
xmit(report->keys[4]);
|
||||
xmit(report->keys[5]);
|
||||
MUX_FOOTER(0x01);
|
||||
}
|
||||
|
||||
static void send_mouse(report_mouse_t *report)
|
||||
{
|
||||
#if defined(MOUSEKEY_ENABLE) || defined(PS2_MOUSE_ENABLE)
|
||||
if (!iwrap_connected() && !iwrap_check_connection()) return;
|
||||
MUX_HEADER(0x01, 0x09);
|
||||
// HID raw mode header
|
||||
xmit(0x9f);
|
||||
xmit(0x07); // Length
|
||||
xmit(0xa1); // DATA(Input)
|
||||
xmit(0x02); // Report ID
|
||||
xmit(report->buttons);
|
||||
xmit(report->x);
|
||||
xmit(report->y);
|
||||
xmit(report->v);
|
||||
xmit(report->h);
|
||||
MUX_FOOTER(0x01);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void send_system(uint16_t data)
|
||||
{
|
||||
/* not supported */
|
||||
}
|
||||
|
||||
static void send_consumer(uint16_t data)
|
||||
{
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
static uint16_t last_data = 0;
|
||||
uint8_t bits1 = 0;
|
||||
uint8_t bits2 = 0;
|
||||
uint8_t bits3 = 0;
|
||||
|
||||
if (!iwrap_connected() && !iwrap_check_connection()) return;
|
||||
if (data == last_data) return;
|
||||
last_data = data;
|
||||
|
||||
// 3.10 HID raw mode(iWRAP_HID_Application_Note.pdf)
|
||||
switch (data) {
|
||||
case AUDIO_VOL_UP:
|
||||
bits1 = 0x01;
|
||||
break;
|
||||
case AUDIO_VOL_DOWN:
|
||||
bits1 = 0x02;
|
||||
break;
|
||||
case AUDIO_MUTE:
|
||||
bits1 = 0x04;
|
||||
break;
|
||||
case TRANSPORT_PLAY_PAUSE:
|
||||
bits1 = 0x08;
|
||||
break;
|
||||
case TRANSPORT_NEXT_TRACK:
|
||||
bits1 = 0x10;
|
||||
break;
|
||||
case TRANSPORT_PREV_TRACK:
|
||||
bits1 = 0x20;
|
||||
break;
|
||||
case TRANSPORT_STOP:
|
||||
bits1 = 0x40;
|
||||
break;
|
||||
case TRANSPORT_EJECT:
|
||||
bits1 = 0x80;
|
||||
break;
|
||||
case AL_EMAIL:
|
||||
bits2 = 0x01;
|
||||
break;
|
||||
case AC_SEARCH:
|
||||
bits2 = 0x02;
|
||||
break;
|
||||
case AC_BOOKMARKS:
|
||||
bits2 = 0x04;
|
||||
break;
|
||||
case AC_HOME:
|
||||
bits2 = 0x08;
|
||||
break;
|
||||
case AC_BACK:
|
||||
bits2 = 0x10;
|
||||
break;
|
||||
case AC_FORWARD:
|
||||
bits2 = 0x20;
|
||||
break;
|
||||
case AC_STOP:
|
||||
bits2 = 0x40;
|
||||
break;
|
||||
case AC_REFRESH:
|
||||
bits2 = 0x80;
|
||||
break;
|
||||
case AL_CC_CONFIG:
|
||||
bits3 = 0x01;
|
||||
break;
|
||||
case AL_CALCULATOR:
|
||||
bits3 = 0x04;
|
||||
break;
|
||||
case AL_LOCK:
|
||||
bits3 = 0x08;
|
||||
break;
|
||||
case AL_LOCAL_BROWSER:
|
||||
bits3 = 0x10;
|
||||
break;
|
||||
case AC_MINIMIZE:
|
||||
bits3 = 0x20;
|
||||
break;
|
||||
case TRANSPORT_RECORD:
|
||||
bits3 = 0x40;
|
||||
break;
|
||||
case TRANSPORT_REWIND:
|
||||
bits3 = 0x80;
|
||||
break;
|
||||
}
|
||||
|
||||
MUX_HEADER(0x01, 0x07);
|
||||
xmit(0x9f);
|
||||
xmit(0x05); // Length
|
||||
xmit(0xa1); // DATA(Input)
|
||||
xmit(0x03); // Report ID
|
||||
xmit(bits1);
|
||||
xmit(bits2);
|
||||
xmit(bits3);
|
||||
MUX_FOOTER(0x01);
|
||||
#endif
|
||||
}
|
49
tmk_core/protocol/iwrap/iwrap.h
Normal file
49
tmk_core/protocol/iwrap/iwrap.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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/>.
|
||||
*/
|
||||
|
||||
#ifndef IWRAP_H
|
||||
#define IWRAP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "host_driver.h"
|
||||
|
||||
|
||||
/* enable iWRAP MUX mode */
|
||||
#define MUX_MODE
|
||||
|
||||
|
||||
host_driver_t *iwrap_driver(void);
|
||||
|
||||
void iwrap_init(void);
|
||||
void iwrap_send(const char *s);
|
||||
void iwrap_mux_send(const char *s);
|
||||
void iwrap_buf_send(void);
|
||||
void iwrap_buf_add(uint8_t c);
|
||||
void iwrap_buf_del(void);
|
||||
|
||||
void iwrap_call(void);
|
||||
void iwrap_kill(void);
|
||||
void iwrap_unpair(void);
|
||||
void iwrap_sleep(void);
|
||||
void iwrap_sniff(void);
|
||||
void iwrap_subrate(void);
|
||||
bool iwrap_failed(void);
|
||||
uint8_t iwrap_connected(void);
|
||||
uint8_t iwrap_check_connection(void);
|
||||
|
||||
#endif
|
376
tmk_core/protocol/iwrap/main.c
Normal file
376
tmk_core/protocol/iwrap/main.c
Normal file
|
@ -0,0 +1,376 @@
|
|||
/*
|
||||
Copyright 2011 Jun Wako <wakojun@gmail.com>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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/>.
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <avr/io.h>
|
||||
//#include <avr/wdt.h>
|
||||
#include "wd.h" // in order to use watchdog in interrupt mode
|
||||
#include <avr/sleep.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/power.h>
|
||||
#include "keyboard.h"
|
||||
#include "matrix.h"
|
||||
#include "host.h"
|
||||
#include "action.h"
|
||||
#include "iwrap.h"
|
||||
#ifdef PROTOCOL_VUSB
|
||||
# include "vusb.h"
|
||||
# include "usbdrv.h"
|
||||
#endif
|
||||
#include "uart.h"
|
||||
#include "suart.h"
|
||||
#include "timer.h"
|
||||
#include "debug.h"
|
||||
#include "keycode.h"
|
||||
#include "command.h"
|
||||
|
||||
|
||||
static void sleep(uint8_t term);
|
||||
static bool console(void);
|
||||
static bool console_command(uint8_t c);
|
||||
static uint8_t key2asc(uint8_t key);
|
||||
|
||||
|
||||
/*
|
||||
static void set_prr(void)
|
||||
{
|
||||
power_adc_disable();
|
||||
power_spi_disable();
|
||||
power_twi_disable();
|
||||
#ifndef TIMER_H
|
||||
//power_timer0_disable(); // used in timer.c
|
||||
#endif
|
||||
power_timer1_disable();
|
||||
power_timer2_disable();
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
static void pullup_pins(void)
|
||||
{
|
||||
// DDRs are set to 0(input) by default.
|
||||
#ifdef PORTA
|
||||
PORTA = 0xFF;
|
||||
#endif
|
||||
PORTB = 0xFF;
|
||||
PORTC = 0xFF;
|
||||
PORTD = 0xFF;
|
||||
#ifdef PORTE
|
||||
PORTE = 0xFF;
|
||||
#endif
|
||||
#ifdef PORTE
|
||||
PORTF = 0xFF;
|
||||
#endif
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
#ifdef PROTOCOL_VUSB
|
||||
static void disable_vusb(void)
|
||||
{
|
||||
// disable interrupt & disconnect to prevent host from enumerating
|
||||
USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT);
|
||||
usbDeviceDisconnect();
|
||||
}
|
||||
|
||||
static void enable_vusb(void)
|
||||
{
|
||||
USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT);
|
||||
usbDeviceConnect();
|
||||
}
|
||||
|
||||
static void init_vusb(void)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
usbInit();
|
||||
disable_vusb();
|
||||
/* fake USB disconnect for > 250 ms */
|
||||
while(--i){
|
||||
_delay_ms(1);
|
||||
}
|
||||
enable_vusb();
|
||||
}
|
||||
#endif
|
||||
|
||||
void change_driver(host_driver_t *driver)
|
||||
{
|
||||
/*
|
||||
host_clear_keyboard_report();
|
||||
host_swap_keyboard_report();
|
||||
host_clear_keyboard_report();
|
||||
host_send_keyboard_report();
|
||||
*/
|
||||
clear_keyboard();
|
||||
_delay_ms(1000);
|
||||
host_set_driver(driver);
|
||||
}
|
||||
|
||||
|
||||
static bool sleeping = false;
|
||||
static bool insomniac = false; // TODO: should be false for power saving
|
||||
static uint16_t last_timer = 0;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
MCUSR = 0;
|
||||
clock_prescale_set(clock_div_1);
|
||||
WD_SET(WD_OFF);
|
||||
|
||||
// power saving: the result is worse than nothing... why?
|
||||
//pullup_pins();
|
||||
//set_prr();
|
||||
|
||||
#ifdef PROTOCOL_VUSB
|
||||
disable_vusb();
|
||||
#endif
|
||||
uart_init(115200);
|
||||
keyboard_init();
|
||||
print("\nSend BREAK for UART Console Commands.\n");
|
||||
|
||||
// TODO: move to iWRAP/suart file
|
||||
print("suart init\n");
|
||||
// suart init
|
||||
// PC4: Tx Output IDLE(Hi)
|
||||
PORTC |= (1<<4);
|
||||
DDRC |= (1<<4);
|
||||
// PC5: Rx Input(pull-up)
|
||||
PORTC |= (1<<5);
|
||||
DDRC &= ~(1<<5);
|
||||
// suart receive interrut(PC5/PCINT13)
|
||||
PCMSK1 = 0b00100000;
|
||||
PCICR = 0b00000010;
|
||||
|
||||
host_set_driver(iwrap_driver());
|
||||
|
||||
print("iwrap_init()\n");
|
||||
iwrap_init();
|
||||
iwrap_call();
|
||||
|
||||
last_timer = timer_read();
|
||||
while (true) {
|
||||
#ifdef PROTOCOL_VUSB
|
||||
if (host_get_driver() == vusb_driver())
|
||||
usbPoll();
|
||||
#endif
|
||||
keyboard_task();
|
||||
#ifdef PROTOCOL_VUSB
|
||||
if (host_get_driver() == vusb_driver())
|
||||
vusb_transfer_keyboard();
|
||||
#endif
|
||||
// TODO: depricated
|
||||
if (matrix_is_modified() || console()) {
|
||||
last_timer = timer_read();
|
||||
sleeping = false;
|
||||
} else if (!sleeping && timer_elapsed(last_timer) > 4000) {
|
||||
sleeping = true;
|
||||
iwrap_check_connection();
|
||||
}
|
||||
|
||||
// TODO: suspend.h
|
||||
if (host_get_driver() == iwrap_driver()) {
|
||||
if (sleeping && !insomniac) {
|
||||
_delay_ms(1); // wait for UART to send
|
||||
iwrap_sleep();
|
||||
sleep(WDTO_60MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void sleep(uint8_t term)
|
||||
{
|
||||
WD_SET(WD_IRQ, term);
|
||||
|
||||
cli();
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
|
||||
sleep_enable();
|
||||
sleep_bod_disable();
|
||||
sei();
|
||||
sleep_cpu();
|
||||
sleep_disable();
|
||||
|
||||
WD_SET(WD_OFF);
|
||||
}
|
||||
|
||||
static bool console(void)
|
||||
{
|
||||
// Send to Bluetoot module WT12
|
||||
static bool breaked = false;
|
||||
if (!uart_available())
|
||||
return false;
|
||||
else {
|
||||
uint8_t c;
|
||||
c = uart_getchar();
|
||||
uart_putchar(c);
|
||||
switch (c) {
|
||||
case 0x00: // BREAK signal
|
||||
if (!breaked) {
|
||||
print("break(? for help): ");
|
||||
breaked = true;
|
||||
}
|
||||
break;
|
||||
case '\r':
|
||||
uart_putchar('\n');
|
||||
iwrap_buf_send();
|
||||
break;
|
||||
case '\b':
|
||||
iwrap_buf_del();
|
||||
break;
|
||||
default:
|
||||
if (breaked) {
|
||||
print("\n");
|
||||
console_command(c);
|
||||
breaked = false;
|
||||
} else {
|
||||
iwrap_buf_add(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool command_extra(uint8_t code)
|
||||
{
|
||||
return console_command(key2asc(code));
|
||||
}
|
||||
|
||||
static bool console_command(uint8_t c)
|
||||
{
|
||||
switch (c) {
|
||||
case 'h':
|
||||
case '?':
|
||||
print("\nCommands for Bluetooth(WT12/iWRAP):\n");
|
||||
print("r: reset. software reset by watchdog\n");
|
||||
print("i: insomniac. prevent KB from sleeping\n");
|
||||
print("c: iwrap_call. CALL for BT connection.\n");
|
||||
#ifdef PROTOCOL_VUSB
|
||||
print("u: USB mode. switch to USB.\n");
|
||||
print("w: BT mode. switch to Bluetooth.\n");
|
||||
#endif
|
||||
print("k: kill first connection.\n");
|
||||
print("Del: unpair first pairing.\n");
|
||||
print("\n");
|
||||
return 0;
|
||||
case 'r':
|
||||
print("reset\n");
|
||||
WD_AVR_RESET();
|
||||
return 1;
|
||||
case 'i':
|
||||
insomniac = !insomniac;
|
||||
if (insomniac)
|
||||
print("insomniac\n");
|
||||
else
|
||||
print("not insomniac\n");
|
||||
return 1;
|
||||
case 'c':
|
||||
print("iwrap_call()\n");
|
||||
iwrap_call();
|
||||
return 1;
|
||||
#ifdef PROTOCOL_VUSB
|
||||
case 'u':
|
||||
print("USB mode\n");
|
||||
init_vusb();
|
||||
change_driver(vusb_driver());
|
||||
//iwrap_kill();
|
||||
//iwrap_sleep();
|
||||
// disable suart receive interrut(PC5/PCINT13)
|
||||
PCMSK1 &= ~(0b00100000);
|
||||
PCICR &= ~(0b00000010);
|
||||
return 1;
|
||||
case 'w':
|
||||
print("iWRAP mode\n");
|
||||
change_driver(iwrap_driver());
|
||||
disable_vusb();
|
||||
// enable suart receive interrut(PC5/PCINT13)
|
||||
PCMSK1 |= 0b00100000;
|
||||
PCICR |= 0b00000010;
|
||||
return 1;
|
||||
#endif
|
||||
case 'k':
|
||||
print("kill\n");
|
||||
iwrap_kill();
|
||||
return 1;
|
||||
case 0x7F: // DELETE
|
||||
print("unpair\n");
|
||||
iwrap_unpair();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// convert keycode into ascii charactor
|
||||
static uint8_t key2asc(uint8_t key)
|
||||
{
|
||||
switch (key) {
|
||||
case KC_A: return 'a';
|
||||
case KC_B: return 'b';
|
||||
case KC_C: return 'c';
|
||||
case KC_D: return 'd';
|
||||
case KC_E: return 'e';
|
||||
case KC_F: return 'f';
|
||||
case KC_G: return 'g';
|
||||
case KC_H: return 'h';
|
||||
case KC_I: return 'i';
|
||||
case KC_J: return 'j';
|
||||
case KC_K: return 'k';
|
||||
case KC_L: return 'l';
|
||||
case KC_M: return 'm';
|
||||
case KC_N: return 'n';
|
||||
case KC_O: return 'o';
|
||||
case KC_P: return 'p';
|
||||
case KC_Q: return 'q';
|
||||
case KC_R: return 'r';
|
||||
case KC_S: return 's';
|
||||
case KC_T: return 't';
|
||||
case KC_U: return 'u';
|
||||
case KC_V: return 'v';
|
||||
case KC_W: return 'w';
|
||||
case KC_X: return 'x';
|
||||
case KC_Y: return 'y';
|
||||
case KC_Z: return 'z';
|
||||
case KC_1: return '1';
|
||||
case KC_2: return '2';
|
||||
case KC_3: return '3';
|
||||
case KC_4: return '4';
|
||||
case KC_5: return '5';
|
||||
case KC_6: return '6';
|
||||
case KC_7: return '7';
|
||||
case KC_8: return '8';
|
||||
case KC_9: return '9';
|
||||
case KC_0: return '0';
|
||||
case KC_ENTER: return '\n';
|
||||
case KC_ESCAPE: return 0x1B;
|
||||
case KC_BSPACE: return '\b';
|
||||
case KC_TAB: return '\t';
|
||||
case KC_SPACE: return ' ';
|
||||
case KC_MINUS: return '-';
|
||||
case KC_EQUAL: return '=';
|
||||
case KC_LBRACKET: return '[';
|
||||
case KC_RBRACKET: return ']';
|
||||
case KC_BSLASH: return '\\';
|
||||
case KC_NONUS_HASH: return '\\';
|
||||
case KC_SCOLON: return ';';
|
||||
case KC_QUOTE: return '\'';
|
||||
case KC_GRAVE: return '`';
|
||||
case KC_COMMA: return ',';
|
||||
case KC_DOT: return '.';
|
||||
case KC_SLASH: return '/';
|
||||
default: return 0x00;
|
||||
}
|
||||
}
|
7
tmk_core/protocol/iwrap/mux_exit.rb
Normal file
7
tmk_core/protocol/iwrap/mux_exit.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
#
|
||||
# Rescue from Bluegiga iWRAP MUX mode
|
||||
# 6.75 of iWRAP5_User_Guid.pdf
|
||||
#
|
||||
[0xBF, 0xFF, 0x00, 0x11, 0x53, 0x45, 0x54, 0x20, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x4f, 0x4c, 0x20, 0x4d, 0x55, 0x58, 0x20, 0x30, 0x00].each do |x|
|
||||
print x.chr
|
||||
end
|
156
tmk_core/protocol/iwrap/suart.S
Normal file
156
tmk_core/protocol/iwrap/suart.S
Normal file
|
@ -0,0 +1,156 @@
|
|||
;---------------------------------------------------------------------------;
|
||||
; Software implemented UART module ;
|
||||
; (C)ChaN, 2005 (http://elm-chan.org/) ;
|
||||
;---------------------------------------------------------------------------;
|
||||
; Bit rate settings:
|
||||
;
|
||||
; 1MHz 2MHz 4MHz 6MHz 8MHz 10MHz 12MHz 16MHz 20MHz
|
||||
; 2.4kbps 138 - - - - - - - -
|
||||
; 4.8kbps 68 138 - - - - - - -
|
||||
; 9.6kbps 33 68 138 208 - - - - -
|
||||
; 19.2kbps - 33 68 102 138 173 208 - -
|
||||
; 38.4kbps - - 33 50 68 85 102 138 172
|
||||
; 57.6kbps - - 21 33 44 56 68 91 114
|
||||
; 115.2kbps - - - - 21 27 33 44 56
|
||||
|
||||
.nolist
|
||||
#include <avr/io.h>
|
||||
.list
|
||||
|
||||
#define BPS 102 /* Bit delay. (see above table) */
|
||||
#define BIDIR 0 /* 0:Separated Tx/Rx, 1:Shared Tx/Rx */
|
||||
|
||||
#define OUT_1 sbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 1 */
|
||||
#define OUT_0 cbi _SFR_IO_ADDR(SUART_OUT_PORT), SUART_OUT_BIT /* Output 0 */
|
||||
#define SKIP_IN_1 sbis _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 1 */
|
||||
#define SKIP_IN_0 sbic _SFR_IO_ADDR(SUART_IN_PIN), SUART_IN_BIT /* Skip if 0 */
|
||||
|
||||
|
||||
|
||||
#ifdef SPM_PAGESIZE
|
||||
.macro _LPMI reg
|
||||
lpm \reg, Z+
|
||||
.endm
|
||||
.macro _MOVW dh,dl, sh,sl
|
||||
movw \dl, \sl
|
||||
.endm
|
||||
#else
|
||||
.macro _LPMI reg
|
||||
lpm
|
||||
mov \reg, r0
|
||||
adiw ZL, 1
|
||||
.endm
|
||||
.macro _MOVW dh,dl, sh,sl
|
||||
mov \dl, \sl
|
||||
mov \dh, \sh
|
||||
.endm
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------;
|
||||
; Transmit a byte in serial format of N81
|
||||
;
|
||||
;Prototype: void xmit (uint8_t data);
|
||||
;Size: 16 words
|
||||
|
||||
.global xmit
|
||||
.func xmit
|
||||
xmit:
|
||||
#if BIDIR
|
||||
ldi r23, BPS-1 ;Pre-idle time for bidirectional data line
|
||||
5: dec r23 ;
|
||||
brne 5b ;/
|
||||
#endif
|
||||
in r0, _SFR_IO_ADDR(SREG) ;Save flags
|
||||
|
||||
com r24 ;C = start bit
|
||||
ldi r25, 10 ;Bit counter
|
||||
cli ;Start critical section
|
||||
|
||||
1: ldi r23, BPS-1 ;----- Bit transferring loop
|
||||
2: dec r23 ;Wait for a bit time
|
||||
brne 2b ;/
|
||||
brcs 3f ;MISO = bit to be sent
|
||||
OUT_1 ;
|
||||
3: brcc 4f ;
|
||||
OUT_0 ;/
|
||||
4: lsr r24 ;Get next bit into C
|
||||
dec r25 ;All bits sent?
|
||||
brne 1b ; no, coutinue
|
||||
|
||||
out _SFR_IO_ADDR(SREG), r0 ;End of critical section
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
|
||||
|
||||
;---------------------------------------------------------------------------;
|
||||
; Receive a byte
|
||||
;
|
||||
;Prototype: uint8_t rcvr (void);
|
||||
;Size: 19 words
|
||||
|
||||
.global rcvr
|
||||
.func rcvr
|
||||
rcvr:
|
||||
in r0, _SFR_IO_ADDR(SREG) ;Save flags
|
||||
|
||||
ldi r24, 0x80 ;Receiving shift reg
|
||||
cli ;Start critical section
|
||||
|
||||
1: SKIP_IN_1 ;Wait for idle
|
||||
rjmp 1b
|
||||
2: SKIP_IN_0 ;Wait for start bit
|
||||
rjmp 2b
|
||||
ldi r25, BPS/2 ;Wait for half bit time
|
||||
3: dec r25
|
||||
brne 3b
|
||||
|
||||
4: ldi r25, BPS ;----- Bit receiving loop
|
||||
5: dec r25 ;Wait for a bit time
|
||||
brne 5b ;/
|
||||
lsr r24 ;Next bit
|
||||
SKIP_IN_0 ;Get a data bit into r24.7
|
||||
ori r24, 0x80
|
||||
brcc 4b ;All bits received? no, continue
|
||||
|
||||
out _SFR_IO_ADDR(SREG), r0 ;End of critical section
|
||||
ret
|
||||
.endfunc
|
||||
|
||||
|
||||
; Not wait for start bit. This should be called after detecting start bit.
|
||||
.global recv
|
||||
.func recv
|
||||
recv:
|
||||
in r0, _SFR_IO_ADDR(SREG) ;Save flags
|
||||
|
||||
ldi r24, 0x80 ;Receiving shift reg
|
||||
cli ;Start critical section
|
||||
|
||||
;1: SKIP_IN_1 ;Wait for idle
|
||||
; rjmp 1b
|
||||
;2: SKIP_IN_0 ;Wait for start bit
|
||||
; rjmp 2b
|
||||
ldi r25, BPS/2 ;Wait for half bit time
|
||||
3: dec r25
|
||||
brne 3b
|
||||
|
||||
4: ldi r25, BPS ;----- Bit receiving loop
|
||||
5: dec r25 ;Wait for a bit time
|
||||
brne 5b ;/
|
||||
lsr r24 ;Next bit
|
||||
SKIP_IN_0 ;Get a data bit into r24.7
|
||||
ori r24, 0x80
|
||||
brcc 4b ;All bits received? no, continue
|
||||
|
||||
ldi r25, BPS/2 ;Wait for half bit time
|
||||
6: dec r25
|
||||
brne 6b
|
||||
7: SKIP_IN_1 ;Wait for stop bit
|
||||
rjmp 7b
|
||||
|
||||
out _SFR_IO_ADDR(SREG), r0 ;End of critical section
|
||||
ret
|
||||
.endfunc
|
8
tmk_core/protocol/iwrap/suart.h
Normal file
8
tmk_core/protocol/iwrap/suart.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef SUART
|
||||
#define SUART
|
||||
|
||||
void xmit(uint8_t);
|
||||
uint8_t rcvr(void);
|
||||
uint8_t recv(void);
|
||||
|
||||
#endif /* SUART */
|
159
tmk_core/protocol/iwrap/wd.h
Normal file
159
tmk_core/protocol/iwrap/wd.h
Normal file
|
@ -0,0 +1,159 @@
|
|||
/* This is from http://www.mtcnet.net/~henryvm/wdt/ */
|
||||
#ifndef _AVR_WD_H_
|
||||
#define _AVR_WD_H_
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
/*
|
||||
Copyright (c) 2009, Curt Van Maanen
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
include usage-
|
||||
#include "wd.h" //if in same directory as project
|
||||
#include <avr/wd.h> //if wd.h is in avr directory
|
||||
|
||||
set watchdog modes and prescale
|
||||
|
||||
usage-
|
||||
WD_SET(mode,[timeout]); //prescale always set
|
||||
|
||||
modes-
|
||||
WD_OFF disabled
|
||||
WD_RST normal reset mode
|
||||
WD_IRQ interrupt only mode (if supported)
|
||||
WD_RST_IRQ interrupt+reset mode (if supported)
|
||||
|
||||
timeout-
|
||||
WDTO_15MS default if no timeout provided
|
||||
WDTO_30MS
|
||||
WDTO_60MS
|
||||
WDTO_120MS
|
||||
WDTO_250MS
|
||||
WDTO_500MS
|
||||
WDTO_1S
|
||||
WDTO_2S
|
||||
WDTO_4S (if supported)
|
||||
WDTO_8S (if supported)
|
||||
|
||||
examples-
|
||||
WD_SET(WD_RST,WDTO_1S); //reset mode, 1s timeout
|
||||
WD_SET(WD_OFF); //watchdog disabled (if not fused on)
|
||||
WD_SET(WD_RST); //reset mode, 15ms (default timeout)
|
||||
WD_SET(WD_IRQ,WDTO_120MS); //interrupt only mode, 120ms timeout
|
||||
WD_SET(WD_RST_IRQ,WDTO_2S); //interrupt+reset mode, 2S timeout
|
||||
|
||||
|
||||
for enhanced watchdogs, if the watchdog is not being used WDRF should be
|
||||
cleared on every power up or reset, along with disabling the watchdog-
|
||||
WD_DISABLE(); //clear WDRF, then turn off watchdog
|
||||
|
||||
*/
|
||||
|
||||
//reset registers to the same name (MCUCSR)
|
||||
#if !defined(MCUCSR)
|
||||
#define MCUCSR MCUSR
|
||||
#endif
|
||||
|
||||
//watchdog registers to the same name (WDTCSR)
|
||||
#if !defined(WDTCSR)
|
||||
#define WDTCSR WDTCR
|
||||
#endif
|
||||
|
||||
//if enhanced watchdog, define irq values, create disable macro
|
||||
#if defined(WDIF)
|
||||
#define WD_IRQ 0xC0
|
||||
#define WD_RST_IRQ 0xC8
|
||||
#define WD_DISABLE() do{ \
|
||||
MCUCSR &= ~(1<<WDRF); \
|
||||
WD_SET(WD_OFF); \
|
||||
}while(0)
|
||||
#endif
|
||||
|
||||
//all watchdogs
|
||||
#define WD_RST 8
|
||||
#define WD_OFF 0
|
||||
|
||||
//prescale values
|
||||
#define WDTO_15MS 0
|
||||
#define WDTO_30MS 1
|
||||
#define WDTO_60MS 2
|
||||
#define WDTO_120MS 3
|
||||
#define WDTO_250MS 4
|
||||
#define WDTO_500MS 5
|
||||
#define WDTO_1S 6
|
||||
#define WDTO_2S 7
|
||||
|
||||
//prescale values for avrs with WDP3
|
||||
#if defined(WDP3)
|
||||
#define WDTO_4S 0x20
|
||||
#define WDTO_8S 0x21
|
||||
#endif
|
||||
|
||||
//watchdog reset
|
||||
#define WDR() __asm__ __volatile__("wdr")
|
||||
|
||||
//avr reset using watchdog
|
||||
#define WD_AVR_RESET() do{ \
|
||||
__asm__ __volatile__("cli"); \
|
||||
WD_SET_UNSAFE(WD_RST); \
|
||||
while(1); \
|
||||
}while(0)
|
||||
|
||||
/*set the watchdog-
|
||||
1. save SREG
|
||||
2. turn off irq's
|
||||
3. reset watchdog timer
|
||||
4. enable watchdog change
|
||||
5. write watchdog value
|
||||
6. restore SREG (restoring irq status)
|
||||
*/
|
||||
#define WD_SET(val,...) \
|
||||
__asm__ __volatile__( \
|
||||
"in __tmp_reg__,__SREG__" "\n\t" \
|
||||
"cli" "\n\t" \
|
||||
"wdr" "\n\t" \
|
||||
"sts %[wdreg],%[wden]" "\n\t" \
|
||||
"sts %[wdreg],%[wdval]" "\n\t" \
|
||||
"out __SREG__,__tmp_reg__" "\n\t" \
|
||||
: \
|
||||
: [wdreg] "M" (&WDTCSR), \
|
||||
[wden] "r" ((uint8_t)(0x18)), \
|
||||
[wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
|
||||
: "r0" \
|
||||
)
|
||||
|
||||
/*set the watchdog when I bit in SREG known to be clear-
|
||||
1. reset watchdog timer
|
||||
2. enable watchdog change
|
||||
5. write watchdog value
|
||||
*/
|
||||
#define WD_SET_UNSAFE(val,...) \
|
||||
__asm__ __volatile__( \
|
||||
"wdr" "\n\t" \
|
||||
"sts %[wdreg],%[wden]" "\n\t" \
|
||||
"sts %[wdreg],%[wdval]" "\n\t" \
|
||||
: \
|
||||
: [wdreg] "M" (&WDTCSR), \
|
||||
[wden] "r" ((uint8_t)(0x18)), \
|
||||
[wdval] "r" ((uint8_t)(val|(__VA_ARGS__+0))) \
|
||||
)
|
||||
|
||||
|
||||
//for compatibility with avr/wdt.h
|
||||
#define wdt_enable(val) WD_SET(WD_RST,val)
|
||||
#define wdt_disable() WD_SET(WD_OFF)
|
||||
|
||||
|
||||
#endif /* _AVR_WD_H_ */
|
59
tmk_core/protocol/lufa.mk
Normal file
59
tmk_core/protocol/lufa.mk
Normal file
|
@ -0,0 +1,59 @@
|
|||
LUFA_DIR = protocol/lufa
|
||||
|
||||
# Path to the LUFA library
|
||||
LUFA_PATH ?= $(LUFA_DIR)/LUFA-git
|
||||
|
||||
|
||||
# Create the LUFA source path variables by including the LUFA makefile
|
||||
ifneq (, $(wildcard $(TMK_DIR)/$(LUFA_PATH)/LUFA/Build/lufa_sources.mk))
|
||||
# New build system from 20120730
|
||||
LUFA_ROOT_PATH = $(LUFA_PATH)/LUFA
|
||||
include $(TMK_DIR)/$(LUFA_PATH)/LUFA/Build/lufa_sources.mk
|
||||
else
|
||||
include $(TMK_DIR)/$(LUFA_PATH)/LUFA/makefile
|
||||
endif
|
||||
|
||||
LUFA_SRC = $(LUFA_DIR)/lufa.c \
|
||||
$(LUFA_DIR)/descriptor.c \
|
||||
$(LUFA_SRC_USB)
|
||||
|
||||
ifdef MIDI_ENABLE
|
||||
LUFA_SRC += $(LUFA_DIR)/midi/midi.c \
|
||||
$(LUFA_DIR)/midi/midi_device.c \
|
||||
$(LUFA_DIR)/midi/bytequeue/bytequeue.c \
|
||||
$(LUFA_DIR)/midi/bytequeue/interrupt_setting.c \
|
||||
$(LUFA_SRC_USBCLASS)
|
||||
endif
|
||||
|
||||
ifdef BLUETOOTH_ENABLE
|
||||
LUFA_SRC += $(LUFA_DIR)/bluetooth.c \
|
||||
$(TMK_DIR)/protocol/serial_uart.c
|
||||
endif
|
||||
|
||||
SRC += $(LUFA_SRC)
|
||||
|
||||
# Search Path
|
||||
VPATH += $(TMK_DIR)/$(LUFA_DIR)
|
||||
VPATH += $(TMK_DIR)/$(LUFA_PATH)
|
||||
|
||||
# Option modules
|
||||
#ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)
|
||||
#endif
|
||||
|
||||
#ifdef EXTRAKEY_ENABLE
|
||||
#endif
|
||||
|
||||
# LUFA library compile-time options and predefined tokens
|
||||
LUFA_OPTS = -DUSB_DEVICE_ONLY
|
||||
LUFA_OPTS += -DUSE_FLASH_DESCRIPTORS
|
||||
LUFA_OPTS += -DUSE_STATIC_OPTIONS="(USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)"
|
||||
#LUFA_OPTS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||
LUFA_OPTS += -DFIXED_CONTROL_ENDPOINT_SIZE=8
|
||||
LUFA_OPTS += -DFIXED_NUM_CONFIGURATIONS=1
|
||||
|
||||
OPT_DEFS += -DF_USB=$(F_USB)UL
|
||||
OPT_DEFS += -DARCH=ARCH_$(ARCH)
|
||||
OPT_DEFS += $(LUFA_OPTS)
|
||||
|
||||
# This indicates using LUFA stack
|
||||
OPT_DEFS += -DPROTOCOL_LUFA
|
14
tmk_core/protocol/lufa/LUFA-git/.gitignore
vendored
Normal file
14
tmk_core/protocol/lufa/LUFA-git/.gitignore
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
*.o
|
||||
*.d
|
||||
*.elf
|
||||
*.hex
|
||||
*.eep
|
||||
*.sym
|
||||
*.bin
|
||||
*.lss
|
||||
*.map
|
||||
*.bak
|
||||
*.class
|
||||
Documentation/
|
||||
LUFA/StudioIntegration/ProjectGenerator/*
|
||||
LUFA/StudioIntegration/DocBook/*
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Bootloader user application API functions.
|
||||
*/
|
||||
|
||||
#include "BootloaderAPI.h"
|
||||
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_erase_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_WritePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_write_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word)
|
||||
{
|
||||
boot_page_fill_safe(Address, Word);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address)
|
||||
{
|
||||
return boot_signature_byte_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadLock(void)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(GET_LOCK_BITS);
|
||||
}
|
||||
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits)
|
||||
{
|
||||
boot_lock_bits_set_safe(LockBits);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderAPI.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_API_H_
|
||||
#define _BOOTLOADER_API_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/boot.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
|
||||
#include "Config/AppConfig.h"
|
||||
|
||||
/* Function Prototypes: */
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address);
|
||||
void BootloaderAPI_WritePage(const uint32_t Address);
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word);
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadLock(void);
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
; Trampolines to actual API implementations if the target address is outside the
|
||||
; range of a rjmp instruction (can happen with large bootloader sections)
|
||||
.section .apitable_trampolines, "ax"
|
||||
.global BootloaderAPI_Trampolines
|
||||
BootloaderAPI_Trampolines:
|
||||
|
||||
BootloaderAPI_ErasePage_Trampoline:
|
||||
jmp BootloaderAPI_ErasePage
|
||||
BootloaderAPI_WritePage_Trampoline:
|
||||
jmp BootloaderAPI_WritePage
|
||||
BootloaderAPI_FillWord_Trampoline:
|
||||
jmp BootloaderAPI_FillWord
|
||||
BootloaderAPI_ReadSignature_Trampoline:
|
||||
jmp BootloaderAPI_ReadSignature
|
||||
BootloaderAPI_ReadFuse_Trampoline:
|
||||
jmp BootloaderAPI_ReadFuse
|
||||
BootloaderAPI_ReadLock_Trampoline:
|
||||
jmp BootloaderAPI_ReadLock
|
||||
BootloaderAPI_WriteLock_Trampoline:
|
||||
jmp BootloaderAPI_WriteLock
|
||||
BootloaderAPI_UNUSED1:
|
||||
ret
|
||||
BootloaderAPI_UNUSED2:
|
||||
ret
|
||||
BootloaderAPI_UNUSED3:
|
||||
ret
|
||||
BootloaderAPI_UNUSED4:
|
||||
ret
|
||||
BootloaderAPI_UNUSED5:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; API function jump table
|
||||
.section .apitable_jumptable, "ax"
|
||||
.global BootloaderAPI_JumpTable
|
||||
BootloaderAPI_JumpTable:
|
||||
|
||||
rjmp BootloaderAPI_ErasePage_Trampoline
|
||||
rjmp BootloaderAPI_WritePage_Trampoline
|
||||
rjmp BootloaderAPI_FillWord_Trampoline
|
||||
rjmp BootloaderAPI_ReadSignature_Trampoline
|
||||
rjmp BootloaderAPI_ReadFuse_Trampoline
|
||||
rjmp BootloaderAPI_ReadLock_Trampoline
|
||||
rjmp BootloaderAPI_WriteLock_Trampoline
|
||||
rjmp BootloaderAPI_UNUSED1 ; UNUSED ENTRY 1
|
||||
rjmp BootloaderAPI_UNUSED2 ; UNUSED ENTRY 2
|
||||
rjmp BootloaderAPI_UNUSED3 ; UNUSED ENTRY 3
|
||||
rjmp BootloaderAPI_UNUSED4 ; UNUSED ENTRY 4
|
||||
rjmp BootloaderAPI_UNUSED5 ; UNUSED ENTRY 5
|
||||
|
||||
|
||||
|
||||
; Bootloader table signatures and information
|
||||
.section .apitable_signatures, "ax"
|
||||
.global BootloaderAPI_Signatures
|
||||
BootloaderAPI_Signatures:
|
||||
|
||||
.long BOOT_START_ADDR ; Start address of the bootloader
|
||||
.word 0xDF00 ; Signature for the CDC class bootloader
|
||||
.word 0xDCFB ; Signature for a LUFA class bootloader
|
641
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/BootloaderCDC.c
Normal file
641
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/BootloaderCDC.c
Normal file
|
@ -0,0 +1,641 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the CDC class bootloader. This file contains the complete bootloader logic.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_BOOTLOADERCDC_C
|
||||
#include "BootloaderCDC.h"
|
||||
|
||||
/** Contains the current baud rate and other settings of the first virtual serial port. This must be retained as some
|
||||
* operating systems will not open the port unless the settings can be set successfully.
|
||||
*/
|
||||
static CDC_LineEncoding_t LineEncoding = { .BaudRateBPS = 0,
|
||||
.CharFormat = CDC_LINEENCODING_OneStopBit,
|
||||
.ParityType = CDC_PARITY_None,
|
||||
.DataBits = 8 };
|
||||
|
||||
/** Current address counter. This stores the current address of the FLASH or EEPROM as set by the host,
|
||||
* and is used when reading or writing to the AVRs memory (either FLASH or EEPROM depending on the issued
|
||||
* command.)
|
||||
*/
|
||||
static uint32_t CurrAddress;
|
||||
|
||||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
|
||||
* via a watchdog reset. When cleared the bootloader will exit, starting the watchdog and entering an infinite
|
||||
* loop until the AVR restarts and the application runs.
|
||||
*/
|
||||
static bool RunBootloader = true;
|
||||
|
||||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader
|
||||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held
|
||||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value
|
||||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start.
|
||||
*/
|
||||
uint16_t MagicBootKey ATTR_NO_INIT;
|
||||
|
||||
|
||||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application
|
||||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid,
|
||||
* this will force the user application to start via a software jump.
|
||||
*/
|
||||
void Application_Jump_Check(void)
|
||||
{
|
||||
bool JumpToApplication = false;
|
||||
|
||||
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
|
||||
/* Disable JTAG debugging */
|
||||
JTAG_DISABLE();
|
||||
|
||||
/* Enable pull-up on the JTAG TCK pin so we can use it to select the mode */
|
||||
PORTF |= (1 << 4);
|
||||
Delay_MS(10);
|
||||
|
||||
/* If the TCK pin is not jumpered to ground, start the user application instead */
|
||||
JumpToApplication |= ((PINF & (1 << 4)) != 0);
|
||||
|
||||
/* Re-enable JTAG debugging */
|
||||
JTAG_ENABLE();
|
||||
#endif
|
||||
|
||||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
|
||||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
|
||||
JumpToApplication |= true;
|
||||
|
||||
/* If a request has been made to jump to the user application, honor it */
|
||||
if (JumpToApplication)
|
||||
{
|
||||
/* Turn off the watchdog */
|
||||
MCUSR &= ~(1<<WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Clear the boot key and jump to the user application */
|
||||
MagicBootKey = 0;
|
||||
|
||||
// cppcheck-suppress constStatement
|
||||
((void (*)(void))0x0000)();
|
||||
}
|
||||
}
|
||||
|
||||
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
|
||||
* runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start
|
||||
* the loaded application code.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
/* Setup hardware required for the bootloader */
|
||||
SetupHardware();
|
||||
|
||||
/* Turn on first LED on the board to indicate that the bootloader has started */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Enable global interrupts so that the USB stack can function */
|
||||
GlobalInterruptEnable();
|
||||
|
||||
while (RunBootloader)
|
||||
{
|
||||
CDC_Task();
|
||||
USB_USBTask();
|
||||
}
|
||||
|
||||
/* Disconnect from the host - USB interface will be reset later along with the AVR */
|
||||
USB_Detach();
|
||||
|
||||
/* Unlock the forced application start mode of the bootloader if it is restarted */
|
||||
MagicBootKey = MAGIC_BOOT_KEY;
|
||||
|
||||
/* Enable the watchdog and force a timeout to reset the AVR */
|
||||
wdt_enable(WDTO_250MS);
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
/** Configures all hardware required for the bootloader. */
|
||||
static void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Relocate the interrupt vector table to the bootloader section */
|
||||
MCUCR = (1 << IVCE);
|
||||
MCUCR = (1 << IVSEL);
|
||||
|
||||
/* Initialize the USB and other board hardware drivers */
|
||||
USB_Init();
|
||||
LEDs_Init();
|
||||
|
||||
/* Bootloader active LED toggle timer initialization */
|
||||
TIMSK1 = (1 << TOIE1);
|
||||
TCCR1B = ((1 << CS11) | (1 << CS10));
|
||||
}
|
||||
|
||||
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */
|
||||
ISR(TIMER1_OVF_vect, ISR_BLOCK)
|
||||
{
|
||||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
|
||||
* to relay data to and from the attached USB host.
|
||||
*/
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
/* Setup CDC Notification, Rx and Tx Endpoints */
|
||||
Endpoint_ConfigureEndpoint(CDC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT,
|
||||
CDC_NOTIFICATION_EPSIZE, 1);
|
||||
|
||||
Endpoint_ConfigureEndpoint(CDC_TX_EPADDR, EP_TYPE_BULK, CDC_TXRX_EPSIZE, 1);
|
||||
|
||||
Endpoint_ConfigureEndpoint(CDC_RX_EPADDR, EP_TYPE_BULK, CDC_TXRX_EPSIZE, 1);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
|
||||
* the device from the USB host before passing along unhandled control requests to the library for processing
|
||||
* internally.
|
||||
*/
|
||||
void EVENT_USB_Device_ControlRequest(void)
|
||||
{
|
||||
/* Ignore any requests that aren't directed to the CDC interface */
|
||||
if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) !=
|
||||
(REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Activity - toggle indicator LEDs */
|
||||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
|
||||
|
||||
/* Process CDC specific control requests */
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case CDC_REQ_GetLineEncoding:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Write the line coding data to the control endpoint */
|
||||
Endpoint_Write_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t));
|
||||
Endpoint_ClearOUT();
|
||||
}
|
||||
|
||||
break;
|
||||
case CDC_REQ_SetLineEncoding:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Read the line coding data in from the host into the global struct */
|
||||
Endpoint_Read_Control_Stream_LE(&LineEncoding, sizeof(CDC_LineEncoding_t));
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
break;
|
||||
case CDC_REQ_SetControlLineState:
|
||||
if (USB_ControlRequest.bmRequestType == (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
Endpoint_ClearSETUP();
|
||||
Endpoint_ClearStatusStage();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(NO_BLOCK_SUPPORT)
|
||||
/** Reads or writes a block of EEPROM or FLASH memory to or from the appropriate CDC data endpoint, depending
|
||||
* on the AVR109 protocol command issued.
|
||||
*
|
||||
* \param[in] Command Single character AVR109 protocol command indicating what memory operation to perform
|
||||
*/
|
||||
static void ReadWriteMemoryBlock(const uint8_t Command)
|
||||
{
|
||||
uint16_t BlockSize;
|
||||
char MemoryType;
|
||||
|
||||
uint8_t HighByte = 0;
|
||||
uint8_t LowByte = 0;
|
||||
|
||||
BlockSize = (FetchNextCommandByte() << 8);
|
||||
BlockSize |= FetchNextCommandByte();
|
||||
|
||||
MemoryType = FetchNextCommandByte();
|
||||
|
||||
if ((MemoryType != MEMORY_TYPE_FLASH) && (MemoryType != MEMORY_TYPE_EEPROM))
|
||||
{
|
||||
/* Send error byte back to the host */
|
||||
WriteNextResponseByte('?');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Check if command is to read a memory block */
|
||||
if (Command == AVR109_COMMAND_BlockRead)
|
||||
{
|
||||
/* Re-enable RWW section */
|
||||
boot_rww_enable();
|
||||
|
||||
while (BlockSize--)
|
||||
{
|
||||
if (MemoryType == MEMORY_TYPE_FLASH)
|
||||
{
|
||||
/* Read the next FLASH byte from the current FLASH page */
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
WriteNextResponseByte(pgm_read_byte_far(CurrAddress | HighByte));
|
||||
#else
|
||||
WriteNextResponseByte(pgm_read_byte(CurrAddress | HighByte));
|
||||
#endif
|
||||
|
||||
/* If both bytes in current word have been read, increment the address counter */
|
||||
if (HighByte)
|
||||
CurrAddress += 2;
|
||||
|
||||
HighByte = !HighByte;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Read the next EEPROM byte into the endpoint */
|
||||
WriteNextResponseByte(eeprom_read_byte((uint8_t*)(intptr_t)(CurrAddress >> 1)));
|
||||
|
||||
/* Increment the address counter after use */
|
||||
CurrAddress += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t PageStartAddress = CurrAddress;
|
||||
|
||||
if (MemoryType == MEMORY_TYPE_FLASH)
|
||||
{
|
||||
boot_page_erase(PageStartAddress);
|
||||
boot_spm_busy_wait();
|
||||
}
|
||||
|
||||
while (BlockSize--)
|
||||
{
|
||||
if (MemoryType == MEMORY_TYPE_FLASH)
|
||||
{
|
||||
/* If both bytes in current word have been written, increment the address counter */
|
||||
if (HighByte)
|
||||
{
|
||||
/* Write the next FLASH word to the current FLASH page */
|
||||
boot_page_fill(CurrAddress, ((FetchNextCommandByte() << 8) | LowByte));
|
||||
|
||||
/* Increment the address counter after use */
|
||||
CurrAddress += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
LowByte = FetchNextCommandByte();
|
||||
}
|
||||
|
||||
HighByte = !HighByte;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write the next EEPROM byte from the endpoint */
|
||||
eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte());
|
||||
|
||||
/* Increment the address counter after use */
|
||||
CurrAddress += 2;
|
||||
}
|
||||
}
|
||||
|
||||
/* If in FLASH programming mode, commit the page after writing */
|
||||
if (MemoryType == MEMORY_TYPE_FLASH)
|
||||
{
|
||||
/* Commit the flash page to memory */
|
||||
boot_page_write(PageStartAddress);
|
||||
|
||||
/* Wait until write operation has completed */
|
||||
boot_spm_busy_wait();
|
||||
}
|
||||
|
||||
/* Send response byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Retrieves the next byte from the host in the CDC data OUT endpoint, and clears the endpoint bank if needed
|
||||
* to allow reception of the next data packet from the host.
|
||||
*
|
||||
* \return Next received byte from the host in the CDC data OUT endpoint
|
||||
*/
|
||||
static uint8_t FetchNextCommandByte(void)
|
||||
{
|
||||
/* Select the OUT endpoint so that the next data byte can be read */
|
||||
Endpoint_SelectEndpoint(CDC_RX_EPADDR);
|
||||
|
||||
/* If OUT endpoint empty, clear it and wait for the next packet from the host */
|
||||
while (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
while (!(Endpoint_IsOUTReceived()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fetch the next byte from the OUT endpoint */
|
||||
return Endpoint_Read_8();
|
||||
}
|
||||
|
||||
/** Writes the next response byte to the CDC data IN endpoint, and sends the endpoint back if needed to free up the
|
||||
* bank when full ready for the next byte in the packet to the host.
|
||||
*
|
||||
* \param[in] Response Next response byte to send to the host
|
||||
*/
|
||||
static void WriteNextResponseByte(const uint8_t Response)
|
||||
{
|
||||
/* Select the IN endpoint so that the next data byte can be written */
|
||||
Endpoint_SelectEndpoint(CDC_TX_EPADDR);
|
||||
|
||||
/* If IN endpoint full, clear it and wait until ready for the next packet to the host */
|
||||
if (!(Endpoint_IsReadWriteAllowed()))
|
||||
{
|
||||
Endpoint_ClearIN();
|
||||
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the next byte to the IN endpoint */
|
||||
Endpoint_Write_8(Response);
|
||||
}
|
||||
|
||||
/** Task to read in AVR109 commands from the CDC data OUT endpoint, process them, perform the required actions
|
||||
* and send the appropriate response back to the host.
|
||||
*/
|
||||
static void CDC_Task(void)
|
||||
{
|
||||
/* Select the OUT endpoint */
|
||||
Endpoint_SelectEndpoint(CDC_RX_EPADDR);
|
||||
|
||||
/* Check if endpoint has a command in it sent from the host */
|
||||
if (!(Endpoint_IsOUTReceived()))
|
||||
return;
|
||||
|
||||
/* Read in the bootloader command (first byte sent from host) */
|
||||
uint8_t Command = FetchNextCommandByte();
|
||||
|
||||
if (Command == AVR109_COMMAND_ExitBootloader)
|
||||
{
|
||||
RunBootloader = false;
|
||||
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
else if ((Command == AVR109_COMMAND_SetLED) || (Command == AVR109_COMMAND_ClearLED) ||
|
||||
(Command == AVR109_COMMAND_SelectDeviceType))
|
||||
{
|
||||
FetchNextCommandByte();
|
||||
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
else if ((Command == AVR109_COMMAND_EnterProgrammingMode) || (Command == AVR109_COMMAND_LeaveProgrammingMode))
|
||||
{
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadPartCode)
|
||||
{
|
||||
/* Return ATMEGA128 part code - this is only to allow AVRProg to use the bootloader */
|
||||
WriteNextResponseByte(0x44);
|
||||
WriteNextResponseByte(0x00);
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadAutoAddressIncrement)
|
||||
{
|
||||
/* Indicate auto-address increment is supported */
|
||||
WriteNextResponseByte('Y');
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_SetCurrentAddress)
|
||||
{
|
||||
/* Set the current address to that given by the host (translate 16-bit word address to byte address) */
|
||||
CurrAddress = (FetchNextCommandByte() << 9);
|
||||
CurrAddress |= (FetchNextCommandByte() << 1);
|
||||
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadBootloaderInterface)
|
||||
{
|
||||
/* Indicate serial programmer back to the host */
|
||||
WriteNextResponseByte('S');
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadBootloaderIdentifier)
|
||||
{
|
||||
/* Write the 7-byte software identifier to the endpoint */
|
||||
for (uint8_t CurrByte = 0; CurrByte < 7; CurrByte++)
|
||||
WriteNextResponseByte(SOFTWARE_IDENTIFIER[CurrByte]);
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadBootloaderSWVersion)
|
||||
{
|
||||
WriteNextResponseByte('0' + BOOTLOADER_VERSION_MAJOR);
|
||||
WriteNextResponseByte('0' + BOOTLOADER_VERSION_MINOR);
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadSignature)
|
||||
{
|
||||
WriteNextResponseByte(AVR_SIGNATURE_3);
|
||||
WriteNextResponseByte(AVR_SIGNATURE_2);
|
||||
WriteNextResponseByte(AVR_SIGNATURE_1);
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_EraseFLASH)
|
||||
{
|
||||
/* Clear the application section of flash */
|
||||
for (uint32_t CurrFlashAddress = 0; CurrFlashAddress < (uint32_t)BOOT_START_ADDR; CurrFlashAddress += SPM_PAGESIZE)
|
||||
{
|
||||
boot_page_erase(CurrFlashAddress);
|
||||
boot_spm_busy_wait();
|
||||
boot_page_write(CurrFlashAddress);
|
||||
boot_spm_busy_wait();
|
||||
}
|
||||
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
#if !defined(NO_LOCK_BYTE_WRITE_SUPPORT)
|
||||
else if (Command == AVR109_COMMAND_WriteLockbits)
|
||||
{
|
||||
/* Set the lock bits to those given by the host */
|
||||
boot_lock_bits_set(FetchNextCommandByte());
|
||||
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
#endif
|
||||
else if (Command == AVR109_COMMAND_ReadLockbits)
|
||||
{
|
||||
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOCK_BITS));
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadLowFuses)
|
||||
{
|
||||
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_LOW_FUSE_BITS));
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadHighFuses)
|
||||
{
|
||||
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_HIGH_FUSE_BITS));
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadExtendedFuses)
|
||||
{
|
||||
WriteNextResponseByte(boot_lock_fuse_bits_get(GET_EXTENDED_FUSE_BITS));
|
||||
}
|
||||
#if !defined(NO_BLOCK_SUPPORT)
|
||||
else if (Command == AVR109_COMMAND_GetBlockWriteSupport)
|
||||
{
|
||||
WriteNextResponseByte('Y');
|
||||
|
||||
/* Send block size to the host */
|
||||
WriteNextResponseByte(SPM_PAGESIZE >> 8);
|
||||
WriteNextResponseByte(SPM_PAGESIZE & 0xFF);
|
||||
}
|
||||
else if ((Command == AVR109_COMMAND_BlockWrite) || (Command == AVR109_COMMAND_BlockRead))
|
||||
{
|
||||
/* Delegate the block write/read to a separate function for clarity */
|
||||
ReadWriteMemoryBlock(Command);
|
||||
}
|
||||
#endif
|
||||
#if !defined(NO_FLASH_BYTE_SUPPORT)
|
||||
else if (Command == AVR109_COMMAND_FillFlashPageWordHigh)
|
||||
{
|
||||
/* Write the high byte to the current flash page */
|
||||
boot_page_fill(CurrAddress, FetchNextCommandByte());
|
||||
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_FillFlashPageWordLow)
|
||||
{
|
||||
/* Write the low byte to the current flash page */
|
||||
boot_page_fill(CurrAddress | 0x01, FetchNextCommandByte());
|
||||
|
||||
/* Increment the address */
|
||||
CurrAddress += 2;
|
||||
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_WriteFlashPage)
|
||||
{
|
||||
/* Commit the flash page to memory */
|
||||
boot_page_write(CurrAddress);
|
||||
|
||||
/* Wait until write operation has completed */
|
||||
boot_spm_busy_wait();
|
||||
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadFLASHWord)
|
||||
{
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
uint16_t ProgramWord = pgm_read_word_far(CurrAddress);
|
||||
#else
|
||||
uint16_t ProgramWord = pgm_read_word(CurrAddress);
|
||||
#endif
|
||||
|
||||
WriteNextResponseByte(ProgramWord >> 8);
|
||||
WriteNextResponseByte(ProgramWord & 0xFF);
|
||||
}
|
||||
#endif
|
||||
#if !defined(NO_EEPROM_BYTE_SUPPORT)
|
||||
else if (Command == AVR109_COMMAND_WriteEEPROM)
|
||||
{
|
||||
/* Read the byte from the endpoint and write it to the EEPROM */
|
||||
eeprom_write_byte((uint8_t*)((intptr_t)(CurrAddress >> 1)), FetchNextCommandByte());
|
||||
|
||||
/* Increment the address after use */
|
||||
CurrAddress += 2;
|
||||
|
||||
/* Send confirmation byte back to the host */
|
||||
WriteNextResponseByte('\r');
|
||||
}
|
||||
else if (Command == AVR109_COMMAND_ReadEEPROM)
|
||||
{
|
||||
/* Read the EEPROM byte and write it to the endpoint */
|
||||
WriteNextResponseByte(eeprom_read_byte((uint8_t*)((intptr_t)(CurrAddress >> 1))));
|
||||
|
||||
/* Increment the address after use */
|
||||
CurrAddress += 2;
|
||||
}
|
||||
#endif
|
||||
else if (Command != AVR109_COMMAND_Sync)
|
||||
{
|
||||
/* Unknown (non-sync) command, return fail code */
|
||||
WriteNextResponseByte('?');
|
||||
}
|
||||
|
||||
/* Select the IN endpoint */
|
||||
Endpoint_SelectEndpoint(CDC_TX_EPADDR);
|
||||
|
||||
/* Remember if the endpoint is completely full before clearing it */
|
||||
bool IsEndpointFull = !(Endpoint_IsReadWriteAllowed());
|
||||
|
||||
/* Send the endpoint data to the host */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* If a full endpoint's worth of data was sent, we need to send an empty packet afterwards to signal end of transfer */
|
||||
if (IsEndpointFull)
|
||||
{
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
Endpoint_ClearIN();
|
||||
}
|
||||
|
||||
/* Wait until the data has been sent to the host */
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Select the OUT endpoint */
|
||||
Endpoint_SelectEndpoint(CDC_RX_EPADDR);
|
||||
|
||||
/* Acknowledge the command from the host */
|
||||
Endpoint_ClearOUT();
|
||||
}
|
||||
|
144
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/BootloaderCDC.h
Normal file
144
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/BootloaderCDC.h
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderCDC.c.
|
||||
*/
|
||||
|
||||
#ifndef _CDC_H_
|
||||
#define _CDC_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
#include "BootloaderAPI.h"
|
||||
#include "Config/AppConfig.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Platform/Platform.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__OPTIMIZE_SIZE__)
|
||||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** Version major of the CDC bootloader. */
|
||||
#define BOOTLOADER_VERSION_MAJOR 0x01
|
||||
|
||||
/** Version minor of the CDC bootloader. */
|
||||
#define BOOTLOADER_VERSION_MINOR 0x00
|
||||
|
||||
/** Hardware version major of the CDC bootloader. */
|
||||
#define BOOTLOADER_HWVERSION_MAJOR 0x01
|
||||
|
||||
/** Hardware version minor of the CDC bootloader. */
|
||||
#define BOOTLOADER_HWVERSION_MINOR 0x00
|
||||
|
||||
/** Eight character bootloader firmware identifier reported to the host when requested. */
|
||||
#define SOFTWARE_IDENTIFIER "LUFACDC"
|
||||
|
||||
/** Magic bootloader key to unlock forced application start mode. */
|
||||
#define MAGIC_BOOT_KEY 0xDC42
|
||||
|
||||
/* Enums: */
|
||||
/** Possible memory types that can be addressed via the bootloader. */
|
||||
enum AVR109_Memories
|
||||
{
|
||||
MEMORY_TYPE_FLASH = 'F',
|
||||
MEMORY_TYPE_EEPROM = 'E',
|
||||
};
|
||||
|
||||
/** Possible commands that can be issued to the bootloader. */
|
||||
enum AVR109_Commands
|
||||
{
|
||||
AVR109_COMMAND_Sync = 27,
|
||||
AVR109_COMMAND_ReadEEPROM = 'd',
|
||||
AVR109_COMMAND_WriteEEPROM = 'D',
|
||||
AVR109_COMMAND_ReadFLASHWord = 'R',
|
||||
AVR109_COMMAND_WriteFlashPage = 'm',
|
||||
AVR109_COMMAND_FillFlashPageWordLow = 'c',
|
||||
AVR109_COMMAND_FillFlashPageWordHigh = 'C',
|
||||
AVR109_COMMAND_GetBlockWriteSupport = 'b',
|
||||
AVR109_COMMAND_BlockWrite = 'B',
|
||||
AVR109_COMMAND_BlockRead = 'g',
|
||||
AVR109_COMMAND_ReadExtendedFuses = 'Q',
|
||||
AVR109_COMMAND_ReadHighFuses = 'N',
|
||||
AVR109_COMMAND_ReadLowFuses = 'F',
|
||||
AVR109_COMMAND_ReadLockbits = 'r',
|
||||
AVR109_COMMAND_WriteLockbits = 'l',
|
||||
AVR109_COMMAND_EraseFLASH = 'e',
|
||||
AVR109_COMMAND_ReadSignature = 's',
|
||||
AVR109_COMMAND_ReadBootloaderSWVersion = 'V',
|
||||
AVR109_COMMAND_ReadBootloaderHWVersion = 'v',
|
||||
AVR109_COMMAND_ReadBootloaderIdentifier = 'S',
|
||||
AVR109_COMMAND_ReadBootloaderInterface = 'p',
|
||||
AVR109_COMMAND_SetCurrentAddress = 'A',
|
||||
AVR109_COMMAND_ReadAutoAddressIncrement = 'a',
|
||||
AVR109_COMMAND_ReadPartCode = 't',
|
||||
AVR109_COMMAND_EnterProgrammingMode = 'P',
|
||||
AVR109_COMMAND_LeaveProgrammingMode = 'L',
|
||||
AVR109_COMMAND_SelectDeviceType = 'T',
|
||||
AVR109_COMMAND_SetLED = 'x',
|
||||
AVR109_COMMAND_ClearLED = 'y',
|
||||
AVR109_COMMAND_ExitBootloader = 'E',
|
||||
};
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a non-returning pointer to the start of the loaded application in flash memory. */
|
||||
typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
|
||||
|
||||
/* Function Prototypes: */
|
||||
static void CDC_Task(void);
|
||||
static void SetupHardware(void);
|
||||
|
||||
void Application_Jump_Check(void) ATTR_INIT_SECTION(3);
|
||||
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_BOOTLOADERCDC_C) || defined(__DOXYGEN__)
|
||||
#if !defined(NO_BLOCK_SUPPORT)
|
||||
static void ReadWriteMemoryBlock(const uint8_t Command);
|
||||
#endif
|
||||
static uint8_t FetchNextCommandByte(void);
|
||||
static void WriteNextResponseByte(const uint8_t Response);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,240 @@
|
|||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage CDC Class USB AVR Bootloader
|
||||
*
|
||||
* \section Sec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* \li Series 7 USB AVRs (AT90USBxxx7)
|
||||
* \li Series 6 USB AVRs (AT90USBxxx6)
|
||||
* \li Series 4 USB AVRs (ATMEGAxxU4)
|
||||
* \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2)
|
||||
*
|
||||
* \section Sec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Communications Device Class (CDC)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Abstract Control Model (ACM)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF CDC Class Standard</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Supported USB Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section Sec_Description Project Description:
|
||||
*
|
||||
* This bootloader enumerates to the host as a CDC Class device (virtual serial port), allowing for AVR109
|
||||
* protocol compatible programming software to load firmware onto the AVR.
|
||||
*
|
||||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit
|
||||
* into 4KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to
|
||||
* edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile.
|
||||
*
|
||||
* When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the
|
||||
* bootloader from the normal user application.
|
||||
*
|
||||
* \warning <b>THIS BOOTLOADER IS NOT SECURE.</b> Malicious entities can recover written data, even if the device
|
||||
* lockbits are set.
|
||||
*
|
||||
* \section Sec_Running Running the Bootloader
|
||||
*
|
||||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
|
||||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
|
||||
* fuse is cleared.
|
||||
*
|
||||
* For board specific exceptions to the above, see below.
|
||||
*
|
||||
* \subsection SSec_XPLAIN Atmel Xplain Board
|
||||
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the
|
||||
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
|
||||
*
|
||||
* \subsection SSec_Leonardo Arduino Leonardo Board
|
||||
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the
|
||||
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
|
||||
*
|
||||
* \section Sec_Installation Driver Installation
|
||||
*
|
||||
* After running this bootloader for the first time on a new computer, you will need to supply the .INF
|
||||
* file located in this bootloader project's directory as the device's driver when running under Windows.
|
||||
* This will enable Windows to use its inbuilt CDC drivers, negating the need for custom drivers for the
|
||||
* device. Other Operating Systems should automatically use their own inbuilt CDC-ACM drivers.
|
||||
*
|
||||
* \section Sec_HostApp Host Controller Application
|
||||
*
|
||||
* This bootloader is compatible with the open source application AVRDUDE, Atmel's AVRPROG, or other
|
||||
* applications implementing the AVR109 protocol, which is documented on the Atmel website as an application
|
||||
* note.
|
||||
*
|
||||
* \subsection SSec_AVRDude AVRDUDE (Windows, Mac, Linux)
|
||||
*
|
||||
* AVRDude is a free, cross-platform and open source command line programmer for Atmel and third party AVR
|
||||
* programmers. It is available on the the Windows platform as part of the "WinAVR" package, or on other systems
|
||||
* either from a build from the official source code, or in many distributions as a precompiled binary package.
|
||||
*
|
||||
* To load a new HEX file with AVRDude, specify "AVR109" as the programmer, with the allocated COM port. On Windows
|
||||
* platforms this will be a COMx port name:
|
||||
* \code
|
||||
* avrdude -c AVR109 -p at90usb1287 -P COM0 -U flash:w:Mouse.hex
|
||||
* \endcode
|
||||
*
|
||||
* On Linux systems, this will typically be a /dev/ttyACMx port name:
|
||||
* \code
|
||||
* avrdude -c AVR109 -p at90usb1287 -P /dev/ttyACM0 -U flash:w:Mouse.hex
|
||||
* \endcode
|
||||
*
|
||||
* Refer to the AVRDude project documentation for additional usage instructions.
|
||||
*
|
||||
* \section Sec_API User Application API
|
||||
*
|
||||
* Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader,
|
||||
* allowing the user application to call into the bootloader at runtime to read and write FLASH data.
|
||||
*
|
||||
* By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the
|
||||
* following layout:
|
||||
*
|
||||
* \code
|
||||
* #define BOOTLOADER_API_TABLE_SIZE 32
|
||||
* #define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE)
|
||||
* #define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2)
|
||||
*
|
||||
* void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0);
|
||||
* void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1);
|
||||
* void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2);
|
||||
* uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3);
|
||||
* uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4);
|
||||
* uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5);
|
||||
* void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6);
|
||||
*
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2))
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB
|
||||
*
|
||||
* #define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4))
|
||||
* #define BOOTLOADER_CDC_SIGNATURE 0xDF00
|
||||
*
|
||||
* #define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8))
|
||||
* #define BOOTLOADER_ADDRESS_LENGTH 4
|
||||
* \endcode
|
||||
*
|
||||
* From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address
|
||||
* \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader
|
||||
* can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them
|
||||
* to the value \c BOOTLOADER_CDC_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes of FLASH
|
||||
* memory starting from address \c BOOTLOADER_ADDRESS_START.
|
||||
*
|
||||
* \subsection SSec_API_MemLayout Device Memory Map
|
||||
* The following illustration indicates the final memory map of the device when loaded with the bootloader.
|
||||
*
|
||||
* \verbatim
|
||||
* +----------------------------+ 0x0000
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | User Application |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE
|
||||
* | |
|
||||
* | Bootloader Application |
|
||||
* | (Not User App. Accessible) |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - 96
|
||||
* | API Table Trampolines |
|
||||
* | (Not User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 32
|
||||
* | Bootloader API Table |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 8
|
||||
* | Bootloader ID Constants |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND
|
||||
* \endverbatim
|
||||
*
|
||||
* \section Sec_KnownIssues Known Issues:
|
||||
*
|
||||
* \par On Linux machines, the CDC bootloader is unstable or inaccessible.
|
||||
* A change to the \c ModemManager module in many Linux distributions causes
|
||||
* this module to try to take control over inserted CDC devices, corrupting the
|
||||
* datastream. A UDEV rule is required to prevent this.
|
||||
* See <a href=https://groups.google.com/d/msg/lufa-support/CP9cy2bc8yo/kBqsOu-RBeMJ>here</a> for resolution steps.
|
||||
* If the issue still persists then uninstall modemmanager by executing <tt>sudo apt-get remove modemmanager</tt>, or
|
||||
* the equivalent using your chosen distribution's package manager.
|
||||
*
|
||||
* \par On Linux machines, the CDC bootloader is inaccessible.
|
||||
* On many Linux systems, non-root users do not have automatic access to newly
|
||||
* inserted CDC devices. Root privileges or a UDEV rule is required to gain
|
||||
* access.
|
||||
* See <a href=https://groups.google.com/d/msg/lufa-support/CP9cy2bc8yo/kBqsOu-RBeMJ>here</a> for resolution steps.
|
||||
*
|
||||
* \par After loading an application, it is not run automatically on startup.
|
||||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader
|
||||
* to run automatically when the device is reset. In most cases, the BOOTRST
|
||||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader
|
||||
* when needed.
|
||||
*
|
||||
* \section Sec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th><b>Define Name:</b></th>
|
||||
* <th><b>Location:</b></th>
|
||||
* <th><b>Description:</b></th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>NO_BLOCK_SUPPORT</td>
|
||||
* <td>AppConfig.h</td>
|
||||
* <td>Define to disable memory block read/write support in the bootloader, requiring all reads and writes to be made
|
||||
* using the byte-level commands.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>NO_EEPROM_BYTE_SUPPORT</td>
|
||||
* <td>AppConfig.h</td>
|
||||
* <td>Define to disable EEPROM memory byte read/write support in the bootloader, requiring all EEPROM reads and writes
|
||||
* to be made using the block-level commands.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>NO_FLASH_BYTE_SUPPORT</td>
|
||||
* <td>AppConfig.h</td>
|
||||
* <td>Define to disable FLASH memory byte read/write support in the bootloader, requiring all FLASH reads and writes
|
||||
* to be made using the block-level commands.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>NO_LOCK_BYTE_WRITE_SUPPORT</td>
|
||||
* <td>AppConfig.h</td>
|
||||
* <td>Define to disable lock byte write support in the bootloader, preventing the lock bits from being set programmatically.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Application Configuration Header File
|
||||
*
|
||||
* This is a header file which is be used to configure LUFA's
|
||||
* compile time options, as an alternative to the compile time
|
||||
* constants supplied through a makefile.
|
||||
*
|
||||
* For information on what each token does, refer to the
|
||||
* \ref Sec_Options section of the application documentation.
|
||||
*/
|
||||
|
||||
#ifndef _APP_CONFIG_H_
|
||||
#define _APP_CONFIG_H_
|
||||
|
||||
// #define NO_BLOCK_SUPPORT
|
||||
// #define NO_EEPROM_BYTE_SUPPORT
|
||||
// #define NO_FLASH_BYTE_SUPPORT
|
||||
// #define NO_LOCK_BYTE_WRITE_SUPPORT
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Library Configuration Header File
|
||||
*
|
||||
* This header file is used to configure LUFA's compile time options,
|
||||
* as an alternative to the compile time constants supplied through
|
||||
* a makefile.
|
||||
*
|
||||
* For information on what each token does, refer to the LUFA
|
||||
* manual section "Summary of Compile Tokens".
|
||||
*/
|
||||
|
||||
#ifndef _LUFA_CONFIG_H_
|
||||
#define _LUFA_CONFIG_H_
|
||||
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
/* Non-USB Related Configuration Tokens: */
|
||||
// #define DISABLE_TERMINAL_CODES
|
||||
|
||||
/* USB Class Driver Related Tokens: */
|
||||
// #define HID_HOST_BOOT_PROTOCOL_ONLY
|
||||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_MAX_COLLECTIONS {Insert Value Here}
|
||||
// #define HID_MAX_REPORTITEMS {Insert Value Here}
|
||||
// #define HID_MAX_REPORT_IDS {Insert Value Here}
|
||||
// #define NO_CLASS_DRIVER_AUTOFLUSH
|
||||
|
||||
/* General USB Driver Related Tokens: */
|
||||
#define ORDERED_EP_CONFIG
|
||||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
|
||||
#define USB_DEVICE_ONLY
|
||||
// #define USB_HOST_ONLY
|
||||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
|
||||
// #define NO_LIMITED_CONTROLLER_CONNECT
|
||||
#define NO_SOF_EVENTS
|
||||
|
||||
/* USB Device Mode Driver Related Tokens: */
|
||||
#define USE_RAM_DESCRIPTORS
|
||||
// #define USE_FLASH_DESCRIPTORS
|
||||
// #define USE_EEPROM_DESCRIPTORS
|
||||
#define NO_INTERNAL_SERIAL
|
||||
#define FIXED_CONTROL_ENDPOINT_SIZE 8
|
||||
#define DEVICE_STATE_AS_GPIOR 0
|
||||
#define FIXED_NUM_CONFIGURATIONS 1
|
||||
// #define CONTROL_ONLY_DEVICE
|
||||
// #define INTERRUPT_CONTROL_ENDPOINT
|
||||
#define NO_DEVICE_REMOTE_WAKEUP
|
||||
#define NO_DEVICE_SELF_POWER
|
||||
|
||||
/* USB Host Mode Driver Related Tokens: */
|
||||
// #define HOST_STATE_AS_GPIOR {Insert Value Here}
|
||||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
|
||||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
|
||||
// #define NO_AUTO_VBUS_MANAGEMENT
|
||||
// #define INVERTED_VBUS_ENABLE_LINE
|
||||
|
||||
#else
|
||||
|
||||
#error Unsupported architecture for this LUFA configuration file.
|
||||
|
||||
#endif
|
||||
#endif
|
244
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/Descriptors.c
Normal file
244
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/Descriptors.c
Normal file
|
@ -0,0 +1,244 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
|
||||
* computer-readable structures which the host requests upon device enumeration, to determine
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
|
||||
* device characteristics, including the supported USB version, control endpoint size and the
|
||||
* number of device configurations. The descriptor is read out by the USB host when the enumeration
|
||||
* process begins.
|
||||
*/
|
||||
const USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(1,1,0),
|
||||
.Class = CDC_CSCP_CDCClass,
|
||||
.SubClass = CDC_CSCP_NoSpecificSubclass,
|
||||
.Protocol = CDC_CSCP_NoSpecificProtocol,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x204A,
|
||||
.ReleaseNumber = VERSION_BCD(1,0,0),
|
||||
|
||||
.ManufacturerStrIndex = STRING_ID_Manufacturer,
|
||||
.ProductStrIndex = STRING_ID_Product,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage
|
||||
* of the device in one of its supported configurations, including information about any device interfaces
|
||||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
|
||||
* a configuration so that the host may correctly communicate with the USB device.
|
||||
*/
|
||||
const USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 2,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.CDC_CCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = INTERFACE_ID_CDC_CCI,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = CDC_CSCP_CDCClass,
|
||||
.SubClass = CDC_CSCP_ACMSubclass,
|
||||
.Protocol = CDC_CSCP_ATCommandProtocol,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC_Functional_Header =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
|
||||
.Subtype = 0x00,
|
||||
|
||||
.CDCSpecification = VERSION_BCD(1,1,0),
|
||||
},
|
||||
|
||||
.CDC_Functional_ACM =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
|
||||
.Subtype = 0x02,
|
||||
|
||||
.Capabilities = 0x02,
|
||||
},
|
||||
|
||||
.CDC_Functional_Union =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
|
||||
.Subtype = 0x06,
|
||||
|
||||
.MasterInterfaceNumber = INTERFACE_ID_CDC_CCI,
|
||||
.SlaveInterfaceNumber = INTERFACE_ID_CDC_DCI,
|
||||
},
|
||||
|
||||
.CDC_NotificationEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = CDC_NOTIFICATION_EPADDR,
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_NOTIFICATION_EPSIZE,
|
||||
.PollingIntervalMS = 0xFF
|
||||
},
|
||||
|
||||
.CDC_DCI_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = INTERFACE_ID_CDC_DCI,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = CDC_CSCP_CDCDataClass,
|
||||
.SubClass = CDC_CSCP_NoDataSubclass,
|
||||
.Protocol = CDC_CSCP_NoDataProtocol,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.CDC_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = CDC_RX_EPADDR,
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x05
|
||||
},
|
||||
|
||||
.CDC_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = CDC_TX_EPADDR,
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = CDC_TXRX_EPSIZE,
|
||||
.PollingIntervalMS = 0x05
|
||||
}
|
||||
};
|
||||
|
||||
/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests
|
||||
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
const USB_Descriptor_String_t LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG);
|
||||
|
||||
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
|
||||
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
||||
* Descriptor.
|
||||
*/
|
||||
const USB_Descriptor_String_t ManufacturerString = USB_STRING_DESCRIPTOR(L"Dean Camera");
|
||||
|
||||
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
|
||||
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
||||
* Descriptor.
|
||||
*/
|
||||
const USB_Descriptor_String_t ProductString = USB_STRING_DESCRIPTOR(L"LUFA CDC");
|
||||
|
||||
/** This function is called by the library when in device mode, and must be overridden (see LUFA library "USB Descriptors"
|
||||
* documentation) by the application code so that the address and size of a requested descriptor can be given
|
||||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
{
|
||||
const uint8_t DescriptorType = (wValue >> 8);
|
||||
const uint8_t DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
const void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = &DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = &ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
if (DescriptorNumber == STRING_ID_Language)
|
||||
{
|
||||
Address = &LanguageString;
|
||||
Size = LanguageString.Header.Size;
|
||||
}
|
||||
else if (DescriptorNumber == STRING_ID_Manufacturer)
|
||||
{
|
||||
Address = &ManufacturerString;
|
||||
Size = ManufacturerString.Header.Size;
|
||||
}
|
||||
else if (DescriptorNumber == STRING_ID_Product)
|
||||
{
|
||||
Address = &ProductString;
|
||||
Size = ProductString.Header.Size;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
158
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/Descriptors.h
Normal file
158
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/Descriptors.h
Normal file
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include "Config/AppConfig.h"
|
||||
|
||||
/* Macros: */
|
||||
#if defined(__AVR_AT90USB1287__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB647__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x87
|
||||
#elif defined(__AVR_ATmega16U4__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U2__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x8A
|
||||
#elif defined(__AVR_ATmega16U2__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega8U2__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#elif defined(__AVR_AT90USB82__)
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#else
|
||||
#error The selected AVR part is not currently supported by this bootloader.
|
||||
#endif
|
||||
|
||||
/** Endpoint address for the CDC control interface event notification endpoint. */
|
||||
#define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | 2)
|
||||
|
||||
/** Endpoint address for the CDC data interface TX (data IN) endpoint. */
|
||||
#define CDC_TX_EPADDR (ENDPOINT_DIR_IN | 3)
|
||||
|
||||
/** Endpoint address for the CDC data interface RX (data OUT) endpoint. */
|
||||
#define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | 4)
|
||||
|
||||
/** Size of the CDC data interface TX and RX data endpoint banks, in bytes. */
|
||||
#define CDC_TXRX_EPSIZE 16
|
||||
|
||||
/** Size of the CDC control interface notification endpoint bank, in bytes. */
|
||||
#define CDC_NOTIFICATION_EPSIZE 8
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for the device configuration descriptor structure. This must be defined in the
|
||||
* application code, as the configuration descriptor contains several sub-descriptors which
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
|
||||
// CDC Control Interface
|
||||
USB_Descriptor_Interface_t CDC_CCI_Interface;
|
||||
USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
|
||||
USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
|
||||
USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
|
||||
USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
|
||||
|
||||
// CDC Data Interface
|
||||
USB_Descriptor_Interface_t CDC_DCI_Interface;
|
||||
USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
|
||||
USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor
|
||||
* should have a unique ID index associated with it, which can be used to refer to the
|
||||
* interface from other descriptors.
|
||||
*/
|
||||
enum InterfaceDescriptors_t
|
||||
{
|
||||
INTERFACE_ID_CDC_CCI = 0, /**< CDC CCI interface descriptor ID */
|
||||
INTERFACE_ID_CDC_DCI = 1, /**< CDC DCI interface descriptor ID */
|
||||
};
|
||||
|
||||
/** Enum for the device string descriptor IDs within the device. Each string descriptor should
|
||||
* have a unique ID index associated with it, which can be used to refer to the string from
|
||||
* other descriptors.
|
||||
*/
|
||||
enum StringDescriptors_t
|
||||
{
|
||||
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
|
||||
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
|
||||
STRING_ID_Product = 2, /**< Product string ID */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
;************************************************************
|
||||
; Windows USB CDC ACM Setup File
|
||||
; Copyright (c) 2000 Microsoft Corporation
|
||||
;************************************************************
|
||||
|
||||
[DefaultInstall]
|
||||
CopyINF="LUFA CDC Bootloader.inf"
|
||||
|
||||
[Version]
|
||||
Signature="$Windows NT$"
|
||||
Class=Ports
|
||||
ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
|
||||
Provider=%MFGNAME%
|
||||
DriverVer=7/1/2012,10.0.0.0
|
||||
|
||||
[Manufacturer]
|
||||
%MFGNAME%=DeviceList, NTx86, NTamd64, NTia64
|
||||
|
||||
[SourceDisksNames]
|
||||
|
||||
[SourceDisksFiles]
|
||||
|
||||
[DestinationDirs]
|
||||
DefaultDestDir=12
|
||||
|
||||
[DriverInstall]
|
||||
Include=mdmcpq.inf
|
||||
CopyFiles=FakeModemCopyFileSection
|
||||
AddReg=DriverInstall.AddReg
|
||||
|
||||
[DriverInstall.Services]
|
||||
Include=mdmcpq.inf
|
||||
AddService=usbser, 0x00000002, LowerFilter_Service_Inst
|
||||
|
||||
[DriverInstall.AddReg]
|
||||
HKR,,EnumPropPages32,,"msports.dll,SerialPortPropPageProvider"
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; Vendor and Product ID Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
; When developing your USB device, the VID and PID used in the PC side
|
||||
; application program and the firmware on the microcontroller must match.
|
||||
; Modify the below line to use your VID and PID. Use the format as shown below.
|
||||
; Note: One INF file can be used for multiple devices with different VID and PIDs.
|
||||
; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
|
||||
;------------------------------------------------------------------------------
|
||||
[DeviceList]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
|
||||
|
||||
[DeviceList.NTx86]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
|
||||
|
||||
[DeviceList.NTamd64]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
|
||||
|
||||
[DeviceList.NTia64]
|
||||
%DESCRIPTION%=DriverInstall, USB\VID_03EB&PID_204A
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; String Definitions
|
||||
;------------------------------------------------------------------------------
|
||||
;Modify these strings to customize your device
|
||||
;------------------------------------------------------------------------------
|
||||
[Strings]
|
||||
MFGNAME="http://www.lufa-lib.org"
|
||||
DESCRIPTION="LUFA CDC Class Bootloader"
|
161
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/asf.xml
Normal file
161
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/asf.xml
Normal file
|
@ -0,0 +1,161 @@
|
|||
<asf xmlversion="1.0">
|
||||
<project caption="CDC Bootloader - 128KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.128_4" force-caption="true" workspace-name="lufa_cdc_128kb_4kb_">
|
||||
<require idref="lufa.bootloaders.cdc"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb1287"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1F000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1F000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="CDC Bootloader - 64KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.64_4" force-caption="true" workspace-name="lufa_cdc_64kb_4kb_">
|
||||
<require idref="lufa.bootloaders.cdc"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb647"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0xF000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xF000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0xFFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0xFFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0xFFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="CDC Bootloader - 32KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.32_4" force-caption="true" workspace-name="lufa_cdc_32kb_4kb_">
|
||||
<require idref="lufa.bootloaders.cdc"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega32u4"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x7FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x7FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x7FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="CDC Bootloader - 16KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.16_4" force-caption="true" workspace-name="lufa_cdc_16kb_4kb_">
|
||||
<require idref="lufa.bootloaders.cdc"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega16u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x3000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x3FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x3FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x3FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="CDC Bootloader - 8KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.cdc.avr8.8_4" force-caption="true" workspace-name="lufa_cdc_8kb_4kb_">
|
||||
<require idref="lufa.bootloaders.cdc"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega8u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<module type="application" id="lufa.bootloaders.cdc" caption="CDC Bootloader">
|
||||
<info type="description" value="summary">
|
||||
CDC Class Bootloader, capable of reprogramming a device using avrdude or other AVR109 protocol compliant software when plugged into a host.
|
||||
</info>
|
||||
|
||||
<info type="gui-flag" value="move-to-root"/>
|
||||
|
||||
<info type="keyword" value="Technology">
|
||||
<keyword value="Bootloaders"/>
|
||||
<keyword value="USB Device"/>
|
||||
</info>
|
||||
|
||||
<device-support-alias value="lufa_avr8"/>
|
||||
<device-support-alias value="lufa_xmega"/>
|
||||
<device-support-alias value="lufa_uc3"/>
|
||||
|
||||
<build type="include-path" value="."/>
|
||||
<build type="c-source" value="BootloaderCDC.c"/>
|
||||
<build type="header-file" value="BootloaderCDC.h"/>
|
||||
<build type="c-source" value="Descriptors.c"/>
|
||||
<build type="header-file" value="Descriptors.h"/>
|
||||
<build type="c-source" value="BootloaderAPI.c"/>
|
||||
<build type="header-file" value="BootloaderAPI.h"/>
|
||||
<build type="asm-source" value="BootloaderAPITable.S"/>
|
||||
|
||||
<build type="module-config" subtype="path" value="Config"/>
|
||||
<build type="header-file" value="Config/LUFAConfig.h"/>
|
||||
<build type="header-file" value="Config/AppConfig.h"/>
|
||||
|
||||
<build type="distribute" subtype="user-file" value="doxyfile"/>
|
||||
<build type="distribute" subtype="user-file" value="BootloaderCDC.txt"/>
|
||||
<build type="distribute" subtype="user-file" value="LUFA CDC Bootloader.inf"/>
|
||||
|
||||
<require idref="lufa.common"/>
|
||||
<require idref="lufa.platform"/>
|
||||
<require idref="lufa.drivers.usb"/>
|
||||
<require idref="lufa.drivers.board"/>
|
||||
<require idref="lufa.drivers.board.leds"/>
|
||||
</module>
|
||||
</asf>
|
2365
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/doxyfile
Normal file
2365
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/doxyfile
Normal file
File diff suppressed because it is too large
Load diff
55
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/makefile
Normal file
55
tmk_core/protocol/lufa/LUFA-git/Bootloaders/CDC/makefile
Normal file
|
@ -0,0 +1,55 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.lufa-lib.org
|
||||
#
|
||||
# --------------------------------------
|
||||
# LUFA Project Makefile.
|
||||
# --------------------------------------
|
||||
|
||||
# Run "make help" for target help.
|
||||
|
||||
MCU = at90usb1287
|
||||
ARCH = AVR8
|
||||
BOARD = USBKEY
|
||||
F_CPU = 8000000
|
||||
F_USB = $(F_CPU)
|
||||
OPTIMIZATION = s
|
||||
TARGET = BootloaderCDC
|
||||
SRC = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S $(LUFA_SRC_USB)
|
||||
LUFA_PATH = ../../LUFA
|
||||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET)
|
||||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS)
|
||||
|
||||
# Flash size and bootloader section sizes of the target, in KB. These must
|
||||
# match the target's total FLASH size and the bootloader size set in the
|
||||
# device's fuses.
|
||||
FLASH_SIZE_KB = 128
|
||||
BOOT_SECTION_SIZE_KB = 8
|
||||
|
||||
# Bootloader address calculation formulas
|
||||
# Do not modify these macros, but rather modify the dependent values above.
|
||||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) )
|
||||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 )
|
||||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) )
|
||||
|
||||
# Bootloader linker section flags for relocating the API table sections to
|
||||
# known FLASH addresses - these should not normally be user-edited.
|
||||
BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2))
|
||||
BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8)
|
||||
|
||||
# Default target
|
||||
all:
|
||||
|
||||
# Include LUFA build script makefiles
|
||||
include $(LUFA_PATH)/Build/lufa_core.mk
|
||||
include $(LUFA_PATH)/Build/lufa_sources.mk
|
||||
include $(LUFA_PATH)/Build/lufa_build.mk
|
||||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk
|
||||
include $(LUFA_PATH)/Build/lufa_doxygen.mk
|
||||
include $(LUFA_PATH)/Build/lufa_avrdude.mk
|
||||
include $(LUFA_PATH)/Build/lufa_atprogram.mk
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Bootloader user application API functions.
|
||||
*/
|
||||
|
||||
#include "BootloaderAPI.h"
|
||||
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_erase_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_WritePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_write_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word)
|
||||
{
|
||||
boot_page_fill_safe(Address, Word);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address)
|
||||
{
|
||||
return boot_signature_byte_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadLock(void)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(GET_LOCK_BITS);
|
||||
}
|
||||
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits)
|
||||
{
|
||||
boot_lock_bits_set_safe(LockBits);
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderAPI.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_API_H_
|
||||
#define _BOOTLOADER_API_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/boot.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
|
||||
#include "Config/AppConfig.h"
|
||||
|
||||
/* Function Prototypes: */
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address);
|
||||
void BootloaderAPI_WritePage(const uint32_t Address);
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word);
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadLock(void);
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
; Trampolines to actual API implementations if the target address is outside the
|
||||
; range of a rjmp instruction (can happen with large bootloader sections)
|
||||
.section .apitable_trampolines, "ax"
|
||||
.global BootloaderAPI_Trampolines
|
||||
BootloaderAPI_Trampolines:
|
||||
|
||||
BootloaderAPI_ErasePage_Trampoline:
|
||||
jmp BootloaderAPI_ErasePage
|
||||
BootloaderAPI_WritePage_Trampoline:
|
||||
jmp BootloaderAPI_WritePage
|
||||
BootloaderAPI_FillWord_Trampoline:
|
||||
jmp BootloaderAPI_FillWord
|
||||
BootloaderAPI_ReadSignature_Trampoline:
|
||||
jmp BootloaderAPI_ReadSignature
|
||||
BootloaderAPI_ReadFuse_Trampoline:
|
||||
jmp BootloaderAPI_ReadFuse
|
||||
BootloaderAPI_ReadLock_Trampoline:
|
||||
jmp BootloaderAPI_ReadLock
|
||||
BootloaderAPI_WriteLock_Trampoline:
|
||||
jmp BootloaderAPI_WriteLock
|
||||
BootloaderAPI_UNUSED1:
|
||||
ret
|
||||
BootloaderAPI_UNUSED2:
|
||||
ret
|
||||
BootloaderAPI_UNUSED3:
|
||||
ret
|
||||
BootloaderAPI_UNUSED4:
|
||||
ret
|
||||
BootloaderAPI_UNUSED5:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; API function jump table
|
||||
.section .apitable_jumptable, "ax"
|
||||
.global BootloaderAPI_JumpTable
|
||||
BootloaderAPI_JumpTable:
|
||||
|
||||
rjmp BootloaderAPI_ErasePage_Trampoline
|
||||
rjmp BootloaderAPI_WritePage_Trampoline
|
||||
rjmp BootloaderAPI_FillWord_Trampoline
|
||||
rjmp BootloaderAPI_ReadSignature_Trampoline
|
||||
rjmp BootloaderAPI_ReadFuse_Trampoline
|
||||
rjmp BootloaderAPI_ReadLock_Trampoline
|
||||
rjmp BootloaderAPI_WriteLock_Trampoline
|
||||
rjmp BootloaderAPI_UNUSED1 ; UNUSED ENTRY 1
|
||||
rjmp BootloaderAPI_UNUSED2 ; UNUSED ENTRY 2
|
||||
rjmp BootloaderAPI_UNUSED3 ; UNUSED ENTRY 3
|
||||
rjmp BootloaderAPI_UNUSED4 ; UNUSED ENTRY 4
|
||||
rjmp BootloaderAPI_UNUSED5 ; UNUSED ENTRY 5
|
||||
|
||||
|
||||
|
||||
; Bootloader table signatures and information
|
||||
.section .apitable_signatures, "ax"
|
||||
.global BootloaderAPI_Signatures
|
||||
BootloaderAPI_Signatures:
|
||||
|
||||
.long BOOT_START_ADDR ; Start address of the bootloader
|
||||
.word 0xDF10 ; Signature for the DFU class bootloader, V1
|
||||
.word 0xDCFB ; Signature for a LUFA class bootloader
|
804
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/BootloaderDFU.c
Normal file
804
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/BootloaderDFU.c
Normal file
|
@ -0,0 +1,804 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the DFU class bootloader. This file contains the complete bootloader logic.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_BOOTLOADER_C
|
||||
#include "BootloaderDFU.h"
|
||||
|
||||
/** Flag to indicate if the bootloader is currently running in secure mode, disallowing memory operations
|
||||
* other than erase. This is initially set to the value set by SECURE_MODE, and cleared by the bootloader
|
||||
* once a memory erase has completed in a bootloader session.
|
||||
*/
|
||||
static bool IsSecure = SECURE_MODE;
|
||||
|
||||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
|
||||
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application
|
||||
* jumped to via an indirect jump to location 0x0000 (or other location specified by the host).
|
||||
*/
|
||||
static bool RunBootloader = true;
|
||||
|
||||
/** Flag to indicate if the bootloader is waiting to exit. When the host requests the bootloader to exit and
|
||||
* jump to the application address it specifies, it sends two sequential commands which must be properly
|
||||
* acknowledged. Upon reception of the first the RunBootloader flag is cleared and the WaitForExit flag is set,
|
||||
* causing the bootloader to wait for the final exit command before shutting down.
|
||||
*/
|
||||
static bool WaitForExit = false;
|
||||
|
||||
/** Current DFU state machine state, one of the values in the DFU_State_t enum. */
|
||||
static uint8_t DFU_State = dfuIDLE;
|
||||
|
||||
/** Status code of the last executed DFU command. This is set to one of the values in the DFU_Status_t enum after
|
||||
* each operation, and returned to the host when a Get Status DFU request is issued.
|
||||
*/
|
||||
static uint8_t DFU_Status = OK;
|
||||
|
||||
/** Data containing the DFU command sent from the host. */
|
||||
static DFU_Command_t SentCommand;
|
||||
|
||||
/** Response to the last issued Read Data DFU command. Unlike other DFU commands, the read command
|
||||
* requires a single byte response from the bootloader containing the read data when the next DFU_UPLOAD command
|
||||
* is issued by the host.
|
||||
*/
|
||||
static uint8_t ResponseByte;
|
||||
|
||||
/** Pointer to the start of the user application. By default this is 0x0000 (the reset vector), however the host
|
||||
* may specify an alternate address when issuing the application soft-start command.
|
||||
*/
|
||||
static AppPtr_t AppStartPtr = (AppPtr_t)0x0000;
|
||||
|
||||
/** 64-bit flash page number. This is concatenated with the current 16-bit address on USB AVRs containing more than
|
||||
* 64KB of flash memory.
|
||||
*/
|
||||
static uint8_t Flash64KBPage = 0;
|
||||
|
||||
/** Memory start address, indicating the current address in the memory being addressed (either FLASH or EEPROM
|
||||
* depending on the issued command from the host).
|
||||
*/
|
||||
static uint16_t StartAddr = 0x0000;
|
||||
|
||||
/** Memory end address, indicating the end address to read from/write to in the memory being addressed (either FLASH
|
||||
* of EEPROM depending on the issued command from the host).
|
||||
*/
|
||||
static uint16_t EndAddr = 0x0000;
|
||||
|
||||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader
|
||||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held
|
||||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value
|
||||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start.
|
||||
*/
|
||||
uint16_t MagicBootKey ATTR_NO_INIT;
|
||||
|
||||
|
||||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application
|
||||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid,
|
||||
* this will force the user application to start via a software jump.
|
||||
*/
|
||||
void Application_Jump_Check(void)
|
||||
{
|
||||
bool JumpToApplication = false;
|
||||
|
||||
#if ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
|
||||
/* Disable JTAG debugging */
|
||||
JTAG_DISABLE();
|
||||
|
||||
/* Enable pull-up on the JTAG TCK pin so we can use it to select the mode */
|
||||
PORTF |= (1 << 4);
|
||||
Delay_MS(10);
|
||||
|
||||
/* If the TCK pin is not jumpered to ground, start the user application instead */
|
||||
JumpToApplication |= ((PINF & (1 << 4)) != 0);
|
||||
|
||||
/* Re-enable JTAG debugging */
|
||||
JTAG_ENABLE();
|
||||
#endif
|
||||
|
||||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
|
||||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
|
||||
JumpToApplication |= true;
|
||||
|
||||
/* If a request has been made to jump to the user application, honor it */
|
||||
if (JumpToApplication)
|
||||
{
|
||||
/* Turn off the watchdog */
|
||||
MCUSR &= ~(1<<WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Clear the boot key and jump to the user application */
|
||||
MagicBootKey = 0;
|
||||
|
||||
// cppcheck-suppress constStatement
|
||||
((void (*)(void))0x0000)();
|
||||
}
|
||||
}
|
||||
|
||||
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
|
||||
* runs the bootloader processing routine until instructed to soft-exit, or hard-reset via the watchdog to start
|
||||
* the loaded application code.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
/* Configure hardware required by the bootloader */
|
||||
SetupHardware();
|
||||
|
||||
/* Turn on first LED on the board to indicate that the bootloader has started */
|
||||
LEDs_SetAllLEDs(LEDS_LED1);
|
||||
|
||||
/* Enable global interrupts so that the USB stack can function */
|
||||
GlobalInterruptEnable();
|
||||
|
||||
/* Run the USB management task while the bootloader is supposed to be running */
|
||||
while (RunBootloader || WaitForExit)
|
||||
USB_USBTask();
|
||||
|
||||
/* Reset configured hardware back to their original states for the user application */
|
||||
ResetHardware();
|
||||
|
||||
/* Start the user application */
|
||||
AppStartPtr();
|
||||
}
|
||||
|
||||
/** Configures all hardware required for the bootloader. */
|
||||
static void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Relocate the interrupt vector table to the bootloader section */
|
||||
MCUCR = (1 << IVCE);
|
||||
MCUCR = (1 << IVSEL);
|
||||
|
||||
/* Initialize the USB and other board hardware drivers */
|
||||
USB_Init();
|
||||
LEDs_Init();
|
||||
|
||||
/* Bootloader active LED toggle timer initialization */
|
||||
TIMSK1 = (1 << TOIE1);
|
||||
TCCR1B = ((1 << CS11) | (1 << CS10));
|
||||
}
|
||||
|
||||
/** Resets all configured hardware required for the bootloader back to their original states. */
|
||||
static void ResetHardware(void)
|
||||
{
|
||||
/* Shut down the USB and other board hardware drivers */
|
||||
USB_Disable();
|
||||
LEDs_Disable();
|
||||
|
||||
/* Disable Bootloader active LED toggle timer */
|
||||
TIMSK1 = 0;
|
||||
TCCR1B = 0;
|
||||
|
||||
/* Relocate the interrupt vector table back to the application section */
|
||||
MCUCR = (1 << IVCE);
|
||||
MCUCR = 0;
|
||||
}
|
||||
|
||||
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */
|
||||
ISR(TIMER1_OVF_vect, ISR_BLOCK)
|
||||
{
|
||||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
|
||||
* the device from the USB host before passing along unhandled control requests to the library for processing
|
||||
* internally.
|
||||
*/
|
||||
void EVENT_USB_Device_ControlRequest(void)
|
||||
{
|
||||
/* Ignore any requests that aren't directed to the DFU interface */
|
||||
if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) !=
|
||||
(REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Activity - toggle indicator LEDs */
|
||||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
|
||||
|
||||
/* Get the size of the command and data from the wLength value */
|
||||
SentCommand.DataSize = USB_ControlRequest.wLength;
|
||||
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case DFU_REQ_DNLOAD:
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Check if bootloader is waiting to terminate */
|
||||
if (WaitForExit)
|
||||
{
|
||||
/* Bootloader is terminating - process last received command */
|
||||
ProcessBootloaderCommand();
|
||||
|
||||
/* Indicate that the last command has now been processed - free to exit bootloader */
|
||||
WaitForExit = false;
|
||||
}
|
||||
|
||||
/* If the request has a data stage, load it into the command struct */
|
||||
if (SentCommand.DataSize)
|
||||
{
|
||||
while (!(Endpoint_IsOUTReceived()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
/* First byte of the data stage is the DNLOAD request's command */
|
||||
SentCommand.Command = Endpoint_Read_8();
|
||||
|
||||
/* One byte of the data stage is the command, so subtract it from the total data bytes */
|
||||
SentCommand.DataSize--;
|
||||
|
||||
/* Load in the rest of the data stage as command parameters */
|
||||
for (uint8_t DataByte = 0; (DataByte < sizeof(SentCommand.Data)) &&
|
||||
Endpoint_BytesInEndpoint(); DataByte++)
|
||||
{
|
||||
SentCommand.Data[DataByte] = Endpoint_Read_8();
|
||||
SentCommand.DataSize--;
|
||||
}
|
||||
|
||||
/* Process the command */
|
||||
ProcessBootloaderCommand();
|
||||
}
|
||||
|
||||
/* Check if currently downloading firmware */
|
||||
if (DFU_State == dfuDNLOAD_IDLE)
|
||||
{
|
||||
if (!(SentCommand.DataSize))
|
||||
{
|
||||
DFU_State = dfuIDLE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Throw away the filler bytes before the start of the firmware */
|
||||
DiscardFillerBytes(DFU_FILLER_BYTES_SIZE);
|
||||
|
||||
/* Throw away the packet alignment filler bytes before the start of the firmware */
|
||||
DiscardFillerBytes(StartAddr % FIXED_CONTROL_ENDPOINT_SIZE);
|
||||
|
||||
/* Calculate the number of bytes remaining to be written */
|
||||
uint16_t BytesRemaining = ((EndAddr - StartAddr) + 1);
|
||||
|
||||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) // Write flash
|
||||
{
|
||||
/* Calculate the number of words to be written from the number of bytes to be written */
|
||||
uint16_t WordsRemaining = (BytesRemaining >> 1);
|
||||
|
||||
union
|
||||
{
|
||||
uint16_t Words[2];
|
||||
uint32_t Long;
|
||||
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}};
|
||||
|
||||
uint32_t CurrFlashPageStartAddress = CurrFlashAddress.Long;
|
||||
uint8_t WordsInFlashPage = 0;
|
||||
|
||||
while (WordsRemaining--)
|
||||
{
|
||||
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
while (!(Endpoint_IsOUTReceived()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the next word into the current flash page */
|
||||
boot_page_fill(CurrFlashAddress.Long, Endpoint_Read_16_LE());
|
||||
|
||||
/* Adjust counters */
|
||||
WordsInFlashPage += 1;
|
||||
CurrFlashAddress.Long += 2;
|
||||
|
||||
/* See if an entire page has been written to the flash page buffer */
|
||||
if ((WordsInFlashPage == (SPM_PAGESIZE >> 1)) || !(WordsRemaining))
|
||||
{
|
||||
/* Commit the flash page to memory */
|
||||
boot_page_write(CurrFlashPageStartAddress);
|
||||
boot_spm_busy_wait();
|
||||
|
||||
/* Check if programming incomplete */
|
||||
if (WordsRemaining)
|
||||
{
|
||||
CurrFlashPageStartAddress = CurrFlashAddress.Long;
|
||||
WordsInFlashPage = 0;
|
||||
|
||||
/* Erase next page's temp buffer */
|
||||
boot_page_erase(CurrFlashAddress.Long);
|
||||
boot_spm_busy_wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Once programming complete, start address equals the end address */
|
||||
StartAddr = EndAddr;
|
||||
|
||||
/* Re-enable the RWW section of flash */
|
||||
boot_rww_enable();
|
||||
}
|
||||
else // Write EEPROM
|
||||
{
|
||||
while (BytesRemaining--)
|
||||
{
|
||||
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
while (!(Endpoint_IsOUTReceived()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the byte from the USB interface and write to to the EEPROM */
|
||||
eeprom_write_byte((uint8_t*)StartAddr, Endpoint_Read_8());
|
||||
|
||||
/* Adjust counters */
|
||||
StartAddr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Throw away the currently unused DFU file suffix */
|
||||
DiscardFillerBytes(DFU_FILE_SUFFIX_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
|
||||
break;
|
||||
case DFU_REQ_UPLOAD:
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
if (DFU_State != dfuUPLOAD_IDLE)
|
||||
{
|
||||
if ((DFU_State == dfuERROR) && IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Blank Check
|
||||
{
|
||||
/* Blank checking is performed in the DFU_DNLOAD request - if we get here we've told the host
|
||||
that the memory isn't blank, and the host is requesting the first non-blank address */
|
||||
Endpoint_Write_16_LE(StartAddr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Idle state upload - send response to last issued command */
|
||||
Endpoint_Write_8(ResponseByte);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Determine the number of bytes remaining in the current block */
|
||||
uint16_t BytesRemaining = ((EndAddr - StartAddr) + 1);
|
||||
|
||||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) // Read FLASH
|
||||
{
|
||||
/* Calculate the number of words to be written from the number of bytes to be written */
|
||||
uint16_t WordsRemaining = (BytesRemaining >> 1);
|
||||
|
||||
union
|
||||
{
|
||||
uint16_t Words[2];
|
||||
uint32_t Long;
|
||||
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}};
|
||||
|
||||
while (WordsRemaining--)
|
||||
{
|
||||
/* Check if endpoint is full - if so clear it and wait until ready for next packet */
|
||||
if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE)
|
||||
{
|
||||
Endpoint_ClearIN();
|
||||
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the flash word and send it via USB to the host */
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
Endpoint_Write_16_LE(pgm_read_word_far(CurrFlashAddress.Long));
|
||||
#else
|
||||
Endpoint_Write_16_LE(pgm_read_word(CurrFlashAddress.Long));
|
||||
#endif
|
||||
|
||||
/* Adjust counters */
|
||||
CurrFlashAddress.Long += 2;
|
||||
}
|
||||
|
||||
/* Once reading is complete, start address equals the end address */
|
||||
StartAddr = EndAddr;
|
||||
}
|
||||
else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x02)) // Read EEPROM
|
||||
{
|
||||
while (BytesRemaining--)
|
||||
{
|
||||
/* Check if endpoint is full - if so clear it and wait until ready for next packet */
|
||||
if (Endpoint_BytesInEndpoint() == FIXED_CONTROL_ENDPOINT_SIZE)
|
||||
{
|
||||
Endpoint_ClearIN();
|
||||
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the EEPROM byte and send it via USB to the host */
|
||||
Endpoint_Write_8(eeprom_read_byte((uint8_t*)StartAddr));
|
||||
|
||||
/* Adjust counters */
|
||||
StartAddr++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return to idle state */
|
||||
DFU_State = dfuIDLE;
|
||||
}
|
||||
|
||||
Endpoint_ClearIN();
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
break;
|
||||
case DFU_REQ_GETSTATUS:
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write 8-bit status value */
|
||||
Endpoint_Write_8(DFU_Status);
|
||||
|
||||
/* Write 24-bit poll timeout value */
|
||||
Endpoint_Write_8(0);
|
||||
Endpoint_Write_16_LE(0);
|
||||
|
||||
/* Write 8-bit state value */
|
||||
Endpoint_Write_8(DFU_State);
|
||||
|
||||
/* Write 8-bit state string ID number */
|
||||
Endpoint_Write_8(0);
|
||||
|
||||
Endpoint_ClearIN();
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
break;
|
||||
case DFU_REQ_CLRSTATUS:
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Reset the status value variable to the default OK status */
|
||||
DFU_Status = OK;
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
break;
|
||||
case DFU_REQ_GETSTATE:
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
while (!(Endpoint_IsINReady()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write the current device state to the endpoint */
|
||||
Endpoint_Write_8(DFU_State);
|
||||
|
||||
Endpoint_ClearIN();
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
break;
|
||||
case DFU_REQ_ABORT:
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Reset the current state variable to the default idle state */
|
||||
DFU_State = dfuIDLE;
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Routine to discard the specified number of bytes from the control endpoint stream. This is used to
|
||||
* discard unused bytes in the stream from the host, including the memory program block suffix.
|
||||
*
|
||||
* \param[in] NumberOfBytes Number of bytes to discard from the host from the control endpoint
|
||||
*/
|
||||
static void DiscardFillerBytes(uint8_t NumberOfBytes)
|
||||
{
|
||||
while (NumberOfBytes--)
|
||||
{
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
/* Wait until next data packet received */
|
||||
while (!(Endpoint_IsOUTReceived()))
|
||||
{
|
||||
if (USB_DeviceState == DEVICE_STATE_Unattached)
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Endpoint_Discard_8();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Routine to process an issued command from the host, via a DFU_DNLOAD request wrapper. This routine ensures
|
||||
* that the command is allowed based on the current secure mode flag value, and passes the command off to the
|
||||
* appropriate handler function.
|
||||
*/
|
||||
static void ProcessBootloaderCommand(void)
|
||||
{
|
||||
/* Check if device is in secure mode */
|
||||
if (IsSecure)
|
||||
{
|
||||
/* Don't process command unless it is a READ or chip erase command */
|
||||
if (!(((SentCommand.Command == COMMAND_WRITE) &&
|
||||
IS_TWOBYTE_COMMAND(SentCommand.Data, 0x00, 0xFF)) ||
|
||||
(SentCommand.Command == COMMAND_READ)))
|
||||
{
|
||||
/* Set the state and status variables to indicate the error */
|
||||
DFU_State = dfuERROR;
|
||||
DFU_Status = errWRITE;
|
||||
|
||||
/* Stall command */
|
||||
Endpoint_StallTransaction();
|
||||
|
||||
/* Don't process the command */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dispatch the required command processing routine based on the command type */
|
||||
switch (SentCommand.Command)
|
||||
{
|
||||
case COMMAND_PROG_START:
|
||||
ProcessMemProgCommand();
|
||||
break;
|
||||
case COMMAND_DISP_DATA:
|
||||
ProcessMemReadCommand();
|
||||
break;
|
||||
case COMMAND_WRITE:
|
||||
ProcessWriteCommand();
|
||||
break;
|
||||
case COMMAND_READ:
|
||||
ProcessReadCommand();
|
||||
break;
|
||||
case COMMAND_CHANGE_BASE_ADDR:
|
||||
if (IS_TWOBYTE_COMMAND(SentCommand.Data, 0x03, 0x00)) // Set 64KB flash page command
|
||||
Flash64KBPage = SentCommand.Data[2];
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Routine to concatenate the given pair of 16-bit memory start and end addresses from the host, and store them
|
||||
* in the StartAddr and EndAddr global variables.
|
||||
*/
|
||||
static void LoadStartEndAddresses(void)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t Bytes[2];
|
||||
uint16_t Word;
|
||||
} Address[2] = {{.Bytes = {SentCommand.Data[2], SentCommand.Data[1]}},
|
||||
{.Bytes = {SentCommand.Data[4], SentCommand.Data[3]}}};
|
||||
|
||||
/* Load in the start and ending read addresses from the sent data packet */
|
||||
StartAddr = Address[0].Word;
|
||||
EndAddr = Address[1].Word;
|
||||
}
|
||||
|
||||
/** Handler for a Memory Program command issued by the host. This routine handles the preparations needed
|
||||
* to write subsequent data from the host into the specified memory.
|
||||
*/
|
||||
static void ProcessMemProgCommand(void)
|
||||
{
|
||||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00) || // Write FLASH command
|
||||
IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Write EEPROM command
|
||||
{
|
||||
/* Load in the start and ending read addresses */
|
||||
LoadStartEndAddresses();
|
||||
|
||||
/* If FLASH is being written to, we need to pre-erase the first page to write to */
|
||||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00))
|
||||
{
|
||||
union
|
||||
{
|
||||
uint16_t Words[2];
|
||||
uint32_t Long;
|
||||
} CurrFlashAddress = {.Words = {StartAddr, Flash64KBPage}};
|
||||
|
||||
/* Erase the current page's temp buffer */
|
||||
boot_page_erase(CurrFlashAddress.Long);
|
||||
boot_spm_busy_wait();
|
||||
}
|
||||
|
||||
/* Set the state so that the next DNLOAD requests reads in the firmware */
|
||||
DFU_State = dfuDNLOAD_IDLE;
|
||||
}
|
||||
}
|
||||
|
||||
/** Handler for a Memory Read command issued by the host. This routine handles the preparations needed
|
||||
* to read subsequent data from the specified memory out to the host, as well as implementing the memory
|
||||
* blank check command.
|
||||
*/
|
||||
static void ProcessMemReadCommand(void)
|
||||
{
|
||||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00) || // Read FLASH command
|
||||
IS_ONEBYTE_COMMAND(SentCommand.Data, 0x02)) // Read EEPROM command
|
||||
{
|
||||
/* Load in the start and ending read addresses */
|
||||
LoadStartEndAddresses();
|
||||
|
||||
/* Set the state so that the next UPLOAD requests read out the firmware */
|
||||
DFU_State = dfuUPLOAD_IDLE;
|
||||
}
|
||||
else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Blank check FLASH command
|
||||
{
|
||||
uint32_t CurrFlashAddress = 0;
|
||||
|
||||
while (CurrFlashAddress < (uint32_t)BOOT_START_ADDR)
|
||||
{
|
||||
/* Check if the current byte is not blank */
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
if (pgm_read_byte_far(CurrFlashAddress) != 0xFF)
|
||||
#else
|
||||
if (pgm_read_byte(CurrFlashAddress) != 0xFF)
|
||||
#endif
|
||||
{
|
||||
/* Save the location of the first non-blank byte for response back to the host */
|
||||
Flash64KBPage = (CurrFlashAddress >> 16);
|
||||
StartAddr = CurrFlashAddress;
|
||||
|
||||
/* Set state and status variables to the appropriate error values */
|
||||
DFU_State = dfuERROR;
|
||||
DFU_Status = errCHECK_ERASED;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
CurrFlashAddress++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Handler for a Data Write command issued by the host. This routine handles non-programming commands such as
|
||||
* bootloader exit (both via software jumps and hardware watchdog resets) and flash memory erasure.
|
||||
*/
|
||||
static void ProcessWriteCommand(void)
|
||||
{
|
||||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x03)) // Start application
|
||||
{
|
||||
/* Indicate that the bootloader is terminating */
|
||||
WaitForExit = true;
|
||||
|
||||
/* Check if data supplied for the Start Program command - no data executes the program */
|
||||
if (SentCommand.DataSize)
|
||||
{
|
||||
if (SentCommand.Data[1] == 0x01) // Start via jump
|
||||
{
|
||||
union
|
||||
{
|
||||
uint8_t Bytes[2];
|
||||
AppPtr_t FuncPtr;
|
||||
} Address = {.Bytes = {SentCommand.Data[4], SentCommand.Data[3]}};
|
||||
|
||||
/* Load in the jump address into the application start address pointer */
|
||||
AppStartPtr = Address.FuncPtr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SentCommand.Data[1] == 0x00) // Start via watchdog
|
||||
{
|
||||
/* Unlock the forced application start mode of the bootloader if it is restarted */
|
||||
MagicBootKey = MAGIC_BOOT_KEY;
|
||||
|
||||
/* Start the watchdog to reset the AVR once the communications are finalized */
|
||||
wdt_enable(WDTO_250MS);
|
||||
}
|
||||
else // Start via jump
|
||||
{
|
||||
/* Set the flag to terminate the bootloader at next opportunity */
|
||||
RunBootloader = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (IS_TWOBYTE_COMMAND(SentCommand.Data, 0x00, 0xFF)) // Erase flash
|
||||
{
|
||||
uint32_t CurrFlashAddress = 0;
|
||||
|
||||
/* Clear the application section of flash */
|
||||
while (CurrFlashAddress < (uint32_t)BOOT_START_ADDR)
|
||||
{
|
||||
boot_page_erase(CurrFlashAddress);
|
||||
boot_spm_busy_wait();
|
||||
boot_page_write(CurrFlashAddress);
|
||||
boot_spm_busy_wait();
|
||||
|
||||
CurrFlashAddress += SPM_PAGESIZE;
|
||||
}
|
||||
|
||||
/* Re-enable the RWW section of flash as writing to the flash locks it out */
|
||||
boot_rww_enable();
|
||||
|
||||
/* Memory has been erased, reset the security bit so that programming/reading is allowed */
|
||||
IsSecure = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** Handler for a Data Read command issued by the host. This routine handles bootloader information retrieval
|
||||
* commands such as device signature and bootloader version retrieval.
|
||||
*/
|
||||
static void ProcessReadCommand(void)
|
||||
{
|
||||
const uint8_t BootloaderInfo[3] = {BOOTLOADER_VERSION, BOOTLOADER_ID_BYTE1, BOOTLOADER_ID_BYTE2};
|
||||
const uint8_t SignatureInfo[4] = {0x58, AVR_SIGNATURE_1, AVR_SIGNATURE_2, AVR_SIGNATURE_3};
|
||||
|
||||
uint8_t DataIndexToRead = SentCommand.Data[1];
|
||||
|
||||
if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x00)) // Read bootloader info
|
||||
{
|
||||
ResponseByte = BootloaderInfo[DataIndexToRead];
|
||||
}
|
||||
else if (IS_ONEBYTE_COMMAND(SentCommand.Data, 0x01)) // Read signature byte
|
||||
{
|
||||
if (DataIndexToRead < 0x60)
|
||||
ResponseByte = SignatureInfo[DataIndexToRead - 0x30];
|
||||
else
|
||||
ResponseByte = SignatureInfo[DataIndexToRead - 0x60 + 3];
|
||||
}
|
||||
}
|
||||
|
216
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/BootloaderDFU.h
Normal file
216
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/BootloaderDFU.h
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderDFU.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_H_
|
||||
#define _BOOTLOADER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/eeprom.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <util/delay.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
#include "BootloaderAPI.h"
|
||||
#include "Config/AppConfig.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Platform/Platform.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__OPTIMIZE_SIZE__)
|
||||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** Major bootloader version number. */
|
||||
#define BOOTLOADER_VERSION_MINOR 2
|
||||
|
||||
/** Minor bootloader version number. */
|
||||
#define BOOTLOADER_VERSION_REV 0
|
||||
|
||||
/** Magic bootloader key to unlock forced application start mode. */
|
||||
#define MAGIC_BOOT_KEY 0xDC42
|
||||
|
||||
/** Complete bootloader version number expressed as a packed byte, constructed from the
|
||||
* two individual bootloader version macros.
|
||||
*/
|
||||
#define BOOTLOADER_VERSION ((BOOTLOADER_VERSION_MINOR << 4) | BOOTLOADER_VERSION_REV)
|
||||
|
||||
/** First byte of the bootloader identification bytes, used to identify a device's bootloader. */
|
||||
#define BOOTLOADER_ID_BYTE1 0xDC
|
||||
|
||||
/** Second byte of the bootloader identification bytes, used to identify a device's bootloader. */
|
||||
#define BOOTLOADER_ID_BYTE2 0xFB
|
||||
|
||||
/** Convenience macro, used to determine if the issued command is the given one-byte long command.
|
||||
*
|
||||
* \param[in] dataarr Command byte array to check against
|
||||
* \param[in] cb1 First command byte to check
|
||||
*/
|
||||
#define IS_ONEBYTE_COMMAND(dataarr, cb1) (dataarr[0] == (cb1))
|
||||
|
||||
/** Convenience macro, used to determine if the issued command is the given two-byte long command.
|
||||
*
|
||||
* \param[in] dataarr Command byte array to check against
|
||||
* \param[in] cb1 First command byte to check
|
||||
* \param[in] cb2 Second command byte to check
|
||||
*/
|
||||
#define IS_TWOBYTE_COMMAND(dataarr, cb1, cb2) ((dataarr[0] == (cb1)) && (dataarr[1] == (cb2)))
|
||||
|
||||
/** Length of the DFU file suffix block, appended to the end of each complete memory write command.
|
||||
* The DFU file suffix is currently unused (but is designed to give extra file information, such as
|
||||
* a CRC of the complete firmware for error checking) and so is discarded.
|
||||
*/
|
||||
#define DFU_FILE_SUFFIX_SIZE 16
|
||||
|
||||
/** Length of the DFU file filler block, appended to the start of each complete memory write command.
|
||||
* Filler bytes are added to the start of each complete memory write command, and must be discarded.
|
||||
*/
|
||||
#define DFU_FILLER_BYTES_SIZE 26
|
||||
|
||||
/** DFU class command request to detach from the host. */
|
||||
#define DFU_REQ_DETATCH 0x00
|
||||
|
||||
/** DFU class command request to send data from the host to the bootloader. */
|
||||
#define DFU_REQ_DNLOAD 0x01
|
||||
|
||||
/** DFU class command request to send data from the bootloader to the host. */
|
||||
#define DFU_REQ_UPLOAD 0x02
|
||||
|
||||
/** DFU class command request to get the current DFU status and state from the bootloader. */
|
||||
#define DFU_REQ_GETSTATUS 0x03
|
||||
|
||||
/** DFU class command request to reset the current DFU status and state variables to their defaults. */
|
||||
#define DFU_REQ_CLRSTATUS 0x04
|
||||
|
||||
/** DFU class command request to get the current DFU state of the bootloader. */
|
||||
#define DFU_REQ_GETSTATE 0x05
|
||||
|
||||
/** DFU class command request to abort the current multi-request transfer and return to the dfuIDLE state. */
|
||||
#define DFU_REQ_ABORT 0x06
|
||||
|
||||
/** DFU command to begin programming the device's memory. */
|
||||
#define COMMAND_PROG_START 0x01
|
||||
|
||||
/** DFU command to begin reading the device's memory. */
|
||||
#define COMMAND_DISP_DATA 0x03
|
||||
|
||||
/** DFU command to issue a write command. */
|
||||
#define COMMAND_WRITE 0x04
|
||||
|
||||
/** DFU command to issue a read command. */
|
||||
#define COMMAND_READ 0x05
|
||||
|
||||
/** DFU command to issue a memory base address change command, to set the current 64KB flash page
|
||||
* that subsequent flash operations should use. */
|
||||
#define COMMAND_CHANGE_BASE_ADDR 0x06
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a non-returning function pointer to the loaded application. */
|
||||
typedef void (*AppPtr_t)(void) ATTR_NO_RETURN;
|
||||
|
||||
/** Type define for a structure containing a complete DFU command issued by the host. */
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Command; /**< Single byte command to perform, one of the \c COMMAND_* macro values */
|
||||
uint8_t Data[5]; /**< Command parameters */
|
||||
uint16_t DataSize; /**< Size of the command parameters */
|
||||
} DFU_Command_t;
|
||||
|
||||
/* Enums: */
|
||||
/** DFU bootloader states. Refer to the DFU class specification for information on each state. */
|
||||
enum DFU_State_t
|
||||
{
|
||||
appIDLE = 0,
|
||||
appDETACH = 1,
|
||||
dfuIDLE = 2,
|
||||
dfuDNLOAD_SYNC = 3,
|
||||
dfuDNBUSY = 4,
|
||||
dfuDNLOAD_IDLE = 5,
|
||||
dfuMANIFEST_SYNC = 6,
|
||||
dfuMANIFEST = 7,
|
||||
dfuMANIFEST_WAIT_RESET = 8,
|
||||
dfuUPLOAD_IDLE = 9,
|
||||
dfuERROR = 10
|
||||
};
|
||||
|
||||
/** DFU command status error codes. Refer to the DFU class specification for information on each error code. */
|
||||
enum DFU_Status_t
|
||||
{
|
||||
OK = 0,
|
||||
errTARGET = 1,
|
||||
errFILE = 2,
|
||||
errWRITE = 3,
|
||||
errERASE = 4,
|
||||
errCHECK_ERASED = 5,
|
||||
errPROG = 6,
|
||||
errVERIFY = 7,
|
||||
errADDRESS = 8,
|
||||
errNOTDONE = 9,
|
||||
errFIRMWARE = 10,
|
||||
errVENDOR = 11,
|
||||
errUSBR = 12,
|
||||
errPOR = 13,
|
||||
errUNKNOWN = 14,
|
||||
errSTALLEDPKT = 15
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
static void SetupHardware(void);
|
||||
static void ResetHardware(void);
|
||||
|
||||
void EVENT_USB_Device_ControlRequest(void);
|
||||
|
||||
#if defined(INCLUDE_FROM_BOOTLOADER_C)
|
||||
static void DiscardFillerBytes(uint8_t NumberOfBytes);
|
||||
static void ProcessBootloaderCommand(void);
|
||||
static void LoadStartEndAddresses(void);
|
||||
static void ProcessMemProgCommand(void);
|
||||
static void ProcessMemReadCommand(void);
|
||||
static void ProcessWriteCommand(void);
|
||||
static void ProcessReadCommand(void);
|
||||
#endif
|
||||
|
||||
void Application_Jump_Check(void) ATTR_INIT_SECTION(3);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,233 @@
|
|||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage DFU Class USB AVR Bootloader
|
||||
*
|
||||
* \section Sec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* \li Series 7 USB AVRs (AT90USBxxx7)
|
||||
* \li Series 6 USB AVRs (AT90USBxxx6)
|
||||
* \li Series 4 USB AVRs (ATMEGAxxU4) - <i>See \ref SSec_Aux_Space</i>
|
||||
* \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2) - <i>See \ref SSec_Aux_Space</i>
|
||||
*
|
||||
* \section Sec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Device Firmware Update Class (DFU)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>None</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF DFU Class Standard, Atmel USB Bootloader Datasheet</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Supported USB Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section Sec_Description Project Description:
|
||||
*
|
||||
* This bootloader enumerates to the host as a DFU Class device, allowing for DFU-compatible programming
|
||||
* software to load firmware onto the AVR.
|
||||
*
|
||||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit
|
||||
* into 4KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to
|
||||
* edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile.
|
||||
*
|
||||
* When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the
|
||||
* bootloader from the normal user application.
|
||||
*
|
||||
* \section Sec_Running Running the Bootloader
|
||||
*
|
||||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
|
||||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
|
||||
* fuse is cleared.
|
||||
*
|
||||
* For board specific exceptions to the above, see below.
|
||||
*
|
||||
* \subsection SSec_XPLAIN Atmel Xplain Board
|
||||
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the
|
||||
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
|
||||
*
|
||||
* \subsection SSec_Leonardo Arduino Leonardo Board
|
||||
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the
|
||||
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
|
||||
*
|
||||
* \section Sec_Installation Driver Installation
|
||||
*
|
||||
* This bootloader is designed to be compatible with Atmel's provided Windows DFU class drivers. You will need to
|
||||
* install Atmel's DFU drivers prior to using this bootloader on Windows platforms. If you are using a 64 bit Windows
|
||||
* OS, you will need to either disable the driver signing requirement (see online tutorials for details) or use a
|
||||
* digitally signed version of the official Atmel driver provided by a third party AVR user at
|
||||
* <a>http://www.avrfreaks.net/index.php?module=Freaks%20Academy&func=viewItem&item_id=2196&item_type=project</a>.
|
||||
*
|
||||
* \note This device spoofs Atmel's DFU Bootloader USB VID and PID so that the Atmel DFU bootloader
|
||||
* drivers included with FLIP will work. If you do not wish to use Atmel's ID codes, please
|
||||
* manually change them in Descriptors.c and alter your driver's INF file accordingly.
|
||||
*
|
||||
* \section Sec_HostApp Host Controller Application
|
||||
*
|
||||
* This bootloader is compatible with Atmel's FLIP utility on Windows machines, and dfu-programmer on Linux machines.
|
||||
*
|
||||
* \subsection SSec_FLIP FLIP (Windows)
|
||||
*
|
||||
* FLIP (Flexible In-System Programmer) is a utility written by Atmel, and distributed for free on the Atmel website.
|
||||
* The FLIP utility is designed to assist in the bootloader programming of a range of Atmel devices, through several
|
||||
* popular physical interfaces including USB. It is written in Java, however makes use of native extensions for USB
|
||||
* support and thus is only offered on Windows.
|
||||
*
|
||||
* To program a device using FLIP, refer to the Atmel FLIP documentation.
|
||||
*
|
||||
* \subsection SSec_DFUProgrammer dfu-programmer (Linux)
|
||||
*
|
||||
* dfu-programmer is an open-source command line solution for the bootloader programming of Atmel devices through a
|
||||
* USB connection, using the DFU protocol, available for download at <a>http://sourceforge.net/projects/dfu-programmer/</a>.
|
||||
*
|
||||
* The following example loads a HEX file into the AVR's FLASH memory using dfu-programmer:
|
||||
* \code
|
||||
* dfu-programmer at90usb1287 erase flash Mouse.hex
|
||||
* \endcode
|
||||
*
|
||||
* \section Sec_API User Application API
|
||||
*
|
||||
* Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader,
|
||||
* allowing the user application to call into the bootloader at runtime to read and write FLASH data.
|
||||
*
|
||||
* \warning The APIs exposed by the DFU class bootloader are \b NOT compatible with the API exposed by the official Atmel DFU bootloader.
|
||||
*
|
||||
* By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the
|
||||
* following layout:
|
||||
*
|
||||
* \code
|
||||
* #define BOOTLOADER_API_TABLE_SIZE 32
|
||||
* #define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE)
|
||||
* #define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2)
|
||||
*
|
||||
* void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0);
|
||||
* void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1);
|
||||
* void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2);
|
||||
* uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3);
|
||||
* uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4);
|
||||
* uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5);
|
||||
* void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6);
|
||||
*
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2))
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB
|
||||
*
|
||||
* #define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4))
|
||||
* #define BOOTLOADER_DFU_SIGNATURE 0xDF10
|
||||
*
|
||||
* #define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8))
|
||||
* #define BOOTLOADER_ADDRESS_LENGTH 4
|
||||
* \endcode
|
||||
*
|
||||
* From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address
|
||||
* \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader
|
||||
* can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them
|
||||
* to the value \c BOOTLOADER_DFU_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes of FLASH
|
||||
* memory starting from address \c BOOTLOADER_ADDRESS_START.
|
||||
*
|
||||
* \subsection SSec_API_MemLayout Device Memory Map
|
||||
* The following illustration indicates the final memory map of the device when loaded with the bootloader.
|
||||
*
|
||||
* \verbatim
|
||||
* +----------------------------+ 0x0000
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | User Application |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - BOOT_AUX_SECTION_SIZE
|
||||
* | Booloader Start Trampoline |
|
||||
* | (Not User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - (BOOT_AUX_SECTION_SIZE - 4)
|
||||
* | |
|
||||
* | Auxillery Bootloader |
|
||||
* | Space for Smaller Devices |
|
||||
* | (Not User App. Accessible) |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE
|
||||
* | |
|
||||
* | Bootloader Application |
|
||||
* | (Not User App. Accessible) |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - 96
|
||||
* | API Table Trampolines |
|
||||
* | (Not User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 32
|
||||
* | Bootloader API Table |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 8
|
||||
* | Bootloader ID Constants |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND
|
||||
* \endverbatim
|
||||
*
|
||||
* \subsection SSec_Aux_Space Auxiliary Bootloader Section
|
||||
* To make the bootloader function on smaller devices (those with a physical
|
||||
* bootloader section of smaller than 6KB)
|
||||
*
|
||||
* \section Sec_KnownIssues Known Issues:
|
||||
*
|
||||
* \par On Linux machines, the DFU bootloader is inaccessible.
|
||||
* On many Linux systems, non-root users do not have automatic access to newly
|
||||
* inserted DFU devices. Root privileges or a UDEV rule is required to gain
|
||||
* access.
|
||||
* See <a href=https://groups.google.com/d/msg/lufa-support/CP9cy2bc8yo/kBqsOu-RBeMJ>here</a> for resolution steps.
|
||||
*
|
||||
* \par After loading an application, it is not run automatically on startup.
|
||||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader
|
||||
* to run automatically when the device is reset. In most cases, the BOOTRST
|
||||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader
|
||||
* when needed.
|
||||
*
|
||||
* \section Sec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th><b>Define Name:</b></th>
|
||||
* <th><b>Location:</b></th>
|
||||
* <th><b>Description:</b></th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>SECURE_MODE</td>
|
||||
* <td>AppConfig.h</td>
|
||||
* <td>If defined to \c true, the bootloader will not accept any memory commands other than a chip erase on start-up, until an
|
||||
* erase has been performed. This can be used in conjunction with the AVR's lockbits to prevent the AVRs firmware from
|
||||
* being dumped by unauthorized persons. When false, all memory operations are allowed at any time.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Application Configuration Header File
|
||||
*
|
||||
* This is a header file which is be used to configure some of
|
||||
* the application's compile time options, as an alternative to
|
||||
* specifying the compile time constants supplied through a
|
||||
* makefile or build system.
|
||||
*
|
||||
* For information on what each token does, refer to the
|
||||
* \ref Sec_Options section of the application documentation.
|
||||
*/
|
||||
|
||||
#ifndef _APP_CONFIG_H_
|
||||
#define _APP_CONFIG_H_
|
||||
|
||||
#define SECURE_MODE false
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Library Configuration Header File
|
||||
*
|
||||
* This header file is used to configure LUFA's compile time options,
|
||||
* as an alternative to the compile time constants supplied through
|
||||
* a makefile.
|
||||
*
|
||||
* For information on what each token does, refer to the LUFA
|
||||
* manual section "Summary of Compile Tokens".
|
||||
*/
|
||||
|
||||
#ifndef _LUFA_CONFIG_H_
|
||||
#define _LUFA_CONFIG_H_
|
||||
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
/* Non-USB Related Configuration Tokens: */
|
||||
// #define DISABLE_TERMINAL_CODES
|
||||
|
||||
/* USB Class Driver Related Tokens: */
|
||||
// #define HID_HOST_BOOT_PROTOCOL_ONLY
|
||||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_MAX_COLLECTIONS {Insert Value Here}
|
||||
// #define HID_MAX_REPORTITEMS {Insert Value Here}
|
||||
// #define HID_MAX_REPORT_IDS {Insert Value Here}
|
||||
// #define NO_CLASS_DRIVER_AUTOFLUSH
|
||||
|
||||
/* General USB Driver Related Tokens: */
|
||||
// #define ORDERED_EP_CONFIG
|
||||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
|
||||
#define USB_DEVICE_ONLY
|
||||
// #define USB_HOST_ONLY
|
||||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
|
||||
// #define NO_LIMITED_CONTROLLER_CONNECT
|
||||
#define NO_SOF_EVENTS
|
||||
|
||||
/* USB Device Mode Driver Related Tokens: */
|
||||
#define USE_RAM_DESCRIPTORS
|
||||
// #define USE_FLASH_DESCRIPTORS
|
||||
// #define USE_EEPROM_DESCRIPTORS
|
||||
#define NO_INTERNAL_SERIAL
|
||||
#define FIXED_CONTROL_ENDPOINT_SIZE 32
|
||||
#define DEVICE_STATE_AS_GPIOR 0
|
||||
#define FIXED_NUM_CONFIGURATIONS 1
|
||||
#define CONTROL_ONLY_DEVICE
|
||||
// #define INTERRUPT_CONTROL_ENDPOINT
|
||||
#define NO_DEVICE_REMOTE_WAKEUP
|
||||
#define NO_DEVICE_SELF_POWER
|
||||
|
||||
/* USB Host Mode Driver Related Tokens: */
|
||||
// #define HOST_STATE_AS_GPIOR {Insert Value Here}
|
||||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
|
||||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
|
||||
// #define NO_AUTO_VBUS_MANAGEMENT
|
||||
// #define INVERTED_VBUS_ENABLE_LINE
|
||||
|
||||
#else
|
||||
|
||||
#error Unsupported architecture for this LUFA configuration file.
|
||||
|
||||
#endif
|
||||
#endif
|
185
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/Descriptors.c
Normal file
185
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/Descriptors.c
Normal file
|
@ -0,0 +1,185 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
|
||||
* computer-readable structures which the host requests upon device enumeration, to determine
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
|
||||
* device characteristics, including the supported USB version, control endpoint size and the
|
||||
* number of device configurations. The descriptor is read out by the USB host when the enumeration
|
||||
* process begins.
|
||||
*/
|
||||
const USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(1,1,0),
|
||||
.Class = USB_CSCP_NoDeviceClass,
|
||||
.SubClass = USB_CSCP_NoDeviceSubclass,
|
||||
.Protocol = USB_CSCP_NoDeviceProtocol,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = PRODUCT_ID_CODE,
|
||||
.ReleaseNumber = VERSION_BCD(0,0,0),
|
||||
|
||||
.ManufacturerStrIndex = STRING_ID_Manufacturer,
|
||||
.ProductStrIndex = STRING_ID_Product,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage
|
||||
* of the device in one of its supported configurations, including information about any device interfaces
|
||||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
|
||||
* a configuration so that the host may correctly communicate with the USB device.
|
||||
*/
|
||||
const USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.DFU_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = INTERFACE_ID_DFU,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 0,
|
||||
|
||||
.Class = 0xFE,
|
||||
.SubClass = 0x01,
|
||||
.Protocol = 0x02,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.DFU_Functional =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_DFU_Functional_t), .Type = DTYPE_DFUFunctional},
|
||||
|
||||
.Attributes = (ATTR_CAN_UPLOAD | ATTR_CAN_DOWNLOAD),
|
||||
|
||||
.DetachTimeout = 0x0000,
|
||||
.TransferSize = 0x0C00,
|
||||
|
||||
.DFUSpecification = VERSION_BCD(1,1,0)
|
||||
}
|
||||
};
|
||||
|
||||
/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests
|
||||
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
const USB_Descriptor_String_t LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG);
|
||||
|
||||
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
|
||||
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
||||
* Descriptor.
|
||||
*/
|
||||
const USB_Descriptor_String_t ManufacturerString = USB_STRING_DESCRIPTOR(L"Dean Camera");
|
||||
|
||||
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
|
||||
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
||||
* Descriptor.
|
||||
*/
|
||||
const USB_Descriptor_String_t ProductString = USB_STRING_DESCRIPTOR(L"LUFA DFU");
|
||||
|
||||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
|
||||
* documentation) by the application code so that the address and size of a requested descriptor can be given
|
||||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
{
|
||||
const uint8_t DescriptorType = (wValue >> 8);
|
||||
const uint8_t DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
const void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = &DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = &ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
if (DescriptorNumber == STRING_ID_Language)
|
||||
{
|
||||
Address = &LanguageString;
|
||||
Size = LanguageString.Header.Size;
|
||||
}
|
||||
else if (DescriptorNumber == STRING_ID_Manufacturer)
|
||||
{
|
||||
Address = &ManufacturerString;
|
||||
Size = ManufacturerString.Header.Size;
|
||||
}
|
||||
else if (DescriptorNumber == STRING_ID_Product)
|
||||
{
|
||||
Address = &ProductString;
|
||||
Size = ProductString.Header.Size;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
194
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/Descriptors.h
Normal file
194
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/Descriptors.h
Normal file
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include "Config/AppConfig.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Descriptor type value for a DFU class functional descriptor. */
|
||||
#define DTYPE_DFUFunctional 0x21
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device will detach and re-attach when a DFU_DETACH
|
||||
* command is issued, rather than the host issuing a USB Reset.
|
||||
*/
|
||||
#define ATTR_WILL_DETATCH (1 << 3)
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device can communicate during the manifestation phase
|
||||
* (memory programming phase).
|
||||
*/
|
||||
#define ATTR_MANEFESTATION_TOLLERANT (1 << 2)
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device can accept DFU_UPLOAD requests to send data from
|
||||
* the device to the host.
|
||||
*/
|
||||
#define ATTR_CAN_UPLOAD (1 << 1)
|
||||
|
||||
/** DFU attribute mask, indicating that the DFU device can accept DFU_DNLOAD requests to send data from
|
||||
* the host to the device.
|
||||
*/
|
||||
#define ATTR_CAN_DOWNLOAD (1 << 0)
|
||||
|
||||
#if defined(__AVR_AT90USB1287__)
|
||||
#define PRODUCT_ID_CODE 0x2FFB
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB647__)
|
||||
#define PRODUCT_ID_CODE 0x2FF9
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
#define PRODUCT_ID_CODE 0x2FFB
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x97
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
#define PRODUCT_ID_CODE 0x2FF9
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x96
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define PRODUCT_ID_CODE 0x2FF4
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x87
|
||||
#elif defined(__AVR_ATmega16U4__)
|
||||
#define PRODUCT_ID_CODE 0x2FF3
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x88
|
||||
#elif defined(__AVR_ATmega32U2__)
|
||||
#define PRODUCT_ID_CODE 0x2FF0
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x95
|
||||
#define AVR_SIGNATURE_3 0x8A
|
||||
#elif defined(__AVR_ATmega16U2__)
|
||||
#define PRODUCT_ID_CODE 0x2FEF
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define PRODUCT_ID_CODE 0x2FFA
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#elif defined(__AVR_ATmega8U2__)
|
||||
#define PRODUCT_ID_CODE 0x2FEE
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x93
|
||||
#define AVR_SIGNATURE_3 0x89
|
||||
#elif defined(__AVR_AT90USB82__)
|
||||
#define PRODUCT_ID_CODE 0x2FF7
|
||||
#define AVR_SIGNATURE_1 0x1E
|
||||
#define AVR_SIGNATURE_2 0x94
|
||||
#define AVR_SIGNATURE_3 0x82
|
||||
#else
|
||||
#error The selected AVR part is not currently supported by this bootloader.
|
||||
#endif
|
||||
|
||||
#if !defined(PRODUCT_ID_CODE)
|
||||
#error Current AVR model is not supported by this bootloader.
|
||||
#endif
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for a DFU class function descriptor. This descriptor gives DFU class information
|
||||
* to the host when read, indicating the DFU device's capabilities.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Header_t Header; /**< Standard descriptor header structure */
|
||||
|
||||
uint8_t Attributes; /**< DFU device attributes, a mask comprising of the
|
||||
* ATTR_* macros listed in this source file
|
||||
*/
|
||||
uint16_t DetachTimeout; /**< Timeout in milliseconds between a USB_DETACH
|
||||
* command being issued and the device detaching
|
||||
* from the USB bus
|
||||
*/
|
||||
uint16_t TransferSize; /**< Maximum number of bytes the DFU device can accept
|
||||
* from the host in a transaction
|
||||
*/
|
||||
uint16_t DFUSpecification; /**< BCD packed DFU specification number this DFU
|
||||
* device complies with
|
||||
*/
|
||||
} USB_Descriptor_DFU_Functional_t;
|
||||
|
||||
/** Type define for the device configuration descriptor structure. This must be defined in the
|
||||
* application code, as the configuration descriptor contains several sub-descriptors which
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
|
||||
// DFU Interface
|
||||
USB_Descriptor_Interface_t DFU_Interface;
|
||||
USB_Descriptor_DFU_Functional_t DFU_Functional;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor
|
||||
* should have a unique ID index associated with it, which can be used to refer to the
|
||||
* interface from other descriptors.
|
||||
*/
|
||||
enum InterfaceDescriptors_t
|
||||
{
|
||||
INTERFACE_ID_DFU = 0, /**< DFU interface descriptor ID */
|
||||
};
|
||||
|
||||
/** Enum for the device string descriptor IDs within the device. Each string descriptor should
|
||||
* have a unique ID index associated with it, which can be used to refer to the string from
|
||||
* other descriptors.
|
||||
*/
|
||||
enum StringDescriptors_t
|
||||
{
|
||||
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
|
||||
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
|
||||
STRING_ID_Product = 2, /**< Product string ID */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
#endif
|
||||
|
156
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/asf.xml
Normal file
156
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/asf.xml
Normal file
|
@ -0,0 +1,156 @@
|
|||
<asf xmlversion="1.0">
|
||||
<project caption="DFU Bootloader - 128KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.128_4" force-caption="true" workspace-name="lufa_dfu_128kb_4kb_">
|
||||
<require idref="lufa.bootloaders.dfu"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb1287"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1F000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1F000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="DFU Bootloader - 64KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.64_4" force-caption="true" workspace-name="lufa_dfu_64kb_4kb_">
|
||||
<require idref="lufa.bootloaders.dfu"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb647"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0xF000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xF000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0xFFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0xFFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0xFFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="DFU Bootloader - 32KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.32_4" force-caption="true" workspace-name="lufa_dfu_32kb_4kb_">
|
||||
<require idref="lufa.bootloaders.dfu"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega32u4"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x7FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x7FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x7FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="DFU Bootloader - 16KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.16_4" force-caption="true" workspace-name="lufa_dfu_16kb_4kb_">
|
||||
<require idref="lufa.bootloaders.dfu"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega16u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x3000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x3FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x3FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x3FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="DFU Bootloader - 8KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.dfu.avr8.8_4" force-caption="true" workspace-name="lufa_dfu_8kb_4kb_">
|
||||
<require idref="lufa.bootloaders.dfu"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega8u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<module type="application" id="lufa.bootloaders.dfu" caption="DFU Bootloader">
|
||||
<info type="description" value="summary">
|
||||
DFU Class Bootloader, capable of reprogramming a device using the Atmel FLIP or other AVR DFU programming software when plugged into a host.
|
||||
</info>
|
||||
|
||||
<info type="gui-flag" value="move-to-root"/>
|
||||
|
||||
<info type="keyword" value="Technology">
|
||||
<keyword value="Bootloaders"/>
|
||||
<keyword value="USB Device"/>
|
||||
</info>
|
||||
|
||||
<device-support-alias value="lufa_avr8"/>
|
||||
<device-support-alias value="lufa_xmega"/>
|
||||
<device-support-alias value="lufa_uc3"/>
|
||||
|
||||
<build type="include-path" value="."/>
|
||||
<build type="c-source" value="BootloaderDFU.c"/>
|
||||
<build type="header-file" value="BootloaderDFU.h"/>
|
||||
<build type="c-source" value="Descriptors.c"/>
|
||||
<build type="header-file" value="Descriptors.h"/>
|
||||
<build type="c-source" value="BootloaderAPI.c"/>
|
||||
<build type="header-file" value="BootloaderAPI.h"/>
|
||||
<build type="asm-source" value="BootloaderAPITable.S"/>
|
||||
|
||||
<build type="module-config" subtype="path" value="Config"/>
|
||||
<build type="header-file" value="Config/LUFAConfig.h"/>
|
||||
<build type="header-file" value="Config/AppConfig.h"/>
|
||||
|
||||
<build type="distribute" subtype="user-file" value="doxyfile"/>
|
||||
<build type="distribute" subtype="user-file" value="BootloaderDFU.txt"/>
|
||||
|
||||
<require idref="lufa.common"/>
|
||||
<require idref="lufa.platform"/>
|
||||
<require idref="lufa.drivers.usb"/>
|
||||
<require idref="lufa.drivers.board"/>
|
||||
<require idref="lufa.drivers.board.leds"/>
|
||||
</module>
|
||||
</asf>
|
2365
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/doxyfile
Normal file
2365
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/doxyfile
Normal file
File diff suppressed because it is too large
Load diff
55
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/makefile
Normal file
55
tmk_core/protocol/lufa/LUFA-git/Bootloaders/DFU/makefile
Normal file
|
@ -0,0 +1,55 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.lufa-lib.org
|
||||
#
|
||||
# --------------------------------------
|
||||
# LUFA Project Makefile.
|
||||
# --------------------------------------
|
||||
|
||||
# Run "make help" for target help.
|
||||
|
||||
MCU = at90usb1287
|
||||
ARCH = AVR8
|
||||
BOARD = USBKEY
|
||||
F_CPU = 8000000
|
||||
F_USB = $(F_CPU)
|
||||
OPTIMIZATION = s
|
||||
TARGET = BootloaderDFU
|
||||
SRC = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S $(LUFA_SRC_USB)
|
||||
LUFA_PATH = ../../LUFA
|
||||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET)
|
||||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS)
|
||||
|
||||
# Flash size and bootloader section sizes of the target, in KB. These must
|
||||
# match the target's total FLASH size and the bootloader size set in the
|
||||
# device's fuses.
|
||||
FLASH_SIZE_KB = 128
|
||||
BOOT_SECTION_SIZE_KB = 8
|
||||
|
||||
# Bootloader address calculation formulas
|
||||
# Do not modify these macros, but rather modify the dependent values above.
|
||||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) )
|
||||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 )
|
||||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) )
|
||||
|
||||
# Bootloader linker section flags for relocating the API table sections to
|
||||
# known FLASH addresses - these should not normally be user-edited.
|
||||
BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2))
|
||||
BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8)
|
||||
|
||||
# Default target
|
||||
all:
|
||||
|
||||
# Include LUFA build script makefiles
|
||||
include $(LUFA_PATH)/Build/lufa_core.mk
|
||||
include $(LUFA_PATH)/Build/lufa_sources.mk
|
||||
include $(LUFA_PATH)/Build/lufa_build.mk
|
||||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk
|
||||
include $(LUFA_PATH)/Build/lufa_doxygen.mk
|
||||
include $(LUFA_PATH)/Build/lufa_avrdude.mk
|
||||
include $(LUFA_PATH)/Build/lufa_atprogram.mk
|
190
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/BootloaderHID.c
Normal file
190
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/BootloaderHID.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the HID class bootloader. This file contains the complete bootloader logic.
|
||||
*/
|
||||
|
||||
#include "BootloaderHID.h"
|
||||
|
||||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
|
||||
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application
|
||||
* started via a forced watchdog reset.
|
||||
*/
|
||||
static bool RunBootloader = true;
|
||||
|
||||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader
|
||||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held
|
||||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value
|
||||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start.
|
||||
*/
|
||||
uint16_t MagicBootKey ATTR_NO_INIT;
|
||||
|
||||
|
||||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application
|
||||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid,
|
||||
* this will force the user application to start via a software jump.
|
||||
*/
|
||||
void Application_Jump_Check(void)
|
||||
{
|
||||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
|
||||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
|
||||
{
|
||||
MagicBootKey = 0;
|
||||
|
||||
// cppcheck-suppress constStatement
|
||||
((void (*)(void))0x0000)();
|
||||
}
|
||||
}
|
||||
|
||||
/** Main program entry point. This routine configures the hardware required by the bootloader, then continuously
|
||||
* runs the bootloader processing routine until instructed to soft-exit.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
/* Setup hardware required for the bootloader */
|
||||
SetupHardware();
|
||||
|
||||
/* Enable global interrupts so that the USB stack can function */
|
||||
GlobalInterruptEnable();
|
||||
|
||||
while (RunBootloader)
|
||||
USB_USBTask();
|
||||
|
||||
/* Disconnect from the host - USB interface will be reset later along with the AVR */
|
||||
USB_Detach();
|
||||
|
||||
/* Unlock the forced application start mode of the bootloader if it is restarted */
|
||||
MagicBootKey = MAGIC_BOOT_KEY;
|
||||
|
||||
/* Enable the watchdog and force a timeout to reset the AVR */
|
||||
wdt_enable(WDTO_250MS);
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
/** Configures all hardware required for the bootloader. */
|
||||
static void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Relocate the interrupt vector table to the bootloader section */
|
||||
MCUCR = (1 << IVCE);
|
||||
MCUCR = (1 << IVSEL);
|
||||
|
||||
/* Initialize USB subsystem */
|
||||
USB_Init();
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ConfigurationChanged event. This configures the device's endpoints ready
|
||||
* to relay data to and from the attached USB host.
|
||||
*/
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
/* Setup HID Report Endpoint */
|
||||
Endpoint_ConfigureEndpoint(HID_IN_EPADDR, EP_TYPE_INTERRUPT, HID_IN_EPSIZE, 1);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
|
||||
* the device from the USB host before passing along unhandled control requests to the library for processing
|
||||
* internally.
|
||||
*/
|
||||
void EVENT_USB_Device_ControlRequest(void)
|
||||
{
|
||||
/* Ignore any requests that aren't directed to the HID interface */
|
||||
if ((USB_ControlRequest.bmRequestType & (CONTROL_REQTYPE_TYPE | CONTROL_REQTYPE_RECIPIENT)) !=
|
||||
(REQTYPE_CLASS | REQREC_INTERFACE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Process HID specific control requests */
|
||||
switch (USB_ControlRequest.bRequest)
|
||||
{
|
||||
case HID_REQ_SetReport:
|
||||
Endpoint_ClearSETUP();
|
||||
|
||||
/* Wait until the command has been sent by the host */
|
||||
while (!(Endpoint_IsOUTReceived()));
|
||||
|
||||
/* Read in the write destination address */
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
uint32_t PageAddress = ((uint32_t)Endpoint_Read_16_LE() << 8);
|
||||
#else
|
||||
uint16_t PageAddress = Endpoint_Read_16_LE();
|
||||
#endif
|
||||
|
||||
/* Check if the command is a program page command, or a start application command */
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
if ((uint16_t)(PageAddress >> 8) == COMMAND_STARTAPPLICATION)
|
||||
#else
|
||||
if (PageAddress == COMMAND_STARTAPPLICATION)
|
||||
#endif
|
||||
{
|
||||
RunBootloader = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Erase the given FLASH page, ready to be programmed */
|
||||
boot_page_erase(PageAddress);
|
||||
boot_spm_busy_wait();
|
||||
|
||||
/* Write each of the FLASH page's bytes in sequence */
|
||||
for (uint8_t PageWord = 0; PageWord < (SPM_PAGESIZE / 2); PageWord++)
|
||||
{
|
||||
/* Check if endpoint is empty - if so clear it and wait until ready for next packet */
|
||||
if (!(Endpoint_BytesInEndpoint()))
|
||||
{
|
||||
Endpoint_ClearOUT();
|
||||
while (!(Endpoint_IsOUTReceived()));
|
||||
}
|
||||
|
||||
/* Write the next data word to the FLASH page */
|
||||
boot_page_fill(PageAddress + ((uint16_t)PageWord << 1), Endpoint_Read_16_LE());
|
||||
}
|
||||
|
||||
/* Write the filled FLASH page to memory */
|
||||
boot_page_write(PageAddress);
|
||||
boot_spm_busy_wait();
|
||||
|
||||
/* Re-enable RWW section */
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
Endpoint_ClearStatusStage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderHID.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADERHID_H_
|
||||
#define _BOOTLOADERHID_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/boot.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Platform/Platform.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__OPTIMIZE_SIZE__)
|
||||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** Bootloader special address to start the user application */
|
||||
#define COMMAND_STARTAPPLICATION 0xFFFF
|
||||
|
||||
/** Magic bootloader key to unlock forced application start mode. */
|
||||
#define MAGIC_BOOT_KEY 0xDC42
|
||||
|
||||
/* Function Prototypes: */
|
||||
static void SetupHardware(void);
|
||||
|
||||
void Application_Jump_Check(void) ATTR_INIT_SECTION(3);
|
||||
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_UnhandledControlRequest(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage HID Class USB AVR Bootloader
|
||||
*
|
||||
* \section SSec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* \li Series 7 USB AVRs (AT90USBxxx7)
|
||||
* \li Series 6 USB AVRs (AT90USBxxx6)
|
||||
* \li Series 4 USB AVRs (ATMEGAxxU4)
|
||||
* \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2)
|
||||
*
|
||||
* \section SSec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Human Interface Device Class (HID)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>N/A</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF HID Class Standard \n
|
||||
* Teensy Programming Protocol Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Supported USB Speeds:</b></td>
|
||||
* <td>Low Speed Mode \n
|
||||
* Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section SSec_Description Project Description:
|
||||
*
|
||||
* This bootloader enumerates to the host as a HID Class device, allowing for device FLASH programming through
|
||||
* the supplied command line software, which is a modified version of Paul's TeensyHID Command Line loader code
|
||||
* from PJRC (used with permission). This bootloader is deliberately non-compatible with the proprietary PJRC
|
||||
* HalfKay bootloader GUI; only the command line interface software accompanying this bootloader will work with it.
|
||||
*
|
||||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit
|
||||
* into 2KB of bootloader space for the Series 2 USB AVRs (ATMEGAxxU2, AT90USBxx2) or 4KB of bootloader space for
|
||||
* all other models. If you wish to alter this size and/or change the AVR model, you will need to edit the MCU,
|
||||
* FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile.
|
||||
*
|
||||
* \warning <b>THIS BOOTLOADER IS NOT SECURE.</b> Malicious entities can recover written data, even if the device
|
||||
* lockbits are set.
|
||||
*
|
||||
* \section Sec_Running Running the Bootloader
|
||||
*
|
||||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
|
||||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
|
||||
* fuse is cleared.
|
||||
*
|
||||
* \section Sec_Installation Driver Installation
|
||||
*
|
||||
* This bootloader uses the HID class driver inbuilt into all modern operating systems, thus no additional drivers
|
||||
* need to be supplied for correct operation.
|
||||
*
|
||||
* \section Sec_HostApp Host Controller Application
|
||||
*
|
||||
* Due to licensing issues, the supplied bootloader is compatible with the HalfKay bootloader protocol designed
|
||||
* by PJRC, but is non-compatible with the cross-platform loader GUI. A modified version of the open source
|
||||
* cross-platform TeensyLoader application is supplied, which can be compiled under most operating systems. The
|
||||
* command-line loader application should remain compatible with genuine Teensy boards in addition to boards using
|
||||
* this custom bootloader.
|
||||
*
|
||||
* Once compiled, programs can be loaded into the AVR's FLASH memory through the following example command:
|
||||
* \code
|
||||
* hid_bootloader_cli -mmcu=at90usb1287 Mouse.hex
|
||||
* \endcode
|
||||
*
|
||||
* \section Sec_KnownIssues Known Issues:
|
||||
*
|
||||
* \par After loading an application, it is not run automatically on startup.
|
||||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader
|
||||
* to run automatically when the device is reset. In most cases, the BOOTRST
|
||||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader
|
||||
* when needed.
|
||||
*
|
||||
* \section SSec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Library Configuration Header File
|
||||
*
|
||||
* This header file is used to configure LUFA's compile time options,
|
||||
* as an alternative to the compile time constants supplied through
|
||||
* a makefile.
|
||||
*
|
||||
* For information on what each token does, refer to the LUFA
|
||||
* manual section "Summary of Compile Tokens".
|
||||
*/
|
||||
|
||||
#ifndef _LUFA_CONFIG_H_
|
||||
#define _LUFA_CONFIG_H_
|
||||
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
/* Non-USB Related Configuration Tokens: */
|
||||
// #define DISABLE_TERMINAL_CODES
|
||||
|
||||
/* USB Class Driver Related Tokens: */
|
||||
// #define HID_HOST_BOOT_PROTOCOL_ONLY
|
||||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_MAX_COLLECTIONS {Insert Value Here}
|
||||
// #define HID_MAX_REPORTITEMS {Insert Value Here}
|
||||
// #define HID_MAX_REPORT_IDS {Insert Value Here}
|
||||
// #define NO_CLASS_DRIVER_AUTOFLUSH
|
||||
|
||||
/* General USB Driver Related Tokens: */
|
||||
#define ORDERED_EP_CONFIG
|
||||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
|
||||
#define USB_DEVICE_ONLY
|
||||
// #define USB_HOST_ONLY
|
||||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
|
||||
// #define NO_LIMITED_CONTROLLER_CONNECT
|
||||
#define NO_SOF_EVENTS
|
||||
|
||||
/* USB Device Mode Driver Related Tokens: */
|
||||
#define USE_RAM_DESCRIPTORS
|
||||
// #define USE_FLASH_DESCRIPTORS
|
||||
// #define USE_EEPROM_DESCRIPTORS
|
||||
#define NO_INTERNAL_SERIAL
|
||||
#define FIXED_CONTROL_ENDPOINT_SIZE 8
|
||||
#define DEVICE_STATE_AS_GPIOR 0
|
||||
#define FIXED_NUM_CONFIGURATIONS 1
|
||||
// #define CONTROL_ONLY_DEVICE
|
||||
// #define INTERRUPT_CONTROL_ENDPOINT
|
||||
#define NO_DEVICE_REMOTE_WAKEUP
|
||||
#define NO_DEVICE_SELF_POWER
|
||||
|
||||
/* USB Host Mode Driver Related Tokens: */
|
||||
// #define HOST_STATE_AS_GPIOR {Insert Value Here}
|
||||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
|
||||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
|
||||
// #define NO_AUTO_VBUS_MANAGEMENT
|
||||
// #define INVERTED_VBUS_ENABLE_LINE
|
||||
|
||||
#else
|
||||
|
||||
#error Unsupported architecture for this LUFA configuration file.
|
||||
|
||||
#endif
|
||||
#endif
|
187
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/Descriptors.c
Normal file
187
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/Descriptors.c
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
|
||||
* computer-readable structures which the host requests upon device enumeration, to determine
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
/** HID class report descriptor. This is a special descriptor constructed with values from the
|
||||
* USBIF HID class specification to describe the reports and capabilities of the HID device. This
|
||||
* descriptor is parsed by the host and its contents used to determine what data (and in what encoding)
|
||||
* the device will send, and what it may be sent back from the host. Refer to the HID specification for
|
||||
* more details on HID report descriptors.
|
||||
*/
|
||||
const USB_Descriptor_HIDReport_Datatype_t HIDReport[] =
|
||||
{
|
||||
HID_RI_USAGE_PAGE(16, 0xFFDC), /* Vendor Page 0xDC */
|
||||
HID_RI_USAGE(8, 0xFB), /* Vendor Usage 0xFB */
|
||||
HID_RI_COLLECTION(8, 0x01), /* Vendor Usage 1 */
|
||||
HID_RI_USAGE(8, 0x02), /* Vendor Usage 2 */
|
||||
HID_RI_LOGICAL_MINIMUM(8, 0x00),
|
||||
HID_RI_LOGICAL_MAXIMUM(8, 0xFF),
|
||||
HID_RI_REPORT_SIZE(8, 0x08),
|
||||
HID_RI_REPORT_COUNT(16, (sizeof(uint16_t) + SPM_PAGESIZE)),
|
||||
HID_RI_OUTPUT(8, HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE | HID_IOF_NON_VOLATILE),
|
||||
HID_RI_END_COLLECTION(0),
|
||||
};
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
|
||||
* device characteristics, including the supported USB version, control endpoint size and the
|
||||
* number of device configurations. The descriptor is read out by the USB host when the enumeration
|
||||
* process begins.
|
||||
*/
|
||||
const USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(1,1,0),
|
||||
.Class = USB_CSCP_NoDeviceClass,
|
||||
.SubClass = USB_CSCP_NoDeviceSubclass,
|
||||
.Protocol = USB_CSCP_NoDeviceProtocol,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2067,
|
||||
.ReleaseNumber = VERSION_BCD(0,0,1),
|
||||
|
||||
.ManufacturerStrIndex = NO_DESCRIPTOR,
|
||||
.ProductStrIndex = NO_DESCRIPTOR,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage
|
||||
* of the device in one of its supported configurations, including information about any device interfaces
|
||||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
|
||||
* a configuration so that the host may correctly communicate with the USB device.
|
||||
*/
|
||||
const USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.HID_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = INTERFACE_ID_Printer,
|
||||
.AlternateSetting = 0x00,
|
||||
|
||||
.TotalEndpoints = 1,
|
||||
|
||||
.Class = HID_CSCP_HIDClass,
|
||||
.SubClass = HID_CSCP_NonBootSubclass,
|
||||
.Protocol = HID_CSCP_NonBootProtocol,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.HID_VendorHID =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_HID_Descriptor_HID_t), .Type = HID_DTYPE_HID},
|
||||
|
||||
.HIDSpec = VERSION_BCD(1,1,1),
|
||||
.CountryCode = 0x00,
|
||||
.TotalReportDescriptors = 1,
|
||||
.HIDReportType = HID_DTYPE_Report,
|
||||
.HIDReportLength = sizeof(HIDReport)
|
||||
},
|
||||
|
||||
.HID_ReportINEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = HID_IN_EPADDR,
|
||||
.Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = HID_IN_EPSIZE,
|
||||
.PollingIntervalMS = 0x05
|
||||
},
|
||||
};
|
||||
|
||||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
|
||||
* documentation) by the application code so that the address and size of a requested descriptor can be given
|
||||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
{
|
||||
const uint8_t DescriptorType = (wValue >> 8);
|
||||
|
||||
const void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
/* If/Else If chain compiles slightly smaller than a switch case */
|
||||
if (DescriptorType == DTYPE_Device)
|
||||
{
|
||||
Address = &DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
}
|
||||
else if (DescriptorType == DTYPE_Configuration)
|
||||
{
|
||||
Address = &ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
}
|
||||
else if (DescriptorType == HID_DTYPE_HID)
|
||||
{
|
||||
Address = &ConfigurationDescriptor.HID_VendorHID;
|
||||
Size = sizeof(USB_HID_Descriptor_HID_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
Address = &HIDReport;
|
||||
Size = sizeof(HIDReport);
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for the device configuration descriptor structure. This must be defined in the
|
||||
* application code, as the configuration descriptor contains several sub-descriptors which
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
|
||||
// Generic HID Interface
|
||||
USB_Descriptor_Interface_t HID_Interface;
|
||||
USB_HID_Descriptor_HID_t HID_VendorHID;
|
||||
USB_Descriptor_Endpoint_t HID_ReportINEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor
|
||||
* should have a unique ID index associated with it, which can be used to refer to the
|
||||
* interface from other descriptors.
|
||||
*/
|
||||
enum InterfaceDescriptors_t
|
||||
{
|
||||
INTERFACE_ID_Printer = 0, /**< Printer interface descriptor ID */
|
||||
};
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint address of the HID data IN endpoint. */
|
||||
#define HID_IN_EPADDR (ENDPOINT_DIR_IN | 1)
|
||||
|
||||
/** Size in bytes of the HID reporting IN endpoint. */
|
||||
#define HID_IN_EPSIZE 64
|
||||
|
||||
/* Function Prototypes: */
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
OS ?= LINUX
|
||||
#OS ?= WINDOWS
|
||||
#OS ?= MACOSX
|
||||
#OS ?= BSD
|
||||
|
||||
ifeq ($(OS), LINUX) # also works on FreeBSD
|
||||
CC ?= gcc
|
||||
CFLAGS ?= -O2 -Wall
|
||||
hid_bootloader_cli: hid_bootloader_cli.c
|
||||
$(CC) $(CFLAGS) -s -DUSE_LIBUSB -o hid_bootloader_cli hid_bootloader_cli.c -lusb
|
||||
|
||||
|
||||
else ifeq ($(OS), WINDOWS)
|
||||
CC = i586-mingw32msvc-gcc
|
||||
CFLAGS ?= -O2 -Wall
|
||||
hid_bootloader_cli.exe: hid_bootloader_cli.c
|
||||
$(CC) $(CFLAGS) -s -DUSE_WIN32 -o hid_bootloader_cli.exe hid_bootloader_cli.c -lhid -lsetupapi
|
||||
|
||||
|
||||
else ifeq ($(OS), MACOSX)
|
||||
CC ?= gcc
|
||||
SDK ?= /Developer/SDKs/MacOSX10.5.sdk
|
||||
CFLAGS ?= -O2 -Wall
|
||||
hid_bootloader_cli: hid_bootloader_cli.c
|
||||
$(CC) $(CFLAGS) -DUSE_APPLE_IOKIT -isysroot $(SDK) -o hid_bootloader_cli hid_bootloader_cli.c -Wl,-syslibroot,$(SDK) -framework IOKit -framework CoreFoundation
|
||||
|
||||
|
||||
else ifeq ($(OS), BSD) # works on NetBSD and OpenBSD
|
||||
CC ?= gcct
|
||||
CFLAGS ?= -O2 -Wall
|
||||
hid_bootloader_cli: hid_bootloader_cli.c
|
||||
$(CC) $(CFLAGS) -s -DUSE_UHID -o hid_bootloader_cli hid_bootloader_cli.c
|
||||
|
||||
|
||||
endif
|
||||
|
||||
|
||||
clean:
|
||||
rm -f hid_bootloader_cli hid_bootloader_cli.exe
|
|
@ -0,0 +1,21 @@
|
|||
OS ?= FreeBSD
|
||||
#OS ?= NetBSD
|
||||
#OS ?= OpenBSD
|
||||
|
||||
CFLAGS ?= -O2 -Wall
|
||||
CC ?= gcc
|
||||
|
||||
.if $(OS) == "FreeBSD"
|
||||
CFLAGS += -DUSE_LIBUSB
|
||||
LIBS = -lusb
|
||||
.elif $(OS) == "NetBSD" || $(OS) == "OpenBSD"
|
||||
CFLAGS += -DUSE_UHID
|
||||
LIBS =
|
||||
.endif
|
||||
|
||||
|
||||
hid_bootloader_cli: hid_bootloader_cli.c
|
||||
$(CC) $(CFLAGS) -s -o hid_bootloader_cli hid_bootloader_cli.c $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f hid_bootloader_cli
|
|
@ -0,0 +1,674 @@
|
|||
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>.
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,120 @@
|
|||
"""
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
"""
|
||||
|
||||
"""
|
||||
Front-end programmer for the LUFA HID class bootloader.
|
||||
|
||||
Usage:
|
||||
python hid_bootloader_loader.py <Device> <Input>.hex
|
||||
|
||||
Example:
|
||||
python hid_bootloader_loader.py at90usb1287 Mouse.hex
|
||||
|
||||
Requires the pywinusb (https://pypi.python.org/pypi/pywinusb/) and
|
||||
IntelHex (http://bialix.com/intelhex/) libraries.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pywinusb import hid
|
||||
from intelhex import IntelHex
|
||||
|
||||
|
||||
# Device information table
|
||||
device_info_map = dict()
|
||||
device_info_map['at90usb1287'] = {'page_size': 256, 'flash_kb': 128}
|
||||
device_info_map['at90usb1286'] = {'page_size': 256, 'flash_kb': 128}
|
||||
device_info_map['at90usb647'] = {'page_size': 256, 'flash_kb': 64}
|
||||
device_info_map['at90usb646'] = {'page_size': 256, 'flash_kb': 64}
|
||||
device_info_map['atmega32u4'] = {'page_size': 128, 'flash_kb': 32}
|
||||
device_info_map['atmega32u2'] = {'page_size': 128, 'flash_kb': 32}
|
||||
device_info_map['atmega16u4'] = {'page_size': 128, 'flash_kb': 16}
|
||||
device_info_map['atmega16u2'] = {'page_size': 128, 'flash_kb': 16}
|
||||
device_info_map['at90usb162'] = {'page_size': 128, 'flash_kb': 16}
|
||||
device_info_map['atmega8u2'] = {'page_size': 128, 'flash_kb': 8}
|
||||
device_info_map['at90usb82'] = {'page_size': 128, 'flash_kb': 8}
|
||||
|
||||
|
||||
def get_hid_device_handle():
|
||||
hid_device_filter = hid.HidDeviceFilter(vendor_id=0x03EB,
|
||||
product_id=0x2067)
|
||||
|
||||
valid_hid_devices = hid_device_filter.get_devices()
|
||||
|
||||
if len(valid_hid_devices) is 0:
|
||||
return None
|
||||
else:
|
||||
return valid_hid_devices[0]
|
||||
|
||||
|
||||
def send_page_data(hid_device, address, data):
|
||||
# Bootloader page data should be the HID Report ID (always zero) followed
|
||||
# by the starting address to program, then one device's flash page worth
|
||||
# of data
|
||||
output_report_data = [0]
|
||||
output_report_data.extend([address & 0xFF, address >> 8])
|
||||
output_report_data.extend(data)
|
||||
|
||||
hid_device.send_output_report(output_report_data)
|
||||
|
||||
|
||||
def program_device(hex_data, device_info):
|
||||
hid_device = get_hid_device_handle()
|
||||
|
||||
if hid_device is None:
|
||||
print("No valid HID device found.")
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
hid_device.open()
|
||||
print("Connected to bootloader.")
|
||||
|
||||
# Program in all data from the loaded HEX file, in a number of device
|
||||
# page sized chunks
|
||||
for addr in range(0, hex_data.maxaddr(), device_info['page_size']):
|
||||
# Compute the address range of the current page in the device
|
||||
current_page_range = range(addr, addr+device_info['page_size'])
|
||||
|
||||
# Extract the data from the hex file at the specified start page
|
||||
# address and convert it to a regular list of bytes
|
||||
page_data = [hex_data[i] for i in current_page_range]
|
||||
|
||||
print("Writing address 0x%04X-0x%04X" % (current_page_range[0], current_page_range[-1]))
|
||||
|
||||
# Devices with more than 64KB of flash should shift down the page
|
||||
# address so that it is 16-bit (page size is guaranteed to be
|
||||
# >= 256 bytes so no non-zero address bits are discarded)
|
||||
if device_info['flash_kb'] < 64:
|
||||
send_page_data(hid_device, addr, page_data)
|
||||
else:
|
||||
send_page_data(hid_device, addr >> 8, page_data)
|
||||
|
||||
# Once programming is complete, start the application via a dummy page
|
||||
# program to the page address 0xFFFF
|
||||
print("Programming complete, starting application.")
|
||||
send_page_data(hid_device, 0xFFFF, [0] * device_info['page_size'])
|
||||
|
||||
finally:
|
||||
hid_device.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Load the specified HEX file
|
||||
try:
|
||||
hex_data = IntelHex(sys.argv[2])
|
||||
except:
|
||||
print("Could not open the specified HEX file.")
|
||||
sys.exit(1)
|
||||
|
||||
# Retrieve the device information entry for the specified device
|
||||
try:
|
||||
device_info = device_info_map[sys.argv[1]]
|
||||
except:
|
||||
print("Unknown device name specified.")
|
||||
sys.exit(1)
|
||||
|
||||
program_device(hex_data, device_info)
|
123
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/asf.xml
Normal file
123
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/asf.xml
Normal file
|
@ -0,0 +1,123 @@
|
|||
<asf xmlversion="1.0">
|
||||
<project caption="HID Bootloader - 128KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.128_4" force-caption="true" workspace-name="lufa_hid_128kb_4kb_">
|
||||
<require idref="lufa.bootloaders.hid"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb1287"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1F000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1F000"/>
|
||||
</project>
|
||||
|
||||
<project caption="HID Bootloader - 64KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.64_4" force-caption="true" workspace-name="lufa_hid_64kb_4kb_">
|
||||
<require idref="lufa.bootloaders.hid"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb647"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0xF000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xF000"/>
|
||||
</project>
|
||||
|
||||
<project caption="HID Bootloader - 32KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.32_4" force-caption="true" workspace-name="lufa_hid_32kb_4kb_">
|
||||
<require idref="lufa.bootloaders.hid"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega32u4"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/>
|
||||
</project>
|
||||
|
||||
<project caption="HID Bootloader - 16KB FLASH / 2KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.16_2" force-caption="true" workspace-name="lufa_hid_16kb_2kb_">
|
||||
<require idref="lufa.bootloaders.hid"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega16u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x3800"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3800"/>
|
||||
</project>
|
||||
|
||||
<project caption="HID Bootloader - 8KB FLASH / 2KB Boot - AVR8 Architecture" id="lufa.bootloaders.hid.avr8.8_2" force-caption="true" workspace-name="lufa_hid_8kb_2kb_">
|
||||
<require idref="lufa.bootloaders.hid"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega8u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1800"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1800"/>
|
||||
</project>
|
||||
|
||||
<module type="application" id="lufa.bootloaders.hid" caption="HID Bootloader">
|
||||
<info type="description" value="summary">
|
||||
HID Class Bootloader, capable of reprogramming a device via a custom cross-platform command line utility when plugged into a host.
|
||||
</info>
|
||||
|
||||
<info type="gui-flag" value="move-to-root"/>
|
||||
|
||||
<info type="keyword" value="Technology">
|
||||
<keyword value="Bootloaders"/>
|
||||
<keyword value="USB Device"/>
|
||||
</info>
|
||||
|
||||
<device-support-alias value="lufa_avr8"/>
|
||||
<device-support-alias value="lufa_xmega"/>
|
||||
<device-support-alias value="lufa_uc3"/>
|
||||
|
||||
<build type="include-path" value="."/>
|
||||
<build type="c-source" value="BootloaderHID.c"/>
|
||||
<build type="header-file" value="BootloaderHID.h"/>
|
||||
<build type="c-source" value="Descriptors.c"/>
|
||||
<build type="header-file" value="Descriptors.h"/>
|
||||
|
||||
<build type="module-config" subtype="path" value="Config"/>
|
||||
<build type="header-file" value="Config/LUFAConfig.h"/>
|
||||
|
||||
<build type="distribute" subtype="user-file" value="doxyfile"/>
|
||||
<build type="distribute" subtype="user-file" value="BootloaderHID.txt"/>
|
||||
<build type="distribute" subtype="directory" value="HostLoaderApp"/>
|
||||
<build type="distribute" subtype="directory" value="HostLoaderApp_Python"/>
|
||||
|
||||
<require idref="lufa.common"/>
|
||||
<require idref="lufa.platform"/>
|
||||
<require idref="lufa.drivers.usb"/>
|
||||
<require idref="lufa.drivers.board"/>
|
||||
<require idref="lufa.drivers.board.leds"/>
|
||||
</module>
|
||||
</asf>
|
2367
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/doxyfile
Normal file
2367
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/doxyfile
Normal file
File diff suppressed because it is too large
Load diff
48
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/makefile
Normal file
48
tmk_core/protocol/lufa/LUFA-git/Bootloaders/HID/makefile
Normal file
|
@ -0,0 +1,48 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.lufa-lib.org
|
||||
#
|
||||
# --------------------------------------
|
||||
# LUFA Project Makefile.
|
||||
# --------------------------------------
|
||||
|
||||
# Run "make help" for target help.
|
||||
|
||||
MCU = at90usb1287
|
||||
ARCH = AVR8
|
||||
BOARD = USBKEY
|
||||
F_CPU = 8000000
|
||||
F_USB = $(F_CPU)
|
||||
OPTIMIZATION = s
|
||||
TARGET = BootloaderHID
|
||||
SRC = $(TARGET).c Descriptors.c $(LUFA_SRC_USB)
|
||||
LUFA_PATH = ../../LUFA
|
||||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/
|
||||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET)
|
||||
|
||||
# Flash size and bootloader section sizes of the target, in KB. These must
|
||||
# match the target's total FLASH size and the bootloader size set in the
|
||||
# device's fuses.
|
||||
FLASH_SIZE_KB := 128
|
||||
BOOT_SECTION_SIZE_KB := 8
|
||||
|
||||
# Bootloader address calculation formulas
|
||||
# Do not modify these macros, but rather modify the dependent values above.
|
||||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) )
|
||||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 )
|
||||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) )
|
||||
|
||||
# Default target
|
||||
all:
|
||||
|
||||
# Include LUFA build script makefiles
|
||||
include $(LUFA_PATH)/Build/lufa_core.mk
|
||||
include $(LUFA_PATH)/Build/lufa_sources.mk
|
||||
include $(LUFA_PATH)/Build/lufa_build.mk
|
||||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk
|
||||
include $(LUFA_PATH)/Build/lufa_doxygen.mk
|
||||
include $(LUFA_PATH)/Build/lufa_avrdude.mk
|
||||
include $(LUFA_PATH)/Build/lufa_atprogram.mk
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Bootloader user application API functions.
|
||||
*/
|
||||
|
||||
#include "BootloaderAPI.h"
|
||||
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_erase_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_WritePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_write_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word)
|
||||
{
|
||||
boot_page_fill_safe(Address, Word);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address)
|
||||
{
|
||||
return boot_signature_byte_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadLock(void)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(GET_LOCK_BITS);
|
||||
}
|
||||
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits)
|
||||
{
|
||||
boot_lock_bits_set_safe(LockBits);
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderAPI.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_API_H_
|
||||
#define _BOOTLOADER_API_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/boot.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
|
||||
/* Macros: */
|
||||
#if AUX_BOOT_SECTION_SIZE > 0
|
||||
#define AUX_BOOT_SECTION __attribute__((section(".boot_aux")))
|
||||
#else
|
||||
#define AUX_BOOT_SECTION
|
||||
#endif
|
||||
|
||||
/* Function Prototypes: */
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address);
|
||||
void BootloaderAPI_WritePage(const uint32_t Address);
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word);
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadLock(void);
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#if AUX_BOOT_SECTION_SIZE > 0
|
||||
#warning Using a AUX bootloader section in addition to the defined bootloader space (see documentation).
|
||||
|
||||
; Trampoline to jump over the AUX bootloader section to the start of the bootloader,
|
||||
; on devices where an AUX bootloader section is used.
|
||||
.section .boot_aux_trampoline, "ax"
|
||||
.global Boot_AUX_Trampoline
|
||||
Boot_AUX_Trampoline:
|
||||
jmp BOOT_START_ADDR
|
||||
#endif
|
||||
|
||||
; Trampolines to actual API implementations if the target address is outside the
|
||||
; range of a rjmp instruction (can happen with large bootloader sections)
|
||||
.section .apitable_trampolines, "ax"
|
||||
.global BootloaderAPI_Trampolines
|
||||
BootloaderAPI_Trampolines:
|
||||
|
||||
BootloaderAPI_ErasePage_Trampoline:
|
||||
jmp BootloaderAPI_ErasePage
|
||||
BootloaderAPI_WritePage_Trampoline:
|
||||
jmp BootloaderAPI_WritePage
|
||||
BootloaderAPI_FillWord_Trampoline:
|
||||
jmp BootloaderAPI_FillWord
|
||||
BootloaderAPI_ReadSignature_Trampoline:
|
||||
jmp BootloaderAPI_ReadSignature
|
||||
BootloaderAPI_ReadFuse_Trampoline:
|
||||
jmp BootloaderAPI_ReadFuse
|
||||
BootloaderAPI_ReadLock_Trampoline:
|
||||
jmp BootloaderAPI_ReadLock
|
||||
BootloaderAPI_WriteLock_Trampoline:
|
||||
jmp BootloaderAPI_WriteLock
|
||||
BootloaderAPI_UNUSED1:
|
||||
ret
|
||||
BootloaderAPI_UNUSED2:
|
||||
ret
|
||||
BootloaderAPI_UNUSED3:
|
||||
ret
|
||||
BootloaderAPI_UNUSED4:
|
||||
ret
|
||||
BootloaderAPI_UNUSED5:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; API function jump table
|
||||
.section .apitable_jumptable, "ax"
|
||||
.global BootloaderAPI_JumpTable
|
||||
BootloaderAPI_JumpTable:
|
||||
|
||||
rjmp BootloaderAPI_ErasePage_Trampoline
|
||||
rjmp BootloaderAPI_WritePage_Trampoline
|
||||
rjmp BootloaderAPI_FillWord_Trampoline
|
||||
rjmp BootloaderAPI_ReadSignature_Trampoline
|
||||
rjmp BootloaderAPI_ReadFuse_Trampoline
|
||||
rjmp BootloaderAPI_ReadLock_Trampoline
|
||||
rjmp BootloaderAPI_WriteLock_Trampoline
|
||||
rjmp BootloaderAPI_UNUSED1 ; UNUSED ENTRY 1
|
||||
rjmp BootloaderAPI_UNUSED2 ; UNUSED ENTRY 2
|
||||
rjmp BootloaderAPI_UNUSED3 ; UNUSED ENTRY 3
|
||||
rjmp BootloaderAPI_UNUSED4 ; UNUSED ENTRY 4
|
||||
rjmp BootloaderAPI_UNUSED5 ; UNUSED ENTRY 5
|
||||
|
||||
|
||||
|
||||
; Bootloader table signatures and information
|
||||
.section .apitable_signatures, "ax"
|
||||
.global BootloaderAPI_Signatures
|
||||
BootloaderAPI_Signatures:
|
||||
|
||||
.long BOOT_START_ADDR ; Start address of the bootloader
|
||||
.word 0xDF30 ; Signature for the MS class bootloader, V1
|
||||
.word 0xDCFB ; Signature for a LUFA class bootloader
|
|
@ -0,0 +1,238 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the Mass Storage class bootloader. This file contains the complete bootloader logic.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_BOOTLOADER_MASSSTORAGE_C
|
||||
#include "BootloaderMassStorage.h"
|
||||
|
||||
/** LUFA Mass Storage Class driver interface configuration and state information. This structure is
|
||||
* passed to all Mass Storage Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_MS_Device_t Disk_MS_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = INTERFACE_ID_MassStorage,
|
||||
.DataINEndpoint =
|
||||
{
|
||||
.Address = MASS_STORAGE_IN_EPADDR,
|
||||
.Size = MASS_STORAGE_IO_EPSIZE,
|
||||
.Banks = 1,
|
||||
},
|
||||
.DataOUTEndpoint =
|
||||
{
|
||||
.Address = MASS_STORAGE_OUT_EPADDR,
|
||||
.Size = MASS_STORAGE_IO_EPSIZE,
|
||||
.Banks = 1,
|
||||
},
|
||||
.TotalLUNs = 1,
|
||||
},
|
||||
};
|
||||
|
||||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
|
||||
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application
|
||||
* started via a forced watchdog reset.
|
||||
*/
|
||||
bool RunBootloader = true;
|
||||
|
||||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader
|
||||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held
|
||||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value
|
||||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start.
|
||||
*/
|
||||
uint16_t MagicBootKey ATTR_NO_INIT;
|
||||
|
||||
/** Indicates if the bootloader is allowed to exit immediately if \ref RunBootloader is \c false. During shutdown all
|
||||
* pending commands must be processed before jumping to the user-application, thus this tracks the main program loop
|
||||
* iterations since a SCSI command from the host was received.
|
||||
*/
|
||||
static uint8_t TicksSinceLastCommand = 0;
|
||||
|
||||
|
||||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application
|
||||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid,
|
||||
* this will force the user application to start via a software jump.
|
||||
*/
|
||||
void Application_Jump_Check(void)
|
||||
{
|
||||
bool JumpToApplication = false;
|
||||
|
||||
#if (BOARD == BOARD_LEONARDO)
|
||||
/* Enable pull-up on the IO13 pin so we can use it to select the mode */
|
||||
PORTC |= (1 << 7);
|
||||
Delay_MS(10);
|
||||
|
||||
/* If IO13 is not jumpered to ground, start the user application instead */
|
||||
JumpToApplication |= ((PINC & (1 << 7)) != 0);
|
||||
|
||||
/* Disable pull-up after the check has completed */
|
||||
PORTC &= ~(1 << 7);
|
||||
#elif ((BOARD == BOARD_XPLAIN) || (BOARD == BOARD_XPLAIN_REV1))
|
||||
/* Disable JTAG debugging */
|
||||
JTAG_DISABLE();
|
||||
|
||||
/* Enable pull-up on the JTAG TCK pin so we can use it to select the mode */
|
||||
PORTF |= (1 << 4);
|
||||
Delay_MS(10);
|
||||
|
||||
/* If the TCK pin is not jumpered to ground, start the user application instead */
|
||||
JumpToApplication |= ((PINF & (1 << 4)) != 0);
|
||||
|
||||
/* Re-enable JTAG debugging */
|
||||
JTAG_ENABLE();
|
||||
#endif
|
||||
|
||||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
|
||||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
|
||||
{
|
||||
MagicBootKey = 0;
|
||||
JumpToApplication = true;
|
||||
}
|
||||
|
||||
if (JumpToApplication)
|
||||
{
|
||||
// cppcheck-suppress constStatement
|
||||
((void (*)(void))0x0000)();
|
||||
}
|
||||
}
|
||||
|
||||
/** Main program entry point. This routine configures the hardware required by the application, then
|
||||
* enters a loop to run the application tasks in sequence.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
GlobalInterruptEnable();
|
||||
|
||||
while (RunBootloader || TicksSinceLastCommand++ < 0xFF)
|
||||
{
|
||||
MS_Device_USBTask(&Disk_MS_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
|
||||
/* Disconnect from the host - USB interface will be reset later along with the AVR */
|
||||
USB_Detach();
|
||||
|
||||
/* Unlock the forced application start mode of the bootloader if it is restarted */
|
||||
MagicBootKey = MAGIC_BOOT_KEY;
|
||||
|
||||
/* Enable the watchdog and force a timeout to reset the AVR */
|
||||
wdt_enable(WDTO_250MS);
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
static void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Relocate the interrupt vector table to the bootloader section */
|
||||
MCUCR = (1 << IVCE);
|
||||
MCUCR = (1 << IVSEL);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
|
||||
/* Bootloader active LED toggle timer initialization */
|
||||
TIMSK1 = (1 << TOIE1);
|
||||
TCCR1B = ((1 << CS11) | (1 << CS10));
|
||||
}
|
||||
|
||||
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */
|
||||
ISR(TIMER1_OVF_vect, ISR_BLOCK)
|
||||
{
|
||||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
/* Indicate USB enumerating */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
|
||||
* the status LEDs and stops the Mass Storage management task.
|
||||
*/
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
/* Indicate USB not ready */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Configuration Changed event. */
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
bool ConfigSuccess = true;
|
||||
|
||||
/* Setup Mass Storage Data Endpoints */
|
||||
ConfigSuccess &= MS_Device_ConfigureEndpoints(&Disk_MS_Interface);
|
||||
|
||||
/* Indicate endpoint configuration success or failure */
|
||||
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the library USB Control Request reception event. */
|
||||
void EVENT_USB_Device_ControlRequest(void)
|
||||
{
|
||||
MS_Device_ProcessControlRequest(&Disk_MS_Interface);
|
||||
}
|
||||
|
||||
/** Mass Storage class driver callback function the reception of SCSI commands from the host, which must be processed.
|
||||
*
|
||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface configuration structure being referenced
|
||||
*/
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
bool CommandSuccess;
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
CommandSuccess = SCSI_DecodeSCSICommand(MSInterfaceInfo);
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
|
||||
/* Signal that a command was processed, must not exit bootloader yet */
|
||||
TicksSinceLastCommand = 0;
|
||||
|
||||
return CommandSuccess;
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderMassStorage.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_MASS_STORAGE_H_
|
||||
#define _BOOTLOADER_MASS_STORAGE_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
#include "Config/AppConfig.h"
|
||||
|
||||
#include "Lib/SCSI.h"
|
||||
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Platform/Platform.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__OPTIMIZE_SIZE__)
|
||||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
|
||||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/** Magic bootloader key to unlock forced application start mode. */
|
||||
#define MAGIC_BOOT_KEY 0xDC42
|
||||
|
||||
/* Global Variables: */
|
||||
extern bool RunBootloader;
|
||||
|
||||
/* Function Prototypes: */
|
||||
int main(void) AUX_BOOT_SECTION;
|
||||
|
||||
void Application_Jump_Check(void) ATTR_INIT_SECTION(3);
|
||||
|
||||
void EVENT_USB_Device_Connect(void) AUX_BOOT_SECTION;
|
||||
void EVENT_USB_Device_Disconnect(void) AUX_BOOT_SECTION;
|
||||
void EVENT_USB_Device_ConfigurationChanged(void) AUX_BOOT_SECTION;
|
||||
void EVENT_USB_Device_ControlRequest(void) AUX_BOOT_SECTION;
|
||||
|
||||
bool CALLBACK_MS_Device_SCSICommandReceived(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
|
||||
#if defined(INCLUDE_FROM_BOOTLOADER_MASSSTORAGE_C)
|
||||
static void SetupHardware(void) AUX_BOOT_SECTION;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Mass Storage Class USB AVR Bootloader
|
||||
*
|
||||
* \section Sec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* \li Series 7 USB AVRs (AT90USBxxx7)
|
||||
* \li Series 6 USB AVRs (AT90USBxxx6)
|
||||
* \li Series 4 USB AVRs (ATMEGAxxU4) - <i>See \ref SSec_Aux_Space</i>
|
||||
* \li ATMEGA32U2 - <i>See \ref SSec_Aux_Space</i>
|
||||
*
|
||||
* \section Sec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Mass Storage Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Bulk-Only Transport</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Mass Storage Standard \n
|
||||
* USB Bulk-Only Transport Standard \n
|
||||
* SCSI Primary Commands Specification \n
|
||||
* SCSI Block Commands Specification</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Supported USB Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section Sec_Description Project Description:
|
||||
*
|
||||
* This bootloader enumerates to the host as a Mass Storage device, capable of reading and writing a new binary
|
||||
* firmware image file, to load firmware onto the AVR.
|
||||
*
|
||||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit
|
||||
* into 6KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to
|
||||
* edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile.
|
||||
*
|
||||
* When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the
|
||||
* bootloader from the normal user application.
|
||||
*
|
||||
* \warning <b>THIS BOOTLOADER IS NOT SECURE.</b> Malicious entities can recover written data, even if the device
|
||||
* lockbits are set.
|
||||
*
|
||||
* \section Sec_Running Running the Bootloader
|
||||
*
|
||||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
|
||||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
|
||||
* fuse is cleared.
|
||||
*
|
||||
* For board specific exceptions to the above, see below.
|
||||
*
|
||||
* \subsection SSec_XPLAIN Atmel Xplain Board
|
||||
* Ground the USB AVR JTAG's \c TCK pin to ground when powering on the board to start the bootloader. This assumes the
|
||||
* \c HWBE fuse is cleared and the \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
|
||||
*
|
||||
* \subsection SSec_Leonardo Arduino Leonardo Board
|
||||
* Ground \c IO13 when powering the board to start the bootloader. This assumes the \c HWBE fuse is cleared and the
|
||||
* \c BOOTRST fuse is set as the HWBE pin is not user accessible on this board.
|
||||
*
|
||||
* \section Sec_Installation Driver Installation
|
||||
*
|
||||
* This bootloader uses the Mass Storage drivers inbuilt into all modern operating systems, thus no additional
|
||||
* drivers need to be supplied for correct operation.
|
||||
*
|
||||
* \section Sec_HostApp Host Controller Application
|
||||
*
|
||||
* This bootloader is compatible with all operating systems that support the FAT12 file system format. To reprogram the
|
||||
* device, overwrite a file stored on the virtual FAT filesystem with a new binary (BIN format) image. Remember to safely
|
||||
* remove your device from the host using the host OS's ejection APIs, to ensure all data is correctly flushed to the
|
||||
* bootloader's virtual filesystem and not cached in the OS's file system driver.
|
||||
*
|
||||
* The current device firmware can be read from the device by reading a file from the virtual FAT filesystem.
|
||||
*
|
||||
* \warning This bootloader is currently <b>incompatible with the Apple MacOS X OS Finder GUI</b>, due to the
|
||||
* large amount of meta files this OS attempts to write to the disk along with the new binaries. On
|
||||
* this platform, firmwares must be copied to the disk via the Terminal application only to prevent
|
||||
* firmware corruption.
|
||||
*
|
||||
* \section Sec_API User Application API
|
||||
*
|
||||
* Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader,
|
||||
* allowing the user application to call into the bootloader at runtime to read and write FLASH data.
|
||||
*
|
||||
* By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the
|
||||
* following layout:
|
||||
*
|
||||
* \code
|
||||
* #define BOOTLOADER_API_TABLE_SIZE 32
|
||||
* #define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE)
|
||||
* #define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2)
|
||||
*
|
||||
* void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0);
|
||||
* void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1);
|
||||
* void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2);
|
||||
* uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3);
|
||||
* uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4);
|
||||
* uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5);
|
||||
* void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6);
|
||||
*
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2))
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB
|
||||
*
|
||||
* #define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4))
|
||||
* #define BOOTLOADER_MASS_STORAGE_SIGNATURE 0xDF30
|
||||
*
|
||||
* #define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8))
|
||||
* #define BOOTLOADER_ADDRESS_LENGTH 4
|
||||
* \endcode
|
||||
*
|
||||
* From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address
|
||||
* \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader
|
||||
* can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them
|
||||
* to the value \c BOOTLOADER_MASS_STORAGE_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes
|
||||
* of FLASH memory starting from address \c BOOTLOADER_ADDRESS_START.
|
||||
*
|
||||
* \subsection SSec_Aux_Space Auxiliary Bootloader Section
|
||||
* To make the bootloader function on smaller devices (those with a physical bootloader section of smaller than 6KB) a second
|
||||
* section of memory (called the <i>Auxiliary Bootloader Section</i>) is added before the start of the real bootloader section,
|
||||
* and is filled with a portion of the bootloader code. This allows smaller devices to run the bootloader, at the cost of an
|
||||
* additional portion of the device's FLASH (the bootloader section size in KB subtracted from the 6KB total size). A small
|
||||
* trampoline is inserted at the start of the auxiliary section so that the bootloader will run normally in the case of a blank
|
||||
* application section.
|
||||
*
|
||||
* On devices supporting a 8KB bootloader section size, the AUX section is not created in the final binary.
|
||||
*
|
||||
* \subsection SSec_API_MemLayout Device Memory Map
|
||||
* The following illustration indicates the final memory map of the device when loaded with the bootloader.
|
||||
*
|
||||
* \verbatim
|
||||
* +----------------------------+ 0x0000
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | User Application |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE
|
||||
* | Booloader Start Trampoline |
|
||||
* | (Not User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE - BOOT_AUX_SECTION_SIZE + 4
|
||||
* | |
|
||||
* | Auxiliary Bootloader |
|
||||
* | Space for Smaller Devices |
|
||||
* | (Not User App. Accessible) |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE
|
||||
* | |
|
||||
* | Bootloader Application |
|
||||
* | (Not User App. Accessible) |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - 96
|
||||
* | API Table Trampolines |
|
||||
* | (Not User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 32
|
||||
* | Bootloader API Table |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 8
|
||||
* | Bootloader ID Constants |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND
|
||||
* \endverbatim
|
||||
*
|
||||
* \section Sec_KnownIssues Known Issues:
|
||||
*
|
||||
* \par In some cases, the application is not fully loaded into the device.
|
||||
* Write-caching on some operating systems may interfere with the normal
|
||||
* operation of the bootloader. Write caching should be disabled when using the
|
||||
* Mass Storage bootloader, or the file system synced via an appropriate command
|
||||
* (such as the OS's normal disk ejection command) before disconnecting the device.
|
||||
*
|
||||
* \par After loading an application, it is not run automatically on startup.
|
||||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader
|
||||
* to run automatically when the device is reset. In most cases, the BOOTRST
|
||||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader
|
||||
* when needed.
|
||||
*
|
||||
* \section Sec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th><b>Define Name:</b></th>
|
||||
* <th><b>Location:</b></th>
|
||||
* <th><b>Description:</b></th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>NO_APP_START_ON_EJECT</td>
|
||||
* <td>AppConfig.h</td>
|
||||
* <td>Define to disable automatic start of the loaded application when the virtual
|
||||
* Mass Storage disk is ejected on the host.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief Application Configuration Header File
|
||||
*
|
||||
* This is a header file which is be used to configure LUFA's
|
||||
* compile time options, as an alternative to the compile time
|
||||
* constants supplied through a makefile.
|
||||
*
|
||||
* For information on what each token does, refer to the
|
||||
* \ref Sec_Options section of the application documentation.
|
||||
*/
|
||||
|
||||
#ifndef _APP_CONFIG_H_
|
||||
#define _APP_CONFIG_H_
|
||||
|
||||
// #define NO_APP_START_ON_EJECT
|
||||
|
||||
#endif
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Library Configuration Header File
|
||||
*
|
||||
* This header file is used to configure LUFA's compile time options,
|
||||
* as an alternative to the compile time constants supplied through
|
||||
* a makefile.
|
||||
*
|
||||
* For information on what each token does, refer to the LUFA
|
||||
* manual section "Summary of Compile Tokens".
|
||||
*/
|
||||
|
||||
#ifndef _LUFA_CONFIG_H_
|
||||
#define _LUFA_CONFIG_H_
|
||||
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
/* Non-USB Related Configuration Tokens: */
|
||||
// #define DISABLE_TERMINAL_CODES
|
||||
|
||||
/* USB Class Driver Related Tokens: */
|
||||
// #define HID_HOST_BOOT_PROTOCOL_ONLY
|
||||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_MAX_COLLECTIONS {Insert Value Here}
|
||||
// #define HID_MAX_REPORTITEMS {Insert Value Here}
|
||||
// #define HID_MAX_REPORT_IDS {Insert Value Here}
|
||||
// #define NO_CLASS_DRIVER_AUTOFLUSH
|
||||
|
||||
/* General USB Driver Related Tokens: */
|
||||
#define ORDERED_EP_CONFIG
|
||||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
|
||||
#define USB_DEVICE_ONLY
|
||||
// #define USB_HOST_ONLY
|
||||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
|
||||
// #define NO_LIMITED_CONTROLLER_CONNECT
|
||||
#define NO_SOF_EVENTS
|
||||
|
||||
/* USB Device Mode Driver Related Tokens: */
|
||||
#define USE_RAM_DESCRIPTORS
|
||||
// #define USE_FLASH_DESCRIPTORS
|
||||
// #define USE_EEPROM_DESCRIPTORS
|
||||
#define NO_INTERNAL_SERIAL
|
||||
#define FIXED_CONTROL_ENDPOINT_SIZE 8
|
||||
#define DEVICE_STATE_AS_GPIOR 0
|
||||
#define FIXED_NUM_CONFIGURATIONS 1
|
||||
// #define CONTROL_ONLY_DEVICE
|
||||
#define INTERRUPT_CONTROL_ENDPOINT
|
||||
#define NO_DEVICE_REMOTE_WAKEUP
|
||||
#define NO_DEVICE_SELF_POWER
|
||||
|
||||
/* USB Host Mode Driver Related Tokens: */
|
||||
// #define HOST_STATE_AS_GPIOR {Insert Value Here}
|
||||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
|
||||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
|
||||
// #define NO_AUTO_VBUS_MANAGEMENT
|
||||
// #define INVERTED_VBUS_ENABLE_LINE
|
||||
|
||||
#else
|
||||
|
||||
#error Unsupported architecture for this LUFA configuration file.
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
|
||||
* computer-readable structures which the host requests upon device enumeration, to determine
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
|
||||
* device characteristics, including the supported USB version, control endpoint size and the
|
||||
* number of device configurations. The descriptor is read out by the USB host when the enumeration
|
||||
* process begins.
|
||||
*/
|
||||
const USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(1,1,0),
|
||||
.Class = USB_CSCP_NoDeviceClass,
|
||||
.SubClass = USB_CSCP_NoDeviceSubclass,
|
||||
.Protocol = USB_CSCP_NoDeviceProtocol,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x2045,
|
||||
.ReleaseNumber = VERSION_BCD(0,0,1),
|
||||
|
||||
.ManufacturerStrIndex = NO_DESCRIPTOR,
|
||||
.ProductStrIndex = NO_DESCRIPTOR,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
|
||||
* of the device in one of its supported configurations, including information about any device interfaces
|
||||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
|
||||
* a configuration so that the host may correctly communicate with the USB device.
|
||||
*/
|
||||
const USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.MS_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = INTERFACE_ID_MassStorage,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = MS_CSCP_MassStorageClass,
|
||||
.SubClass = MS_CSCP_SCSITransparentSubclass,
|
||||
.Protocol = MS_CSCP_BulkOnlyTransportProtocol,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.MS_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = MASS_STORAGE_IN_EPADDR,
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x05
|
||||
},
|
||||
|
||||
.MS_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = MASS_STORAGE_OUT_EPADDR,
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = MASS_STORAGE_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x05
|
||||
}
|
||||
};
|
||||
|
||||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
|
||||
* documentation) by the application code so that the address and size of a requested descriptor can be given
|
||||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
{
|
||||
const uint8_t DescriptorType = (wValue >> 8);
|
||||
|
||||
const void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
/* If/Else If chain compiles slightly smaller than a switch case */
|
||||
if (DescriptorType == DTYPE_Device)
|
||||
{
|
||||
Address = &DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
}
|
||||
else if (DescriptorType == DTYPE_Configuration)
|
||||
{
|
||||
Address = &ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include "BootloaderAPI.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint address of the Mass Storage device-to-host data IN endpoint. */
|
||||
#define MASS_STORAGE_IN_EPADDR (ENDPOINT_DIR_IN | 3)
|
||||
|
||||
/** Endpoint address of the Mass Storage host-to-device data OUT endpoint. */
|
||||
#define MASS_STORAGE_OUT_EPADDR (ENDPOINT_DIR_OUT | 4)
|
||||
|
||||
/** Size in bytes of the Mass Storage data endpoints. */
|
||||
#define MASS_STORAGE_IO_EPSIZE 64
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for the device configuration descriptor structure. This must be defined in the
|
||||
* application code, as the configuration descriptor contains several sub-descriptors which
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
|
||||
// Mass Storage Interface
|
||||
USB_Descriptor_Interface_t MS_Interface;
|
||||
USB_Descriptor_Endpoint_t MS_DataInEndpoint;
|
||||
USB_Descriptor_Endpoint_t MS_DataOutEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
|
||||
/** Enum for the device interface descriptor IDs within the device. Each interface descriptor
|
||||
* should have a unique ID index associated with it, which can be used to refer to the
|
||||
* interface from other descriptors.
|
||||
*/
|
||||
enum InterfaceDescriptors_t
|
||||
{
|
||||
INTERFACE_ID_MassStorage = 0, /**< Mass storage interface descriptor ID */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3) AUX_BOOT_SECTION;
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* SCSI command processing routines, for SCSI commands issued by the host. Mass Storage
|
||||
* devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information,
|
||||
* which wrap around standard SCSI device commands for controlling the actual storage medium.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_SCSI_C
|
||||
#include "SCSI.h"
|
||||
|
||||
/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's
|
||||
* features and capabilities.
|
||||
*/
|
||||
static const SCSI_Inquiry_Response_t InquiryData =
|
||||
{
|
||||
.DeviceType = DEVICE_TYPE_BLOCK,
|
||||
.PeripheralQualifier = 0,
|
||||
|
||||
.Removable = true,
|
||||
|
||||
.Version = 0,
|
||||
|
||||
.ResponseDataFormat = 2,
|
||||
.NormACA = false,
|
||||
.TrmTsk = false,
|
||||
.AERC = false,
|
||||
|
||||
.AdditionalLength = 0x1F,
|
||||
|
||||
.SoftReset = false,
|
||||
.CmdQue = false,
|
||||
.Linked = false,
|
||||
.Sync = false,
|
||||
.WideBus16Bit = false,
|
||||
.WideBus32Bit = false,
|
||||
.RelAddr = false,
|
||||
|
||||
.VendorID = "LUFA",
|
||||
.ProductID = "Bootloader",
|
||||
.RevisionID = {'0','.','0','0'},
|
||||
};
|
||||
|
||||
/** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE
|
||||
* command is issued. This gives information on exactly why the last command failed to complete.
|
||||
*/
|
||||
static SCSI_Request_Sense_Response_t SenseData =
|
||||
{
|
||||
.ResponseCode = 0x70,
|
||||
.AdditionalLength = 0x0A,
|
||||
};
|
||||
|
||||
|
||||
/** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches
|
||||
* to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns
|
||||
* a command failure due to a ILLEGAL REQUEST.
|
||||
*
|
||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
||||
*
|
||||
* \return Boolean \c true if the command completed successfully, \c false otherwise
|
||||
*/
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
bool CommandSuccess = false;
|
||||
|
||||
/* Run the appropriate SCSI command hander function based on the passed command */
|
||||
switch (MSInterfaceInfo->State.CommandBlock.SCSICommandData[0])
|
||||
{
|
||||
case SCSI_CMD_INQUIRY:
|
||||
CommandSuccess = SCSI_Command_Inquiry(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_REQUEST_SENSE:
|
||||
CommandSuccess = SCSI_Command_Request_Sense(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_READ_CAPACITY_10:
|
||||
CommandSuccess = SCSI_Command_Read_Capacity_10(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_WRITE_10:
|
||||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_WRITE);
|
||||
break;
|
||||
case SCSI_CMD_READ_10:
|
||||
CommandSuccess = SCSI_Command_ReadWrite_10(MSInterfaceInfo, DATA_READ);
|
||||
break;
|
||||
case SCSI_CMD_MODE_SENSE_6:
|
||||
CommandSuccess = SCSI_Command_ModeSense_6(MSInterfaceInfo);
|
||||
break;
|
||||
case SCSI_CMD_START_STOP_UNIT:
|
||||
#if !defined(NO_APP_START_ON_EJECT)
|
||||
/* If the user ejected the volume, signal bootloader exit at next opportunity. */
|
||||
RunBootloader = ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[4] & 0x03) != 0x02);
|
||||
#endif
|
||||
case SCSI_CMD_SEND_DIAGNOSTIC:
|
||||
case SCSI_CMD_TEST_UNIT_READY:
|
||||
case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:
|
||||
case SCSI_CMD_VERIFY_10:
|
||||
/* These commands should just succeed, no handling required */
|
||||
CommandSuccess = true;
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength = 0;
|
||||
break;
|
||||
default:
|
||||
/* Update the SENSE key to reflect the invalid command */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_COMMAND,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if command was successfully processed */
|
||||
if (CommandSuccess)
|
||||
{
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,
|
||||
SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features
|
||||
* and capabilities to the host.
|
||||
*
|
||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
||||
*
|
||||
* \return Boolean \c true if the command completed successfully, \c false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
uint16_t AllocationLength = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[3]);
|
||||
uint16_t BytesTransferred = MIN(AllocationLength, sizeof(InquiryData));
|
||||
|
||||
/* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */
|
||||
if ((MSInterfaceInfo->State.CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||
|
||||
MSInterfaceInfo->State.CommandBlock.SCSICommandData[2])
|
||||
{
|
||||
/* Optional but unsupported bits set - update the SENSE key and fail the request */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_INVALID_FIELD_IN_CDB,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, NULL);
|
||||
|
||||
/* Pad out remaining bytes with 0x00 */
|
||||
Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL);
|
||||
|
||||
/* Finalize the stream transfer to send the last packet */
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command,
|
||||
* including the error code and additional error information so that the host can determine why a command failed to complete.
|
||||
*
|
||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
||||
*
|
||||
* \return Boolean \c true if the command completed successfully, \c false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
uint8_t AllocationLength = MSInterfaceInfo->State.CommandBlock.SCSICommandData[4];
|
||||
uint8_t BytesTransferred = MIN(AllocationLength, sizeof(SenseData));
|
||||
|
||||
Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, NULL);
|
||||
Endpoint_Null_Stream((AllocationLength - BytesTransferred), NULL);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= BytesTransferred;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity
|
||||
* on the selected Logical Unit (drive), as a number of OS-sized blocks.
|
||||
*
|
||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
||||
*
|
||||
* \return Boolean \c true if the command completed successfully, \c false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
Endpoint_Write_32_BE(LUN_MEDIA_BLOCKS - 1);
|
||||
Endpoint_Write_32_BE(SECTOR_SIZE_BYTES);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Succeed the command and update the bytes transferred counter */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 8;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address
|
||||
* and total number of blocks to process, then calls the appropriate low-level Dataflash routine to handle the actual
|
||||
* reading and writing of the data.
|
||||
*
|
||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
||||
* \param[in] IsDataRead Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE)
|
||||
*
|
||||
* \return Boolean \c true if the command completed successfully, \c false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
||||
const bool IsDataRead)
|
||||
{
|
||||
uint16_t BlockAddress;
|
||||
uint16_t TotalBlocks;
|
||||
|
||||
/* Load in the 32-bit block address (SCSI uses big-endian, so have to reverse the byte order) */
|
||||
BlockAddress = SwapEndian_32(*(uint32_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[2]);
|
||||
|
||||
/* Load in the 16-bit total blocks (SCSI uses big-endian, so have to reverse the byte order) */
|
||||
TotalBlocks = SwapEndian_16(*(uint16_t*)&MSInterfaceInfo->State.CommandBlock.SCSICommandData[7]);
|
||||
|
||||
/* Check if the block address is outside the maximum allowable value for the LUN */
|
||||
if (BlockAddress >= LUN_MEDIA_BLOCKS)
|
||||
{
|
||||
/* Block address is invalid, update SENSE key and return command fail */
|
||||
SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,
|
||||
SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,
|
||||
SCSI_ASENSEQ_NO_QUALIFIER);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */
|
||||
for (uint16_t i = 0; i < TotalBlocks; i++)
|
||||
{
|
||||
if (IsDataRead == DATA_READ)
|
||||
VirtualFAT_ReadBlock(BlockAddress + i);
|
||||
else
|
||||
VirtualFAT_WriteBlock(BlockAddress + i);
|
||||
}
|
||||
|
||||
/* Update the bytes transferred counter and succeed the command */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * SECTOR_SIZE_BYTES);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Command processing for an issued SCSI MODE SENSE (6) command. This command returns various informational pages about
|
||||
* the SCSI device, as well as the device's Write Protect status.
|
||||
*
|
||||
* \param[in] MSInterfaceInfo Pointer to the Mass Storage class interface structure that the command is associated with
|
||||
*
|
||||
* \return Boolean \c true if the command completed successfully, \c false otherwise.
|
||||
*/
|
||||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo)
|
||||
{
|
||||
/* Send an empty header response indicating Write Protect flag is off */
|
||||
Endpoint_Write_32_LE(0);
|
||||
Endpoint_ClearIN();
|
||||
|
||||
/* Update the bytes transferred counter and succeed the command */
|
||||
MSInterfaceInfo->State.CommandBlock.DataTransferLength -= 4;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for SCSI.c.
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_H_
|
||||
#define _SCSI_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include "../BootloaderMassStorage.h"
|
||||
#include "../Descriptors.h"
|
||||
#include "VirtualFAT.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This
|
||||
* is for convenience, as it allows for all three sense values (returned upon request to the host to give information about
|
||||
* the last command failure) in a quick and easy manner.
|
||||
*
|
||||
* \param[in] Key New SCSI sense key to set the sense code to
|
||||
* \param[in] Acode New SCSI additional sense key to set the additional sense code to
|
||||
* \param[in] Aqual New SCSI additional sense key qualifier to set the additional sense qualifier code to
|
||||
*/
|
||||
#define SCSI_SET_SENSE(Key, Acode, Aqual) do { SenseData.SenseKey = (Key); \
|
||||
SenseData.AdditionalSenseCode = (Acode); \
|
||||
SenseData.AdditionalSenseQualifier = (Aqual); } while (0)
|
||||
|
||||
/** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */
|
||||
#define DATA_READ true
|
||||
|
||||
/** Macro for the \ref SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */
|
||||
#define DATA_WRITE false
|
||||
|
||||
/** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */
|
||||
#define DEVICE_TYPE_BLOCK 0x00
|
||||
|
||||
/* Function Prototypes: */
|
||||
bool SCSI_DecodeSCSICommand(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
|
||||
#if defined(INCLUDE_FROM_SCSI_C)
|
||||
static bool SCSI_Command_Inquiry(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_Request_Sense(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_Read_Capacity_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_ReadWrite_10(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo,
|
||||
const bool IsDataRead) AUX_BOOT_SECTION;
|
||||
static bool SCSI_Command_ModeSense_6(USB_ClassInfo_MS_Device_t* const MSInterfaceInfo) AUX_BOOT_SECTION;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,482 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Virtualized FAT12 filesystem implementation, to perform self-programming
|
||||
* in response to read and write requests to the virtual filesystem by the
|
||||
* host PC.
|
||||
*/
|
||||
|
||||
#define INCLUDE_FROM_VIRTUAL_FAT_C
|
||||
#include "VirtualFAT.h"
|
||||
|
||||
/** FAT filesystem boot sector block, must be the first sector on the physical
|
||||
* disk so that the host can identify the presence of a FAT filesystem. This
|
||||
* block is truncated; normally a large bootstrap section is located near the
|
||||
* end of the block for booting purposes however as this is not meant to be a
|
||||
* bootable disk it is omitted for space reasons.
|
||||
*
|
||||
* \note When returning the boot block to the host, the magic signature 0xAA55
|
||||
* must be added to the very end of the block to identify it as a boot
|
||||
* block.
|
||||
*/
|
||||
static const FATBootBlock_t BootBlock =
|
||||
{
|
||||
.Bootstrap = {0xEB, 0x3C, 0x90},
|
||||
.Description = "mkdosfs",
|
||||
.SectorSize = SECTOR_SIZE_BYTES,
|
||||
.SectorsPerCluster = SECTOR_PER_CLUSTER,
|
||||
.ReservedSectors = 1,
|
||||
.FATCopies = 2,
|
||||
.RootDirectoryEntries = (SECTOR_SIZE_BYTES / sizeof(FATDirectoryEntry_t)),
|
||||
.TotalSectors16 = LUN_MEDIA_BLOCKS,
|
||||
.MediaDescriptor = 0xF8,
|
||||
.SectorsPerFAT = 1,
|
||||
.SectorsPerTrack = (LUN_MEDIA_BLOCKS % 64),
|
||||
.Heads = (LUN_MEDIA_BLOCKS / 64),
|
||||
.HiddenSectors = 0,
|
||||
.TotalSectors32 = 0,
|
||||
.PhysicalDriveNum = 0,
|
||||
.ExtendedBootRecordSig = 0x29,
|
||||
.VolumeSerialNumber = 0x12345678,
|
||||
.VolumeLabel = "LUFA BOOT ",
|
||||
.FilesystemIdentifier = "FAT12 ",
|
||||
};
|
||||
|
||||
/** FAT 8.3 style directory entry, for the virtual FLASH contents file. */
|
||||
static FATDirectoryEntry_t FirmwareFileEntries[] =
|
||||
{
|
||||
/* Root volume label entry; disk label is contained in the Filename and
|
||||
* Extension fields (concatenated) with a special attribute flag - other
|
||||
* fields are ignored. Should be the same as the label in the boot block.
|
||||
*/
|
||||
[DISK_FILE_ENTRY_VolumeID] =
|
||||
{
|
||||
.MSDOS_Directory =
|
||||
{
|
||||
.Name = "LUFA BOOT ",
|
||||
.Attributes = FAT_FLAG_VOLUME_NAME,
|
||||
.Reserved = {0},
|
||||
.CreationTime = 0,
|
||||
.CreationDate = 0,
|
||||
.StartingCluster = 0,
|
||||
.Reserved2 = 0,
|
||||
}
|
||||
},
|
||||
|
||||
/* VFAT Long File Name entry for the virtual firmware file; required to
|
||||
* prevent corruption from systems that are unable to detect the device
|
||||
* as being a legacy MSDOS style FAT12 volume. */
|
||||
[DISK_FILE_ENTRY_FLASH_LFN] =
|
||||
{
|
||||
.VFAT_LongFileName =
|
||||
{
|
||||
.Ordinal = 1 | FAT_ORDINAL_LAST_ENTRY,
|
||||
.Attribute = FAT_FLAG_LONG_FILE_NAME,
|
||||
.Reserved1 = 0,
|
||||
.Reserved2 = 0,
|
||||
|
||||
.Checksum = FAT_CHECKSUM('F','L','A','S','H',' ',' ',' ','B','I','N'),
|
||||
|
||||
.Unicode1 = 'F',
|
||||
.Unicode2 = 'L',
|
||||
.Unicode3 = 'A',
|
||||
.Unicode4 = 'S',
|
||||
.Unicode5 = 'H',
|
||||
.Unicode6 = '.',
|
||||
.Unicode7 = 'B',
|
||||
.Unicode8 = 'I',
|
||||
.Unicode9 = 'N',
|
||||
.Unicode10 = 0,
|
||||
.Unicode11 = 0,
|
||||
.Unicode12 = 0,
|
||||
.Unicode13 = 0,
|
||||
}
|
||||
},
|
||||
|
||||
/* MSDOS file entry for the virtual Firmware image. */
|
||||
[DISK_FILE_ENTRY_FLASH_MSDOS] =
|
||||
{
|
||||
.MSDOS_File =
|
||||
{
|
||||
.Filename = "FLASH ",
|
||||
.Extension = "BIN",
|
||||
.Attributes = 0,
|
||||
.Reserved = {0},
|
||||
.CreationTime = FAT_TIME(1, 1, 0),
|
||||
.CreationDate = FAT_DATE(14, 2, 1989),
|
||||
.StartingCluster = 2,
|
||||
.FileSizeBytes = FLASH_FILE_SIZE_BYTES,
|
||||
}
|
||||
},
|
||||
|
||||
[DISK_FILE_ENTRY_EEPROM_LFN] =
|
||||
{
|
||||
.VFAT_LongFileName =
|
||||
{
|
||||
.Ordinal = 1 | FAT_ORDINAL_LAST_ENTRY,
|
||||
.Attribute = FAT_FLAG_LONG_FILE_NAME,
|
||||
.Reserved1 = 0,
|
||||
.Reserved2 = 0,
|
||||
|
||||
.Checksum = FAT_CHECKSUM('E','E','P','R','O','M',' ',' ','B','I','N'),
|
||||
|
||||
.Unicode1 = 'E',
|
||||
.Unicode2 = 'E',
|
||||
.Unicode3 = 'P',
|
||||
.Unicode4 = 'R',
|
||||
.Unicode5 = 'O',
|
||||
.Unicode6 = 'M',
|
||||
.Unicode7 = '.',
|
||||
.Unicode8 = 'B',
|
||||
.Unicode9 = 'I',
|
||||
.Unicode10 = 'N',
|
||||
.Unicode11 = 0,
|
||||
.Unicode12 = 0,
|
||||
.Unicode13 = 0,
|
||||
}
|
||||
},
|
||||
|
||||
[DISK_FILE_ENTRY_EEPROM_MSDOS] =
|
||||
{
|
||||
.MSDOS_File =
|
||||
{
|
||||
.Filename = "EEPROM ",
|
||||
.Extension = "BIN",
|
||||
.Attributes = 0,
|
||||
.Reserved = {0},
|
||||
.CreationTime = FAT_TIME(1, 1, 0),
|
||||
.CreationDate = FAT_DATE(14, 2, 1989),
|
||||
.StartingCluster = 2 + FILE_CLUSTERS(FLASH_FILE_SIZE_BYTES),
|
||||
.FileSizeBytes = EEPROM_FILE_SIZE_BYTES,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
/** Starting cluster of the virtual FLASH.BIN file on disk, tracked so that the
|
||||
* offset from the start of the data sector can be determined. On Windows
|
||||
* systems files are usually replaced using the original file's disk clusters,
|
||||
* while Linux appears to overwrite with an offset which must be compensated for.
|
||||
*/
|
||||
static const uint16_t* FLASHFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_FLASH_MSDOS].MSDOS_File.StartingCluster;
|
||||
|
||||
/** Starting cluster of the virtual EEPROM.BIN file on disk, tracked so that the
|
||||
* offset from the start of the data sector can be determined. On Windows
|
||||
* systems files are usually replaced using the original file's disk clusters,
|
||||
* while Linux appears to overwrite with an offset which must be compensated for.
|
||||
*/
|
||||
static const uint16_t* EEPROMFileStartCluster = &FirmwareFileEntries[DISK_FILE_ENTRY_EEPROM_MSDOS].MSDOS_File.StartingCluster;
|
||||
|
||||
/** Reads a byte of EEPROM out from the EEPROM memory space.
|
||||
*
|
||||
* \note This function is required as the avr-libc EEPROM functions do not cope
|
||||
* with linker relaxations, and a jump longer than 4K of FLASH on the
|
||||
* larger USB AVRs will break the linker. This function is marked as
|
||||
* never inlinable and placed into the normal text segment so that the
|
||||
* call to the EEPROM function will be short even if the AUX boot section
|
||||
* is used.
|
||||
*
|
||||
* \param[in] Address Address of the EEPROM location to read from
|
||||
*
|
||||
* \return Read byte of EEPROM data.
|
||||
*/
|
||||
static uint8_t ReadEEPROMByte(const uint8_t* const Address)
|
||||
{
|
||||
return eeprom_read_byte(Address);
|
||||
}
|
||||
|
||||
/** Writes a byte of EEPROM out to the EEPROM memory space.
|
||||
*
|
||||
* \note This function is required as the avr-libc EEPROM functions do not cope
|
||||
* with linker relaxations, and a jump longer than 4K of FLASH on the
|
||||
* larger USB AVRs will break the linker. This function is marked as
|
||||
* never inlinable and placed into the normal text segment so that the
|
||||
* call to the EEPROM function will be short even if the AUX boot section
|
||||
* is used.
|
||||
*
|
||||
* \param[in] Address Address of the EEPROM location to write to
|
||||
* \param[in] Data New data to write to the EEPROM location
|
||||
*/
|
||||
static void WriteEEPROMByte(uint8_t* const Address,
|
||||
const uint8_t Data)
|
||||
{
|
||||
eeprom_update_byte(Address, Data);
|
||||
}
|
||||
|
||||
/** Updates a FAT12 cluster entry in the FAT file table with the specified next
|
||||
* chain index. If the cluster is the last in the file chain, the magic value
|
||||
* \c 0xFFF should be used.
|
||||
*
|
||||
* \note FAT data cluster indexes are offset by 2, so that cluster 2 is the
|
||||
* first file data cluster on the disk. See the FAT specification.
|
||||
*
|
||||
* \param[out] FATTable Pointer to the FAT12 allocation table
|
||||
* \param[in] Index Index of the cluster entry to update
|
||||
* \param[in] ChainEntry Next cluster index in the file chain
|
||||
*/
|
||||
static void UpdateFAT12ClusterEntry(uint8_t* const FATTable,
|
||||
const uint16_t Index,
|
||||
const uint16_t ChainEntry)
|
||||
{
|
||||
/* Calculate the starting offset of the cluster entry in the FAT12 table */
|
||||
uint8_t FATOffset = (Index + (Index >> 1));
|
||||
bool UpperNibble = ((Index & 1) != 0);
|
||||
|
||||
/* Check if the start of the entry is at an upper nibble of the byte, fill
|
||||
* out FAT12 entry as required */
|
||||
if (UpperNibble)
|
||||
{
|
||||
FATTable[FATOffset] = (FATTable[FATOffset] & 0x0F) | ((ChainEntry & 0x0F) << 4);
|
||||
FATTable[FATOffset + 1] = (ChainEntry >> 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
FATTable[FATOffset] = ChainEntry;
|
||||
FATTable[FATOffset + 1] = (FATTable[FATOffset] & 0xF0) | (ChainEntry >> 8);
|
||||
}
|
||||
}
|
||||
|
||||
/** Updates a FAT12 cluster chain in the FAT file table with a linear chain of
|
||||
* the specified length.
|
||||
*
|
||||
* \note FAT data cluster indexes are offset by 2, so that cluster 2 is the
|
||||
* first file data cluster on the disk. See the FAT specification.
|
||||
*
|
||||
* \param[out] FATTable Pointer to the FAT12 allocation table
|
||||
* \param[in] Index Index of the start of the cluster chain to update
|
||||
* \param[in] ChainLength Length of the chain to write, in clusters
|
||||
*/
|
||||
static void UpdateFAT12ClusterChain(uint8_t* const FATTable,
|
||||
const uint16_t Index,
|
||||
const uint8_t ChainLength)
|
||||
{
|
||||
for (uint8_t i = 0; i < ChainLength; i++)
|
||||
{
|
||||
uint16_t CurrentCluster = Index + i;
|
||||
uint16_t NextCluster = CurrentCluster + 1;
|
||||
|
||||
/* Mark last cluster as end of file */
|
||||
if (i == (ChainLength - 1))
|
||||
NextCluster = 0xFFF;
|
||||
|
||||
UpdateFAT12ClusterEntry(FATTable, CurrentCluster, NextCluster);
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads or writes a block of data from/to the physical device FLASH using a
|
||||
* block buffer stored in RAM, if the requested block is within the virtual
|
||||
* firmware file's sector ranges in the emulated FAT file system.
|
||||
*
|
||||
* \param[in] BlockNumber Physical disk block to read from/write to
|
||||
* \param[in,out] BlockBuffer Pointer to the start of the block buffer in RAM
|
||||
* \param[in] Read If \c true, the requested block is read, if
|
||||
* \c false, the requested block is written
|
||||
*/
|
||||
static void ReadWriteFLASHFileBlock(const uint16_t BlockNumber,
|
||||
uint8_t* BlockBuffer,
|
||||
const bool Read)
|
||||
{
|
||||
uint16_t FileStartBlock = DISK_BLOCK_DataStartBlock + (*FLASHFileStartCluster - 2) * SECTOR_PER_CLUSTER;
|
||||
uint16_t FileEndBlock = FileStartBlock + (FILE_SECTORS(FLASH_FILE_SIZE_BYTES) - 1);
|
||||
|
||||
/* Range check the write request - abort if requested block is not within the
|
||||
* virtual firmware file sector range */
|
||||
if (!((BlockNumber >= FileStartBlock) && (BlockNumber <= FileEndBlock)))
|
||||
return;
|
||||
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
uint32_t FlashAddress = (uint32_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES;
|
||||
#else
|
||||
uint16_t FlashAddress = (uint16_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES;
|
||||
#endif
|
||||
|
||||
if (Read)
|
||||
{
|
||||
/* Read out the mapped block of data from the device's FLASH */
|
||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
||||
{
|
||||
#if (FLASHEND > 0xFFFF)
|
||||
BlockBuffer[i] = pgm_read_byte_far(FlashAddress++);
|
||||
#else
|
||||
BlockBuffer[i] = pgm_read_byte(FlashAddress++);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write out the mapped block of data to the device's FLASH */
|
||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i += 2)
|
||||
{
|
||||
if ((FlashAddress % SPM_PAGESIZE) == 0)
|
||||
{
|
||||
/* Erase the given FLASH page, ready to be programmed */
|
||||
BootloaderAPI_ErasePage(FlashAddress);
|
||||
}
|
||||
|
||||
/* Write the next data word to the FLASH page */
|
||||
BootloaderAPI_FillWord(FlashAddress, (BlockBuffer[i + 1] << 8) | BlockBuffer[i]);
|
||||
FlashAddress += 2;
|
||||
|
||||
if ((FlashAddress % SPM_PAGESIZE) == 0)
|
||||
{
|
||||
/* Write the filled FLASH page to memory */
|
||||
BootloaderAPI_WritePage(FlashAddress - SPM_PAGESIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads or writes a block of data from/to the physical device EEPROM using a
|
||||
* block buffer stored in RAM, if the requested block is within the virtual
|
||||
* firmware file's sector ranges in the emulated FAT file system.
|
||||
*
|
||||
* \param[in] BlockNumber Physical disk block to read from/write to
|
||||
* \param[in,out] BlockBuffer Pointer to the start of the block buffer in RAM
|
||||
* \param[in] Read If \c true, the requested block is read, if
|
||||
* \c false, the requested block is written
|
||||
*/
|
||||
static void ReadWriteEEPROMFileBlock(const uint16_t BlockNumber,
|
||||
uint8_t* BlockBuffer,
|
||||
const bool Read)
|
||||
{
|
||||
uint16_t FileStartBlock = DISK_BLOCK_DataStartBlock + (*EEPROMFileStartCluster - 2) * SECTOR_PER_CLUSTER;
|
||||
uint16_t FileEndBlock = FileStartBlock + (FILE_SECTORS(EEPROM_FILE_SIZE_BYTES) - 1);
|
||||
|
||||
/* Range check the write request - abort if requested block is not within the
|
||||
* virtual firmware file sector range */
|
||||
if (!((BlockNumber >= FileStartBlock) && (BlockNumber <= FileEndBlock)))
|
||||
return;
|
||||
|
||||
uint16_t EEPROMAddress = (uint16_t)(BlockNumber - FileStartBlock) * SECTOR_SIZE_BYTES;
|
||||
|
||||
if (Read)
|
||||
{
|
||||
/* Read out the mapped block of data from the device's EEPROM */
|
||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
||||
BlockBuffer[i] = ReadEEPROMByte((uint8_t*)EEPROMAddress++);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Write out the mapped block of data to the device's EEPROM */
|
||||
for (uint16_t i = 0; i < SECTOR_SIZE_BYTES; i++)
|
||||
WriteEEPROMByte((uint8_t*)EEPROMAddress++, BlockBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/** Writes a block of data to the virtual FAT filesystem, from the USB Mass
|
||||
* Storage interface.
|
||||
*
|
||||
* \param[in] BlockNumber Index of the block to write.
|
||||
*/
|
||||
void VirtualFAT_WriteBlock(const uint16_t BlockNumber)
|
||||
{
|
||||
uint8_t BlockBuffer[SECTOR_SIZE_BYTES];
|
||||
|
||||
/* Buffer the entire block to be written from the host */
|
||||
Endpoint_Read_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL);
|
||||
Endpoint_ClearOUT();
|
||||
|
||||
switch (BlockNumber)
|
||||
{
|
||||
case DISK_BLOCK_BootBlock:
|
||||
case DISK_BLOCK_FATBlock1:
|
||||
case DISK_BLOCK_FATBlock2:
|
||||
/* Ignore writes to the boot and FAT blocks */
|
||||
|
||||
break;
|
||||
|
||||
case DISK_BLOCK_RootFilesBlock:
|
||||
/* Copy over the updated directory entries */
|
||||
memcpy(FirmwareFileEntries, BlockBuffer, sizeof(FirmwareFileEntries));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ReadWriteFLASHFileBlock(BlockNumber, BlockBuffer, false);
|
||||
ReadWriteEEPROMFileBlock(BlockNumber, BlockBuffer, false);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Reads a block of data from the virtual FAT filesystem, and sends it to the
|
||||
* host via the USB Mass Storage interface.
|
||||
*
|
||||
* \param[in] BlockNumber Index of the block to read.
|
||||
*/
|
||||
void VirtualFAT_ReadBlock(const uint16_t BlockNumber)
|
||||
{
|
||||
uint8_t BlockBuffer[SECTOR_SIZE_BYTES];
|
||||
memset(BlockBuffer, 0x00, sizeof(BlockBuffer));
|
||||
|
||||
switch (BlockNumber)
|
||||
{
|
||||
case DISK_BLOCK_BootBlock:
|
||||
memcpy(BlockBuffer, &BootBlock, sizeof(FATBootBlock_t));
|
||||
|
||||
/* Add the magic signature to the end of the block */
|
||||
BlockBuffer[SECTOR_SIZE_BYTES - 2] = 0x55;
|
||||
BlockBuffer[SECTOR_SIZE_BYTES - 1] = 0xAA;
|
||||
|
||||
break;
|
||||
|
||||
case DISK_BLOCK_FATBlock1:
|
||||
case DISK_BLOCK_FATBlock2:
|
||||
/* Cluster 0: Media type/Reserved */
|
||||
UpdateFAT12ClusterEntry(BlockBuffer, 0, 0xF00 | BootBlock.MediaDescriptor);
|
||||
|
||||
/* Cluster 1: Reserved */
|
||||
UpdateFAT12ClusterEntry(BlockBuffer, 1, 0xFFF);
|
||||
|
||||
/* Cluster 2 onwards: Cluster chain of FLASH.BIN */
|
||||
UpdateFAT12ClusterChain(BlockBuffer, *FLASHFileStartCluster, FILE_CLUSTERS(FLASH_FILE_SIZE_BYTES));
|
||||
|
||||
/* Cluster 2+n onwards: Cluster chain of EEPROM.BIN */
|
||||
UpdateFAT12ClusterChain(BlockBuffer, *EEPROMFileStartCluster, FILE_CLUSTERS(EEPROM_FILE_SIZE_BYTES));
|
||||
|
||||
break;
|
||||
|
||||
case DISK_BLOCK_RootFilesBlock:
|
||||
memcpy(BlockBuffer, FirmwareFileEntries, sizeof(FirmwareFileEntries));
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
ReadWriteFLASHFileBlock(BlockNumber, BlockBuffer, true);
|
||||
ReadWriteEEPROMFileBlock(BlockNumber, BlockBuffer, true);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Write the entire read block Buffer to the host */
|
||||
Endpoint_Write_Stream_LE(BlockBuffer, sizeof(BlockBuffer), NULL);
|
||||
Endpoint_ClearIN();
|
||||
}
|
|
@ -0,0 +1,302 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#ifndef _VIRTUALFAT_H_
|
||||
#define _VIRTUALFAT_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include "../BootloaderAPI.h"
|
||||
|
||||
/* Macros: */
|
||||
/** Size of the virtual FLASH.BIN file in bytes. */
|
||||
#define FLASH_FILE_SIZE_BYTES (FLASHEND - (FLASHEND - BOOT_START_ADDR) - AUX_BOOT_SECTION_SIZE)
|
||||
|
||||
/** Size of the virtual EEPROM.BIN file in bytes. */
|
||||
#define EEPROM_FILE_SIZE_BYTES E2END
|
||||
|
||||
/** Number of sectors that comprise a single logical disk cluster. */
|
||||
#define SECTOR_PER_CLUSTER 4
|
||||
|
||||
/** Size of a single logical sector on the disk. */
|
||||
#define SECTOR_SIZE_BYTES 512
|
||||
|
||||
/** Size of a logical cluster on the disk, in bytes */
|
||||
#define CLUSTER_SIZE_BYTES (SECTOR_PER_CLUSTER * SECTOR_SIZE_BYTES)
|
||||
|
||||
/** Number of sectors required to store a given size in bytes.
|
||||
*
|
||||
* \param[in] size Size of the data that needs to be stored
|
||||
*
|
||||
* \return Number of sectors required to store the given data on the disk.
|
||||
*/
|
||||
#define FILE_SECTORS(size) ((size / SECTOR_SIZE_BYTES) + ((size % SECTOR_SIZE_BYTES) ? 1 : 0))
|
||||
|
||||
/** Number of clusters required to store a given size in bytes.
|
||||
*
|
||||
* \param[in] size Size of the data that needs to be stored
|
||||
*
|
||||
* \return Number of clusters required to store the given data on the disk.
|
||||
*/
|
||||
#define FILE_CLUSTERS(size) ((size / CLUSTER_SIZE_BYTES) + ((size % CLUSTER_SIZE_BYTES) ? 1 : 0))
|
||||
|
||||
/** Total number of logical sectors/blocks on the disk. */
|
||||
#define LUN_MEDIA_BLOCKS (FILE_SECTORS(FLASH_FILE_SIZE_BYTES) + FILE_SECTORS(EEPROM_FILE_SIZE_BYTES) + 32)
|
||||
|
||||
/** Converts a given time in HH:MM:SS format to a FAT filesystem time.
|
||||
*
|
||||
* \note The minimum seconds resolution of FAT is 2, thus odd seconds
|
||||
* will be truncated to the previous integer multiple of 2 seconds.
|
||||
*
|
||||
* \param[in] hh Hours (0-23)
|
||||
* \param[in] mm Minutes (0-59)
|
||||
* \param[in] ss Seconds (0-59)
|
||||
*
|
||||
* \return Given time encoded as a FAT filesystem timestamp
|
||||
*/
|
||||
#define FAT_TIME(hh, mm, ss) ((hh << 11) | (mm << 5) | (ss >> 1))
|
||||
|
||||
/** Converts a given date in DD/MM/YYYY format to a FAT filesystem date.
|
||||
*
|
||||
* \param[in] dd Days in the month (1-31)
|
||||
* \param[in] mm Months in the year (1-12)
|
||||
* \param[in] yyyy Year (1980 - 2107)
|
||||
*
|
||||
* \return Given date encoded as a FAT filesystem datestamp
|
||||
*/
|
||||
#define FAT_DATE(dd, mm, yyyy) (((yyyy - 1980) << 9) | (mm << 5) | (dd << 0))
|
||||
|
||||
/** Bit-rotates a given 8-bit value once to the right.
|
||||
*
|
||||
* \param x Value to rotate right once
|
||||
*
|
||||
* \return Bit-rotated input value, rotated once to the right.
|
||||
*/
|
||||
#define _ROT8(x) ((((x) & 0xFE) >> 1) | (((x) & 1) ? 0x80 : 0x00))
|
||||
|
||||
/** Computes the LFN entry checksum of a MSDOS 8.3 format file entry,
|
||||
* to associate a LFN entry with its short file entry.
|
||||
*
|
||||
* \param n0 MSDOS Filename character 1
|
||||
* \param n1 MSDOS Filename character 2
|
||||
* \param n2 MSDOS Filename character 3
|
||||
* \param n3 MSDOS Filename character 4
|
||||
* \param n4 MSDOS Filename character 5
|
||||
* \param n5 MSDOS Filename character 6
|
||||
* \param n6 MSDOS Filename character 7
|
||||
* \param n7 MSDOS Filename character 8
|
||||
* \param e0 MSDOS Extension character 1
|
||||
* \param e1 MSDOS Extension character 2
|
||||
* \param e2 MSDOS Extension character 3
|
||||
*
|
||||
* \return LFN checksum of the given MSDOS 8.3 filename.
|
||||
*/
|
||||
#define FAT_CHECKSUM(n0, n1, n2, n3, n4, n5, n6, n7, e0, e1, e2) \
|
||||
(uint8_t)(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(_ROT8(n0)+n1)+n2)+n3)+n4)+n5)+n6)+n7)+e0)+e1)+e2)
|
||||
|
||||
/** \name FAT Filesystem Flags */
|
||||
//@{
|
||||
/** FAT attribute flag to indicate a read-only file. */
|
||||
#define FAT_FLAG_READONLY (1 << 0)
|
||||
|
||||
/** FAT attribute flag to indicate a hidden file. */
|
||||
#define FAT_FLAG_HIDDEN (1 << 1)
|
||||
|
||||
/** FAT attribute flag to indicate a system file. */
|
||||
#define FAT_FLAG_SYSTEM (1 << 2)
|
||||
|
||||
/** FAT attribute flag to indicate a Volume name entry. */
|
||||
#define FAT_FLAG_VOLUME_NAME (1 << 3)
|
||||
|
||||
/** FAT attribute flag to indicate a directory entry. */
|
||||
#define FAT_FLAG_DIRECTORY (1 << 4)
|
||||
|
||||
/** FAT attribute flag to indicate a file ready for archiving. */
|
||||
#define FAT_FLAG_ARCHIVE (1 << 5)
|
||||
|
||||
/** FAT pseudo-attribute flag to indicate a Long File Name entry. */
|
||||
#define FAT_FLAG_LONG_FILE_NAME 0x0F
|
||||
|
||||
/** Ordinal flag marker for FAT Long File Name entries to mark the last entry. */
|
||||
#define FAT_ORDINAL_LAST_ENTRY (1 << 6)
|
||||
//@}
|
||||
|
||||
/* Enums: */
|
||||
/** Enum for the Root FAT file entry indexes on the disk. This can be used
|
||||
* to retrieve the current contents of a known directory entry.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
/** Volume ID directory entry, giving the name of the virtual disk. */
|
||||
DISK_FILE_ENTRY_VolumeID = 0,
|
||||
/** Long File Name FAT file entry of the virtual FLASH.BIN image file. */
|
||||
DISK_FILE_ENTRY_FLASH_LFN = 1,
|
||||
/** Legacy MSDOS FAT file entry of the virtual FLASH.BIN image file. */
|
||||
DISK_FILE_ENTRY_FLASH_MSDOS = 2,
|
||||
/** Long File Name FAT file entry of the virtual EEPROM.BIN image file. */
|
||||
DISK_FILE_ENTRY_EEPROM_LFN = 3,
|
||||
/** Legacy MSDOS FAT file entry of the virtual EEPROM.BIN image file. */
|
||||
DISK_FILE_ENTRY_EEPROM_MSDOS = 4,
|
||||
};
|
||||
|
||||
/** Enum for the physical disk blocks of the virtual disk. */
|
||||
enum
|
||||
{
|
||||
/** Boot sector disk block. */
|
||||
DISK_BLOCK_BootBlock = 0,
|
||||
/** First copy of the FAT table block. */
|
||||
DISK_BLOCK_FATBlock1 = 1,
|
||||
/** Second copy of the FAT table block. */
|
||||
DISK_BLOCK_FATBlock2 = 2,
|
||||
/** Root file and directory entries block. */
|
||||
DISK_BLOCK_RootFilesBlock = 3,
|
||||
/** Start block of the disk data section. */
|
||||
DISK_BLOCK_DataStartBlock = 4,
|
||||
};
|
||||
|
||||
/* Type Definitions: */
|
||||
/** FAT boot block structure definition, used to identify the core
|
||||
* parameters of a FAT file system stored on a disk.
|
||||
*
|
||||
* \note This definition is truncated to save space; the magic signature
|
||||
* \c 0xAA55 must be appended to the very end of the block for it
|
||||
* to be detected by the host as a valid boot block.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t Bootstrap[3];
|
||||
uint8_t Description[8];
|
||||
uint16_t SectorSize;
|
||||
uint8_t SectorsPerCluster;
|
||||
uint16_t ReservedSectors;
|
||||
uint8_t FATCopies;
|
||||
uint16_t RootDirectoryEntries;
|
||||
uint16_t TotalSectors16;
|
||||
uint8_t MediaDescriptor;
|
||||
uint16_t SectorsPerFAT;
|
||||
uint16_t SectorsPerTrack;
|
||||
uint16_t Heads;
|
||||
uint32_t HiddenSectors;
|
||||
uint32_t TotalSectors32;
|
||||
uint16_t PhysicalDriveNum;
|
||||
uint8_t ExtendedBootRecordSig;
|
||||
uint32_t VolumeSerialNumber;
|
||||
uint8_t VolumeLabel[11];
|
||||
uint8_t FilesystemIdentifier[8];
|
||||
/* uint8_t BootstrapProgram[448]; */
|
||||
/* uint16_t MagicSignature; */
|
||||
} FATBootBlock_t;
|
||||
|
||||
/** FAT directory entry structure, for the various kinds of File and
|
||||
* directory descriptors on a FAT disk.
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
/** VFAT Long File Name file entry. */
|
||||
struct
|
||||
{
|
||||
uint8_t Ordinal;
|
||||
uint16_t Unicode1;
|
||||
uint16_t Unicode2;
|
||||
uint16_t Unicode3;
|
||||
uint16_t Unicode4;
|
||||
uint16_t Unicode5;
|
||||
uint8_t Attribute;
|
||||
uint8_t Reserved1;
|
||||
uint8_t Checksum;
|
||||
uint16_t Unicode6;
|
||||
uint16_t Unicode7;
|
||||
uint16_t Unicode8;
|
||||
uint16_t Unicode9;
|
||||
uint16_t Unicode10;
|
||||
uint16_t Unicode11;
|
||||
uint16_t Reserved2;
|
||||
uint16_t Unicode12;
|
||||
uint16_t Unicode13;
|
||||
} VFAT_LongFileName;
|
||||
|
||||
/** Legacy FAT MSDOS 8.3 file entry. */
|
||||
struct
|
||||
{
|
||||
uint8_t Filename[8];
|
||||
uint8_t Extension[3];
|
||||
uint8_t Attributes;
|
||||
uint8_t Reserved[10];
|
||||
uint16_t CreationTime;
|
||||
uint16_t CreationDate;
|
||||
uint16_t StartingCluster;
|
||||
uint32_t FileSizeBytes;
|
||||
} MSDOS_File;
|
||||
|
||||
/** Legacy FAT MSDOS (sub-)directory entry. */
|
||||
struct
|
||||
{
|
||||
uint8_t Name[11];
|
||||
uint8_t Attributes;
|
||||
uint8_t Reserved[10];
|
||||
uint16_t CreationTime;
|
||||
uint16_t CreationDate;
|
||||
uint16_t StartingCluster;
|
||||
uint32_t Reserved2;
|
||||
} MSDOS_Directory;
|
||||
} FATDirectoryEntry_t;
|
||||
|
||||
/* Function Prototypes: */
|
||||
#if defined(INCLUDE_FROM_VIRTUAL_FAT_C)
|
||||
static uint8_t ReadEEPROMByte(const uint8_t* const Address) ATTR_NO_INLINE;
|
||||
|
||||
static void WriteEEPROMByte(uint8_t* const Address,
|
||||
const uint8_t Data) ATTR_NO_INLINE;
|
||||
|
||||
static void UpdateFAT12ClusterEntry(uint8_t* const FATTable,
|
||||
const uint16_t Index,
|
||||
const uint16_t ChainEntry) AUX_BOOT_SECTION;
|
||||
|
||||
static void UpdateFAT12ClusterChain(uint8_t* const FATTable,
|
||||
const uint16_t StartIndex,
|
||||
const uint8_t ChainLength) AUX_BOOT_SECTION;
|
||||
|
||||
static void ReadWriteFLASHFileBlock(const uint16_t BlockNumber,
|
||||
uint8_t* BlockBuffer,
|
||||
const bool Read) AUX_BOOT_SECTION;
|
||||
|
||||
static void ReadWriteEEPROMFileBlock(const uint16_t BlockNumber,
|
||||
uint8_t* BlockBuffer,
|
||||
const bool Read) AUX_BOOT_SECTION;
|
||||
#endif
|
||||
|
||||
void VirtualFAT_WriteBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION;
|
||||
void VirtualFAT_ReadBlock(const uint16_t BlockNumber) AUX_BOOT_SECTION;
|
||||
|
||||
#endif
|
156
tmk_core/protocol/lufa/LUFA-git/Bootloaders/MassStorage/asf.xml
Normal file
156
tmk_core/protocol/lufa/LUFA-git/Bootloaders/MassStorage/asf.xml
Normal file
|
@ -0,0 +1,156 @@
|
|||
<asf xmlversion="1.0">
|
||||
<project caption="Mass Storage Bootloader - 128KB FLASH / 8KB Boot - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.128_8" force-caption="true" workspace-name="lufa_ms_128kb_8kb_">
|
||||
<require idref="lufa.bootloaders.mass_storage"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb1287"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1E000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1E000"/>
|
||||
|
||||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="0"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Mass Storage Bootloader - 64KB FLASH / 8KB Boot - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.64_8" force-caption="true" workspace-name="lufa_ms_64kb_8kb_">
|
||||
<require idref="lufa.bootloaders.mass_storage"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb647"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0xE000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xE000"/>
|
||||
|
||||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="0"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0xFFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0xFFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0xFFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Mass Storage Bootloader - 32KB FLASH / 4KB Boot (2KB AUX) - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.32_4" force-caption="true" workspace-name="lufa_ms_32kb_4kb_">
|
||||
<require idref="lufa.bootloaders.mass_storage"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega32u4"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/>
|
||||
|
||||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="2048"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux=0x6810"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux_trampoline=0x6800"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=Boot_AUX_Trampoline"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x7FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x7FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x7FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Mass Storage Bootloader - 16KB FLASH / 4KB Boot (2KB AUX) - AVR8 Architecture" id="lufa.bootloaders.mass_storage.avr8.16_4" force-caption="true" workspace-name="lufa_ms_16kb_4kb_">
|
||||
<require idref="lufa.bootloaders.mass_storage"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega16u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x3000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3000"/>
|
||||
|
||||
<build type="define" name="AUX_BOOT_SECTION_SIZE" value="2048"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux=0x2810"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.boot_aux_trampoline=0x2800"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=Boot_AUX_Trampoline"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x3FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x3FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x3FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<module type="application" id="lufa.bootloaders.mass_storage" caption="Mass Storage Bootloader">
|
||||
<info type="description" value="summary">
|
||||
Mass Storage Class Bootloader, capable of reprogramming a device via binary BIN files copied to the virtual FAT12 file-system it creates when plugged into a host.
|
||||
</info>
|
||||
|
||||
<info type="gui-flag" value="move-to-root"/>
|
||||
|
||||
<info type="keyword" value="Technology">
|
||||
<keyword value="Bootloaders"/>
|
||||
<keyword value="USB Device"/>
|
||||
</info>
|
||||
|
||||
<device-support-alias value="lufa_avr8"/>
|
||||
<device-support-alias value="lufa_xmega"/>
|
||||
<device-support-alias value="lufa_uc3"/>
|
||||
|
||||
<build type="include-path" value="."/>
|
||||
<build type="c-source" value="BootloaderMassStorage.c"/>
|
||||
<build type="header-file" value="BootloaderMassStorage.h"/>
|
||||
<build type="c-source" value="Descriptors.c"/>
|
||||
<build type="header-file" value="Descriptors.h"/>
|
||||
<build type="c-source" value="BootloaderAPI.c"/>
|
||||
<build type="header-file" value="BootloaderAPI.h"/>
|
||||
<build type="asm-source" value="BootloaderAPITable.S"/>
|
||||
|
||||
<build type="module-config" subtype="path" value="Config"/>
|
||||
<build type="header-file" value="Config/LUFAConfig.h"/>
|
||||
<build type="header-file" value="Config/AppConfig.h"/>
|
||||
|
||||
<build type="include-path" value="Lib"/>
|
||||
<build type="header-file" value="Lib/VirtualFAT.h"/>
|
||||
<build type="c-source" value="Lib/VirtualFAT.c"/>
|
||||
<build type="header-file" value="Lib/SCSI.h"/>
|
||||
<build type="c-source" value="Lib/SCSI.c"/>
|
||||
|
||||
<build type="distribute" subtype="user-file" value="doxyfile"/>
|
||||
<build type="distribute" subtype="user-file" value="BootloaderMassStorage.txt"/>
|
||||
|
||||
<require idref="lufa.common"/>
|
||||
<require idref="lufa.platform"/>
|
||||
<require idref="lufa.drivers.usb"/>
|
||||
<require idref="lufa.drivers.board"/>
|
||||
<require idref="lufa.drivers.board.leds"/>
|
||||
</module>
|
||||
</asf>
|
2365
tmk_core/protocol/lufa/LUFA-git/Bootloaders/MassStorage/doxyfile
Normal file
2365
tmk_core/protocol/lufa/LUFA-git/Bootloaders/MassStorage/doxyfile
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,68 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.lufa-lib.org
|
||||
#
|
||||
# --------------------------------------
|
||||
# LUFA Project Makefile.
|
||||
# --------------------------------------
|
||||
|
||||
# Run "make help" for target help.
|
||||
|
||||
MCU = at90usb1287
|
||||
ARCH = AVR8
|
||||
BOARD = USBKEY
|
||||
F_CPU = 8000000
|
||||
F_USB = $(F_CPU)
|
||||
OPTIMIZATION = s
|
||||
TARGET = BootloaderMassStorage
|
||||
SRC = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S Lib/SCSI.c Lib/VirtualFAT.c $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
||||
LUFA_PATH = ../../LUFA
|
||||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET)
|
||||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS)
|
||||
|
||||
# Flash size and bootloader section sizes of the target, in KB. These must
|
||||
# match the target's total FLASH size and the bootloader size set in the
|
||||
# device's fuses.
|
||||
FLASH_SIZE_KB = 128
|
||||
BOOT_SECTION_SIZE_KB = 8
|
||||
|
||||
# Bootloader address calculation formulas
|
||||
# Do not modify these macros, but rather modify the dependent values above.
|
||||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) )
|
||||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 )
|
||||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) )
|
||||
|
||||
# Bootloader linker section flags for relocating the API table sections to
|
||||
# known FLASH addresses - these should not normally be user-edited.
|
||||
BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2))
|
||||
BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8)
|
||||
|
||||
# Check if the bootloader needs an AUX section, located before the real bootloader section to store some of the
|
||||
# bootloader code. This is required for 32KB and smaller devices, where the actual bootloader is 6KB but the maximum
|
||||
# bootloader section size is 4KB. The actual usable application space will be reduced by 6KB for these devices.
|
||||
ifeq ($(BOOT_SECTION_SIZE_KB),8)
|
||||
CC_FLAGS += -DAUX_BOOT_SECTION_SIZE=0
|
||||
else
|
||||
AUX_BOOT_SECTION_SIZE_KB = (6 - $(BOOT_SECTION_SIZE_KB))
|
||||
|
||||
CC_FLAGS += -DAUX_BOOT_SECTION_SIZE='($(AUX_BOOT_SECTION_SIZE_KB) * 1024)'
|
||||
LD_FLAGS += -Wl,--section-start=.boot_aux=$(call BOOT_SEC_OFFSET, (($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_SIZE_KB)) * 1024 - 16))
|
||||
LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .boot_aux_trampoline, Boot_AUX_Trampoline, ($(BOOT_SECTION_SIZE_KB) + $(AUX_BOOT_SECTION_SIZE_KB)) * 1024)
|
||||
endif
|
||||
|
||||
# Default target
|
||||
all:
|
||||
|
||||
# Include LUFA build script makefiles
|
||||
include $(LUFA_PATH)/Build/lufa_core.mk
|
||||
include $(LUFA_PATH)/Build/lufa_sources.mk
|
||||
include $(LUFA_PATH)/Build/lufa_build.mk
|
||||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk
|
||||
include $(LUFA_PATH)/Build/lufa_doxygen.mk
|
||||
include $(LUFA_PATH)/Build/lufa_avrdude.mk
|
||||
include $(LUFA_PATH)/Build/lufa_atprogram.mk
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Bootloader user application API functions.
|
||||
*/
|
||||
|
||||
#include "BootloaderAPI.h"
|
||||
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_erase_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_WritePage(const uint32_t Address)
|
||||
{
|
||||
boot_page_write_safe(Address);
|
||||
boot_spm_busy_wait();
|
||||
boot_rww_enable();
|
||||
}
|
||||
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word)
|
||||
{
|
||||
boot_page_fill_safe(Address, Word);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address)
|
||||
{
|
||||
return boot_signature_byte_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(Address);
|
||||
}
|
||||
|
||||
uint8_t BootloaderAPI_ReadLock(void)
|
||||
{
|
||||
return boot_lock_fuse_bits_get(GET_LOCK_BITS);
|
||||
}
|
||||
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits)
|
||||
{
|
||||
boot_lock_bits_set_safe(LockBits);
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderAPI.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_API_H_
|
||||
#define _BOOTLOADER_API_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/boot.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
|
||||
/* Function Prototypes: */
|
||||
void BootloaderAPI_ErasePage(const uint32_t Address);
|
||||
void BootloaderAPI_WritePage(const uint32_t Address);
|
||||
void BootloaderAPI_FillWord(const uint32_t Address, const uint16_t Word);
|
||||
uint8_t BootloaderAPI_ReadSignature(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadFuse(const uint16_t Address);
|
||||
uint8_t BootloaderAPI_ReadLock(void);
|
||||
void BootloaderAPI_WriteLock(const uint8_t LockBits);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
; Trampolines to actual API implementations if the target address is outside the
|
||||
; range of a rjmp instruction (can happen with large bootloader sections)
|
||||
.section .apitable_trampolines, "ax"
|
||||
.global BootloaderAPI_Trampolines
|
||||
BootloaderAPI_Trampolines:
|
||||
|
||||
BootloaderAPI_ErasePage_Trampoline:
|
||||
jmp BootloaderAPI_ErasePage
|
||||
BootloaderAPI_WritePage_Trampoline:
|
||||
jmp BootloaderAPI_WritePage
|
||||
BootloaderAPI_FillWord_Trampoline:
|
||||
jmp BootloaderAPI_FillWord
|
||||
BootloaderAPI_ReadSignature_Trampoline:
|
||||
jmp BootloaderAPI_ReadSignature
|
||||
BootloaderAPI_ReadFuse_Trampoline:
|
||||
jmp BootloaderAPI_ReadFuse
|
||||
BootloaderAPI_ReadLock_Trampoline:
|
||||
jmp BootloaderAPI_ReadLock
|
||||
BootloaderAPI_WriteLock_Trampoline:
|
||||
jmp BootloaderAPI_WriteLock
|
||||
BootloaderAPI_UNUSED1:
|
||||
ret
|
||||
BootloaderAPI_UNUSED2:
|
||||
ret
|
||||
BootloaderAPI_UNUSED3:
|
||||
ret
|
||||
BootloaderAPI_UNUSED4:
|
||||
ret
|
||||
BootloaderAPI_UNUSED5:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; API function jump table
|
||||
.section .apitable_jumptable, "ax"
|
||||
.global BootloaderAPI_JumpTable
|
||||
BootloaderAPI_JumpTable:
|
||||
|
||||
rjmp BootloaderAPI_ErasePage_Trampoline
|
||||
rjmp BootloaderAPI_WritePage_Trampoline
|
||||
rjmp BootloaderAPI_FillWord_Trampoline
|
||||
rjmp BootloaderAPI_ReadSignature_Trampoline
|
||||
rjmp BootloaderAPI_ReadFuse_Trampoline
|
||||
rjmp BootloaderAPI_ReadLock_Trampoline
|
||||
rjmp BootloaderAPI_WriteLock_Trampoline
|
||||
rjmp BootloaderAPI_UNUSED1 ; UNUSED ENTRY 1
|
||||
rjmp BootloaderAPI_UNUSED2 ; UNUSED ENTRY 2
|
||||
rjmp BootloaderAPI_UNUSED3 ; UNUSED ENTRY 3
|
||||
rjmp BootloaderAPI_UNUSED4 ; UNUSED ENTRY 4
|
||||
rjmp BootloaderAPI_UNUSED5 ; UNUSED ENTRY 5
|
||||
|
||||
|
||||
|
||||
; Bootloader table signatures and information
|
||||
.section .apitable_signatures, "ax"
|
||||
.global BootloaderAPI_Signatures
|
||||
BootloaderAPI_Signatures:
|
||||
|
||||
.long BOOT_START_ADDR ; Start address of the bootloader
|
||||
.word 0xDF20 ; Signature for the Printer class bootloader
|
||||
.word 0xDCFB ; Signature for a LUFA class bootloader
|
|
@ -0,0 +1,431 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Main source file for the Printer class bootloader. This file contains the complete bootloader logic.
|
||||
*/
|
||||
|
||||
#include "BootloaderPrinter.h"
|
||||
|
||||
/** LUFA Printer Class driver interface configuration and state information. This structure is
|
||||
* passed to all Printer Class driver functions, so that multiple instances of the same class
|
||||
* within a device can be differentiated from one another.
|
||||
*/
|
||||
USB_ClassInfo_PRNT_Device_t TextOnly_Printer_Interface =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.InterfaceNumber = INTERFACE_ID_Printer,
|
||||
.DataINEndpoint =
|
||||
{
|
||||
.Address = PRINTER_IN_EPADDR,
|
||||
.Size = PRINTER_IO_EPSIZE,
|
||||
.Banks = 1,
|
||||
},
|
||||
.DataOUTEndpoint =
|
||||
{
|
||||
.Address = PRINTER_OUT_EPADDR,
|
||||
.Size = PRINTER_IO_EPSIZE,
|
||||
.Banks = 1,
|
||||
},
|
||||
.IEEE1284String =
|
||||
"MFG:Generic;"
|
||||
"MDL:Generic_/_Text_Only;"
|
||||
"CMD:1284.4;"
|
||||
"CLS:PRINTER",
|
||||
},
|
||||
};
|
||||
|
||||
/** Intel HEX parser state machine state information, to track the contents of
|
||||
* a HEX file streamed in as a sequence of arbitrary bytes.
|
||||
*/
|
||||
struct
|
||||
{
|
||||
/** Current HEX parser state machine state. */
|
||||
uint8_t ParserState;
|
||||
/** Previously decoded numerical byte of data. */
|
||||
uint8_t PrevData;
|
||||
/** Currently decoded numerical byte of data. */
|
||||
uint8_t Data;
|
||||
/** Indicates if both bytes that correspond to a single decoded numerical
|
||||
* byte of data (HEX encodes values in ASCII HEX, two characters per byte)
|
||||
* have been read.
|
||||
*/
|
||||
bool ReadMSB;
|
||||
/** Intel HEX record type of the current Intel HEX record. */
|
||||
uint8_t RecordType;
|
||||
/** Numerical bytes of data remaining to be read in the current record. */
|
||||
uint8_t DataRem;
|
||||
/** Checksum of the current record received so far. */
|
||||
uint8_t Checksum;
|
||||
/** Starting address of the last addressed FLASH page. */
|
||||
uint32_t PageStartAddress;
|
||||
/** Current 32-bit byte extended base address in FLASH being targeted. */
|
||||
uint32_t CurrBaseAddress;
|
||||
/** Current 32-bit byte address in FLASH being targeted. */
|
||||
uint32_t CurrAddress;
|
||||
} HEXParser;
|
||||
|
||||
/** Indicates if there is data waiting to be written to a physical page of
|
||||
* memory in FLASH.
|
||||
*/
|
||||
static bool PageDirty = false;
|
||||
|
||||
/** Flag to indicate if the bootloader should be running, or should exit and allow the application code to run
|
||||
* via a soft reset. When cleared, the bootloader will abort, the USB interface will shut down and the application
|
||||
* started via a forced watchdog reset.
|
||||
*/
|
||||
static bool RunBootloader = true;
|
||||
|
||||
/** Magic lock for forced application start. If the HWBE fuse is programmed and BOOTRST is unprogrammed, the bootloader
|
||||
* will start if the /HWB line of the AVR is held low and the system is reset. However, if the /HWB line is still held
|
||||
* low when the application attempts to start via a watchdog reset, the bootloader will re-start. If set to the value
|
||||
* \ref MAGIC_BOOT_KEY the special init function \ref Application_Jump_Check() will force the application to start.
|
||||
*/
|
||||
uint16_t MagicBootKey ATTR_NO_INIT;
|
||||
|
||||
|
||||
/** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application
|
||||
* start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid,
|
||||
* this will force the user application to start via a software jump.
|
||||
*/
|
||||
void Application_Jump_Check(void)
|
||||
{
|
||||
/* If the reset source was the bootloader and the key is correct, clear it and jump to the application */
|
||||
if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY))
|
||||
{
|
||||
MagicBootKey = 0;
|
||||
|
||||
// cppcheck-suppress constStatement
|
||||
((void (*)(void))0x0000)();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a given input byte of data from an ASCII encoded HEX value to an integer value.
|
||||
*
|
||||
* \note Input HEX bytes are expected to be in uppercase only.
|
||||
*
|
||||
* \param[in] Byte ASCII byte of data to convert
|
||||
*
|
||||
* \return Integer converted value of the input ASCII encoded HEX byte of data, or -1 if the
|
||||
* input is not valid ASCII encoded HEX.
|
||||
*/
|
||||
static int8_t HexToDecimal(const char Byte)
|
||||
{
|
||||
if ((Byte >= 'A') && (Byte <= 'F'))
|
||||
return (10 + (Byte - 'A'));
|
||||
else if ((Byte >= '0') && (Byte <= '9'))
|
||||
return (Byte - '0');
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes a partially written page of data to physical FLASH, if a page
|
||||
* boundary has been crossed.
|
||||
*
|
||||
* \note If a page flush occurs the global HEX parser state is updated.
|
||||
*/
|
||||
static void FlushPageIfRequired(void)
|
||||
{
|
||||
/* Abort if no data has been buffered for writing to the current page */
|
||||
if (!PageDirty)
|
||||
return;
|
||||
|
||||
/* Flush the FLASH page to physical memory if we are crossing a page boundary */
|
||||
uint32_t NewPageStartAddress = (HEXParser.CurrAddress & ~(SPM_PAGESIZE - 1));
|
||||
if (HEXParser.PageStartAddress != NewPageStartAddress)
|
||||
{
|
||||
boot_page_write(HEXParser.PageStartAddress);
|
||||
boot_spm_busy_wait();
|
||||
|
||||
HEXParser.PageStartAddress = NewPageStartAddress;
|
||||
|
||||
PageDirty = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an input Intel HEX formatted stream one character at a time, loading
|
||||
* the data contents into the device's internal FLASH memory.
|
||||
*
|
||||
* \param[in] ReadCharacter Next input ASCII byte of data to parse
|
||||
*/
|
||||
static void ParseIntelHEXByte(const char ReadCharacter)
|
||||
{
|
||||
/* Reset the line parser while waiting for a new line to start */
|
||||
if ((HEXParser.ParserState == HEX_PARSE_STATE_WAIT_LINE) || (ReadCharacter == ':'))
|
||||
{
|
||||
HEXParser.Checksum = 0;
|
||||
HEXParser.CurrAddress = HEXParser.CurrBaseAddress;
|
||||
HEXParser.ReadMSB = false;
|
||||
|
||||
/* ASCII ':' indicates the start of a new HEX record */
|
||||
if (ReadCharacter == ':')
|
||||
HEXParser.ParserState = HEX_PARSE_STATE_BYTE_COUNT;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only allow ASCII HEX encoded digits, ignore all other characters */
|
||||
int8_t ReadCharacterDec = HexToDecimal(ReadCharacter);
|
||||
if (ReadCharacterDec < 0)
|
||||
return;
|
||||
|
||||
/* Read and convert the next nibble of data from the current character */
|
||||
HEXParser.Data = (HEXParser.Data << 4) | ReadCharacterDec;
|
||||
HEXParser.ReadMSB = !HEXParser.ReadMSB;
|
||||
|
||||
/* Only process further when a full byte (two nibbles) have been read */
|
||||
if (HEXParser.ReadMSB)
|
||||
return;
|
||||
|
||||
/* Intel HEX checksum is for all fields except starting character and the
|
||||
* checksum itself
|
||||
*/
|
||||
if (HEXParser.ParserState != HEX_PARSE_STATE_CHECKSUM)
|
||||
HEXParser.Checksum += HEXParser.Data;
|
||||
|
||||
switch (HEXParser.ParserState)
|
||||
{
|
||||
case HEX_PARSE_STATE_BYTE_COUNT:
|
||||
HEXParser.DataRem = HEXParser.Data;
|
||||
HEXParser.ParserState = HEX_PARSE_STATE_ADDRESS_HIGH;
|
||||
break;
|
||||
|
||||
case HEX_PARSE_STATE_ADDRESS_HIGH:
|
||||
HEXParser.CurrAddress += ((uint16_t)HEXParser.Data << 8);
|
||||
HEXParser.ParserState = HEX_PARSE_STATE_ADDRESS_LOW;
|
||||
break;
|
||||
|
||||
case HEX_PARSE_STATE_ADDRESS_LOW:
|
||||
HEXParser.CurrAddress += HEXParser.Data;
|
||||
HEXParser.ParserState = HEX_PARSE_STATE_RECORD_TYPE;
|
||||
break;
|
||||
|
||||
case HEX_PARSE_STATE_RECORD_TYPE:
|
||||
HEXParser.RecordType = HEXParser.Data;
|
||||
HEXParser.ParserState = (HEXParser.DataRem ? HEX_PARSE_STATE_READ_DATA : HEX_PARSE_STATE_CHECKSUM);
|
||||
break;
|
||||
|
||||
case HEX_PARSE_STATE_READ_DATA:
|
||||
/* Track the number of read data bytes in the record */
|
||||
HEXParser.DataRem--;
|
||||
|
||||
/* Protect the bootloader against being written to */
|
||||
if (HEXParser.CurrAddress >= BOOT_START_ADDR)
|
||||
{
|
||||
HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE;
|
||||
PageDirty = false;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Wait for a machine word (two bytes) of data to be read */
|
||||
if (HEXParser.DataRem & 0x01)
|
||||
{
|
||||
HEXParser.PrevData = HEXParser.Data;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Convert the last two received data bytes into a 16-bit word */
|
||||
uint16_t NewDataWord = ((uint16_t)HEXParser.Data << 8) | HEXParser.PrevData;
|
||||
|
||||
switch (HEXParser.RecordType)
|
||||
{
|
||||
case HEX_RECORD_TYPE_Data:
|
||||
/* If we are writing to a new page, we need to erase it first */
|
||||
if (!(PageDirty))
|
||||
{
|
||||
boot_page_erase(HEXParser.PageStartAddress);
|
||||
boot_spm_busy_wait();
|
||||
|
||||
PageDirty = true;
|
||||
}
|
||||
|
||||
/* Fill the FLASH memory buffer with the new word of data */
|
||||
boot_page_fill(HEXParser.CurrAddress, NewDataWord);
|
||||
HEXParser.CurrAddress += 2;
|
||||
|
||||
/* Flush the FLASH page to physical memory if we are crossing a page boundary */
|
||||
FlushPageIfRequired();
|
||||
break;
|
||||
|
||||
case HEX_RECORD_TYPE_ExtendedSegmentAddress:
|
||||
/* Extended address data - store the upper 12-bits of the new address */
|
||||
HEXParser.CurrBaseAddress = ((uint32_t)NewDataWord << 4);
|
||||
break;
|
||||
|
||||
case HEX_RECORD_TYPE_ExtendedLinearAddress:
|
||||
/* Extended address data - store the upper 16-bits of the new address */
|
||||
HEXParser.CurrBaseAddress = ((uint32_t)NewDataWord << 16);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!HEXParser.DataRem)
|
||||
HEXParser.ParserState = HEX_PARSE_STATE_CHECKSUM;
|
||||
break;
|
||||
|
||||
case HEX_PARSE_STATE_CHECKSUM:
|
||||
/* Verify checksum of the completed record */
|
||||
if (HEXParser.Data != ((~HEXParser.Checksum + 1) & 0xFF))
|
||||
break;
|
||||
|
||||
/* Flush the FLASH page to physical memory if we are crossing a page boundary */
|
||||
FlushPageIfRequired();
|
||||
|
||||
/* If end of the HEX file reached, the bootloader should exit at next opportunity */
|
||||
if (HEXParser.RecordType == HEX_RECORD_TYPE_EndOfFile)
|
||||
RunBootloader = false;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** Main program entry point. This routine configures the hardware required by the application, then
|
||||
* enters a loop to run the application tasks in sequence.
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
SetupHardware();
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
GlobalInterruptEnable();
|
||||
|
||||
while (RunBootloader)
|
||||
{
|
||||
uint8_t BytesReceived = PRNT_Device_BytesReceived(&TextOnly_Printer_Interface);
|
||||
|
||||
if (BytesReceived)
|
||||
{
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_BUSY);
|
||||
|
||||
while (BytesReceived--)
|
||||
{
|
||||
int16_t ReceivedByte = PRNT_Device_ReceiveByte(&TextOnly_Printer_Interface);
|
||||
|
||||
/* Feed the next byte of data to the HEX parser */
|
||||
ParseIntelHEXByte(ReceivedByte);
|
||||
}
|
||||
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_READY);
|
||||
}
|
||||
|
||||
PRNT_Device_USBTask(&TextOnly_Printer_Interface);
|
||||
USB_USBTask();
|
||||
}
|
||||
|
||||
/* Disconnect from the host - USB interface will be reset later along with the AVR */
|
||||
USB_Detach();
|
||||
|
||||
/* Unlock the forced application start mode of the bootloader if it is restarted */
|
||||
MagicBootKey = MAGIC_BOOT_KEY;
|
||||
|
||||
/* Enable the watchdog and force a timeout to reset the AVR */
|
||||
wdt_enable(WDTO_250MS);
|
||||
|
||||
for (;;);
|
||||
}
|
||||
|
||||
/** Configures the board hardware and chip peripherals for the demo's functionality. */
|
||||
static void SetupHardware(void)
|
||||
{
|
||||
/* Disable watchdog if enabled by bootloader/fuses */
|
||||
MCUSR &= ~(1 << WDRF);
|
||||
wdt_disable();
|
||||
|
||||
/* Disable clock division */
|
||||
clock_prescale_set(clock_div_1);
|
||||
|
||||
/* Relocate the interrupt vector table to the bootloader section */
|
||||
MCUCR = (1 << IVCE);
|
||||
MCUCR = (1 << IVSEL);
|
||||
|
||||
/* Hardware Initialization */
|
||||
LEDs_Init();
|
||||
USB_Init();
|
||||
|
||||
/* Bootloader active LED toggle timer initialization */
|
||||
TIMSK1 = (1 << TOIE1);
|
||||
TCCR1B = ((1 << CS11) | (1 << CS10));
|
||||
}
|
||||
|
||||
/** ISR to periodically toggle the LEDs on the board to indicate that the bootloader is active. */
|
||||
ISR(TIMER1_OVF_vect, ISR_BLOCK)
|
||||
{
|
||||
LEDs_ToggleLEDs(LEDS_LED1 | LEDS_LED2);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs. */
|
||||
void EVENT_USB_Device_Connect(void)
|
||||
{
|
||||
/* Indicate USB enumerating */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_ENUMERATING);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_Disconnect event. This indicates that the device is no longer connected to a host via
|
||||
* the status LEDs and stops the Printer management task.
|
||||
*/
|
||||
void EVENT_USB_Device_Disconnect(void)
|
||||
{
|
||||
/* Indicate USB not ready */
|
||||
LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ConfigurationChanged event. This is fired when the host set the current configuration
|
||||
* of the USB device after enumeration - the device endpoints are configured and the Mass Storage management task started.
|
||||
*/
|
||||
void EVENT_USB_Device_ConfigurationChanged(void)
|
||||
{
|
||||
bool ConfigSuccess = true;
|
||||
|
||||
/* Setup Printer Data Endpoints */
|
||||
ConfigSuccess &= PRNT_Device_ConfigureEndpoints(&TextOnly_Printer_Interface);
|
||||
|
||||
/* Reset the HEX parser upon successful connection to a host */
|
||||
HEXParser.ParserState = HEX_PARSE_STATE_WAIT_LINE;
|
||||
|
||||
/* Indicate endpoint configuration success or failure */
|
||||
LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);
|
||||
}
|
||||
|
||||
/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to
|
||||
* the device from the USB host before passing along unhandled control requests to the library for processing
|
||||
* internally.
|
||||
*/
|
||||
void EVENT_USB_Device_ControlRequest(void)
|
||||
{
|
||||
PRNT_Device_ProcessControlRequest(&TextOnly_Printer_Interface);
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for BootloaderPrinter.c.
|
||||
*/
|
||||
|
||||
#ifndef _BOOTLOADER_PRINTER_H_
|
||||
#define _BOOTLOADER_PRINTER_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <avr/io.h>
|
||||
#include <avr/wdt.h>
|
||||
#include <avr/power.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
#include <LUFA/Platform/Platform.h>
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__OPTIMIZE_SIZE__)
|
||||
#error This bootloader requires that it be optimized for size, not speed, to fit into the target device. Change optimization settings and try again.
|
||||
#endif
|
||||
|
||||
/* Macros: */
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is not ready. */
|
||||
#define LEDMASK_USB_NOTREADY LEDS_LED1
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is enumerating. */
|
||||
#define LEDMASK_USB_ENUMERATING (LEDS_LED2 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is ready. */
|
||||
#define LEDMASK_USB_READY (LEDS_LED2 | LEDS_LED4)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that an error has occurred in the USB interface. */
|
||||
#define LEDMASK_USB_ERROR (LEDS_LED1 | LEDS_LED3)
|
||||
|
||||
/** LED mask for the library LED driver, to indicate that the USB interface is busy. */
|
||||
#define LEDMASK_USB_BUSY LEDS_LED2
|
||||
|
||||
/** Magic bootloader key to unlock forced application start mode. */
|
||||
#define MAGIC_BOOT_KEY 0xDC42
|
||||
|
||||
/* Enums: */
|
||||
/** Intel HEX parser state machine states. */
|
||||
enum HEX_Parser_States_t
|
||||
{
|
||||
HEX_PARSE_STATE_WAIT_LINE, /**< Parser is waiting for a HEX Start of Line character. */
|
||||
HEX_PARSE_STATE_BYTE_COUNT, /**< Parser is waiting for a record byte count. */
|
||||
HEX_PARSE_STATE_ADDRESS_HIGH, /**< Parser is waiting for the MSB of a record address. */
|
||||
HEX_PARSE_STATE_ADDRESS_LOW, /**< Parser is waiting for the LSB of a record address. */
|
||||
HEX_PARSE_STATE_RECORD_TYPE, /**< Parser is waiting for the record type. */
|
||||
HEX_PARSE_STATE_READ_DATA, /**< Parser is waiting for more data in the current record. */
|
||||
HEX_PARSE_STATE_CHECKSUM, /**< Parser is waiting for the checksum of the current record. */
|
||||
};
|
||||
|
||||
/** Intel HEX record types, used to indicate the type of record contained in a line of a HEX file. */
|
||||
enum HEX_Record_Types_t
|
||||
{
|
||||
HEX_RECORD_TYPE_Data = 0, /**< Record contains loadable data. */
|
||||
HEX_RECORD_TYPE_EndOfFile = 1, /**< End of file record. */
|
||||
HEX_RECORD_TYPE_ExtendedSegmentAddress = 2, /**< Extended segment start record. */
|
||||
HEX_RECORD_TYPE_StartSegmentAddress = 3, /**< Normal segment start record. */
|
||||
HEX_RECORD_TYPE_ExtendedLinearAddress = 4, /**< Extended linear address start record. */
|
||||
HEX_RECORD_TYPE_StartLinearAddress = 5, /**< Linear address start record. */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
static void SetupHardware(void);
|
||||
|
||||
void EVENT_USB_Device_Connect(void);
|
||||
void EVENT_USB_Device_Disconnect(void);
|
||||
void EVENT_USB_Device_ConfigurationChanged(void);
|
||||
void EVENT_USB_Device_ControlRequest(void);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
/** \file
|
||||
*
|
||||
* This file contains special DoxyGen information for the generation of the main page and other special
|
||||
* documentation pages. It is not a project source file.
|
||||
*/
|
||||
|
||||
/** \mainpage Printer Class USB AVR Bootloader
|
||||
*
|
||||
* \section Sec_Compat Demo Compatibility:
|
||||
*
|
||||
* The following list indicates what microcontrollers are compatible with this demo.
|
||||
*
|
||||
* \li Series 7 USB AVRs (AT90USBxxx7)
|
||||
* \li Series 6 USB AVRs (AT90USBxxx6)
|
||||
* \li Series 4 USB AVRs (ATMEGAxxU4)
|
||||
* \li Series 2 USB AVRs (AT90USBxx2, ATMEGAxxU2)
|
||||
*
|
||||
* \section Sec_Info USB Information:
|
||||
*
|
||||
* The following table gives a rundown of the USB utilization of this demo.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td><b>USB Mode:</b></td>
|
||||
* <td>Device</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Class:</b></td>
|
||||
* <td>Printer Class</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>USB Subclass:</b></td>
|
||||
* <td>Printer Subclass</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Relevant Standards:</b></td>
|
||||
* <td>USBIF Printer Class Standard</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><b>Supported USB Speeds:</b></td>
|
||||
* <td>Full Speed Mode</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* \section Sec_Description Project Description:
|
||||
*
|
||||
* This bootloader enumerates to the host as a Generic Text Only Printer device, capable of reading and parsing
|
||||
* "printed" plain-text Intel HEX files to load firmware onto the AVR.
|
||||
*
|
||||
* Out of the box this bootloader builds for the AT90USB1287 with an 8KB bootloader section size, and will fit
|
||||
* into 4KB of bootloader space. If you wish to alter this size and/or change the AVR model, you will need to
|
||||
* edit the MCU, FLASH_SIZE_KB and BOOT_SECTION_SIZE_KB values in the accompanying makefile.
|
||||
*
|
||||
* When the bootloader is running, the board's LED(s) will flash at regular intervals to distinguish the
|
||||
* bootloader from the normal user application.
|
||||
*
|
||||
* \section Sec_Running Running the Bootloader
|
||||
*
|
||||
* This bootloader is designed to be started via the HWB mechanism of the USB AVRs; ground the HWB pin (see device
|
||||
* datasheet) then momentarily ground /RESET to start the bootloader. This assumes the HWBE fuse is set and the BOOTRST
|
||||
* fuse is cleared.
|
||||
*
|
||||
* \section Sec_Installation Driver Installation
|
||||
*
|
||||
* This bootloader uses the Generic Text-Only printer drivers inbuilt into all modern operating systems, thus no
|
||||
* additional drivers need to be supplied for correct operation.
|
||||
*
|
||||
* \section Sec_HostApp Host Controller Application
|
||||
*
|
||||
* This bootloader is compatible with Notepad under Windows, and the command line \c lpr utility under Linux.
|
||||
*
|
||||
* \subsection SSec_Notepad Notepad (Windows)
|
||||
*
|
||||
* While most text applications under Windows will be compatible with the bootloader, the inbuilt Notepad utility
|
||||
* is recommended as it will introduce minimal formatting changes to the output stream. To program with Notepad,
|
||||
* open the target HEX file and print it to the Generic Text Only printer device the bootloader creates.
|
||||
*
|
||||
* \subsection SSec_LPR LPR (Linux)
|
||||
*
|
||||
* While the CUPS framework under Linux will enumerate the bootloader as a Generic Text-Only printer, many
|
||||
* applications will refuse to print to the device due to the lack of rich formatting options available. As a result,
|
||||
* under Linux HEX files must be printed via the low level \c lpr utility instead.
|
||||
*
|
||||
* \code
|
||||
* cat Mouse.hex | lpr
|
||||
* \endcode
|
||||
*
|
||||
* \section Sec_API User Application API
|
||||
*
|
||||
* Several user application functions for FLASH and other special memory area manipulations are exposed by the bootloader,
|
||||
* allowing the user application to call into the bootloader at runtime to read and write FLASH data.
|
||||
*
|
||||
* By default, the bootloader API jump table is located 32 bytes from the end of the device's FLASH memory, and follows the
|
||||
* following layout:
|
||||
*
|
||||
* \code
|
||||
* #define BOOTLOADER_API_TABLE_SIZE 32
|
||||
* #define BOOTLOADER_API_TABLE_START ((FLASHEND + 1UL) - BOOTLOADER_API_TABLE_SIZE)
|
||||
* #define BOOTLOADER_API_CALL(Index) (void*)((BOOTLOADER_API_TABLE_START + (Index * 2)) / 2)
|
||||
*
|
||||
* void (*BootloaderAPI_ErasePage)(uint32_t Address) = BOOTLOADER_API_CALL(0);
|
||||
* void (*BootloaderAPI_WritePage)(uint32_t Address) = BOOTLOADER_API_CALL(1);
|
||||
* void (*BootloaderAPI_FillWord)(uint32_t Address, uint16_t Word) = BOOTLOADER_API_CALL(2);
|
||||
* uint8_t (*BootloaderAPI_ReadSignature)(uint16_t Address) = BOOTLOADER_API_CALL(3);
|
||||
* uint8_t (*BootloaderAPI_ReadFuse)(uint16_t Address) = BOOTLOADER_API_CALL(4);
|
||||
* uint8_t (*BootloaderAPI_ReadLock)(void) = BOOTLOADER_API_CALL(5);
|
||||
* void (*BootloaderAPI_WriteLock)(uint8_t LockBits) = BOOTLOADER_API_CALL(6);
|
||||
*
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 2))
|
||||
* #define BOOTLOADER_MAGIC_SIGNATURE 0xDCFB
|
||||
*
|
||||
* #define BOOTLOADER_CLASS_SIGNATURE_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 4))
|
||||
* #define BOOTLOADER_PRINTER_SIGNATURE 0xDF20
|
||||
*
|
||||
* #define BOOTLOADER_ADDRESS_START (BOOTLOADER_API_TABLE_START + (BOOTLOADER_API_TABLE_SIZE - 8))
|
||||
* #define BOOTLOADER_ADDRESS_LENGTH 4
|
||||
* \endcode
|
||||
*
|
||||
* From the application the API support of the bootloader can be detected by reading the FLASH memory bytes located at address
|
||||
* \c BOOTLOADER_MAGIC_SIGNATURE_START and comparing them to the value \c BOOTLOADER_MAGIC_SIGNATURE. The class of bootloader
|
||||
* can be determined by reading the FLASH memory bytes located at address \c BOOTLOADER_CLASS_SIGNATURE_START and comparing them
|
||||
* to the value \c BOOTLOADER_PRINTER_SIGNATURE. The start address of the bootloader can be retrieved by reading the bytes of FLASH
|
||||
* memory starting from address \c BOOTLOADER_ADDRESS_START.
|
||||
*
|
||||
* \subsection SSec_API_MemLayout Device Memory Map
|
||||
* The following illustration indicates the final memory map of the device when loaded with the bootloader.
|
||||
*
|
||||
* \verbatim
|
||||
* +----------------------------+ 0x0000
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | User Application |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - BOOT_SECTION_SIZE
|
||||
* | |
|
||||
* | Bootloader Application |
|
||||
* | (Not User App. Accessible) |
|
||||
* | |
|
||||
* +----------------------------+ FLASHEND - 96
|
||||
* | API Table Trampolines |
|
||||
* | (Not User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 32
|
||||
* | Bootloader API Table |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND - 8
|
||||
* | Bootloader ID Constants |
|
||||
* | (User App. Accessible) |
|
||||
* +----------------------------+ FLASHEND
|
||||
* \endverbatim
|
||||
*
|
||||
*
|
||||
* \section Sec_KnownIssues Known Issues:
|
||||
*
|
||||
* \par On Linux machines, new firmware fails to be sent to the device via CUPS.
|
||||
* Only a limited subset of normal printer functionality is exposed via the
|
||||
* bootloader, causing CUPS to reject print requests from applications that
|
||||
* are unable to handle true plain-text printing. For best results, the low
|
||||
* level \c lpr command should be used to print new firmware to the bootloader.
|
||||
*
|
||||
* \par After loading an application, it is not run automatically on startup.
|
||||
* Some USB AVR boards ship with the BOOTRST fuse set, causing the bootloader
|
||||
* to run automatically when the device is reset. In most cases, the BOOTRST
|
||||
* fuse should be disabled and the HWBE fuse used instead to run the bootloader
|
||||
* when needed.
|
||||
*
|
||||
* \section Sec_Options Project Options
|
||||
*
|
||||
* The following defines can be found in this demo, which can control the demo behaviour when defined, or changed in value.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <td>
|
||||
* None
|
||||
* </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Library Configuration Header File
|
||||
*
|
||||
* This header file is used to configure LUFA's compile time options,
|
||||
* as an alternative to the compile time constants supplied through
|
||||
* a makefile.
|
||||
*
|
||||
* For information on what each token does, refer to the LUFA
|
||||
* manual section "Summary of Compile Tokens".
|
||||
*/
|
||||
|
||||
#ifndef _LUFA_CONFIG_H_
|
||||
#define _LUFA_CONFIG_H_
|
||||
|
||||
#if (ARCH == ARCH_AVR8)
|
||||
|
||||
/* Non-USB Related Configuration Tokens: */
|
||||
// #define DISABLE_TERMINAL_CODES
|
||||
|
||||
/* USB Class Driver Related Tokens: */
|
||||
// #define HID_HOST_BOOT_PROTOCOL_ONLY
|
||||
// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
|
||||
// #define HID_MAX_COLLECTIONS {Insert Value Here}
|
||||
// #define HID_MAX_REPORTITEMS {Insert Value Here}
|
||||
// #define HID_MAX_REPORT_IDS {Insert Value Here}
|
||||
// #define NO_CLASS_DRIVER_AUTOFLUSH
|
||||
|
||||
/* General USB Driver Related Tokens: */
|
||||
#define ORDERED_EP_CONFIG
|
||||
#define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL)
|
||||
#define USB_DEVICE_ONLY
|
||||
// #define USB_HOST_ONLY
|
||||
// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
|
||||
// #define NO_LIMITED_CONTROLLER_CONNECT
|
||||
#define NO_SOF_EVENTS
|
||||
|
||||
/* USB Device Mode Driver Related Tokens: */
|
||||
#define USE_RAM_DESCRIPTORS
|
||||
// #define USE_FLASH_DESCRIPTORS
|
||||
// #define USE_EEPROM_DESCRIPTORS
|
||||
#define NO_INTERNAL_SERIAL
|
||||
#define FIXED_CONTROL_ENDPOINT_SIZE 8
|
||||
#define DEVICE_STATE_AS_GPIOR 0
|
||||
#define FIXED_NUM_CONFIGURATIONS 1
|
||||
// #define CONTROL_ONLY_DEVICE
|
||||
// #define INTERRUPT_CONTROL_ENDPOINT
|
||||
#define NO_DEVICE_REMOTE_WAKEUP
|
||||
#define NO_DEVICE_SELF_POWER
|
||||
|
||||
/* USB Host Mode Driver Related Tokens: */
|
||||
// #define HOST_STATE_AS_GPIOR {Insert Value Here}
|
||||
// #define USB_HOST_TIMEOUT_MS {Insert Value Here}
|
||||
// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here}
|
||||
// #define NO_AUTO_VBUS_MANAGEMENT
|
||||
// #define INVERTED_VBUS_ENABLE_LINE
|
||||
|
||||
#else
|
||||
|
||||
#error Unsupported architecture for this LUFA configuration file.
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* USB Device Descriptors, for library use when in USB device mode. Descriptors are special
|
||||
* computer-readable structures which the host requests upon device enumeration, to determine
|
||||
* the device's capabilities and functions.
|
||||
*/
|
||||
|
||||
#include "Descriptors.h"
|
||||
|
||||
|
||||
/** Device descriptor structure. This descriptor, located in SRAM memory, describes the overall
|
||||
* device characteristics, including the supported USB version, control endpoint size and the
|
||||
* number of device configurations. The descriptor is read out by the USB host when the enumeration
|
||||
* process begins.
|
||||
*/
|
||||
const USB_Descriptor_Device_t DeviceDescriptor =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
|
||||
|
||||
.USBSpecification = VERSION_BCD(1,1,0),
|
||||
.Class = USB_CSCP_NoDeviceClass,
|
||||
.SubClass = USB_CSCP_NoDeviceSubclass,
|
||||
.Protocol = USB_CSCP_NoDeviceProtocol,
|
||||
|
||||
.Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
|
||||
|
||||
.VendorID = 0x03EB,
|
||||
.ProductID = 0x206B,
|
||||
.ReleaseNumber = VERSION_BCD(0,0,1),
|
||||
|
||||
.ManufacturerStrIndex = STRING_ID_Manufacturer,
|
||||
.ProductStrIndex = STRING_ID_Product,
|
||||
.SerialNumStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
|
||||
};
|
||||
|
||||
/** Configuration descriptor structure. This descriptor, located in SRAM memory, describes the usage
|
||||
* of the device in one of its supported configurations, including information about any device interfaces
|
||||
* and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
|
||||
* a configuration so that the host may correctly communicate with the USB device.
|
||||
*/
|
||||
const USB_Descriptor_Configuration_t ConfigurationDescriptor =
|
||||
{
|
||||
.Config =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
|
||||
|
||||
.TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
|
||||
.TotalInterfaces = 1,
|
||||
|
||||
.ConfigurationNumber = 1,
|
||||
.ConfigurationStrIndex = NO_DESCRIPTOR,
|
||||
|
||||
.ConfigAttributes = USB_CONFIG_ATTR_RESERVED,
|
||||
|
||||
.MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
|
||||
},
|
||||
|
||||
.Printer_Interface =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
|
||||
|
||||
.InterfaceNumber = INTERFACE_ID_Printer,
|
||||
.AlternateSetting = 0,
|
||||
|
||||
.TotalEndpoints = 2,
|
||||
|
||||
.Class = PRNT_CSCP_PrinterClass,
|
||||
.SubClass = PRNT_CSCP_PrinterSubclass,
|
||||
.Protocol = PRNT_CSCP_BidirectionalProtocol,
|
||||
|
||||
.InterfaceStrIndex = NO_DESCRIPTOR
|
||||
},
|
||||
|
||||
.Printer_DataInEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = PRINTER_IN_EPADDR,
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = PRINTER_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x05
|
||||
},
|
||||
|
||||
.Printer_DataOutEndpoint =
|
||||
{
|
||||
.Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
|
||||
|
||||
.EndpointAddress = PRINTER_OUT_EPADDR,
|
||||
.Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
|
||||
.EndpointSize = PRINTER_IO_EPSIZE,
|
||||
.PollingIntervalMS = 0x05
|
||||
}
|
||||
};
|
||||
|
||||
/** Language descriptor structure. This descriptor, located in SRAM memory, is returned when the host requests
|
||||
* the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
|
||||
* via the language ID table available at USB.org what languages the device supports for its string descriptors.
|
||||
*/
|
||||
const USB_Descriptor_String_t LanguageString = USB_STRING_DESCRIPTOR_ARRAY(LANGUAGE_ID_ENG);
|
||||
|
||||
/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
|
||||
* form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
||||
* Descriptor.
|
||||
*/
|
||||
const USB_Descriptor_String_t ManufacturerString = USB_STRING_DESCRIPTOR(L"Dean Camera");
|
||||
|
||||
/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
|
||||
* and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
|
||||
* Descriptor.
|
||||
*/
|
||||
const USB_Descriptor_String_t ProductString = USB_STRING_DESCRIPTOR(L"LUFA Printer Bootloader");
|
||||
|
||||
/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
|
||||
* documentation) by the application code so that the address and size of a requested descriptor can be given
|
||||
* to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
|
||||
* is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
|
||||
* USB host.
|
||||
*/
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
{
|
||||
const uint8_t DescriptorType = (wValue >> 8);
|
||||
const uint8_t DescriptorNumber = (wValue & 0xFF);
|
||||
|
||||
const void* Address = NULL;
|
||||
uint16_t Size = NO_DESCRIPTOR;
|
||||
|
||||
switch (DescriptorType)
|
||||
{
|
||||
case DTYPE_Device:
|
||||
Address = &DeviceDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Device_t);
|
||||
break;
|
||||
case DTYPE_Configuration:
|
||||
Address = &ConfigurationDescriptor;
|
||||
Size = sizeof(USB_Descriptor_Configuration_t);
|
||||
break;
|
||||
case DTYPE_String:
|
||||
switch (DescriptorNumber)
|
||||
{
|
||||
case STRING_ID_Language:
|
||||
Address = &LanguageString;
|
||||
Size = LanguageString.Header.Size;
|
||||
break;
|
||||
case STRING_ID_Manufacturer:
|
||||
Address = &ManufacturerString;
|
||||
Size = ManufacturerString.Header.Size;
|
||||
break;
|
||||
case STRING_ID_Product:
|
||||
Address = &ProductString;
|
||||
Size = ProductString.Header.Size;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
*DescriptorAddress = Address;
|
||||
return Size;
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
*
|
||||
* Header file for Descriptors.c.
|
||||
*/
|
||||
|
||||
#ifndef _DESCRIPTORS_H_
|
||||
#define _DESCRIPTORS_H_
|
||||
|
||||
/* Includes: */
|
||||
#include <LUFA/Drivers/USB/USB.h>
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
/* Macros: */
|
||||
/** Endpoint address of the Printer device-to-host data IN endpoint. */
|
||||
#define PRINTER_IN_EPADDR (ENDPOINT_DIR_IN | 3)
|
||||
|
||||
/** Endpoint address of the Printer host-to-device data OUT endpoint. */
|
||||
#define PRINTER_OUT_EPADDR (ENDPOINT_DIR_OUT | 4)
|
||||
|
||||
/** Size in bytes of the Printer data endpoints. */
|
||||
#define PRINTER_IO_EPSIZE 64
|
||||
|
||||
/* Type Defines: */
|
||||
/** Type define for the device configuration descriptor structure. This must be defined in the
|
||||
* application code, as the configuration descriptor contains several sub-descriptors which
|
||||
* vary between devices, and which describe the device's usage to the host.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
USB_Descriptor_Configuration_Header_t Config;
|
||||
|
||||
// Printer Interface
|
||||
USB_Descriptor_Interface_t Printer_Interface;
|
||||
USB_Descriptor_Endpoint_t Printer_DataInEndpoint;
|
||||
USB_Descriptor_Endpoint_t Printer_DataOutEndpoint;
|
||||
} USB_Descriptor_Configuration_t;
|
||||
|
||||
/** Enum for the device interface descriptor IDs within the device. Each string descriptor
|
||||
* should have a unique ID index associated with it, which can be used to refer to the
|
||||
* interface from other descriptors.
|
||||
*/
|
||||
enum InterfaceDescriptors_t
|
||||
{
|
||||
INTERFACE_ID_Printer = 0, /**< Printer interface descriptor ID */
|
||||
};
|
||||
|
||||
/** Enum for the device string descriptor IDs within the device. Each string descriptor should
|
||||
* have a unique ID index associated with it, which can be used to refer to the string from
|
||||
* other descriptors.
|
||||
*/
|
||||
enum StringDescriptors_t
|
||||
{
|
||||
STRING_ID_Language = 0, /**< Supported Languages string descriptor ID (must be zero) */
|
||||
STRING_ID_Manufacturer = 1, /**< Manufacturer string ID */
|
||||
STRING_ID_Product = 2, /**< Product string ID */
|
||||
};
|
||||
|
||||
/* Function Prototypes: */
|
||||
uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
|
||||
const uint8_t wIndex,
|
||||
const void** const DescriptorAddress)
|
||||
ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
|
||||
|
||||
#endif
|
||||
|
159
tmk_core/protocol/lufa/LUFA-git/Bootloaders/Printer/asf.xml
Normal file
159
tmk_core/protocol/lufa/LUFA-git/Bootloaders/Printer/asf.xml
Normal file
|
@ -0,0 +1,159 @@
|
|||
<asf xmlversion="1.0">
|
||||
<project caption="Printer Bootloader - 128KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.128_4" force-caption="true" workspace-name="lufa_printer_128kb_4kb_">
|
||||
<require idref="lufa.bootloaders.printer"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb1287"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1F000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1F000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Printer Bootloader - 64KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.64_4" force-caption="true" workspace-name="lufa_printer_64kb_4kb_">
|
||||
<require idref="lufa.bootloaders.printer"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="at90usb647"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0xF000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0xF000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0xFFA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0xFFE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0xFFF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Printer Bootloader - 32KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.32_4" force-caption="true" workspace-name="lufa_printer_32kb_4kb_">
|
||||
<require idref="lufa.bootloaders.printer"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega32u4"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x7000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x7000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x7FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x7FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x7FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Printer Bootloader - 16KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.16_4" force-caption="true" workspace-name="lufa_printer_16kb_4kb_">
|
||||
<require idref="lufa.bootloaders.printer"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega16u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x3000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x3000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x3FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x3FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x3FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<project caption="Printer Bootloader - 8KB FLASH / 4KB Boot - AVR8 Architecture" id="lufa.bootloaders.printer.avr8.8_4" force-caption="true" workspace-name="lufa_printer_8kb_4kb_">
|
||||
<require idref="lufa.bootloaders.printer"/>
|
||||
<require idref="lufa.boards.dummy.avr8"/>
|
||||
<generator value="as5_8"/>
|
||||
|
||||
<device-support value="atmega8u2"/>
|
||||
<config name="lufa.drivers.board.name" value="none"/>
|
||||
|
||||
<config name="config.compiler.optimization.level" value="size"/>
|
||||
|
||||
<build type="define" name="F_CPU" value="16000000UL"/>
|
||||
<build type="define" name="F_USB" value="16000000UL"/>
|
||||
|
||||
<build type="define" name="BOOT_START_ADDR" value="0x1000"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.text=0x1000"/>
|
||||
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_trampolines=0x1FA0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Trampolines"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_jumptable=0x1FE0"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_JumpTable"/>
|
||||
<build type="linker-config" subtype="flags" value="--section-start=.apitable_signatures=0x1FF8"/>
|
||||
<build type="linker-config" subtype="flags" value="--undefined=BootloaderAPI_Signatures"/>
|
||||
</project>
|
||||
|
||||
<module type="application" id="lufa.bootloaders.printer" caption="Printer Bootloader">
|
||||
<info type="description" value="summary">
|
||||
Printer Class Bootloader, capable of reprogramming a device by "printing" new HEX files to the virtual Plain-Text printer it creates when plugged into a host.
|
||||
</info>
|
||||
|
||||
<info type="gui-flag" value="move-to-root"/>
|
||||
|
||||
<info type="keyword" value="Technology">
|
||||
<keyword value="Bootloaders"/>
|
||||
<keyword value="USB Device"/>
|
||||
</info>
|
||||
|
||||
<device-support-alias value="lufa_avr8"/>
|
||||
<device-support-alias value="lufa_xmega"/>
|
||||
<device-support-alias value="lufa_uc3"/>
|
||||
|
||||
<build type="include-path" value="."/>
|
||||
<build type="c-source" value="BootloaderPrinter.c"/>
|
||||
<build type="header-file" value="BootloaderPrinter.h"/>
|
||||
<build type="c-source" value="Descriptors.c"/>
|
||||
<build type="header-file" value="Descriptors.h"/>
|
||||
<build type="c-source" value="BootloaderAPI.c"/>
|
||||
<build type="header-file" value="BootloaderAPI.h"/>
|
||||
<build type="asm-source" value="BootloaderAPITable.S"/>
|
||||
|
||||
<build type="module-config" subtype="path" value="Config"/>
|
||||
<build type="header-file" value="Config/LUFAConfig.h"/>
|
||||
|
||||
<build type="distribute" subtype="user-file" value="doxyfile"/>
|
||||
<build type="distribute" subtype="user-file" value="BootloaderPrinter.txt"/>
|
||||
|
||||
<require idref="lufa.common"/>
|
||||
<require idref="lufa.platform"/>
|
||||
<require idref="lufa.drivers.usb"/>
|
||||
<require idref="lufa.drivers.board"/>
|
||||
<require idref="lufa.drivers.board.leds"/>
|
||||
</module>
|
||||
</asf>
|
2365
tmk_core/protocol/lufa/LUFA-git/Bootloaders/Printer/doxyfile
Normal file
2365
tmk_core/protocol/lufa/LUFA-git/Bootloaders/Printer/doxyfile
Normal file
File diff suppressed because it is too large
Load diff
55
tmk_core/protocol/lufa/LUFA-git/Bootloaders/Printer/makefile
Normal file
55
tmk_core/protocol/lufa/LUFA-git/Bootloaders/Printer/makefile
Normal file
|
@ -0,0 +1,55 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.lufa-lib.org
|
||||
#
|
||||
# --------------------------------------
|
||||
# LUFA Project Makefile.
|
||||
# --------------------------------------
|
||||
|
||||
# Run "make help" for target help.
|
||||
|
||||
MCU = at90usb1287
|
||||
ARCH = AVR8
|
||||
BOARD = USBKEY
|
||||
F_CPU = 8000000
|
||||
F_USB = $(F_CPU)
|
||||
OPTIMIZATION = s
|
||||
TARGET = BootloaderPrinter
|
||||
SRC = $(TARGET).c Descriptors.c BootloaderAPI.c BootloaderAPITable.S $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
|
||||
LUFA_PATH = ../../LUFA
|
||||
CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -IConfig/ -DBOOT_START_ADDR=$(BOOT_START_OFFSET)
|
||||
LD_FLAGS = -Wl,--section-start=.text=$(BOOT_START_OFFSET) $(BOOT_API_LD_FLAGS)
|
||||
|
||||
# Flash size and bootloader section sizes of the target, in KB. These must
|
||||
# match the target's total FLASH size and the bootloader size set in the
|
||||
# device's fuses.
|
||||
FLASH_SIZE_KB = 128
|
||||
BOOT_SECTION_SIZE_KB = 8
|
||||
|
||||
# Bootloader address calculation formulas
|
||||
# Do not modify these macros, but rather modify the dependent values above.
|
||||
CALC_ADDRESS_IN_HEX = $(shell printf "0x%X" $$(( $(1) )) )
|
||||
BOOT_START_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) - $(BOOT_SECTION_SIZE_KB)) * 1024 )
|
||||
BOOT_SEC_OFFSET = $(call CALC_ADDRESS_IN_HEX, ($(FLASH_SIZE_KB) * 1024) - ($(strip $(1))) )
|
||||
|
||||
# Bootloader linker section flags for relocating the API table sections to
|
||||
# known FLASH addresses - these should not normally be user-edited.
|
||||
BOOT_SECTION_LD_FLAG = -Wl,--section-start=$(strip $(1))=$(call BOOT_SEC_OFFSET, $(3)) -Wl,--undefined=$(strip $(2))
|
||||
BOOT_API_LD_FLAGS = $(call BOOT_SECTION_LD_FLAG, .apitable_trampolines, BootloaderAPI_Trampolines, 96)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_jumptable, BootloaderAPI_JumpTable, 32)
|
||||
BOOT_API_LD_FLAGS += $(call BOOT_SECTION_LD_FLAG, .apitable_signatures, BootloaderAPI_Signatures, 8)
|
||||
|
||||
# Default target
|
||||
all:
|
||||
|
||||
# Include LUFA build script makefiles
|
||||
include $(LUFA_PATH)/Build/lufa_core.mk
|
||||
include $(LUFA_PATH)/Build/lufa_sources.mk
|
||||
include $(LUFA_PATH)/Build/lufa_build.mk
|
||||
include $(LUFA_PATH)/Build/lufa_cppcheck.mk
|
||||
include $(LUFA_PATH)/Build/lufa_doxygen.mk
|
||||
include $(LUFA_PATH)/Build/lufa_avrdude.mk
|
||||
include $(LUFA_PATH)/Build/lufa_atprogram.mk
|
46
tmk_core/protocol/lufa/LUFA-git/Bootloaders/makefile
Normal file
46
tmk_core/protocol/lufa/LUFA-git/Bootloaders/makefile
Normal file
|
@ -0,0 +1,46 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.lufa-lib.org
|
||||
#
|
||||
|
||||
# Makefile to build all the LUFA USB Bootloaders. Call with "make all" to
|
||||
# rebuild all bootloaders.
|
||||
|
||||
# Bootloaders are pre-cleaned before each one is built, to ensure any
|
||||
# custom LUFA library build options are reflected in the compiled
|
||||
# code.
|
||||
|
||||
PROJECT_DIRECTORIES := $(shell ls -d */)
|
||||
|
||||
# This makefile is potentially infinitely recursive if something really bad
|
||||
# happens when determining the set of project directories - hard-abort if
|
||||
# more than 10 levels deep to avoid angry emails.
|
||||
ifeq ($(MAKELEVEL), 10)
|
||||
$(error EMERGENCY ABORT: INFINITE RECURSION DETECTED)
|
||||
endif
|
||||
|
||||
# Need to special-case building without a per-project object directory
|
||||
ifeq ($(OBJDIR),)
|
||||
# If no target specified, force "clean all" and disallow parallel build
|
||||
ifeq ($(MAKECMDGOALS),)
|
||||
MAKECMDGOALS := clean all
|
||||
.NOTPARALLEL:
|
||||
endif
|
||||
|
||||
# If one of the targets is to build, force "clean" beforehand and disallow parallel build
|
||||
ifneq ($(findstring all, $(MAKECMDGOALS)),)
|
||||
MAKECMDGOALS := clean $(MAKECMDGOALS)
|
||||
.NOTPARALLEL:
|
||||
endif
|
||||
endif
|
||||
|
||||
%: $(PROJECT_DIRECTORIES)
|
||||
@echo . > /dev/null
|
||||
|
||||
$(PROJECT_DIRECTORIES):
|
||||
@$(MAKE) -C $@ $(MAKECMDGOALS)
|
||||
|
||||
.PHONY: $(PROJECT_DIRECTORIES)
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Custom Board Hardware Information Driver (Template)
|
||||
*
|
||||
* This is a stub driver header file, for implementing custom board
|
||||
* layout hardware with compatible LUFA board specific drivers. If
|
||||
* the library is configured to use the BOARD_USER board mode, this
|
||||
* driver file should be completed and copied into the "/Board/" folder
|
||||
* inside the application's folder.
|
||||
*
|
||||
* This stub is for the board-specific component of the LUFA Board Hardware
|
||||
* information driver.
|
||||
*/
|
||||
|
||||
#ifndef __BOARD_USER_H__
|
||||
#define __BOARD_USER_H__
|
||||
|
||||
/* Includes: */
|
||||
// TODO: Add any required includes here
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_BOARD_H)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Board/Board.h instead.
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Indicates the board has a hardware Buttons mounted if defined. */
|
||||
// #define BOARD_HAS_BUTTONS
|
||||
|
||||
/** Indicates the board has a hardware Dataflash mounted if defined. */
|
||||
// #define BOARD_HAS_DATAFLASH
|
||||
|
||||
/** Indicates the board has a hardware Joystick mounted if defined. */
|
||||
// #define BOARD_HAS_JOYSTICK
|
||||
|
||||
/** Indicates the board has a hardware LEDs mounted if defined. */
|
||||
// #define BOARD_HAS_LEDS
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Custom Board Button Hardware Driver (Template)
|
||||
*
|
||||
* This is a stub driver header file, for implementing custom board
|
||||
* layout hardware with compatible LUFA board specific drivers. If
|
||||
* the library is configured to use the BOARD_USER board mode, this
|
||||
* driver file should be completed and copied into the "/Board/" folder
|
||||
* inside the application's folder.
|
||||
*
|
||||
* This stub is for the board-specific component of the LUFA Buttons driver,
|
||||
* for the control of physical board-mounted GPIO pushbuttons.
|
||||
*/
|
||||
|
||||
#ifndef __BUTTONS_USER_H__
|
||||
#define __BUTTONS_USER_H__
|
||||
|
||||
/* Includes: */
|
||||
// TODO: Add any required includes here
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_BUTTONS_H)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Board/Buttons.h instead.
|
||||
#endif
|
||||
|
||||
#define BOARD_DUMMY_BUTTONS_IMPLEMENTATION
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Button mask for the first button on the board. */
|
||||
#define BUTTONS_BUTTON1 (1 << 0)
|
||||
|
||||
/* Inline Functions: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
static inline void Buttons_Init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void Buttons_Disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline uint8_t Buttons_GetStatus(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t Buttons_GetStatus(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Custom Board Dataflash Hardware Driver (Template)
|
||||
*
|
||||
* This is a stub driver header file, for implementing custom board
|
||||
* layout hardware with compatible LUFA board specific drivers. If
|
||||
* the library is configured to use the BOARD_USER board mode, this
|
||||
* driver file should be completed and copied into the "/Board/" folder
|
||||
* inside the application's folder.
|
||||
*
|
||||
* This stub is for the board-specific component of the LUFA Dataflash
|
||||
* driver.
|
||||
*/
|
||||
|
||||
#ifndef __DATAFLASH_USER_H__
|
||||
#define __DATAFLASH_USER_H__
|
||||
|
||||
/* Includes: */
|
||||
// TODO: Add any required includes here
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_DATAFLASH_H)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Board/Dataflash.h instead.
|
||||
#endif
|
||||
|
||||
#define BOARD_DUMMY_DATAFLASH_IMPLEMENTATION
|
||||
|
||||
/* Private Interface - For use in library only: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
/* Macros: */
|
||||
#define DATAFLASH_CHIPCS_MASK 0
|
||||
#define DATAFLASH_CHIPCS_DDR 0
|
||||
#define DATAFLASH_CHIPCS_PORT 0
|
||||
#endif
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Constant indicating the total number of dataflash ICs mounted on the selected board. */
|
||||
#define DATAFLASH_TOTALCHIPS 1
|
||||
|
||||
/** Mask for no dataflash chip selected. */
|
||||
#define DATAFLASH_NO_CHIP 0
|
||||
|
||||
/** Mask for the first dataflash chip selected. */
|
||||
#define DATAFLASH_CHIP1 0
|
||||
|
||||
/** Mask for the second dataflash chip selected. */
|
||||
#define DATAFLASH_CHIP2 0
|
||||
|
||||
/** Internal main memory page size for the board's dataflash ICs. */
|
||||
#define DATAFLASH_PAGE_SIZE 0
|
||||
|
||||
/** Total number of pages inside each of the board's dataflash ICs. */
|
||||
#define DATAFLASH_PAGES 0
|
||||
|
||||
/* Inline Functions: */
|
||||
/** Initializes the dataflash driver so that commands and data may be sent to an attached dataflash IC.
|
||||
* The microcontroller's SPI driver MUST be initialized before any of the dataflash commands are used.
|
||||
*/
|
||||
static inline void Dataflash_Init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Sends a byte to the currently selected dataflash IC, and returns a byte from the dataflash.
|
||||
*
|
||||
* \param[in] Byte Byte of data to send to the dataflash
|
||||
*
|
||||
* \return Last response byte from the dataflash
|
||||
*/
|
||||
static inline uint8_t Dataflash_TransferByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
|
||||
static inline uint8_t Dataflash_TransferByte(const uint8_t Byte)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Sends a byte to the currently selected dataflash IC, and ignores the next byte from the dataflash.
|
||||
*
|
||||
* \param[in] Byte Byte of data to send to the dataflash
|
||||
*/
|
||||
static inline void Dataflash_SendByte(const uint8_t Byte) ATTR_ALWAYS_INLINE;
|
||||
static inline void Dataflash_SendByte(const uint8_t Byte)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Sends a dummy byte to the currently selected dataflash IC, and returns the next byte from the dataflash.
|
||||
*
|
||||
* \return Last response byte from the dataflash
|
||||
*/
|
||||
static inline uint8_t Dataflash_ReceiveByte(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t Dataflash_ReceiveByte(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Determines the currently selected dataflash chip.
|
||||
*
|
||||
* \return Mask of the currently selected Dataflash chip, either \ref DATAFLASH_NO_CHIP if no chip is selected
|
||||
* or a DATAFLASH_CHIPn mask (where n is the chip number).
|
||||
*/
|
||||
static inline uint8_t Dataflash_GetSelectedChip(void) ATTR_ALWAYS_INLINE ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t Dataflash_GetSelectedChip(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Selects the given dataflash chip.
|
||||
*
|
||||
* \param[in] ChipMask Mask of the Dataflash IC to select, in the form of a \c DATAFLASH_CHIPn mask (where n is
|
||||
* the chip number).
|
||||
*/
|
||||
static inline void Dataflash_SelectChip(const uint8_t ChipMask) ATTR_ALWAYS_INLINE;
|
||||
static inline void Dataflash_SelectChip(const uint8_t ChipMask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Deselects the current dataflash chip, so that no dataflash is selected. */
|
||||
static inline void Dataflash_DeselectChip(void) ATTR_ALWAYS_INLINE;
|
||||
static inline void Dataflash_DeselectChip(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Selects a dataflash IC from the given page number, which should range from 0 to
|
||||
* ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1). For boards containing only one
|
||||
* dataflash IC, this will select DATAFLASH_CHIP1. If the given page number is outside
|
||||
* the total number of pages contained in the boards dataflash ICs, all dataflash ICs
|
||||
* are deselected.
|
||||
*
|
||||
* \param[in] PageAddress Address of the page to manipulate, ranging from
|
||||
* 0 to ((DATAFLASH_PAGES * DATAFLASH_TOTALCHIPS) - 1).
|
||||
*/
|
||||
static inline void Dataflash_SelectChipFromPage(const uint16_t PageAddress)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Toggles the select line of the currently selected dataflash IC, so that it is ready to receive
|
||||
* a new command.
|
||||
*/
|
||||
static inline void Dataflash_ToggleSelectedChipCS(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Spin-loops while the currently selected dataflash is busy executing a command, such as a main
|
||||
* memory page program or main memory to buffer transfer.
|
||||
*/
|
||||
static inline void Dataflash_WaitWhileBusy(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/** Sends a set of page and buffer address bytes to the currently selected dataflash IC, for use with
|
||||
* dataflash commands which require a complete 24-bit address.
|
||||
*
|
||||
* \param[in] PageAddress Page address within the selected dataflash IC
|
||||
* \param[in] BufferByte Address within the dataflash's buffer
|
||||
*/
|
||||
static inline void Dataflash_SendAddressBytes(uint16_t PageAddress, const uint16_t BufferByte)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Custom Board Joystick Hardware Driver (Template)
|
||||
*
|
||||
* This is a stub driver header file, for implementing custom board
|
||||
* layout hardware with compatible LUFA board specific drivers. If
|
||||
* the library is configured to use the BOARD_USER board mode, this
|
||||
* driver file should be completed and copied into the "/Board/" folder
|
||||
* inside the application's folder.
|
||||
*
|
||||
* This stub is for the board-specific component of the LUFA Joystick
|
||||
* driver, for a digital four-way (plus button) joystick.
|
||||
*/
|
||||
|
||||
#ifndef __JOYSTICK_USER_H__
|
||||
#define __JOYSTICK_USER_H__
|
||||
|
||||
/* Includes: */
|
||||
// TODO: Add any required includes here
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_JOYSTICK_H)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Board/Joystick.h instead.
|
||||
#endif
|
||||
|
||||
#define BOARD_DUMMY_JOYSTICK_IMPLEMENTATION
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** Mask for the joystick being pushed in the left direction. */
|
||||
#define JOY_LEFT 0
|
||||
|
||||
/** Mask for the joystick being pushed in the right direction. */
|
||||
#define JOY_RIGHT 0
|
||||
|
||||
/** Mask for the joystick being pushed in the upward direction. */
|
||||
#define JOY_UP 0
|
||||
|
||||
/** Mask for the joystick being pushed in the downward direction. */
|
||||
#define JOY_DOWN 0
|
||||
|
||||
/** Mask for the joystick being pushed inward. */
|
||||
#define JOY_PRESS 0
|
||||
|
||||
/* Inline Functions: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
static inline void Joystick_Init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void Joystick_Disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline uint8_t Joystick_GetStatus(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t Joystick_GetStatus(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
/** \file
|
||||
* \brief LUFA Custom Board LED Hardware Driver (Template)
|
||||
*
|
||||
* This is a stub driver header file, for implementing custom board
|
||||
* layout hardware with compatible LUFA board specific drivers. If
|
||||
* the library is configured to use the BOARD_USER board mode, this
|
||||
* driver file should be completed and copied into the "/Board/" folder
|
||||
* inside the application's folder.
|
||||
*
|
||||
* This stub is for the board-specific component of the LUFA LEDs driver,
|
||||
* for the LEDs (up to four) mounted on most development boards.
|
||||
*/
|
||||
|
||||
#ifndef __LEDS_USER_H__
|
||||
#define __LEDS_USER_H__
|
||||
|
||||
/* Includes: */
|
||||
// TODO: Add any required includes here
|
||||
|
||||
/* Enable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Preprocessor Checks: */
|
||||
#if !defined(__INCLUDE_FROM_LEDS_H)
|
||||
#error Do not include this file directly. Include LUFA/Drivers/Board/LEDS.h instead.
|
||||
#endif
|
||||
|
||||
#define BOARD_DUMMY_LEDS_IMPLEMENTATION
|
||||
|
||||
/* Public Interface - May be used in end-application: */
|
||||
/* Macros: */
|
||||
/** LED mask for the first LED on the board. */
|
||||
#define LEDS_LED1 (1 << 0)
|
||||
|
||||
/** LED mask for the second LED on the board. */
|
||||
#define LEDS_LED2 (1 << 1)
|
||||
|
||||
/** LED mask for the third LED on the board. */
|
||||
#define LEDS_LED3 (1 << 2)
|
||||
|
||||
/** LED mask for the fourth LED on the board. */
|
||||
#define LEDS_LED4 (1 << 3)
|
||||
|
||||
/** LED mask for all the LEDs on the board. */
|
||||
#define LEDS_ALL_LEDS (LEDS_LED1 | LEDS_LED2 | LEDS_LED3 | LEDS_LED4)
|
||||
|
||||
/** LED mask for none of the board LEDs. */
|
||||
#define LEDS_NO_LEDS 0
|
||||
|
||||
/* Inline Functions: */
|
||||
#if !defined(__DOXYGEN__)
|
||||
static inline void LEDs_Init(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void LEDs_Disable(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void LEDs_TurnOnLEDs(const uint8_t LEDMask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void LEDs_TurnOffLEDs(const uint8_t LEDMask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void LEDs_SetAllLEDs(const uint8_t LEDMask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void LEDs_ChangeLEDs(const uint8_t LEDMask, const uint8_t ActiveMask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline void LEDs_ToggleLEDs(const uint8_t LEDMask)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static inline uint8_t LEDs_GetLEDs(void) ATTR_WARN_UNUSED_RESULT;
|
||||
static inline uint8_t LEDs_GetLEDs(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Disable C linkage for C++ Compilers: */
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.lufa-lib.org
|
||||
#
|
||||
#
|
||||
# =============================================================================
|
||||
# Board configuration map script, processed with the "BoardDriverTest"
|
||||
# makefile. This script file maps the possible LUFA target BOARD makefile
|
||||
# values in user projects to a specific architecture and device. This mapping is
|
||||
# then used by the makefile to build all possible drivers for that board, to
|
||||
# detect any missing or erroneous functions. To add a new board mapping, use
|
||||
# the syntax:
|
||||
#
|
||||
# BOARD DEFINE = {ARCH} : {MCU} :
|
||||
#
|
||||
# And re-run the makefile. Note that each board may have only one target.
|
||||
# =============================================================================
|
||||
#
|
||||
#
|
||||
# ----------------- AVR8 Boards ------------------
|
||||
BOARD_ADAFRUITU4 = AVR8 : atmega32u4 :
|
||||
BOARD_ATAVRUSBRF01 = AVR8 : at90usb1287 :
|
||||
BOARD_BENITO = AVR8 : at90usb162 :
|
||||
BOARD_BIGMULTIO = AVR8 : atmega32u4 :
|
||||
BOARD_BLACKCAT = AVR8 : at90usb162 :
|
||||
BOARD_BUI = AVR8 : at90usb646 :
|
||||
BOARD_BUMBLEB = AVR8 : at90usb162 :
|
||||
BOARD_CULV3 = AVR8 : atmega32u4 :
|
||||
BOARD_DUCE = AVR8 : atmega32u2 :
|
||||
BOARD_EVK527 = AVR8 : atmega32u4 :
|
||||
BOARD_JMDBU2 = AVR8 : atmega32u2 :
|
||||
BOARD_LEONARDO = AVR8 : atmega32u4 :
|
||||
BOARD_MAXIMUS = AVR8 : at90usb162 :
|
||||
BOARD_MICROPENDOUS_32U2 = AVR8 : atmega32u2 :
|
||||
BOARD_MICROPENDOUS_A = AVR8 : at90usb1287 :
|
||||
BOARD_MICROPENDOUS_1 = AVR8 : at90usb162 :
|
||||
BOARD_MICROPENDOUS_2 = AVR8 : atmega32u4 :
|
||||
BOARD_MICROPENDOUS_3 = AVR8 : at90usb1287 :
|
||||
BOARD_MICROPENDOUS_4 = AVR8 : at90usb1287 :
|
||||
BOARD_MICROPENDOUS_DIP = AVR8 : at90usb1287 :
|
||||
BOARD_MICROPENDOUS_REV1 = AVR8 : at90usb1287 :
|
||||
BOARD_MICROPENDOUS_REV2 = AVR8 : at90usb1287 :
|
||||
BOARD_MICROSIN162 = AVR8 : atmega162 :
|
||||
BOARD_MINIMUS = AVR8 : atmega32u2 :
|
||||
BOARD_MULTIO = AVR8 : at90usb162 :
|
||||
BOARD_NONE = AVR8 : at90usb1287 :
|
||||
BOARD_OLIMEX162 = AVR8 : at90usb162 :
|
||||
BOARD_OLIMEX32U4 = AVR8 : atmega32u4 :
|
||||
BOARD_OLIMEXT32U4 = AVR8 : atmega32u4 :
|
||||
BOARD_OLIMEXISPMK2 = AVR8 : at90usb162 :
|
||||
BOARD_RZUSBSTICK = AVR8 : at90usb1287 :
|
||||
BOARD_SPARKFUN8U2 = AVR8 : atmega8u2 :
|
||||
BOARD_STK525 = AVR8 : at90usb647 :
|
||||
BOARD_STK526 = AVR8 : at90usb162 :
|
||||
BOARD_TEENSY = AVR8 : at90usb162 :
|
||||
BOARD_TEENSY2 = AVR8 : at90usb646 :
|
||||
BOARD_TUL = AVR8 : atmega32u4 :
|
||||
BOARD_UDIP = AVR8 : atmega32u2 :
|
||||
BOARD_UNO = AVR8 : atmega8u2 :
|
||||
BOARD_USB2AX = AVR8 : atmega32u2 :
|
||||
BOARD_USB2AX_V3 = AVR8 : atmega32u2 :
|
||||
BOARD_USB2AX_V31 = AVR8 : atmega32u2 :
|
||||
BOARD_USBFOO = AVR8 : atmega162 :
|
||||
BOARD_USBKEY = AVR8 : at90usb1287 :
|
||||
BOARD_USBTINYMKII = AVR8 : at90usb162 :
|
||||
BOARD_USER = AVR8 : at90usb1287 :
|
||||
BOARD_XPLAIN = AVR8 : at90usb1287 :
|
||||
BOARD_XPLAIN_REV1 = AVR8 : at90usb1287 :
|
||||
BOARD_STANGE_ISP = AVR8 : at90usb162 :
|
||||
BOARD_U2S = AVR8 : atmega32u2 :
|
||||
BOARD_YUN = AVR8 : atmega32u4 :
|
||||
BOARD_MICRO = AVR8 : atmega32u4 :
|
||||
#
|
||||
# ----------------- XMEGA Boards -----------------
|
||||
BOARD_A3BU_XPLAINED = XMEGA : atxmega256a3bu :
|
||||
BOARD_B1_XPLAINED = XMEGA : atxmega128b1 :
|
||||
BOARD_C3_XPLAINED = XMEGA : atxmega384c3 :
|
||||
#
|
||||
# ------------------ UC3 Boards ------------------
|
||||
BOARD_EVK1100 = UC3 : uc3a0512 :
|
||||
BOARD_EVK1101 = UC3 : uc3b0256 :
|
||||
BOARD_EVK1104 = UC3 : uc3a3256 :
|
||||
BOARD_UC3A3_XPLAINED = UC3 : uc3a3256 :
|
||||
#
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
LUFA Library
|
||||
Copyright (C) Dean Camera, 2014.
|
||||
|
||||
dean [at] fourwalledcubicle [dot] com
|
||||
www.lufa-lib.org
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright 2014 Dean Camera (dean [at] fourwalledcubicle [dot] com)
|
||||
|
||||
Permission to use, copy, modify, distribute, and sell this
|
||||
software and its documentation for any purpose is hereby granted
|
||||
without fee, provided that the above copyright notice appear in
|
||||
all copies and that both that the copyright notice and this
|
||||
permission notice and warranty disclaimer appear in supporting
|
||||
documentation, and that the name of the author not be used in
|
||||
advertising or publicity pertaining to distribution of the
|
||||
software without specific, written prior permission.
|
||||
|
||||
The author disclaims all warranties with regard to this
|
||||
software, including all implied warranties of merchantability
|
||||
and fitness. In no event shall the author be liable for any
|
||||
special, indirect or consequential damages or any damages
|
||||
whatsoever resulting from loss of use, data or profits, whether
|
||||
in an action of contract, negligence or other tortious action,
|
||||
arising out of or in connection with the use or performance of
|
||||
this software.
|
||||
*/
|
||||
|
||||
#include <LUFA/Common/Common.h>
|
||||
#include <LUFA/Drivers/Board/Board.h>
|
||||
#include <LUFA/Drivers/Board/Buttons.h>
|
||||
#include <LUFA/Drivers/Board/Dataflash.h>
|
||||
#include <LUFA/Drivers/Board/LEDs.h>
|
||||
#include <LUFA/Drivers/Board/Joystick.h>
|
||||
|
||||
#if defined(BOARD_HAS_BUTTONS) == defined(BOARD_DUMMY_BUTTONS_IMPLEMENTATION)
|
||||
#error Mismatch between BOARD_HAS_BUTTONS and implementation.
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_HAS_DATAFLASH) == defined(BOARD_DUMMY_DATAFLASH_IMPLEMENTATION)
|
||||
#error Mismatch between BOARD_HAS_DATAFLASH and implementation.
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_HAS_LEDS) == defined(BOARD_DUMMY_LEDS_IMPLEMENTATION)
|
||||
#error Mismatch between BOARD_HAS_LEDS and implementation.
|
||||
#endif
|
||||
|
||||
#if defined(BOARD_HAS_JOYSTICK) == defined(BOARD_DUMMY_JOYSTICK_IMPLEMENTATION)
|
||||
#error Mismatch between BOARD_HAS_JOYSTICK and implementation.
|
||||
#endif
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint_reg_t Dummy;
|
||||
|
||||
/* =============================
|
||||
* Buttons Compile Check
|
||||
* ============================= */
|
||||
// cppcheck-suppress redundantAssignment
|
||||
Dummy = BUTTONS_BUTTON1;
|
||||
Buttons_Init();
|
||||
// cppcheck-suppress redundantAssignment
|
||||
Dummy = Buttons_GetStatus();
|
||||
Buttons_Disable();
|
||||
|
||||
/* =============================
|
||||
* Dataflash Compile Check
|
||||
* ============================= */
|
||||
// cppcheck-suppress redundantAssignment
|
||||
Dummy = DATAFLASH_TOTALCHIPS + DATAFLASH_NO_CHIP + DATAFLASH_CHIP1 + DATAFLASH_PAGE_SIZE + DATAFLASH_PAGES;
|
||||
Dataflash_Init();
|
||||
Dataflash_TransferByte(0);
|
||||
Dataflash_SendByte(0);
|
||||
// cppcheck-suppress redundantAssignment
|
||||
Dummy = Dataflash_ReceiveByte();
|
||||
// cppcheck-suppress redundantAssignment
|
||||
Dummy = Dataflash_GetSelectedChip();
|
||||
Dataflash_SelectChip(DATAFLASH_CHIP1);
|
||||
Dataflash_DeselectChip();
|
||||
Dataflash_SelectChipFromPage(0);
|
||||
Dataflash_ToggleSelectedChipCS();
|
||||
Dataflash_WaitWhileBusy();
|
||||
Dataflash_SendAddressBytes(0, 0);
|
||||
|
||||
/* =============================
|
||||
* LEDs Compile Check
|
||||
* ============================= */
|
||||
// cppcheck-suppress redundantAssignment
|
||||
Dummy = LEDS_LED1 + LEDS_LED2 + LEDS_LED3 + LEDS_LED4;
|
||||
LEDs_Init();
|
||||
LEDs_TurnOnLEDs(LEDS_ALL_LEDS);
|
||||
LEDs_TurnOffLEDs(LEDS_ALL_LEDS);
|
||||
LEDs_SetAllLEDs(LEDS_ALL_LEDS);
|
||||
LEDs_ChangeLEDs(LEDS_ALL_LEDS, LEDS_NO_LEDS);
|
||||
LEDs_ToggleLEDs(LEDS_ALL_LEDS);
|
||||
// cppcheck-suppress redundantAssignment
|
||||
Dummy = LEDs_GetLEDs();
|
||||
LEDs_Disable();
|
||||
|
||||
/* =============================
|
||||
* Joystick Compile Check
|
||||
* ============================= */
|
||||
// cppcheck-suppress redundantAssignment
|
||||
Dummy = JOY_LEFT + JOY_RIGHT + JOY_UP + JOY_DOWN + JOY_PRESS;
|
||||
Joystick_Init();
|
||||
// cppcheck-suppress redundantAssignment
|
||||
Dummy = Joystick_GetStatus();
|
||||
Joystick_Disable();
|
||||
|
||||
(void)Dummy;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.lufa-lib.org
|
||||
#
|
||||
|
||||
# Makefile for the board driver build test. This
|
||||
# test attempts to build a dummy project with all
|
||||
# possible board targets using their respective
|
||||
# compiler.
|
||||
|
||||
# Path to the LUFA library core
|
||||
LUFA_PATH := ../../LUFA/
|
||||
|
||||
# Build test cannot be run with multiple parallel jobs
|
||||
.NOTPARALLEL:
|
||||
|
||||
all: begin makeboardlist testboards clean end
|
||||
|
||||
begin:
|
||||
@echo Executing build test "BoardDriverTest".
|
||||
@echo
|
||||
|
||||
end:
|
||||
@echo Build test "BoardDriverTest" complete.
|
||||
@echo
|
||||
|
||||
makeboardlist:
|
||||
@grep "BOARD_" $(patsubst %/,%,$(LUFA_PATH))/Common/BoardTypes.h | cut -d'#' -f2 | cut -d' ' -f2 | grep "BOARD_" > BoardList.txt
|
||||
|
||||
testboards:
|
||||
@echo "buildtest:" > BuildMakefile
|
||||
|
||||
@while read line; \
|
||||
do \
|
||||
build_cfg=`grep "$$line " BoardDeviceMap.cfg | grep -v "#" | cut -d'=' -f2- | sed 's/ //g'`; \
|
||||
\
|
||||
build_board=$$line; \
|
||||
build_arch=`echo $$build_cfg | cut -d':' -f1`; \
|
||||
build_mcu=`echo $$build_cfg | cut -d':' -f2`; \
|
||||
\
|
||||
if ( test -z "$$build_cfg" ); then \
|
||||
echo "No matching information set for board $$build_board"; \
|
||||
else \
|
||||
echo "Found board configuration for $$build_board - $$build_arch, $$build_mcu"; \
|
||||
\
|
||||
printf "\t@echo Building dummy project for $$build_board...\n" >> BuildMakefile; \
|
||||
printf "\t$(MAKE) -f makefile.test clean elf MCU=%s ARCH=%s BOARD=%s\n\n" $$build_mcu $$build_arch $$build_board >> BuildMakefile; \
|
||||
fi; \
|
||||
done < BoardList.txt
|
||||
|
||||
$(MAKE) -f BuildMakefile buildtest
|
||||
|
||||
clean:
|
||||
rm -f BuildMakefile
|
||||
rm -f BoardList.txt
|
||||
$(MAKE) -f makefile.test clean BOARD=NONE ARCH=AVR8 MCU=at90usb1287
|
||||
$(MAKE) -f makefile.test clean BOARD=NONE ARCH=XMEGA MCU=atxmega128a1u
|
||||
$(MAKE) -f makefile.test clean BOARD=NONE ARCH=UC3 MCU=uc3a0256
|
||||
|
||||
%:
|
||||
|
||||
.PHONY: all begin end makeboardlist testboards clean
|
||||
|
||||
# Include LUFA build script makefiles
|
||||
include $(LUFA_PATH)/Build/lufa_core.mk
|
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# LUFA Library
|
||||
# Copyright (C) Dean Camera, 2014.
|
||||
#
|
||||
# dean [at] fourwalledcubicle [dot] com
|
||||
# www.lufa-lib.org
|
||||
#
|
||||
# --------------------------------------
|
||||
# LUFA Project Makefile.
|
||||
# --------------------------------------
|
||||
|
||||
# Run "make help" for target help.
|
||||
|
||||
MCU =
|
||||
ARCH =
|
||||
BOARD =
|
||||
F_CPU = $(F_USB)
|
||||
F_USB = 8000000
|
||||
OPTIMIZATION = 1
|
||||
TARGET = Test
|
||||
SRC = $(TARGET).c
|
||||
LUFA_PATH = ../../LUFA
|
||||
CC_FLAGS = -Werror
|
||||
DEBUG_LEVEL = 0
|
||||
|
||||
# Include LUFA build script makefiles
|
||||
include $(LUFA_PATH)/Build/lufa_build.mk
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue