Adding dynamic USB power support

- 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)
This commit is contained in:
Jacob Alexander 2016-02-21 19:56:52 -08:00
parent 62ba0c558b
commit aaae9bc0f2
29 changed files with 503 additions and 48 deletions

View file

@ -383,11 +383,17 @@ void LED_reset()
LED_writeReg( addr, 0x00, 0x08, 0x0B );
}
// Disable Software shutdown of ISSI chip
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
// 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 )
{
uint8_t addr = LED_pageBuffer[ ch ].i2c_addr;
LED_writeReg( addr, 0x0A, 0x01, 0x0B );
// Disable Software shutdown of ISSI chip
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
{
uint8_t addr = LED_pageBuffer[ ch ].i2c_addr;
LED_writeReg( addr, 0x0A, 0x01, 0x0B );
}
}
}
@ -509,8 +515,35 @@ void LED_linkedSend()
// LED State processing loop
uint32_t LED_timePrev = 0;
unsigned int LED_currentEvent = 0;
inline void LED_scan()
{
// Check for current change event
if ( LED_currentEvent )
{
// TODO dim LEDs in low power mode instead of shutting off
if ( LED_currentEvent < 150 )
{
// Enable Software shutdown of ISSI chip
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
{
uint8_t addr = LED_pageBuffer[ ch ].i2c_addr;
LED_writeReg( addr, 0x0A, 0x00, 0x0B );
}
}
else
{
// Disable Software shutdown of ISSI chip
for ( uint8_t ch = 0; ch < ISSI_Chips_define; ch++ )
{
uint8_t addr = LED_pageBuffer[ ch ].i2c_addr;
LED_writeReg( addr, 0x0A, 0x01, 0x0B );
}
}
LED_currentEvent = 0;
}
// Check to see if frame buffers are ready to replenish
if ( LED_FrameBufferReset )
{
@ -585,6 +618,15 @@ inline void LED_scan()
}
// Called by parent Scan Module whenver the available current has changed
// current - mA
void LED_currentChange( unsigned int current )
{
// Delay action till next LED scan loop (as this callback sometimes occurs during interrupt requests)
LED_currentEvent = current;
}
// ----- Capabilities -----

View 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
@ -34,3 +34,5 @@ extern uint8_t LED_FrameBuffersReady;
void LED_setup();
void LED_scan();
void LED_currentChange( unsigned int current );

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2015 by Jacob Alexander
/* Copyright (C) 2015-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
@ -111,3 +111,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 );
Port_currentChange( current );
Matrix_currentChange( current );
LED_currentChange( current );
}

View 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
@ -31,10 +31,12 @@
// ----- 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

View 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 -----

View 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 -----

View 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 -----

View 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 -----

View 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 );
}

View 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
@ -31,10 +31,12 @@
// ----- 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

View 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 )

View 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 );

View file

@ -144,6 +144,14 @@ inline uint8_t Port_scan()
}
// Signal from parent Scan Module that available current has changed
// current - mA
void Port_currentChange( unsigned int current )
{
// TODO - Power savings?
}
// ----- Capabilities -----

View 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 Port_setup();
uint8_t Port_scan();
void Port_currentChange( unsigned int current ); // Called by Output Module

View 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 -----

View 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 );

View 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 -----

View 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
@ -168,3 +168,5 @@ void Connect_reset();
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 );

View 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,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 );
}

View 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