From 54c11ebd0785676b078e85cf3f9f57e72c1e5dc3 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Tue, 15 Jul 2014 00:28:12 -0700 Subject: [PATCH] McHCK USB WORKS!! - McHCK uses FLL instead of the PLL for USB (startup, not usb init) - Added optional debug for the pjrc USB module - Cleaned up compiler flags --- CMakeLists.txt | 2 +- Debug/print/print.c | 49 ++++++++++++++++++++++++++++++++++ Debug/print/print.h | 29 +++++++++++--------- Lib/CMake/arm.cmake | 2 +- Lib/CMake/modules.cmake | 2 +- Lib/mk20dx.c | 32 ++++++++++++++-------- Lib/mk20dx128.ld | 2 ++ Lib/mk20dx128vlf5.ld | 1 + Output/pjrcUSB/arm/usb_dev.c | 49 +++++++++++++++++++++------------- Output/pjrcUSB/arm/usb_dev.h | 6 ++--- Output/pjrcUSB/output_com.c | 5 +--- Output/usbMuxUart/output_com.c | 7 +---- 12 files changed, 128 insertions(+), 58 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aed3b4a..4ec941c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,7 +53,7 @@ set( ScanModule "MDPure" ) set( MacroModule "PartialMap" ) ##| Sends the current list of usb key codes through USB HID -set( OutputModule "uartOut" ) +set( OutputModule "pjrcUSB" ) ##| Debugging source to use, each module has it's own set of defines that it sets set( DebugModule "full" ) diff --git a/Debug/print/print.c b/Debug/print/print.c index efe280b..e5d1968 100644 --- a/Debug/print/print.c +++ b/Debug/print/print.c @@ -122,6 +122,20 @@ void printHex_op( uint16_t in, uint8_t op ) dPrintStr( tmpStr ); } +void printHex32_op( uint32_t in, uint8_t op ) +{ + // With an op of 1, the max number of characters is 6 + 1 for null + // e.g. "0xFFFF\0" + // op 2 and 4 require fewer characters (2+1 and 4+1 respectively) + char tmpStr[7]; + + // Convert number + hex32ToStr_op( in, tmpStr, op ); + + // Print number + dPrintStr( tmpStr ); +} + // String Functions @@ -223,6 +237,41 @@ void hexToStr_op( uint16_t in, char* out, uint8_t op ) } +void hex32ToStr_op( uint32_t in, char* out, uint8_t op ) +{ + // Position container + uint32_t pos = 0; + + // Evaluate through digits as hex + do + { + uint32_t cur = in % 16; + out[pos++] = cur + (( cur < 10 ) ? '0' : 'A' - 10); + } + while ( (in /= 16) > 0 ); + + // Output formatting options + switch ( op ) + { + case 1: // Add 0x + out[pos++] = 'x'; + out[pos++] = '0'; + break; + case 2: // 8-bit padding + case 4: // 16-bit padding + while ( pos < op ) + out[pos++] = '0'; + break; + } + + // Append null + out[pos] = '\0'; + + // Reverse the string to the correct order + revsStr(out); +} + + void revsStr( char* in ) { // Iterators diff --git a/Debug/print/print.h b/Debug/print/print.h index a62a9b6..14628f6 100644 --- a/Debug/print/print.h +++ b/Debug/print/print.h @@ -93,25 +93,28 @@ void printstrs( char* first, ... ); // Printing numbers -#define printHex(hex) printHex_op(hex, 1) +#define printHex(hex) printHex_op(hex, 1) +#define printHex32(hex) printHex32_op(hex, 1) -void printInt8 ( uint8_t in ); -void printInt16 ( uint16_t in ); -void printInt32 ( uint32_t in ); -void printHex_op( uint16_t in, uint8_t op ); +void printInt8 ( uint8_t in ); +void printInt16 ( uint16_t in ); +void printInt32 ( uint32_t in ); +void printHex_op ( uint16_t in, uint8_t op ); +void printHex32_op( uint32_t in, uint8_t op ); // String Functions #define hexToStr(hex, out) hexToStr_op(hex, out, 1) -void int8ToStr ( uint8_t in, char* out ); -void int16ToStr ( uint16_t in, char* out ); -void int32ToStr ( uint32_t in, char* out ); -void hexToStr_op( uint16_t in, char* out, uint8_t op ); -void revsStr ( char* in ); -uint16_t lenStr ( char* in ); -int16_t eqStr ( char* str1, char* str2 ); // Returns -1 if identical, last character of str1 comparison (0 if str1 is like str2) -int decToInt ( char* in ); // Returns the int representation of a string +void int8ToStr ( uint8_t in, char* out ); +void int16ToStr ( uint16_t in, char* out ); +void int32ToStr ( uint32_t in, char* out ); +void hexToStr_op ( uint16_t in, char* out, uint8_t op ); +void hex32ToStr_op( uint32_t in, char* out, uint8_t op ); +void revsStr ( char* in ); +uint16_t lenStr ( char* in ); +int16_t eqStr ( char* str1, char* str2 ); // Returns -1 if identical, last character of str1 comparison (0 if str1 is like str2) +int decToInt ( char* in ); // Returns the int representation of a string #endif diff --git a/Lib/CMake/arm.cmake b/Lib/CMake/arm.cmake index 45a60ea..1f8ca42 100644 --- a/Lib/CMake/arm.cmake +++ b/Lib/CMake/arm.cmake @@ -109,7 +109,7 @@ set( WARN "-Wall -g" ) #| Tuning Options #| -f...: tuning, see GCC manual #| NOTE: -fshort-wchar is specified to allow USB strings be passed conveniently -set( TUNING "-mthumb -nostdlib -fdata-sections -ffunction-sections -fshort-wchar -fno-builtin -flto -fno-use-linker-plugin" ) +set( TUNING "-mthumb -nostdlib -fdata-sections -ffunction-sections -fshort-wchar -fno-builtin" ) #| Optimization level, can be [0, 1, 2, 3, s]. diff --git a/Lib/CMake/modules.cmake b/Lib/CMake/modules.cmake index b73b3b6..35b3e2b 100644 --- a/Lib/CMake/modules.cmake +++ b/Lib/CMake/modules.cmake @@ -287,7 +287,7 @@ set_target_properties( ${TARGET_ELF} PROPERTIES #| Convert the .ELF into a .bin to load onto the McHCK -set( TARGET_BIN ${TARGET}.dfu.bin ) +set( TARGET_BIN ${TARGET}.bin.dfu ) add_custom_command( TARGET ${TARGET_ELF} POST_BUILD COMMAND ${CMAKE_OBJCOPY} ${BIN_FLAGS} ${TARGET_ELF} ${TARGET_BIN} COMMENT "Creating binary file to load: ${TARGET_BIN}" diff --git a/Lib/mk20dx.c b/Lib/mk20dx.c index 3f2b51e..5217b01 100644 --- a/Lib/mk20dx.c +++ b/Lib/mk20dx.c @@ -31,6 +31,7 @@ // Local Includes #include "mk20dx.h" +#include @@ -365,19 +366,19 @@ void ResetHandler() uint32_t *src = &_etext; uint32_t *dest = &_sdata; - /* Disable Watchdog */ + // Disable Watchdog WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE; - // enable clocks to always-used peripherals -#if defined(_mk20dx128_) || defined(_mk20dx128vlf5_) - 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; + // Enable clocks to always-used peripherals + SIM_SCGC5 = 0x00043F82; // Clocks active to all GPIO + SIM_SCGC6 = SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL; +#if defined(_mk20dx128_) + SIM_SCGC6 |= SIM_SCGC6_RTC; #elif defined(_mk20dx256_) SIM_SCGC3 = SIM_SCGC3_ADC1 | SIM_SCGC3_FTM2; - 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; + SIM_SCGC6 |= SIM_SCGC6_RTC; #endif #if defined(_mk20dx128_) || defined(_mk20dx256_) // Teensy 3s @@ -390,7 +391,10 @@ void ResetHandler() #endif // release I/O pins hold, if we woke up from VLLS mode - if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO; + if ( PMC_REGSC & PMC_REGSC_ACKISO ) + { + PMC_REGSC |= PMC_REGSC_ACKISO; + } // Prepare RAM while ( dest < &_edata ) *dest++ = *src++; @@ -399,11 +403,17 @@ void ResetHandler() // MCHCK #if defined(_mk20dx128vlf5_) - /* FLL at 48MHz */ + // Default all interrupts to medium priority level + for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ ) + { + NVIC_SET_PRIORITY( i, 128 ); + } + + // FLL at 48MHz MCG_C4 = MCG_C4_DMX32 | MCG_C4_DRST_DRS( 1 ); - //SIM_SOPT2 = SIM_SOPT2_PLLFLLSEL; - SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL( 6 ); + // USB Clock and FLL select + SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_TRACECLKSEL; // Teensy 3.0 and 3.1 #else diff --git a/Lib/mk20dx128.ld b/Lib/mk20dx128.ld index 7644fbf..e246d38 100644 --- a/Lib/mk20dx128.ld +++ b/Lib/mk20dx128.ld @@ -48,6 +48,7 @@ SECTIONS *(.rodata*) . = ALIGN(4); KEEP(*(.init)) + . = ALIGN(4); __preinit_array_start = .; KEEP (*(.preinit_array)) @@ -56,6 +57,7 @@ SECTIONS KEEP (*(SORT(.init_array.*))) KEEP (*(.init_array)) __init_array_end = .; + } > FLASH = 0xFF .ARM.exidx : { diff --git a/Lib/mk20dx128vlf5.ld b/Lib/mk20dx128vlf5.ld index db011c2..d4b3e41 100644 --- a/Lib/mk20dx128vlf5.ld +++ b/Lib/mk20dx128vlf5.ld @@ -44,6 +44,7 @@ SECTIONS KEEP(* (.vectors)) *(.startup*) *(.text*) + *(.rodata*) . = ALIGN(4); KEEP(*(.init)) } > FLASH diff --git a/Output/pjrcUSB/arm/usb_dev.c b/Output/pjrcUSB/arm/usb_dev.c index f4bf2fc..a0366cf 100644 --- a/Output/pjrcUSB/arm/usb_dev.c +++ b/Output/pjrcUSB/arm/usb_dev.c @@ -1,6 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. + * Modified by Jacob Alexander 2013-2014 * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -10,10 +11,10 @@ * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * - * 1. The above copyright notice and this permission notice shall be + * 1. The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * - * 2. If the Software is incorporated into a build system that allows + * 2. If the Software is incorporated into a build system that allows * selection among a list of target devices, then similar target * devices manufactured by PJRC.COM must be included in the list of * target devices and selectable in the same manner. @@ -28,7 +29,11 @@ * SOFTWARE. */ +// Project Includes #include +#include + +// Local Includes #include "usb_dev.h" #include "usb_mem.h" @@ -125,14 +130,16 @@ volatile uint8_t usb_configuration = 0; volatile uint8_t usb_reboot_timer = 0; -static void endpoint0_stall(void) +static void endpoint0_stall() { + //print("STALL"); USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; } static void endpoint0_transmit(const void *data, uint32_t len) { + //print("TRANSMIT"); #if 0 serial_print("tx0:"); serial_phex32((uint32_t)data); @@ -149,8 +156,9 @@ static void endpoint0_transmit(const void *data, uint32_t len) static uint8_t reply_buffer[8]; -static void usb_setup(void) +static void usb_setup() { + //print("SETUP"); const uint8_t *data = NULL; uint32_t datalen = 0; const usb_descriptor_list_t *list; @@ -387,6 +395,7 @@ static void usb_setup(void) static void usb_control(uint32_t stat) { + //print("CONTROL"); bdt_t *b; uint32_t pid, size; uint8_t *buf; @@ -527,6 +536,7 @@ static uint8_t tx_state[NUM_ENDPOINTS]; usb_packet_t *usb_rx(uint32_t endpoint) { + //print("USB RX"); usb_packet_t *ret; endpoint--; if (endpoint >= NUM_ENDPOINTS) return NULL; @@ -586,6 +596,7 @@ uint32_t usb_tx_packet_count(uint32_t endpoint) // void usb_rx_memory(usb_packet_t *packet) { + //print("USB RX MEMORY"); unsigned int i; const uint8_t *cfg; @@ -617,7 +628,7 @@ void usb_rx_memory(usb_packet_t *packet) __enable_irq(); // we should never reach this point. If we get here, it means // usb_rx_memory_needed was set greater than zero, but no memory - // was actually needed. + // was actually needed. usb_rx_memory_needed = 0; usb_free(packet); return; @@ -675,7 +686,7 @@ void usb_device_reload() } -void usb_isr(void) +void usb_isr() { uint8_t status, stat, t; @@ -685,6 +696,11 @@ void usb_isr(void) //serial_print("\n"); restart: status = USB0_ISTAT; + /* + print("USB ISR STATUS: "); + printHex( status ); + print( NL ); + */ if ((status & USB_INTEN_SOFTOKEN /* 04 */ )) { if (usb_configuration) { @@ -885,16 +901,13 @@ void usb_isr(void) -void usb_init(void) +void usb_init() { - int i; + //print("USB INIT"); - //serial_begin(BAUD2DIV(115200)); - //serial_print("usb_init\n"); - - //usb_init_serialnumber(); - - for (i=0; i <= NUM_ENDPOINTS*4; i++) { + // Clear out endpoints table + for ( int i = 0; i <= NUM_ENDPOINTS * 4; i++ ) + { table[i].desc = 0; table[i].addr = 0; } @@ -908,7 +921,7 @@ void usb_init(void) // reset USB module USB0_USBTRC0 = USB_USBTRC_USBRESET; - while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) ; // wait for reset to end + while ( (USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0 ); // wait for reset to end // set desc table base addr USB0_BDTPAGE1 = ((uint32_t)table) >> 8; @@ -930,8 +943,8 @@ void usb_init(void) USB0_INTEN = USB_INTEN_USBRSTEN; // enable interrupt in NVIC... - NVIC_SET_PRIORITY(IRQ_USBOTG, 112); - NVIC_ENABLE_IRQ(IRQ_USBOTG); + NVIC_SET_PRIORITY( IRQ_USBOTG, 112 ); + NVIC_ENABLE_IRQ( IRQ_USBOTG ); // enable d+ pullup USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG; @@ -939,7 +952,7 @@ void usb_init(void) // return 0 if the USB is not configured, or the configuration // number selected by the HOST -uint8_t usb_configured(void) +uint8_t usb_configured() { return usb_configuration; } diff --git a/Output/pjrcUSB/arm/usb_dev.h b/Output/pjrcUSB/arm/usb_dev.h index cc24af6..96b5f84 100644 --- a/Output/pjrcUSB/arm/usb_dev.h +++ b/Output/pjrcUSB/arm/usb_dev.h @@ -39,9 +39,9 @@ #include "usb_mem.h" #include "usb_desc.h" -void usb_init(void); -uint8_t usb_configured(void); // is the USB port configured -void usb_isr(void); +void usb_init(); +uint8_t usb_configured(); // is the USB port configured +void usb_isr(); usb_packet_t *usb_rx(uint32_t endpoint); uint32_t usb_tx_byte_count(uint32_t endpoint); uint32_t usb_tx_packet_count(uint32_t endpoint); diff --git a/Output/pjrcUSB/output_com.c b/Output/pjrcUSB/output_com.c index dea6a3d..79f9f2f 100644 --- a/Output/pjrcUSB/output_com.c +++ b/Output/pjrcUSB/output_com.c @@ -105,10 +105,7 @@ inline void Output_setup() // If the Teensy is powered without a PC connected to the USB port, // this will wait forever. usb_init(); -#include -init_errorLED(); -errorLED( 1 ); -while(1); + while ( !usb_configured() ) /* wait */ ; // Register USB Output CLI dictionary diff --git a/Output/usbMuxUart/output_com.c b/Output/usbMuxUart/output_com.c index 5011ece..f08e088 100644 --- a/Output/usbMuxUart/output_com.c +++ b/Output/usbMuxUart/output_com.c @@ -109,12 +109,7 @@ inline void Output_setup() // If the Teensy is powered without a PC connected to the USB port, // this will wait forever. usb_init(); -/* -#include -init_errorLED(); -errorLED( 1 ); -while(1); -*/ + // Setup UART uart_serial_setup();