]> git.donarmstrong.com Git - kiibohd-controller.git/commitdiff
Adding dynamic USB power support
authorJacob Alexander <haata@kiibohd.com>
Mon, 22 Feb 2016 03:56:52 +0000 (19:56 -0800)
committerJacob Alexander <haata@kiibohd.com>
Mon, 22 Feb 2016 03:56:52 +0000 (19:56 -0800)
- Each scan module now has a current change callback which passes the available current as a parameter
- No longer attempts to use the max 500 mA immediately, starts with 100 mA then goes to 500 mA after enumeration
- If enumeration fails due to bMaxPower of 500 mA, then attempt again at 100 mA (might also be possible to go even lower to 20 mA in certain cases)
- Now working with the Apple Ipad (no over-power messages)
- Fixed Wake-up behaviour on Apple Ipad (and likely other iOS devices)
- More effecient set_feature/clear_feature handling (device handler)
- Initial power handling via Interconnect (still needs work to get it more dynamic)

25 files changed:
Output/pjrcUSB/arm/usb_desc.c
Output/pjrcUSB/arm/usb_desc.h
Output/pjrcUSB/arm/usb_dev.c
Output/pjrcUSB/arm/usb_dev.h
Output/pjrcUSB/output_com.c
Output/pjrcUSB/output_com.h
Output/usbMuxUart/output_com.c
Scan/ISSILed/led_scan.c
Scan/ISSILed/led_scan.h
Scan/KType/scan_loop.c
Scan/KType/scan_loop.h
Scan/MD1.1/scan_loop.c
Scan/MD1.1/scan_loop.h
Scan/MD1/scan_loop.c
Scan/MD1/scan_loop.h
Scan/MDErgo1/scan_loop.c
Scan/MDErgo1/scan_loop.h
Scan/MatrixARM/matrix_scan.c
Scan/MatrixARM/matrix_scan.h
Scan/STLcd/lcd_scan.c
Scan/STLcd/lcd_scan.h
Scan/UARTConnect/connect_scan.c
Scan/UARTConnect/connect_scan.h
Scan/WhiteFox/scan_loop.c
Scan/WhiteFox/scan_loop.h

index b7cb7357692d7f020df89f92d03bfc1326d2d23e..1d9a939ca02771fc592c3019403061ee7791496d 100644 (file)
@@ -1,7 +1,7 @@
 /* Teensyduino Core Library
  * http://www.pjrc.com/teensy/
  * Copyright (c) 2013 PJRC.COM, LLC.
- * Modified by Jacob Alexander (2013-2015)
+ * Modified by Jacob Alexander (2013-2016)
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -451,7 +451,7 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
        1,                                      // bConfigurationValue
        0,                                      // iConfiguration
        0xA0,                                   // bmAttributes
-       250,                                    // bMaxPower
+       250,                                    // bMaxPower - Entry Index 8
 
 // --- Keyboard HID --- Boot Mode Keyboard Interface
 // - 9 bytes -
@@ -695,6 +695,8 @@ static uint8_t config_descriptor[CONFIG_DESC_SIZE] = {
        SYS_CTRL_INTERVAL,                      // bInterval
 };
 
+uint8_t *usb_bMaxPower = &config_descriptor[8];
+
 
 
 // ----- String Descriptors -----
index 33c65898992992fef4b742f9a4765cd77b440774..0e769a18d32af2872bbbb00b1a1706055a758aea 100644 (file)
@@ -1,7 +1,7 @@
 /* Teensyduino Core Library
  * http://www.pjrc.com/teensy/
  * Copyright (c) 2013 PJRC.COM, LLC.
- * Modified by Jacob Alexander (2013-2015)
+ * Modified by Jacob Alexander (2013-2016)
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -137,3 +137,5 @@ extern const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS];
 
 extern const usb_descriptor_list_t usb_descriptor_list[];
 
+extern uint8_t *usb_bMaxPower;
+
index 782f3ace91d024a4e1d5c8bec32cb3b57db762b1..c0e45662a816ae1f11fb4cf5252aa0df4987011f 100644 (file)
@@ -1,7 +1,7 @@
 /* Teensyduino Core Library
  * http://www.pjrc.com/teensy/
  * Copyright (c) 2013 PJRC.COM, LLC.
- * Modifications by Jacob Alexander (2013-2015)
+ * Modifications by Jacob Alexander (2013-2016)
  *
  * Permission is hereby granted, free of charge, to any person obtaining
  * a copy of this software and associated documentation files (the
@@ -168,6 +168,9 @@ volatile uint8_t usb_reboot_timer = 0;
 
 static uint8_t reply_buffer[8];
 
+static uint8_t power_neg_delay;
+static uint32_t power_neg_time;
+
 
 
 // ----- Functions -----
@@ -188,6 +191,34 @@ static void endpoint0_transmit( const void *data, uint32_t len )
        ep0_tx_bdt_bank ^= 1;
 }
 
+// Used to check any USB state changes that may not have a proper interrupt
+// Called once per scan loop, should take minimal processing time or it may affect other modules
+void usb_device_check()
+{
+       // Check to see if we're still waiting for the next USB request after Get Configuration Descriptor
+       // If still waiting, restart the USB initialization with a lower power requirement
+       if ( power_neg_delay )
+       {
+               // Check if 100 ms has elapsed
+               if ( systick_millis_count - power_neg_time > 100 )
+               {
+                       // Update bMaxPower
+                       // The value set is in increments of 2 mA
+                       // So 50 * 2 mA = 100 mA
+                       // XXX Currently only transitions to 100 mA
+                       //     It may be possible to transition down again to 20 mA
+                       *usb_bMaxPower = 50;
+
+                       // Re-initialize USB
+                       power_neg_delay = 0;
+                       usb_configuration = 0; // Clear USB configuration if we have one
+                       USB0_CONTROL = 0; // Disable D+ Pullup to simulate disconnect
+                       delay(10); // Delay is necessary to simulate disconnect
+                       usb_init();
+               }
+       }
+}
+
 static void usb_setup()
 {
        const uint8_t *data = NULL;
@@ -199,6 +230,13 @@ static void usb_setup()
        const uint8_t *cfg;
        int i;
 
+       // If another request is made, disable the power negotiation check
+       // See GET_DESCRIPTOR - Configuration
+       if ( power_neg_delay )
+       {
+               power_neg_delay = 0;
+       }
+
        switch ( setup.wRequestAndType )
        {
        case 0x0500: // SET_ADDRESS
@@ -212,6 +250,10 @@ static void usb_setup()
                Output_Available = usb_configuration;
                reg = &USB0_ENDPT1;
                cfg = usb_endpoint_config_table;
+
+               // Now configured so we can utilize bMaxPower now
+               Output_update_usb_current( *usb_bMaxPower * 2 );
+
                // clear all BDT entries, free any allocated memory...
                for ( i = 4; i < ( NUM_ENDPOINTS + 1) * 4; i++ )
                {
@@ -324,9 +366,27 @@ static void usb_setup()
                goto send;
 
        case 0x0100: // CLEAR_FEATURE (device)
+               switch ( setup.wValue )
+               {
+               // CLEAR_FEATURE(DEVICE_REMOTE_WAKEUP)
+               // See SET_FEATURE(DEVICE_REMOTE_WAKEUP) for details
+               case 0x1:
+                       goto send;
+               }
+
+               warn_msg("SET_FEATURE - Device wValue(");
+               printHex( setup.wValue );
+               print( ")" NL );
+               endpoint0_stall();
+               return;
+
        case 0x0101: // CLEAR_FEATURE (interface)
                // TODO: Currently ignoring, perhaps useful? -HaaTa
-               warn_print("CLEAR_FEATURE - Device/Interface");
+               warn_msg("CLEAR_FEATURE - Interface wValue(");
+               printHex( setup.wValue );
+               print(") wIndex(");
+               printHex( setup.wIndex );
+               print( ")" NL );
                endpoint0_stall();
                return;
 
@@ -342,9 +402,30 @@ static void usb_setup()
                goto send;
 
        case 0x0300: // SET_FEATURE (device)
+               switch ( setup.wValue )
+               {
+               // SET_FEATURE(DEVICE_REMOTE_WAKEUP)
+               // XXX: Only used to confirm Remote Wake
+               //      Used on Mac OSX and Windows not on Linux
+               // Good post on the behaviour:
+               // http://community.silabs.com/t5/8-bit-MCU/Remote-wakeup-HID/m-p/74957#M30802
+               case 0x1:
+                       goto send;
+               }
+
+               warn_msg("SET_FEATURE - Device wValue(");
+               printHex( setup.wValue );
+               print( ")" NL );
+               endpoint0_stall();
+               return;
+
        case 0x0301: // SET_FEATURE (interface)
                // TODO: Currently ignoring, perhaps useful? -HaaTa
-               warn_print("SET_FEATURE - Device/Interface");
+               warn_msg("SET_FEATURE - Interface wValue(");
+               printHex( setup.wValue );
+               print(") wIndex(");
+               printHex( setup.wIndex );
+               print( ")" NL );
                endpoint0_stall();
                return;
 
@@ -385,6 +466,27 @@ static void usb_setup()
                                {
                                        datalen = list->length;
                                }
+
+                               // XXX Power negotiation hack -HaaTa
+                               // Some devices such as the Apple Ipad do not support bMaxPower greater than 100 mA
+                               // However, there is no provision in the basic USB 2.0 stack for power negotiation
+                               // To get around this:
+                               //  * Attempt to set bMaxPower to 500 mA first
+                               //  * If more than 100 ms passes since retrieving a Get Configuration Descriptor
+                               //    (Descriptor with bMaxPower in it)
+                               //  * Change usb_bMaxPower to 50 (100 mA)
+                               //  * Restart the USB init process
+                               // According to notes online, it says that some Apple devices can only do 20 mA
+                               // However, in my testing this hasn't been the case
+                               // (you can also draw as much current as you want if you just lie in the descriptor :P)
+                               // If this becomes an issue we can use this hack a second time to negotiate down to 20 mA
+                               // (which should be fine for just the mcu)
+                               if ( setup.wValue == 0x0200 && setup.wIndex == 0x0 )
+                               {
+                                       power_neg_delay = 1;
+                                       power_neg_time = systick_millis_count;
+                               }
+
                                #if UART_DEBUG
                                print("Desc found, ");
                                printHex32( (uint32_t)data );
@@ -862,6 +964,11 @@ void usb_rx_memory( usb_packet_t *packet )
 
 void usb_tx( uint32_t endpoint, usb_packet_t *packet )
 {
+       // Since we are transmitting data, USB will be brought out of sleep/suspend
+       // if it's in that state
+       // Use the currently set descriptor value
+       Output_update_usb_current( *usb_bMaxPower * 2 );
+
        bdt_t *b = &table[ index( endpoint, TX, EVEN ) ];
        uint8_t next;
 
@@ -1161,9 +1268,12 @@ restart:
                USB0_ISTAT = USB_ISTAT_ERROR;
        }
 
+       // USB Host signalling device to enter 'sleep' state
+       // The USB Module triggers this interrupt when it detects the bus has been idle for 3 ms
        if ( (status & USB_ISTAT_SLEEP /* 10 */ ) )
        {
-               //serial_print("sleep\n");
+               info_print("Host has requested USB sleep/suspend state");
+               Output_update_usb_current( 100 ); // Set to 100 mA
                USB0_ISTAT = USB_ISTAT_SLEEP;
        }
 }
@@ -1220,6 +1330,9 @@ uint8_t usb_init()
        // enable d+ pullup
        USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG;
 
+       // Do not check for power negotiation delay until Get Configuration Descriptor
+       power_neg_delay = 0;
+
        return 1;
 }
 
index 0f445de0d30acb08928929fcaf087c890f10fc32..827f843b6f75e9837fd0cb0a6d67b0be0f153440 100644 (file)
@@ -81,6 +81,7 @@ static inline uint32_t usb_rx_byte_count(uint32_t endpoint)
 }
 
 void usb_device_reload();
+void usb_device_check();
 
 extern void usb_serial_flush_callback();
 
index 2e97e42450060c34ee67c1e926825a71747eb2e4..b18bbdb6a4854f62b6edb956331e621b318dc3fe 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2011-2015 by Jacob Alexander
+/* Copyright (C) 2011-2016 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
@@ -137,6 +137,14 @@ volatile uint8_t  Output_Available = 0;
 // 1 - Debug enabled
 uint8_t  Output_DebugMode = 0;
 
+// mA - Set by outside module if not using USB (i.e. Interconnect)
+// Generally set to 100 mA (low power) or 500 mA (high power)
+uint16_t Output_ExtCurrent_Available = 0;
+
+// mA - Set by USB module (if exists)
+// Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
+uint16_t Output_USBCurrent_Available = 0;
+
 
 
 // ----- Capabilities -----
@@ -535,6 +543,10 @@ inline void Output_setup()
 // USB Data Send
 inline void Output_send()
 {
+       // USB status checks
+       // Non-standard USB state manipulation, usually does nothing
+       usb_device_check();
+
        // Boot Mode Only, unset stale keys
        if ( USBKeys_Protocol == 0 )
                for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
@@ -614,6 +626,72 @@ inline void Output_softReset()
 }
 
 
+// Update USB current (mA)
+// Triggers power change event
+void Output_update_usb_current( unsigned int current )
+{
+       // Only signal if changed
+       if ( current == Output_USBCurrent_Available )
+               return;
+
+       // Update USB current
+       Output_USBCurrent_Available = current;
+
+       unsigned int total_current = Output_current_available();
+       info_msg("USB Available Current Changed. Total Available: ");
+       printInt32( total_current );
+       print(" mA" NL);
+
+       // Send new total current to the Scan Modules
+       Scan_currentChange( Output_current_available() );
+}
+
+
+// Update external current (mA)
+// Triggers power change event
+void Output_update_external_current( unsigned int current )
+{
+       // Only signal if changed
+       if ( current == Output_ExtCurrent_Available )
+               return;
+
+       // Update external current
+       Output_ExtCurrent_Available = current;
+
+       unsigned int total_current = Output_current_available();
+       info_msg("External Available Current Changed. Total Available: ");
+       printInt32( total_current );
+       print(" mA" NL);
+
+       // Send new total current to the Scan Modules
+       Scan_currentChange( Output_current_available() );
+}
+
+
+// Power/Current Available
+unsigned int Output_current_available()
+{
+       unsigned int total_current = 0;
+
+       // Check for USB current source
+       total_current += Output_USBCurrent_Available;
+
+       // Check for external current source
+       total_current += Output_ExtCurrent_Available;
+
+       // XXX If the total available current is still 0
+       // Set to 100 mA, which is generally a safe assumption at startup
+       // before we've been able to determine actual available current
+       if ( total_current == 0 )
+       {
+               total_current = 100;
+       }
+
+       return total_current;
+}
+
+
+
 // ----- CLI Command Functions -----
 
 void cliFunc_kbdProtocol( char* args )
index c82ed989964430986df5273bbc1df39d5858da1a..24486837077fe08a98f874a3e6012342e72a2544 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2013-2015 by Jacob Alexander
+/* Copyright (C) 2013-2016 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
@@ -82,6 +82,8 @@ extern volatile uint8_t  Output_Available; // 0 - Output module not fully functi
 
 extern          uint8_t  Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled
 
+extern          uint16_t Output_ExtCurrent_Available; // mA - Set by outside module if not using USB (i.e. Interconnect)
+
 
 
 // ----- Functions -----
@@ -97,6 +99,12 @@ void Output_softReset();
 // Relies on USB serial module
 unsigned int Output_availablechar();
 
+// Returns the total mA available (total, if used in a chain, each device will have to use a slice of it)
+unsigned int Output_current_available();
+
+void Output_update_external_current( unsigned int current );
+void Output_update_usb_current( unsigned int current );
+
 int Output_getchar();
 int Output_putchar( char c );
 int Output_putstr( char* str );
index 44c5b4920bf1c2c6353f2810c7b7d51e59252db7..55c9553004f4633ab547a6d5541b174106ea5ff1 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -143,6 +143,14 @@ volatile uint8_t  Output_Available = 0;
 // 1 - Debug enabled
 uint8_t  Output_DebugMode = 0;
 
+// mA - Set by outside module if not using USB (i.e. Interconnect)
+// Generally set to 100 mA (low power) or 500 mA (high power)
+uint16_t Output_ExtCurrent_Available = 0;
+
+// mA - Set by USB module (if exists)
+// Initially 100 mA, but may be negotiated higher (e.g. 500 mA)
+uint16_t Output_USBCurrent_Available = 0;
+
 
 
 // ----- Capabilities -----
@@ -544,6 +552,10 @@ inline void Output_setup()
 // USB Data Send
 inline void Output_send()
 {
+       // USB status checks
+       // Non-standard USB state manipulation, usually does nothing
+       usb_device_check();
+
        // Boot Mode Only, unset stale keys
        if ( USBKeys_Protocol == 0 )
                for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
@@ -641,6 +653,72 @@ inline void Output_softReset()
 }
 
 
+// Update USB current (mA)
+// Triggers power change event
+void Output_update_usb_current( unsigned int current )
+{
+       // Only signal if changed
+       if ( current == Output_USBCurrent_Available )
+               return;
+
+       // Update USB current
+       Output_USBCurrent_Available = current;
+
+       unsigned int total_current = Output_current_available();
+       info_msg("USB Available Current Changed. Total Available: ");
+       printInt32( total_current );
+       print(" mA" NL);
+
+       // Send new total current to the Scan Modules
+       Scan_currentChange( Output_current_available() );
+}
+
+
+// Update external current (mA)
+// Triggers power change event
+void Output_update_external_current( unsigned int current )
+{
+       // Only signal if changed
+       if ( current == Output_ExtCurrent_Available )
+               return;
+
+       // Update external current
+       Output_ExtCurrent_Available = current;
+
+       unsigned int total_current = Output_current_available();
+       info_msg("External Available Current Changed. Total Available: ");
+       printInt32( total_current );
+       print(" mA" NL);
+
+       // Send new total current to the Scan Modules
+       Scan_currentChange( Output_current_available() );
+}
+
+
+// Power/Current Available
+unsigned int Output_current_available()
+{
+       unsigned int total_current = 0;
+
+       // Check for USB current source
+       total_current += Output_USBCurrent_Available;
+
+       // Check for external current source
+       total_current += Output_ExtCurrent_Available;
+
+       // XXX If the total available current is still 0
+       // Set to 100 mA, which is generally a safe assumption at startup
+       // before we've been able to determine actual available current
+       if ( total_current == 0 )
+       {
+               total_current = 100;
+       }
+
+       return total_current;
+}
+
+
+
 // ----- CLI Command Functions -----
 
 void cliFunc_kbdProtocol( char* args )
index 8a92b768c67122b4b3e69b5dd037cb550a1f48d7..609f2d713b1f1c503529907d05f45b41ff333392 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 by Jacob Alexander
  *
  * This file is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -406,8 +406,14 @@ inline void LED_setup()
        // Set default brightness
        LED_sendPage( (uint8_t*)LED_defaultBrightness1, sizeof( LED_defaultBrightness1 ), 0 );
 
-       // Disable Software shutdown of ISSI chip
-       LED_writeReg( 0x0A, 0x01, 0x0B );
+       // Do not disable software shutdown of ISSI chip unless current is high enough
+       // Require at least 150 mA
+       // May be enabled/disabled at a later time
+       if ( Output_current_available() >= 150 )
+       {
+               // Disable Software shutdown of ISSI chip
+               LED_writeReg( 0x0A, 0x01, 0x0B );
+       }
 }
 
 
@@ -644,6 +650,24 @@ inline uint8_t LED_scan()
 }
 
 
+// Called by parent Scan Module whenver the available current has changed
+// current - mA
+void LED_currentChange( unsigned int current )
+{
+       // TODO dim LEDs in low power mode instead of shutting off
+       if ( current < 150 )
+       {
+               // Enabled Software shutdown of ISSI chip
+               LED_writeReg( 0x0A, 0x00, 0x0B );
+       }
+       else
+       {
+               // Disable Software shutdown of ISSI chip
+               LED_writeReg( 0x0A, 0x01, 0x0B );
+       }
+}
+
+
 
 // ----- Capabilities -----
 
index 71d8e805fa87df13742b49314e2a4e92e4a1e8bf..545b8b948d3f8be5dbab986ab307f703d212c124 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 by Jacob Alexander
  *
  * This file is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,3 +28,5 @@
 void LED_setup();
 uint8_t LED_scan();
 
+void LED_currentChange( unsigned int current );
+
index 799985345825ec5b614755cbff9476e4641f5a9f..4e527066df6d204a9d5945b9a8407220b9d3fe32 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -97,3 +97,14 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys )
        Scan_scanCount = 0;
 }
 
+
+// Signal from the Output Module that the available current has changed
+// current - mA
+void Scan_currentChange( unsigned int current )
+{
+       // Indicate to all submodules current change
+       Connect_currentChange( current );
+       Matrix_currentChange( current );
+       LED_currentChange( current );
+}
+
index 17a06fccb86a4773f9fa092b5ee27971979011ac..b18a0cab57939de5f37161379b35088e08ec6b9e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
 // ----- Functions -----
 
 // Functions to be called by main.c
-void Scan_setup( void );
-uint8_t Scan_loop( void );
+void Scan_setup();
+uint8_t Scan_loop();
 
 // Call-backs
 void Scan_finishedWithMacro( uint8_t sentKeys );  // Called by Macro Module
 void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
 
+void Scan_currentChange( unsigned int current ); // Called by Output Module
+
index 74218a0eed7751e0f9a8476533d0e80c01457515..3b2bad1514142debdf0363e9a6d386d87ea00a0a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014,2016 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -90,6 +90,16 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys )
 }
 
 
+// Signal from the Output Module that the available current has changed
+// current - mA
+void Scan_currentChange( unsigned int current )
+{
+       // Indicate to all submodules current change
+       Matrix_currentChange( current );
+       LED_currentChange( current );
+}
+
+
 
 // ----- Capabilities -----
 
index 0c89838dee5bdda892923636108a2993918a2bec..339ede543d887c251ce28bf71d36a9b3df84e218 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -38,6 +38,8 @@ uint8_t Scan_loop( void );
 void Scan_finishedWithMacro( uint8_t sentKeys );  // Called by Macro Module
 void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
 
+void Scan_currentChange( unsigned int current ); // Called by Output Module
+
 
 // ----- Capabilities -----
 
index 22d43c2a26987586abe48c2f6c1d73cb40dd6c21..d9348e17d1cd4e26818e4e0c91ca07d4aa2b321a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -175,6 +175,15 @@ void CustomAction_blockKey_capability( uint8_t state, uint8_t stateType, uint8_t
 }
 
 
+// Signal from the Output Module that the available current has changed
+// current - mA
+void Scan_currentChange( unsigned int current )
+{
+       // Indicate to all submodules current change
+       Matrix_currentChange( current );
+}
+
+
 
 // ----- CLI Command Functions -----
 
index 0c89838dee5bdda892923636108a2993918a2bec..339ede543d887c251ce28bf71d36a9b3df84e218 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -38,6 +38,8 @@ uint8_t Scan_loop( void );
 void Scan_finishedWithMacro( uint8_t sentKeys );  // Called by Macro Module
 void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
 
+void Scan_currentChange( unsigned int current ); // Called by Output Module
+
 
 // ----- Capabilities -----
 
index d5e97e54b4e37051ae7e560c9bcf3635290a1410..e80119b6d8d00546f2742c0f62d1ac1bea0d58e0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -102,3 +102,15 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys )
        Scan_scanCount = 0;
 }
 
+
+// Signal from the Output Module that the available current has changed
+// current - mA
+void Scan_currentChange( unsigned int current )
+{
+       // Indicate to all submodules current change
+       Connect_currentChange( current );
+       Matrix_currentChange( current );
+       LED_currentChange( current );
+       LCD_currentChange( current );
+}
+
index 17a06fccb86a4773f9fa092b5ee27971979011ac..b18a0cab57939de5f37161379b35088e08ec6b9e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
 // ----- Functions -----
 
 // Functions to be called by main.c
-void Scan_setup( void );
-uint8_t Scan_loop( void );
+void Scan_setup();
+uint8_t Scan_loop();
 
 // Call-backs
 void Scan_finishedWithMacro( uint8_t sentKeys );  // Called by Macro Module
 void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
 
+void Scan_currentChange( unsigned int current ); // Called by Output Module
+
index 90343feb26b0395b836ea16684edbfae54e5f0db..017161d7e4d482a08a4ac1067f28ef1ca749372d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -428,7 +428,7 @@ void Matrix_scan( uint16_t scanNum )
 
 
        // Matrix ghosting check and elimination
-       // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+       // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 #ifdef GHOSTING_MATRIX
        // strobe = column, sense = row
 
@@ -465,7 +465,7 @@ void Matrix_scan( uint16_t scanNum )
                row_use[row] = used;
                row_ghost[row] = 0;  // clear
        }
-       
+
        // Check if matrix has ghost
        // Happens when key is pressed and some other key is pressed in same row and another in same column
        //print("  G ");
@@ -494,10 +494,10 @@ void Matrix_scan( uint16_t scanNum )
                        uint8_t key = Matrix_colsNum * row + col;
                        KeyState *state = &Matrix_scanArray[ key ];
                        KeyGhost *st = &Matrix_ghostArray[ key ];
-                       
+
                        // col or row is ghosting (crossed)
                        uint8_t ghost = (col_ghost[col] > 0 || row_ghost[row] > 0) ? 1 : 0;
-                       
+
                        st->prev = st->cur;  // previous
                        // save state if no ghost or outside ghosted area
                        if ( ghost == 0 )
@@ -505,9 +505,9 @@ void Matrix_scan( uint16_t scanNum )
                        // final
                        // use saved state if ghosting, or current if not
                        st->cur = ghost > 0 ? st->saved : state->curState;
-                       
+
                        //  Send keystate to macro module
-                       KeyPosition k = !st->cur 
+                       KeyPosition k = !st->cur
                                ? (!st->prev ? KeyState_Off : KeyState_Release)
                                : ( st->prev ? KeyState_Hold : KeyState_Press);
                        //if (!st->cur && !st->prev)  k = KeyState_Off; else
@@ -518,7 +518,7 @@ void Matrix_scan( uint16_t scanNum )
                }
        }
 #endif
-       // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
+       // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
 
        // State Table Output Debug
@@ -567,6 +567,15 @@ void Matrix_scan( uint16_t scanNum )
 }
 
 
+// Called by parent scan module whenever the available current changes
+// current - mA
+void Matrix_currentChange( unsigned int current )
+{
+       // TODO - Any potential power savings?
+}
+
+
+
 // ----- CLI Command Functions -----
 
 void cliFunc_matrixDebug ( char* args )
index 8b9cee79ee19684c844e6877641cdb405f5227bc..3a8f0e2ffe8e140de2b65372f5118f58e09ce129 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -158,3 +158,5 @@ inline uint8_t keyOn(/*KeyPosition*/uint8_t st)
 void Matrix_setup();
 void Matrix_scan( uint16_t scanNum );
 
+void Matrix_currentChange( unsigned int current );
+
index c4bf0805490e7e106950f88c58bb7591f5bd8021..1dd912682d5c557cfab102c9426fb606de3299f8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015 by Jacob Alexander
+/* Copyright (C) 2015-2016 by Jacob Alexander
  *
  * This file is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -346,6 +346,14 @@ inline uint8_t LCD_scan()
 }
 
 
+// Signal from parent Scan Module that available current has changed
+// current - mA
+void LCD_currentChange( unsigned int current )
+{
+       // TODO - Power savings?
+}
+
+
 
 // ----- Capabilities -----
 
index 36884a257a763f8ef86867f36243de7db22a4947..096107bc223db0eab800a5a24be33778769abee9 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2015 by Jacob Alexander
+/* Copyright (C) 2015-2016 by Jacob Alexander
  *
  * This file is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -28,3 +28,5 @@
 void LCD_setup();
 uint8_t LCD_scan();
 
+void LCD_currentChange( unsigned int current );
+
index 55f6619c61325d3509074b454cd2a29d487a0d33..4c56c3cf2d06e90db2006a5f9d54da7b6e5017e5 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 by Jacob Alexander
  *
  * This file is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -470,6 +470,14 @@ uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8
                        }
                        else
                        {
+                               // Lower current requirement during errors
+                               // USB minimum
+                               // Only if this is not the master node
+                               if ( Connect_id != 0 )
+                               {
+                                       Output_update_external_current( 100 );
+                               }
+
                                Connect_cableFaultsMaster++;
                                Connect_cableOkMaster = 0;
                                print(" Master ");
@@ -489,6 +497,12 @@ uint8_t Connect_receive_CableCheck( uint8_t byte, uint16_t *pending_bytes, uint8
                        }
                        else
                        {
+                               // If we already have an Id, then set max current again
+                               if ( Connect_id != 255 && Connect_id != 0 )
+                               {
+                                       // TODO reset to original negotiated current
+                                       Output_update_external_current( 500 );
+                               }
                                Connect_cableChecksMaster++;
                        }
                }
@@ -560,6 +574,14 @@ uint8_t Connect_receive_IdEnumeration( uint8_t id, uint16_t *pending_bytes, uint
        // Send reponse back to master
        Connect_send_IdReport( id );
 
+       // Node now enumerated, set external power to USB Max
+       // Only set if this is not the master node
+       // TODO Determine power slice for each node as part of protocol
+       if ( Connect_id != 0 )
+       {
+               Output_update_external_current( 500 );
+       }
+
        // Propogate next Id if the connection is ok
        if ( Connect_cableOkSlave )
        {
@@ -1177,6 +1199,13 @@ void Connect_scan()
 }
 
 
+// Called by parent Scan module whenever the available current changes
+void Connect_currentChange( unsigned int current )
+{
+       // TODO - Any potential power saving here?
+}
+
+
 
 // ----- CLI Command Functions -----
 
index cdd7ed0ae6ff5da84069e7bcdd5ecd19623db3d2..1d87dfdf6689ca0541395f782ccd5bec14503cb9 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 by Jacob Alexander
  *
  * This file is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -167,3 +167,5 @@ void Connect_scan();
 void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t numScanCodes );
 void Connect_send_RemoteCapability( uint8_t id, uint8_t capabilityIndex, uint8_t state, uint8_t stateType, uint8_t numArgs, uint8_t *args );
 
+void Connect_currentChange( unsigned int current );
+
index 16cefa2d67b0d5e02c4d5b3f5e6502cd1825c1e1..56fa9959dfc6bfdd845d914c6c885fae34fc991b 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -90,3 +90,13 @@ inline void Scan_finishedWithOutput( uint8_t sentKeys )
        Scan_scanCount = 0;
 }
 
+
+// Signal from the Output Module that the available current has changed
+// current - mA
+void Scan_currentChange( unsigned int current )
+{
+       // Indicate to all submodules current change
+       Matrix_currentChange( current );
+       LED_currentChange( current );
+}
+
index 17a06fccb86a4773f9fa092b5ee27971979011ac..9e9a8f14b3e5d13d7a5f6b028f34a9f501416015 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2014-2015 by Jacob Alexander
+/* Copyright (C) 2014-2016 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
@@ -38,3 +38,5 @@ uint8_t Scan_loop( void );
 void Scan_finishedWithMacro( uint8_t sentKeys );  // Called by Macro Module
 void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module
 
+void Scan_currentChange( unsigned int current ); // Called by Output Module
+