Adding initial Teensy 3 support, compiles, but not fully functional yet.
- CDC Output seems to be working - USB Keyboard output has not been tested, but is "ready" - UART and Timers have not been tested, or fully utilized - Issues using Timer 0 - Initial template for MBC-55X Scan module (only module currently compatible with the arm build) - Updated the interface to the AVR usb module for symmetry with the ARM usb module - Much gutting was done to the Teensy 3 usb keyboard module, though not in an ideal state yet
This commit is contained in:
parent
6da1558b78
commit
c8b4baf652
@ -27,8 +27,8 @@ include( AddFileDependencies )
|
||||
#| "avr" # Teensy++ 1.0
|
||||
#| "avr" # Teensy++ 2.0
|
||||
#| "arm" # Teensy 3.0
|
||||
#set( COMPILER_FAMILY "arm" )
|
||||
set( COMPILER_FAMILY "avr" )
|
||||
set( COMPILER_FAMILY "arm" )
|
||||
#set( COMPILER_FAMILY "avr" )
|
||||
|
||||
message( STATUS "Compiler Family:" )
|
||||
message( "${COMPILER_FAMILY}" )
|
||||
|
@ -50,7 +50,11 @@
|
||||
*/
|
||||
|
||||
// Function Aliases
|
||||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
|
||||
#define dPrint(c) usb_debug_putchar(c)
|
||||
#elif defined(_mk20dx128_) // ARM
|
||||
#define dPrint(c) usb_debug_putstr (c)
|
||||
#endif
|
||||
#define dPrintStr(c) usb_debug_putstr (c)
|
||||
#define dPrintStrs(...) usb_debug_putstrs(__VA_ARGS__, "\0\0\0") // Convenience Variadic Macro
|
||||
#define dPrintStrNL(c) dPrintStrs (c, NL) // Appends New Line Macro
|
||||
|
63
Lib/Interrupts.h
Normal file
63
Lib/Interrupts.h
Normal file
@ -0,0 +1,63 @@
|
||||
/* Copyright (C) 2013 by Jacob Alexander
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
// This include file unifies some of the nomenclature between the AVR and ARM compilers
|
||||
|
||||
|
||||
// ----- Includes -----
|
||||
|
||||
#ifndef __INTERRUPTS_H
|
||||
#define __INTERRUPTS_H
|
||||
|
||||
// ARM
|
||||
#if defined(_mk20dx128_)
|
||||
|
||||
#include <Lib/mk20dx128.h>
|
||||
|
||||
// AVR
|
||||
#elif defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_)
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// ----- Defines -----
|
||||
|
||||
// ARM
|
||||
#if defined(_mk20dx128_)
|
||||
|
||||
// Map the Interrupt Enable/Disable to the AVR names
|
||||
#define cli() __disable_irq()
|
||||
#define sei() __enable_irq()
|
||||
|
||||
|
||||
// AVR
|
||||
#elif defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
37
Lib/aliased_bitband.h
Normal file
37
Lib/aliased_bitband.h
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
#ifndef __aliased_bitband_h
|
||||
#define __aliased_bitband_h
|
||||
|
||||
|
||||
// Aliased Regions for single bit (0th) register access
|
||||
|
||||
// Chapter 4: Memory Map (Table 4-1)
|
||||
|
||||
|
||||
|
||||
// TODO
|
||||
// - Not all tested, and not all sections added
|
||||
|
||||
|
||||
|
||||
// 0x2200 0000 - 0x23FF FFFF - Aliased to SRAM_U bitband
|
||||
// TODO
|
||||
|
||||
|
||||
|
||||
// 0x4200 0000 - 0x43FF FFFF - Aliased to AIPS and GPIO bitband
|
||||
#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
|
||||
#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
|
||||
|
||||
// XXX - Only MODREG is tested to work...
|
||||
#define GPIO_BITBAND_OUTREG(reg, bit) *((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) + 0)
|
||||
#define GPIO_BITBAND_SETREG(reg, bit) *((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) + 32)
|
||||
#define GPIO_BITBAND_CLRREG(reg, bit) *((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) + 64)
|
||||
#define GPIO_BITBAND_TOGREG(reg, bit) *((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) + 96)
|
||||
#define GPIO_BITBAND_INPREG(reg, bit) *((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) + 128)
|
||||
#define GPIO_BITBAND_MODREG(reg, bit) *((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)) + 160)
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
37
Lib/delay.c
Normal file
37
Lib/delay.c
Normal file
@ -0,0 +1,37 @@
|
||||
|
||||
#include "delay.h"
|
||||
#include "mk20dx128.h"
|
||||
|
||||
// the systick interrupt is supposed to increment this at 1 kHz rate
|
||||
volatile uint32_t systick_millis_count = 0;
|
||||
|
||||
void yield(void) {};
|
||||
|
||||
uint32_t micros(void)
|
||||
{
|
||||
uint32_t count, current, istatus;
|
||||
|
||||
__disable_irq();
|
||||
current = SYST_CVR;
|
||||
count = systick_millis_count;
|
||||
istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
|
||||
__enable_irq();
|
||||
if ((istatus & SCB_ICSR_PENDSTSET) && current > ((F_CPU / 1000) - 50)) count++;
|
||||
current = ((F_CPU / 1000) - 1) - current;
|
||||
return count * 1000 + current / (F_CPU / 1000000);
|
||||
}
|
||||
|
||||
void delay(uint32_t ms)
|
||||
{
|
||||
uint32_t start = micros();
|
||||
|
||||
while (1) {
|
||||
if ((micros() - start) >= 1000) {
|
||||
ms--;
|
||||
if (ms == 0) break;
|
||||
start += 1000;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
}
|
||||
|
48
Lib/delay.h
Normal file
48
Lib/delay.h
Normal file
@ -0,0 +1,48 @@
|
||||
|
||||
#ifndef __DELAY_H
|
||||
#define __DELAY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Convenience Macros, for delay compatibility with AVR-GCC
|
||||
#define _delay_ms(val) delay( val )
|
||||
#define _delay_us(val) delayMicroseconds( val )
|
||||
|
||||
|
||||
// the systick interrupt is supposed to increment this at 1 kHz rate
|
||||
extern volatile uint32_t systick_millis_count;
|
||||
|
||||
static inline uint32_t millis(void) __attribute__((always_inline, unused));
|
||||
static inline uint32_t millis(void)
|
||||
{
|
||||
return systick_millis_count; // single aligned 32 bit is atomic;
|
||||
}
|
||||
|
||||
|
||||
static inline void delayMicroseconds(uint32_t) __attribute__((always_inline, unused));
|
||||
static inline void delayMicroseconds(uint32_t usec)
|
||||
{
|
||||
#if F_CPU == 96000000
|
||||
uint32_t n = usec << 5;
|
||||
#elif F_CPU == 48000000
|
||||
uint32_t n = usec << 4;
|
||||
#elif F_CPU == 24000000
|
||||
uint32_t n = usec << 3;
|
||||
#endif
|
||||
asm volatile(
|
||||
"L_%=_delayMicroseconds:" "\n\t"
|
||||
"subs %0, #1" "\n\t"
|
||||
"bne L_%=_delayMicroseconds" "\n"
|
||||
: "+r" (n) :
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
void yield(void) __attribute__ ((weak));
|
||||
|
||||
uint32_t micros(void);
|
||||
|
||||
void delay(uint32_t ms);
|
||||
|
||||
#endif
|
||||
|
328
Lib/mk20dx128.c
Normal file
328
Lib/mk20dx128.c
Normal file
@ -0,0 +1,328 @@
|
||||
#include "mk20dx128.h"
|
||||
|
||||
|
||||
extern unsigned long _stext;
|
||||
extern unsigned long _etext;
|
||||
extern unsigned long _sdata;
|
||||
extern unsigned long _edata;
|
||||
extern unsigned long _sbss;
|
||||
extern unsigned long _ebss;
|
||||
extern unsigned long _estack;
|
||||
//extern void __init_array_start(void);
|
||||
//extern void __init_array_end(void);
|
||||
extern int main (void);
|
||||
void ResetHandler(void);
|
||||
void _init_Teensyduino_internal_(void);
|
||||
void __libc_init_array(void);
|
||||
|
||||
|
||||
void fault_isr(void)
|
||||
{
|
||||
while (1); // die
|
||||
}
|
||||
|
||||
void unused_isr(void)
|
||||
{
|
||||
while (1); // die
|
||||
}
|
||||
|
||||
extern volatile uint32_t systick_millis_count;
|
||||
void systick_default_isr(void)
|
||||
{
|
||||
systick_millis_count++;
|
||||
}
|
||||
|
||||
void nmi_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void hard_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void memmanage_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void bus_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void usage_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void svcall_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void debugmonitor_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pendablesrvreq_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void systick_isr(void) __attribute__ ((weak, alias("systick_default_isr")));
|
||||
|
||||
void dma_ch0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void dma_ch1_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void dma_ch2_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void dma_ch3_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void dma_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void flash_cmd_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void flash_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void low_voltage_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void wakeup_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void watchdog_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void i2c0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void spi0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void i2s0_tx_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void i2s0_rx_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart0_lon_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart0_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart0_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart1_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart1_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart2_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart2_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void adc0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void cmp0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void cmp1_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void ftm0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void ftm1_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void cmt_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void rtc_alarm_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void rtc_seconds_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pit0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pit1_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pit2_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pit3_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pdb_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void usb_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void usb_charge_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void tsi0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void mcg_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void lptmr_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void porta_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void portb_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void portc_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void portd_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void porte_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void software_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
|
||||
|
||||
// TODO: create AVR-stype ISR() macro, with default linkage to undefined handler
|
||||
//
|
||||
__attribute__ ((section(".vectors"), used))
|
||||
void (* const gVectors[])(void) =
|
||||
{
|
||||
(void (*)(void))((unsigned long)&_estack), // 0 ARM: Initial Stack Pointer
|
||||
ResetHandler, // 1 ARM: Initial Program Counter
|
||||
nmi_isr, // 2 ARM: Non-maskable Interrupt (NMI)
|
||||
hard_fault_isr, // 3 ARM: Hard Fault
|
||||
memmanage_fault_isr, // 4 ARM: MemManage Fault
|
||||
bus_fault_isr, // 5 ARM: Bus Fault
|
||||
usage_fault_isr, // 6 ARM: Usage Fault
|
||||
fault_isr, // 7 --
|
||||
fault_isr, // 8 --
|
||||
fault_isr, // 9 --
|
||||
fault_isr, // 10 --
|
||||
svcall_isr, // 11 ARM: Supervisor call (SVCall)
|
||||
debugmonitor_isr, // 12 ARM: Debug Monitor
|
||||
fault_isr, // 13 --
|
||||
pendablesrvreq_isr, // 14 ARM: Pendable req serv(PendableSrvReq)
|
||||
systick_isr, // 15 ARM: System tick timer (SysTick)
|
||||
dma_ch0_isr, // 16 DMA channel 0 transfer complete
|
||||
dma_ch1_isr, // 17 DMA channel 1 transfer complete
|
||||
dma_ch2_isr, // 18 DMA channel 2 transfer complete
|
||||
dma_ch3_isr, // 19 DMA channel 3 transfer complete
|
||||
dma_error_isr, // 20 DMA error interrupt channel
|
||||
unused_isr, // 21 DMA --
|
||||
flash_cmd_isr, // 22 Flash Memory Command complete
|
||||
flash_error_isr, // 23 Flash Read collision
|
||||
low_voltage_isr, // 24 Low-voltage detect/warning
|
||||
wakeup_isr, // 25 Low Leakage Wakeup
|
||||
watchdog_isr, // 26 Both EWM and WDOG interrupt
|
||||
i2c0_isr, // 27 I2C0
|
||||
spi0_isr, // 28 SPI0
|
||||
i2s0_tx_isr, // 29 I2S0 Transmit
|
||||
i2s0_rx_isr, // 30 I2S0 Receive
|
||||
uart0_lon_isr, // 31 UART0 CEA709.1-B (LON) status
|
||||
uart0_status_isr, // 32 UART0 status
|
||||
uart0_error_isr, // 33 UART0 error
|
||||
uart1_status_isr, // 34 UART1 status
|
||||
uart1_error_isr, // 35 UART1 error
|
||||
uart2_status_isr, // 36 UART2 status
|
||||
uart2_error_isr, // 37 UART2 error
|
||||
adc0_isr, // 38 ADC0
|
||||
cmp0_isr, // 39 CMP0
|
||||
cmp1_isr, // 40 CMP1
|
||||
ftm0_isr, // 41 FTM0
|
||||
ftm1_isr, // 42 FTM1
|
||||
cmt_isr, // 43 CMT
|
||||
rtc_alarm_isr, // 44 RTC Alarm interrupt
|
||||
rtc_seconds_isr, // 45 RTC Seconds interrupt
|
||||
pit0_isr, // 46 PIT Channel 0
|
||||
pit1_isr, // 47 PIT Channel 1
|
||||
pit2_isr, // 48 PIT Channel 2
|
||||
pit3_isr, // 49 PIT Channel 3
|
||||
pdb_isr, // 50 PDB Programmable Delay Block
|
||||
usb_isr, // 51 USB OTG
|
||||
usb_charge_isr, // 52 USB Charger Detect
|
||||
tsi0_isr, // 53 TSI0
|
||||
mcg_isr, // 54 MCG
|
||||
lptmr_isr, // 55 Low Power Timer
|
||||
porta_isr, // 56 Pin detect (Port A)
|
||||
portb_isr, // 57 Pin detect (Port B)
|
||||
portc_isr, // 58 Pin detect (Port C)
|
||||
portd_isr, // 59 Pin detect (Port D)
|
||||
porte_isr, // 60 Pin detect (Port E)
|
||||
software_isr, // 61 Software interrupt
|
||||
};
|
||||
|
||||
//void usb_isr(void)
|
||||
//{
|
||||
//}
|
||||
|
||||
__attribute__ ((section(".flashconfig"), used))
|
||||
const uint8_t flashconfigbytes[16] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
|
||||
// Automatically initialize the RTC. When the build defines the compile
|
||||
// time, and the user has added a crystal, the RTC will automatically
|
||||
// begin at the time of the first upload.
|
||||
#ifndef TIME_T
|
||||
#define TIME_T 1349049600 // default 1 Oct 2012
|
||||
#endif
|
||||
extern void rtc_set(unsigned long t);
|
||||
|
||||
|
||||
|
||||
void startup_unused_hook(void) {}
|
||||
void startup_early_hook(void) __attribute__ ((weak, alias("startup_unused_hook")));
|
||||
void startup_late_hook(void) __attribute__ ((weak, alias("startup_unused_hook")));
|
||||
|
||||
|
||||
__attribute__ ((section(".startup")))
|
||||
void ResetHandler(void)
|
||||
{
|
||||
uint32_t *src = &_etext;
|
||||
uint32_t *dest = &_sdata;
|
||||
|
||||
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
|
||||
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
|
||||
WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE;
|
||||
startup_early_hook();
|
||||
|
||||
// enable clocks to always-used peripherals
|
||||
SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO
|
||||
SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;
|
||||
// if the RTC oscillator isn't enabled, get it started early
|
||||
if (!(RTC_CR & RTC_CR_OSCE)) {
|
||||
RTC_SR = 0;
|
||||
RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
|
||||
}
|
||||
|
||||
// TODO: do this while the PLL is waiting to lock....
|
||||
while (dest < &_edata) *dest++ = *src++;
|
||||
dest = &_sbss;
|
||||
while (dest < &_ebss) *dest++ = 0;
|
||||
SCB_VTOR = 0; // use vector table in flash
|
||||
|
||||
// start in FEI mode
|
||||
// enable capacitors for crystal
|
||||
OSC0_CR = OSC_SC8P | OSC_SC2P;
|
||||
// enable osc, 8-32 MHz range, low power mode
|
||||
MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS;
|
||||
// switch to crystal as clock source, FLL input = 16 MHz / 512
|
||||
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4);
|
||||
// wait for crystal oscillator to begin
|
||||
while ((MCG_S & MCG_S_OSCINIT0) == 0) ;
|
||||
// wait for FLL to use oscillator
|
||||
while ((MCG_S & MCG_S_IREFST) != 0) ;
|
||||
// wait for MCGOUT to use oscillator
|
||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ;
|
||||
// now we're in FBE mode
|
||||
// config PLL input for 16 MHz Crystal / 4 = 4 MHz
|
||||
MCG_C5 = MCG_C5_PRDIV0(3);
|
||||
// config PLL for 96 MHz output
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0);
|
||||
// wait for PLL to start using xtal as its input
|
||||
while (!(MCG_S & MCG_S_PLLST)) ;
|
||||
// wait for PLL to lock
|
||||
while (!(MCG_S & MCG_S_LOCK0)) ;
|
||||
// now we're in PBE mode
|
||||
#if F_CPU == 96000000
|
||||
// config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash
|
||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3);
|
||||
#elif F_CPU == 48000000
|
||||
// config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash
|
||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3);
|
||||
#elif F_CPU == 24000000
|
||||
// config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash
|
||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(3) | SIM_CLKDIV1_OUTDIV4(3);
|
||||
#else
|
||||
#error "Error, F_CPU must be 96000000, 48000000, or 24000000"
|
||||
#endif
|
||||
// switch to PLL as clock source, FLL input = 16 MHz / 512
|
||||
MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4);
|
||||
// wait for PLL clock to be used
|
||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ;
|
||||
// now we're in PEE mode
|
||||
// configure USB for 48 MHz clock
|
||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // USB = 96 MHz PLL / 2
|
||||
// USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0
|
||||
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6);
|
||||
|
||||
// initialize the SysTick counter
|
||||
SYST_RVR = (F_CPU / 1000) - 1;
|
||||
SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE;
|
||||
|
||||
//init_pins();
|
||||
__enable_irq();
|
||||
|
||||
//_init_Teensyduino_internal_(); XXX HaaTa - Why is this here? Perhaps fixed in a new version of the API?
|
||||
//if (RTC_SR & RTC_SR_TIF) rtc_set(TIME_T); XXX HaaTa - We don't care about the rtc
|
||||
|
||||
__libc_init_array();
|
||||
|
||||
/*
|
||||
for (ptr = &__init_array_start; ptr < &__init_array_end; ptr++) {
|
||||
(*ptr)();
|
||||
}
|
||||
*/
|
||||
startup_late_hook();
|
||||
main();
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
// TODO: is this needed for c++ and where does it come from?
|
||||
/*
|
||||
void _init(void)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
void * _sbrk(int incr)
|
||||
{
|
||||
static char *heap_end = (char *)&_ebss;
|
||||
char *prev = heap_end;
|
||||
|
||||
heap_end += incr;
|
||||
return prev;
|
||||
}
|
||||
|
||||
int _read(int file, char *ptr, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _close(int fd)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _lseek(int fd, long long offset, int whence)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _exit(int status)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
void __cxa_pure_virtual()
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
|
||||
|
1486
Lib/mk20dx128.h
Normal file
1486
Lib/mk20dx128.h
Normal file
File diff suppressed because it is too large
Load Diff
73
Lib/mk20dx128.ld
Normal file
73
Lib/mk20dx128.ld
Normal file
@ -0,0 +1,73 @@
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K
|
||||
RAM (rwx) : ORIGIN = 0x1FFFE000, LENGTH = 16K
|
||||
}
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
. = 0;
|
||||
KEEP(*(.vectors))
|
||||
*(.startup*)
|
||||
/* TODO: does linker detect startup overflow onto flashconfig? */
|
||||
. = 0x400;
|
||||
KEEP(*(.flashconfig*))
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.init))
|
||||
. = ALIGN(4);
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
} > FLASH = 0xFF
|
||||
|
||||
.ARM.exidx : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
__exidx_end = .;
|
||||
} > FLASH
|
||||
_etext = .;
|
||||
|
||||
.usbdescriptortable (NOLOAD) : {
|
||||
/* . = ORIGIN(RAM); */
|
||||
. = ALIGN(512);
|
||||
*(.usbdescriptortable*)
|
||||
} > RAM
|
||||
|
||||
.usbbuffers (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
*(.usbbuffers*)
|
||||
} > RAM
|
||||
|
||||
.data : AT (_etext) {
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > RAM
|
||||
|
||||
.noinit (NOLOAD) : {
|
||||
*(.noinit*)
|
||||
} > RAM
|
||||
|
||||
.bss : {
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
} > RAM
|
||||
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
}
|
||||
|
||||
|
46
Lib/pin_map.teensy3
Normal file
46
Lib/pin_map.teensy3
Normal file
@ -0,0 +1,46 @@
|
||||
// Pin Arduino
|
||||
// 0 B16 RXD
|
||||
// 1 B17 TXD
|
||||
// 2 D0
|
||||
// 3 A12 FTM1_CH0
|
||||
// 4 A13 FTM1_CH1
|
||||
// 5 D7 FTM0_CH7 OC0B/T1
|
||||
// 6 D4 FTM0_CH4 OC0A
|
||||
// 7 D2
|
||||
// 8 D3 ICP1
|
||||
// 9 C3 FTM0_CH2 OC1A
|
||||
// 10 C4 FTM0_CH3 SS/OC1B
|
||||
// 11 C6 MOSI/OC2A
|
||||
// 12 C7 MISO
|
||||
// 13 C5 SCK
|
||||
// 14 D1
|
||||
// 15 C0
|
||||
// 16 B0 (FTM1_CH0)
|
||||
// 17 B1 (FTM1_CH1)
|
||||
// 18 B3 SDA
|
||||
// 19 B2 SCL
|
||||
// 20 D5 FTM0_CH5
|
||||
// 21 D6 FTM0_CH6
|
||||
// 22 C1 FTM0_CH0
|
||||
// 23 C2 FTM0_CH1
|
||||
// 24 A5 (FTM0_CH2)
|
||||
// 25 B19
|
||||
// 26 E1
|
||||
// 27 C9
|
||||
// 28 C8
|
||||
// 29 C10
|
||||
// 30 C11
|
||||
// 31 E0
|
||||
// 32 B18
|
||||
// 33 A4 (FTM0_CH1)
|
||||
// (34) analog only
|
||||
// (35) analog only
|
||||
// (36) analog only
|
||||
// (37) analog only
|
||||
|
||||
// not available to user:
|
||||
// A0 FTM0_CH5 SWD Clock
|
||||
// A1 FTM0_CH6 USB ID
|
||||
// A2 FTM0_CH7 SWD Trace
|
||||
// A3 FTM0_CH0 SWD Data
|
||||
|
236
Scan/MBC-55X/scan_loop.c
Normal file
236
Scan/MBC-55X/scan_loop.c
Normal file
@ -0,0 +1,236 @@
|
||||
/* Copyright (C) 2013 by Jacob Alexander
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// ----- Includes -----
|
||||
|
||||
// Compiler Includes
|
||||
#include <Lib/ScanLib.h>
|
||||
|
||||
// Project Includes
|
||||
#include <led.h>
|
||||
#include <print.h>
|
||||
|
||||
// Local Includes
|
||||
#include "scan_loop.h"
|
||||
|
||||
|
||||
|
||||
// ----- Defines -----
|
||||
|
||||
|
||||
// ----- Macros -----
|
||||
|
||||
// Make sure we haven't overflowed the buffer
|
||||
#define bufferAdd(byte) \
|
||||
if ( KeyIndex_BufferUsed < KEYBOARD_BUFFER ) \
|
||||
KeyIndex_Buffer[KeyIndex_BufferUsed++] = byte
|
||||
|
||||
|
||||
|
||||
// ----- Variables -----
|
||||
|
||||
// Buffer used to inform the macro processing module which keys have been detected as pressed
|
||||
volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
|
||||
volatile uint8_t KeyIndex_BufferUsed;
|
||||
|
||||
|
||||
|
||||
// ----- Function Declarations -----
|
||||
|
||||
void processKeyValue( uint8_t valueType );
|
||||
void removeKeyValue( uint8_t keyValue );
|
||||
|
||||
|
||||
|
||||
// ----- Interrupt Functions -----
|
||||
|
||||
// UART Receive Buffer Full Interrupt
|
||||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
|
||||
ISR(USART1_RX_vect)
|
||||
#elif defined(_mk20dx128_) // ARM
|
||||
void uart0_status_isr(void)
|
||||
#endif
|
||||
{
|
||||
cli(); // Disable Interrupts
|
||||
|
||||
// Read part of the scan code (3 8bit chunks) from USART
|
||||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
|
||||
uint8_t tmp = UDR1;
|
||||
#elif defined(_mk20dx128_) // ARM
|
||||
// TODO
|
||||
uint8_t tmp = 0;
|
||||
#endif
|
||||
|
||||
// Debug
|
||||
char tmpStr[6];
|
||||
hexToStr( tmp, tmpStr );
|
||||
dPrintStrs( tmpStr, " " ); // Debug
|
||||
|
||||
// TODO
|
||||
|
||||
sei(); // Re-enable Interrupts
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ----- Functions -----
|
||||
|
||||
// Setup
|
||||
inline void scan_setup()
|
||||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
|
||||
{
|
||||
// Setup the the USART interface for keyboard data input
|
||||
|
||||
// TODO
|
||||
// Setup baud rate
|
||||
// 16 MHz / ( 16 * Baud ) = UBRR
|
||||
// Baud: 4817 -> 16 MHz / ( 16 * 4817 ) = 207.5981
|
||||
// Thus baud setting = 208
|
||||
uint16_t baud = 208; // Max setting of 4095
|
||||
UBRR1H = (uint8_t)(baud >> 8);
|
||||
UBRR1L = (uint8_t)baud;
|
||||
|
||||
// Enable the receiver, transmitter, and RX Complete Interrupt
|
||||
UCSR1B = 0x98;
|
||||
|
||||
// Set frame format: 8 data, 1 stop bit, odd parity
|
||||
// Asynchrounous USART mode
|
||||
UCSR1C = 0x36;
|
||||
|
||||
// Reset the keyboard before scanning, we might be in a wierd state
|
||||
scan_resetKeyboard();
|
||||
}
|
||||
#elif defined(_mk20dx128_) // ARM
|
||||
{
|
||||
// Setup the the UART interface for keyboard data input
|
||||
|
||||
// Setup baud rate
|
||||
// TODO
|
||||
|
||||
// Reset the keyboard before scanning, we might be in a wierd state
|
||||
scan_resetKeyboard();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Main Detection Loop
|
||||
inline uint8_t scan_loop()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void processKeyValue( uint8_t keyValue )
|
||||
{
|
||||
// TODO Process ASCII
|
||||
|
||||
// Make sure the key isn't already in the buffer
|
||||
for ( uint8_t c = 0; c < KeyIndex_BufferUsed + 1; c++ )
|
||||
{
|
||||
// Key isn't in the buffer yet
|
||||
if ( c == KeyIndex_BufferUsed )
|
||||
{
|
||||
bufferAdd( keyValue );
|
||||
break;
|
||||
}
|
||||
|
||||
// Key already in the buffer
|
||||
if ( KeyIndex_Buffer[c] == keyValue )
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void removeKeyValue( uint8_t keyValue )
|
||||
{
|
||||
// Check for the released key, and shift the other keys lower on the buffer
|
||||
uint8_t c;
|
||||
for ( c = 0; c < KeyIndex_BufferUsed; c++ )
|
||||
{
|
||||
// Key to release found
|
||||
if ( KeyIndex_Buffer[c] == keyValue )
|
||||
{
|
||||
// Shift keys from c position
|
||||
for ( uint8_t k = c; k < KeyIndex_BufferUsed - 1; k++ )
|
||||
KeyIndex_Buffer[k] = KeyIndex_Buffer[k + 1];
|
||||
|
||||
// Decrement Buffer
|
||||
KeyIndex_BufferUsed--;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Error case (no key to release)
|
||||
if ( c == KeyIndex_BufferUsed + 1 )
|
||||
{
|
||||
errorLED( 1 );
|
||||
char tmpStr[6];
|
||||
hexToStr( keyValue, tmpStr );
|
||||
erro_dPrint( "Could not find key to release: ", tmpStr );
|
||||
}
|
||||
}
|
||||
|
||||
// Send data
|
||||
uint8_t scan_sendData( uint8_t dataPayload )
|
||||
{
|
||||
// Debug
|
||||
char tmpStr[6];
|
||||
hexToStr( dataPayload, tmpStr );
|
||||
info_dPrint( "Sending - ", tmpStr );
|
||||
|
||||
#if defined(_at90usb162_) || defined(_atmega32u4_) || defined(_at90usb646_) || defined(_at90usb1286_) // AVR
|
||||
UDR1 = dataPayload;
|
||||
#elif defined(_mk20dx128_) // ARM
|
||||
// TODO
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Signal KeyIndex_Buffer that it has been properly read
|
||||
void scan_finishedWithBuffer( uint8_t sentKeys )
|
||||
{
|
||||
}
|
||||
|
||||
// Signal that the keys have been properly sent over USB
|
||||
void scan_finishedWithUSBBuffer( uint8_t sentKeys )
|
||||
{
|
||||
}
|
||||
|
||||
// Reset/Hold keyboard
|
||||
// NOTE: Does nothing with the FACOM6684
|
||||
void scan_lockKeyboard( void )
|
||||
{
|
||||
}
|
||||
|
||||
// NOTE: Does nothing with the FACOM6684
|
||||
void scan_unlockKeyboard( void )
|
||||
{
|
||||
}
|
||||
|
||||
// Reset Keyboard
|
||||
void scan_resetKeyboard( void )
|
||||
{
|
||||
// Not a calculated valued...
|
||||
_delay_ms( 50 );
|
||||
|
||||
KeyIndex_BufferUsed = 0;
|
||||
}
|
||||
|
67
Scan/MBC-55X/scan_loop.h
Normal file
67
Scan/MBC-55X/scan_loop.h
Normal file
@ -0,0 +1,67 @@
|
||||
/* Copyright (C) 2013 by Jacob Alexander
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __SCAN_LOOP_H
|
||||
#define __SCAN_LOOP_H
|
||||
|
||||
// ----- Includes -----
|
||||
|
||||
// Compiler Includes
|
||||
#include <stdint.h>
|
||||
|
||||
// Local Includes
|
||||
|
||||
|
||||
|
||||
// ----- Defines -----
|
||||
|
||||
#define KEYBOARD_KEYS 0x7F // 127 - Size of the array space for the keyboard(max index)
|
||||
#define KEYBOARD_BUFFER 24 // Max number of key signals to buffer
|
||||
|
||||
|
||||
|
||||
// ----- Variables -----
|
||||
|
||||
extern volatile uint8_t KeyIndex_Buffer[KEYBOARD_BUFFER];
|
||||
extern volatile uint8_t KeyIndex_BufferUsed;
|
||||
extern volatile uint8_t KeyIndex_Add_InputSignal;
|
||||
|
||||
|
||||
|
||||
// ----- Functions -----
|
||||
|
||||
// Functions used by main.c
|
||||
void scan_setup( void );
|
||||
uint8_t scan_loop( void );
|
||||
|
||||
|
||||
// Functions available to macro.c
|
||||
uint8_t scan_sendData( uint8_t dataPayload );
|
||||
|
||||
void scan_finishedWithBuffer( uint8_t sentKeys );
|
||||
void scan_finishedWithUSBBuffer( uint8_t sentKeys );
|
||||
void scan_lockKeyboard( void );
|
||||
void scan_unlockKeyboard( void );
|
||||
void scan_resetKeyboard( void );
|
||||
|
||||
|
||||
#endif // __SCAN_LOOP_H
|
||||
|
48
Scan/MBC-55X/setup.cmake
Normal file
48
Scan/MBC-55X/setup.cmake
Normal file
@ -0,0 +1,48 @@
|
||||
###| CMake Kiibohd Controller Scan Module |###
|
||||
#
|
||||
# Written by Jacob Alexander in 2013 for the Kiibohd Controller
|
||||
#
|
||||
# Released into the Public Domain
|
||||
#
|
||||
# For the Sanyo MBC-55X Series of keyboards
|
||||
#
|
||||
###
|
||||
|
||||
|
||||
###
|
||||
# Module C files
|
||||
#
|
||||
|
||||
set( SCAN_SRCS
|
||||
scan_loop.c
|
||||
)
|
||||
|
||||
|
||||
###
|
||||
# Module H files
|
||||
#
|
||||
set( SCAN_HDRS
|
||||
scan_loop.h
|
||||
)
|
||||
|
||||
|
||||
###
|
||||
# File Dependency Setup
|
||||
#
|
||||
ADD_FILE_DEPENDENCIES( scan_loop.c ${SCAN_HDRS} )
|
||||
#add_file_dependencies( scan_loop.c ${SCAN_HDRS} )
|
||||
#add_file_dependencies( macro.c keymap.h facom6684.h )
|
||||
|
||||
|
||||
###
|
||||
# Module Specific Options
|
||||
#
|
||||
add_definitions( -I${HEAD_DIR}/Keymap )
|
||||
|
||||
#| Keymap Settings
|
||||
add_definitions(
|
||||
-DMODIFIER_MASK=facom6684_ModifierMask
|
||||
#-DKEYINDEX_MASK=facom6684_ColemakMap
|
||||
-DKEYINDEX_MASK=facom6684_DefaultMap
|
||||
)
|
||||
|
556
USB/pjrc/arm/usb_desc.c
Normal file
556
USB/pjrc/arm/usb_desc.c
Normal file
@ -0,0 +1,556 @@
|
||||
#include "usb_desc.h"
|
||||
|
||||
|
||||
// USB Descriptors are binary data which the USB host reads to
|
||||
// automatically detect a USB device's capabilities. The format
|
||||
// and meaning of every field is documented in numerous USB
|
||||
// standards. When working with USB descriptors, despite the
|
||||
// complexity of the standards and poor writing quality in many
|
||||
// of those documents, remember descriptors are nothing more
|
||||
// than constant binary data that tells the USB host what the
|
||||
// device can do. Computers will load drivers based on this data.
|
||||
// Those drivers then communicate on the endpoints specified by
|
||||
// the descriptors.
|
||||
|
||||
// To configure a new combination of interfaces or make minor
|
||||
// changes to existing configuration (eg, change the name or ID
|
||||
// numbers), usually you would edit "usb_desc.h". This file
|
||||
// is meant to be configured by the header, so generally it is
|
||||
// only edited to add completely new USB interfaces or features.
|
||||
|
||||
|
||||
|
||||
// **************************************************************
|
||||
// USB Device
|
||||
// **************************************************************
|
||||
|
||||
#define LSB(n) ((n) & 255)
|
||||
#define MSB(n) (((n) >> 8) & 255)
|
||||
|
||||
// USB Device Descriptor. The USB host reads this first, to learn
|
||||
// what type of device is connected.
|
||||
static uint8_t device_descriptor[] = {
|
||||
18, // bLength
|
||||
1, // bDescriptorType
|
||||
0x00, 0x02, // bcdUSB
|
||||
#ifdef DEVICE_CLASS
|
||||
DEVICE_CLASS, // bDeviceClass
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
#ifdef DEVICE_SUBCLASS
|
||||
DEVICE_SUBCLASS, // bDeviceSubClass
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
#ifdef DEVICE_PROTOCOL
|
||||
DEVICE_PROTOCOL, // bDeviceProtocol
|
||||
#else
|
||||
0,
|
||||
#endif
|
||||
EP0_SIZE, // bMaxPacketSize0
|
||||
LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor
|
||||
LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct
|
||||
0x00, 0x01, // bcdDevice
|
||||
1, // iManufacturer
|
||||
2, // iProduct
|
||||
3, // iSerialNumber
|
||||
1 // bNumConfigurations
|
||||
};
|
||||
|
||||
// These descriptors must NOT be "const", because the USB DMA
|
||||
// has trouble accessing flash memory with enough bandwidth
|
||||
// while the processor is executing from flash.
|
||||
|
||||
|
||||
|
||||
// **************************************************************
|
||||
// HID Report Descriptors
|
||||
// **************************************************************
|
||||
|
||||
// Each HID interface needs a special report descriptor that tells
|
||||
// the meaning and format of the data.
|
||||
|
||||
#ifdef KEYBOARD_INTERFACE
|
||||
// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60
|
||||
static uint8_t keyboard_report_desc[] = {
|
||||
0x05, 0x01, // Usage Page (Generic Desktop),
|
||||
0x09, 0x06, // Usage (Keyboard),
|
||||
0xA1, 0x01, // Collection (Application),
|
||||
0x75, 0x01, // Report Size (1),
|
||||
0x95, 0x08, // Report Count (8),
|
||||
0x05, 0x07, // Usage Page (Key Codes),
|
||||
0x19, 0xE0, // Usage Minimum (224),
|
||||
0x29, 0xE7, // Usage Maximum (231),
|
||||
0x15, 0x00, // Logical Minimum (0),
|
||||
0x25, 0x01, // Logical Maximum (1),
|
||||
0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte
|
||||
0x95, 0x08, // Report Count (8),
|
||||
0x75, 0x01, // Report Size (1),
|
||||
0x15, 0x00, // Logical Minimum (0),
|
||||
0x25, 0x01, // Logical Maximum (1),
|
||||
0x05, 0x0C, // Usage Page (Consumer),
|
||||
0x09, 0xE9, // Usage (Volume Increment),
|
||||
0x09, 0xEA, // Usage (Volume Decrement),
|
||||
0x09, 0xE2, // Usage (Mute),
|
||||
0x09, 0xCD, // Usage (Play/Pause),
|
||||
0x09, 0xB5, // Usage (Scan Next Track),
|
||||
0x09, 0xB6, // Usage (Scan Previous Track),
|
||||
0x09, 0xB7, // Usage (Stop),
|
||||
0x09, 0xB8, // Usage (Eject),
|
||||
0x81, 0x02, // Input (Data, Variable, Absolute), ;Media keys
|
||||
0x95, 0x05, // Report Count (5),
|
||||
0x75, 0x01, // Report Size (1),
|
||||
0x05, 0x08, // Usage Page (LEDs),
|
||||
0x19, 0x01, // Usage Minimum (1),
|
||||
0x29, 0x05, // Usage Maximum (5),
|
||||
0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report
|
||||
0x95, 0x01, // Report Count (1),
|
||||
0x75, 0x03, // Report Size (3),
|
||||
0x91, 0x03, // Output (Constant), ;LED report padding
|
||||
0x95, 0x06, // Report Count (6),
|
||||
0x75, 0x08, // Report Size (8),
|
||||
0x15, 0x00, // Logical Minimum (0),
|
||||
0x25, 0x7F, // Logical Maximum(104),
|
||||
0x05, 0x07, // Usage Page (Key Codes),
|
||||
0x19, 0x00, // Usage Minimum (0),
|
||||
0x29, 0x7F, // Usage Maximum (104),
|
||||
0x81, 0x00, // Input (Data, Array), ;Normal keys
|
||||
0xc0 // End Collection
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef MOUSE_INTERFACE
|
||||
// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension
|
||||
static uint8_t mouse_report_desc[] = {
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x02, // Usage (Mouse)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x05, 0x09, // Usage Page (Button)
|
||||
0x19, 0x01, // Usage Minimum (Button #1)
|
||||
0x29, 0x03, // Usage Maximum (Button #3)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x95, 0x03, // Report Count (3)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x81, 0x02, // Input (Data, Variable, Absolute)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x75, 0x05, // Report Size (5)
|
||||
0x81, 0x03, // Input (Constant)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x30, // Usage (X)
|
||||
0x09, 0x31, // Usage (Y)
|
||||
0x15, 0x81, // Logical Minimum (-127)
|
||||
0x25, 0x7F, // Logical Maximum (127)
|
||||
0x75, 0x08, // Report Size (8),
|
||||
0x95, 0x02, // Report Count (2),
|
||||
0x81, 0x06, // Input (Data, Variable, Relative)
|
||||
0x09, 0x38, // Usage (Wheel)
|
||||
0x95, 0x01, // Report Count (1),
|
||||
0x81, 0x06, // Input (Data, Variable, Relative)
|
||||
0xC0 // End Collection
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef JOYSTICK_INTERFACE
|
||||
static uint8_t joystick_report_desc[] = {
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x04, // Usage (Joystick)
|
||||
0xA1, 0x01, // Collection (Application)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x01, // Logical Maximum (1)
|
||||
0x75, 0x01, // Report Size (1)
|
||||
0x95, 0x20, // Report Count (32)
|
||||
0x05, 0x09, // Usage Page (Button)
|
||||
0x19, 0x01, // Usage Minimum (Button #1)
|
||||
0x29, 0x20, // Usage Maximum (Button #32)
|
||||
0x81, 0x02, // Input (variable,absolute)
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x25, 0x07, // Logical Maximum (7)
|
||||
0x35, 0x00, // Physical Minimum (0)
|
||||
0x46, 0x3B, 0x01, // Physical Maximum (315)
|
||||
0x75, 0x04, // Report Size (4)
|
||||
0x95, 0x01, // Report Count (1)
|
||||
0x65, 0x14, // Unit (20)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x39, // Usage (Hat switch)
|
||||
0x81, 0x42, // Input (variable,absolute,null_state)
|
||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||
0x09, 0x01, // Usage (Pointer)
|
||||
0xA1, 0x00, // Collection ()
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x03, // Logical Maximum (1023)
|
||||
0x75, 0x0A, // Report Size (10)
|
||||
0x95, 0x04, // Report Count (4)
|
||||
0x09, 0x30, // Usage (X)
|
||||
0x09, 0x31, // Usage (Y)
|
||||
0x09, 0x32, // Usage (Z)
|
||||
0x09, 0x35, // Usage (Rz)
|
||||
0x81, 0x02, // Input (variable,absolute)
|
||||
0xC0, // End Collection
|
||||
0x15, 0x00, // Logical Minimum (0)
|
||||
0x26, 0xFF, 0x03, // Logical Maximum (1023)
|
||||
0x75, 0x0A, // Report Size (10)
|
||||
0x95, 0x02, // Report Count (2)
|
||||
0x09, 0x36, // Usage (Slider)
|
||||
0x09, 0x36, // Usage (Slider)
|
||||
0x81, 0x02, // Input (variable,absolute)
|
||||
0xC0 // End Collection
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// **************************************************************
|
||||
// USB Configuration
|
||||
// **************************************************************
|
||||
|
||||
// USB Configuration Descriptor. This huge descriptor tells all
|
||||
// of the devices capbilities.
|
||||
static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
|
||||
// configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10
|
||||
9, // bLength;
|
||||
2, // bDescriptorType;
|
||||
LSB(CONFIG_DESC_SIZE), // wTotalLength
|
||||
MSB(CONFIG_DESC_SIZE),
|
||||
NUM_INTERFACE, // bNumInterfaces
|
||||
1, // bConfigurationValue
|
||||
0, // iConfiguration
|
||||
0xC0, // bmAttributes
|
||||
50, // bMaxPower
|
||||
|
||||
#ifdef CDC_IAD_DESCRIPTOR
|
||||
// interface association descriptor, USB ECN, Table 9-Z
|
||||
8, // bLength
|
||||
11, // bDescriptorType
|
||||
CDC_STATUS_INTERFACE, // bFirstInterface
|
||||
2, // bInterfaceCount
|
||||
0x02, // bFunctionClass
|
||||
0x02, // bFunctionSubClass
|
||||
0x01, // bFunctionProtocol
|
||||
4, // iFunction
|
||||
#endif
|
||||
|
||||
#ifdef CDC_DATA_INTERFACE
|
||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
|
||||
9, // bLength
|
||||
4, // bDescriptorType
|
||||
CDC_STATUS_INTERFACE, // bInterfaceNumber
|
||||
0, // bAlternateSetting
|
||||
1, // bNumEndpoints
|
||||
0x02, // bInterfaceClass
|
||||
0x02, // bInterfaceSubClass
|
||||
0x01, // bInterfaceProtocol
|
||||
0, // iInterface
|
||||
// CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26
|
||||
5, // bFunctionLength
|
||||
0x24, // bDescriptorType
|
||||
0x00, // bDescriptorSubtype
|
||||
0x10, 0x01, // bcdCDC
|
||||
// Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27
|
||||
5, // bFunctionLength
|
||||
0x24, // bDescriptorType
|
||||
0x01, // bDescriptorSubtype
|
||||
0x01, // bmCapabilities
|
||||
1, // bDataInterface
|
||||
// Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28
|
||||
4, // bFunctionLength
|
||||
0x24, // bDescriptorType
|
||||
0x02, // bDescriptorSubtype
|
||||
0x06, // bmCapabilities
|
||||
// Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33
|
||||
5, // bFunctionLength
|
||||
0x24, // bDescriptorType
|
||||
0x06, // bDescriptorSubtype
|
||||
CDC_STATUS_INTERFACE, // bMasterInterface
|
||||
CDC_DATA_INTERFACE, // bSlaveInterface0
|
||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
|
||||
7, // bLength
|
||||
5, // bDescriptorType
|
||||
CDC_ACM_ENDPOINT | 0x80, // bEndpointAddress
|
||||
0x03, // bmAttributes (0x03=intr)
|
||||
CDC_ACM_SIZE, 0, // wMaxPacketSize
|
||||
64, // bInterval
|
||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
|
||||
9, // bLength
|
||||
4, // bDescriptorType
|
||||
CDC_DATA_INTERFACE, // bInterfaceNumber
|
||||
0, // bAlternateSetting
|
||||
2, // bNumEndpoints
|
||||
0x0A, // bInterfaceClass
|
||||
0x00, // bInterfaceSubClass
|
||||
0x00, // bInterfaceProtocol
|
||||
0, // iInterface
|
||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
|
||||
7, // bLength
|
||||
5, // bDescriptorType
|
||||
CDC_RX_ENDPOINT, // bEndpointAddress
|
||||
0x02, // bmAttributes (0x02=bulk)
|
||||
CDC_RX_SIZE, 0, // wMaxPacketSize
|
||||
0, // bInterval
|
||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
|
||||
7, // bLength
|
||||
5, // bDescriptorType
|
||||
CDC_TX_ENDPOINT | 0x80, // bEndpointAddress
|
||||
0x02, // bmAttributes (0x02=bulk)
|
||||
CDC_TX_SIZE, 0, // wMaxPacketSize
|
||||
0, // bInterval
|
||||
#endif // CDC_DATA_INTERFACE
|
||||
|
||||
#ifdef KEYBOARD_INTERFACE
|
||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
|
||||
9, // bLength
|
||||
4, // bDescriptorType
|
||||
KEYBOARD_INTERFACE, // bInterfaceNumber
|
||||
0, // bAlternateSetting
|
||||
1, // bNumEndpoints
|
||||
0x03, // bInterfaceClass (0x03 = HID)
|
||||
0x01, // bInterfaceSubClass (0x01 = Boot)
|
||||
0x01, // bInterfaceProtocol (0x01 = Keyboard)
|
||||
0, // iInterface
|
||||
// HID interface descriptor, HID 1.11 spec, section 6.2.1
|
||||
9, // bLength
|
||||
0x21, // bDescriptorType
|
||||
0x11, 0x01, // bcdHID
|
||||
0, // bCountryCode
|
||||
1, // bNumDescriptors
|
||||
0x22, // bDescriptorType
|
||||
LSB(sizeof(keyboard_report_desc)), // wDescriptorLength
|
||||
MSB(sizeof(keyboard_report_desc)),
|
||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
|
||||
7, // bLength
|
||||
5, // bDescriptorType
|
||||
KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress
|
||||
0x03, // bmAttributes (0x03=intr)
|
||||
KEYBOARD_SIZE, 0, // wMaxPacketSize
|
||||
KEYBOARD_INTERVAL, // bInterval
|
||||
#endif // KEYBOARD_INTERFACE
|
||||
|
||||
#ifdef MOUSE_INTERFACE
|
||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
|
||||
9, // bLength
|
||||
4, // bDescriptorType
|
||||
MOUSE_INTERFACE, // bInterfaceNumber
|
||||
0, // bAlternateSetting
|
||||
1, // bNumEndpoints
|
||||
0x03, // bInterfaceClass (0x03 = HID)
|
||||
0x01, // bInterfaceSubClass (0x01 = Boot)
|
||||
0x02, // bInterfaceProtocol (0x02 = Mouse)
|
||||
0, // iInterface
|
||||
// HID interface descriptor, HID 1.11 spec, section 6.2.1
|
||||
9, // bLength
|
||||
0x21, // bDescriptorType
|
||||
0x11, 0x01, // bcdHID
|
||||
0, // bCountryCode
|
||||
1, // bNumDescriptors
|
||||
0x22, // bDescriptorType
|
||||
LSB(sizeof(mouse_report_desc)), // wDescriptorLength
|
||||
MSB(sizeof(mouse_report_desc)),
|
||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
|
||||
7, // bLength
|
||||
5, // bDescriptorType
|
||||
MOUSE_ENDPOINT | 0x80, // bEndpointAddress
|
||||
0x03, // bmAttributes (0x03=intr)
|
||||
MOUSE_SIZE, 0, // wMaxPacketSize
|
||||
MOUSE_INTERVAL, // bInterval
|
||||
#endif // MOUSE_INTERFACE
|
||||
|
||||
#ifdef JOYSTICK_INTERFACE
|
||||
// interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12
|
||||
9, // bLength
|
||||
4, // bDescriptorType
|
||||
JOYSTICK_INTERFACE, // bInterfaceNumber
|
||||
0, // bAlternateSetting
|
||||
1, // bNumEndpoints
|
||||
0x03, // bInterfaceClass (0x03 = HID)
|
||||
0x00, // bInterfaceSubClass
|
||||
0x00, // bInterfaceProtocol
|
||||
0, // iInterface
|
||||
// HID interface descriptor, HID 1.11 spec, section 6.2.1
|
||||
9, // bLength
|
||||
0x21, // bDescriptorType
|
||||
0x11, 0x01, // bcdHID
|
||||
0, // bCountryCode
|
||||
1, // bNumDescriptors
|
||||
0x22, // bDescriptorType
|
||||
LSB(sizeof(joystick_report_desc)), // wDescriptorLength
|
||||
MSB(sizeof(joystick_report_desc)),
|
||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13
|
||||
7, // bLength
|
||||
5, // bDescriptorType
|
||||
JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress
|
||||
0x03, // bmAttributes (0x03=intr)
|
||||
JOYSTICK_SIZE, 0, // wMaxPacketSize
|
||||
JOYSTICK_INTERVAL, // bInterval
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
// **************************************************************
|
||||
// String Descriptors
|
||||
// **************************************************************
|
||||
|
||||
// The descriptors above can provide human readable strings,
|
||||
// referenced by index numbers. These descriptors are the
|
||||
// actual string data
|
||||
|
||||
struct usb_string_descriptor_struct {
|
||||
uint8_t bLength;
|
||||
uint8_t bDescriptorType;
|
||||
uint16_t wString[];
|
||||
};
|
||||
|
||||
static struct usb_string_descriptor_struct string0 = {
|
||||
4,
|
||||
3,
|
||||
{0x0409}
|
||||
};
|
||||
|
||||
static struct usb_string_descriptor_struct string1 = {
|
||||
2 + MANUFACTURER_NAME_LEN * 2,
|
||||
3,
|
||||
MANUFACTURER_NAME
|
||||
};
|
||||
static struct usb_string_descriptor_struct string2 = {
|
||||
2 + PRODUCT_NAME_LEN * 2,
|
||||
3,
|
||||
PRODUCT_NAME
|
||||
};
|
||||
static struct usb_string_descriptor_struct string3 = {
|
||||
12,
|
||||
3,
|
||||
{'1','2','3','4','5'}
|
||||
};
|
||||
|
||||
|
||||
// **************************************************************
|
||||
// Descriptors List
|
||||
// **************************************************************
|
||||
|
||||
// This table provides access to all the descriptor data above.
|
||||
|
||||
const usb_descriptor_list_t usb_descriptor_list[] = {
|
||||
//wValue, wIndex, address, length
|
||||
{0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)},
|
||||
{0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)},
|
||||
#ifdef KEYBOARD_INTERFACE
|
||||
{0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)},
|
||||
{0x2100, KEYBOARD_INTERFACE, config_descriptor+KEYBOARD_DESC_OFFSET, 9},
|
||||
#endif
|
||||
#ifdef MOUSE_INTERFACE
|
||||
{0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)},
|
||||
{0x2100, MOUSE_INTERFACE, config_descriptor+MOUSE_DESC_OFFSET, 9},
|
||||
#endif
|
||||
#ifdef JOYSTICK_INTERFACE
|
||||
{0x2200, JOYSTICK_INTERFACE, joystick_report_desc, sizeof(joystick_report_desc)},
|
||||
{0x2100, JOYSTICK_INTERFACE, config_descriptor+JOYSTICK_DESC_OFFSET, 9},
|
||||
#endif
|
||||
{0x0300, 0x0000, (const uint8_t *)&string0, 4},
|
||||
{0x0301, 0x0409, (const uint8_t *)&string1, 2 + MANUFACTURER_NAME_LEN * 2},
|
||||
{0x0302, 0x0409, (const uint8_t *)&string2, 2 + PRODUCT_NAME_LEN * 2},
|
||||
{0x0303, 0x0409, (const uint8_t *)&string3, 12},
|
||||
{0, 0, NULL, 0}
|
||||
};
|
||||
|
||||
|
||||
// **************************************************************
|
||||
// Endpoint Configuration
|
||||
// **************************************************************
|
||||
|
||||
#if 0
|
||||
// 0x00 = not used
|
||||
// 0x19 = Recieve only
|
||||
// 0x15 = Transmit only
|
||||
// 0x1D = Transmit & Recieve
|
||||
//
|
||||
const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] =
|
||||
{
|
||||
0x00, 0x15, 0x19, 0x15, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] =
|
||||
{
|
||||
#if (defined(ENDPOINT1_CONFIG) && NUM_ENDPOINTS >= 1)
|
||||
ENDPOINT1_CONFIG,
|
||||
#elif (NUM_ENDPOINTS >= 1)
|
||||
ENDPOINT_UNUSED,
|
||||
#endif
|
||||
#if (defined(ENDPOINT2_CONFIG) && NUM_ENDPOINTS >= 2)
|
||||
ENDPOINT2_CONFIG,
|
||||
#elif (NUM_ENDPOINTS >= 2)
|
||||
ENDPOINT_UNUSED,
|
||||
#endif
|
||||
#if (defined(ENDPOINT3_CONFIG) && NUM_ENDPOINTS >= 3)
|
||||
ENDPOINT3_CONFIG,
|
||||
#elif (NUM_ENDPOINTS >= 3)
|
||||
ENDPOINT_UNUSED,
|
||||
#endif
|
||||
#if (defined(ENDPOINT4_CONFIG) && NUM_ENDPOINTS >= 4)
|
||||
ENDPOINT4_CONFIG,
|
||||
#elif (NUM_ENDPOINTS >= 4)
|
||||
ENDPOINT_UNUSED,
|
||||
#endif
|
||||
#if (defined(ENDPOINT5_CONFIG) && NUM_ENDPOINTS >= 5)
|
||||
ENDPOINT5_CONFIG,
|
||||
#elif (NUM_ENDPOINTS >= 5)
|
||||
ENDPOINT_UNUSED,
|
||||
#endif
|
||||
#if (defined(ENDPOINT6_CONFIG) && NUM_ENDPOINTS >= 6)
|
||||
ENDPOINT6_CONFIG,
|
||||
#elif (NUM_ENDPOINTS >= 6)
|
||||
ENDPOINT_UNUSED,
|
||||
#endif
|
||||
#if (defined(ENDPOINT7_CONFIG) && NUM_ENDPOINTS >= 7)
|
||||
ENDPOINT7_CONFIG,
|
||||