Browse Source

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)
capsense
Jacob Alexander 8 years ago
parent
commit
46765e85c5

+ 4
- 2
Output/pjrcUSB/arm/usb_desc.c View File

/* Teensyduino Core Library /* Teensyduino Core Library
* http://www.pjrc.com/teensy/ * http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC. * 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 * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the
1, // bConfigurationValue 1, // bConfigurationValue
0, // iConfiguration 0, // iConfiguration
0xA0, // bmAttributes 0xA0, // bmAttributes
250, // bMaxPower
250, // bMaxPower - Entry Index 8


// --- Keyboard HID --- Boot Mode Keyboard Interface // --- Keyboard HID --- Boot Mode Keyboard Interface
// - 9 bytes - // - 9 bytes -
SYS_CTRL_INTERVAL, // bInterval SYS_CTRL_INTERVAL, // bInterval
}; };


uint8_t *usb_bMaxPower = &config_descriptor[8];





// ----- String Descriptors ----- // ----- String Descriptors -----

+ 3
- 1
Output/pjrcUSB/arm/usb_desc.h View File

/* Teensyduino Core Library /* Teensyduino Core Library
* http://www.pjrc.com/teensy/ * http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC. * 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 * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the


extern const usb_descriptor_list_t usb_descriptor_list[]; extern const usb_descriptor_list_t usb_descriptor_list[];


extern uint8_t *usb_bMaxPower;


+ 117
- 4
Output/pjrcUSB/arm/usb_dev.c View File

/* Teensyduino Core Library /* Teensyduino Core Library
* http://www.pjrc.com/teensy/ * http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC. * 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 * Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the * a copy of this software and associated documentation files (the


static uint8_t reply_buffer[8]; static uint8_t reply_buffer[8];


static uint8_t power_neg_delay;
static uint32_t power_neg_time;





// ----- Functions ----- // ----- Functions -----
ep0_tx_bdt_bank ^= 1; 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() static void usb_setup()
{ {
const uint8_t *data = NULL; const uint8_t *data = NULL;
const uint8_t *cfg; const uint8_t *cfg;
int i; 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 ) switch ( setup.wRequestAndType )
{ {
case 0x0500: // SET_ADDRESS case 0x0500: // SET_ADDRESS
Output_Available = usb_configuration; Output_Available = usb_configuration;
reg = &USB0_ENDPT1; reg = &USB0_ENDPT1;
cfg = usb_endpoint_config_table; 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... // clear all BDT entries, free any allocated memory...
for ( i = 4; i < ( NUM_ENDPOINTS + 1) * 4; i++ ) for ( i = 4; i < ( NUM_ENDPOINTS + 1) * 4; i++ )
{ {
goto send; goto send;


case 0x0100: // CLEAR_FEATURE (device) 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) case 0x0101: // CLEAR_FEATURE (interface)
// TODO: Currently ignoring, perhaps useful? -HaaTa // 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(); endpoint0_stall();
return; return;


goto send; goto send;


case 0x0300: // SET_FEATURE (device) 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) case 0x0301: // SET_FEATURE (interface)
// TODO: Currently ignoring, perhaps useful? -HaaTa // 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(); endpoint0_stall();
return; return;


{ {
datalen = list->length; 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 #if UART_DEBUG
print("Desc found, "); print("Desc found, ");
printHex32( (uint32_t)data ); printHex32( (uint32_t)data );


void usb_tx( uint32_t endpoint, 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 ) ]; bdt_t *b = &table[ index( endpoint, TX, EVEN ) ];
uint8_t next; uint8_t next;


USB0_ISTAT = USB_ISTAT_ERROR; 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 */ ) ) 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; USB0_ISTAT = USB_ISTAT_SLEEP;
} }
} }
// enable d+ pullup // enable d+ pullup
USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG; USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG;


// Do not check for power negotiation delay until Get Configuration Descriptor
power_neg_delay = 0;

return 1; return 1;
} }



+ 1
- 0
Output/pjrcUSB/arm/usb_dev.h View File

} }


void usb_device_reload(); void usb_device_reload();
void usb_device_check();


extern void usb_serial_flush_callback(); extern void usb_serial_flush_callback();



+ 79
- 1
Output/pjrcUSB/output_com.c View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
// 1 - Debug enabled // 1 - Debug enabled
uint8_t Output_DebugMode = 0; 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 ----- // ----- Capabilities -----
// USB Data Send // USB Data Send
inline void Output_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 // Boot Mode Only, unset stale keys
if ( USBKeys_Protocol == 0 ) if ( USBKeys_Protocol == 0 )
for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ ) for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
} }




// 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 ----- // ----- CLI Command Functions -----


void cliFunc_kbdProtocol( char* args ) void cliFunc_kbdProtocol( char* args )

+ 9
- 1
Output/pjrcUSB/output_com.h View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal


extern uint8_t Output_DebugMode; // 0 - Debug disabled, 1 - Debug enabled 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 ----- // ----- Functions -----
// Relies on USB serial module // Relies on USB serial module
unsigned int Output_availablechar(); 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_getchar();
int Output_putchar( char c ); int Output_putchar( char c );
int Output_putstr( char* str ); int Output_putstr( char* str );

+ 79
- 1
Output/usbMuxUart/output_com.c View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
// 1 - Debug enabled // 1 - Debug enabled
uint8_t Output_DebugMode = 0; 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 ----- // ----- Capabilities -----
// USB Data Send // USB Data Send
inline void Output_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 // Boot Mode Only, unset stale keys
if ( USBKeys_Protocol == 0 ) if ( USBKeys_Protocol == 0 )
for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ ) for ( uint8_t c = USBKeys_Sent; c < USB_BOOT_MAX_KEYS; c++ )
} }




// 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 ----- // ----- CLI Command Functions -----


void cliFunc_kbdProtocol( char* args ) void cliFunc_kbdProtocol( char* args )

+ 27
- 3
Scan/ISSILed/led_scan.c View File

/* 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 * 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 * it under the terms of the GNU General Public License as published by
// Set default brightness // Set default brightness
LED_sendPage( (uint8_t*)LED_defaultBrightness1, sizeof( LED_defaultBrightness1 ), 0 ); 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 );
}
} }




} }




// 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 ----- // ----- Capabilities -----



+ 3
- 1
Scan/ISSILed/led_scan.h View File

/* 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 * 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 * it under the terms of the GNU General Public License as published by
void LED_setup(); void LED_setup();
uint8_t LED_scan(); uint8_t LED_scan();


void LED_currentChange( unsigned int current );


+ 12
- 1
Scan/KType/scan_loop.c View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
Scan_scanCount = 0; 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 );
}


+ 5
- 3
Scan/KType/scan_loop.h View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
// ----- Functions ----- // ----- Functions -----


// Functions to be called by main.c // 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 // Call-backs
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module


void Scan_currentChange( unsigned int current ); // Called by Output Module


+ 11
- 1
Scan/MD1.1/scan_loop.c View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
} }




// 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 ----- // ----- Capabilities -----



+ 3
- 1
Scan/MD1.1/scan_loop.h View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module


void Scan_currentChange( unsigned int current ); // Called by Output Module



// ----- Capabilities ----- // ----- Capabilities -----



+ 10
- 1
Scan/MD1/scan_loop.c View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
} }




// 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 ----- // ----- CLI Command Functions -----



+ 3
- 1
Scan/MD1/scan_loop.h View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module


void Scan_currentChange( unsigned int current ); // Called by Output Module



// ----- Capabilities ----- // ----- Capabilities -----



+ 13
- 1
Scan/MDErgo1/scan_loop.c View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
Scan_scanCount = 0; 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 );
}


+ 5
- 3
Scan/MDErgo1/scan_loop.h View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
// ----- Functions ----- // ----- Functions -----


// Functions to be called by main.c // 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 // Call-backs
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module


void Scan_currentChange( unsigned int current ); // Called by Output Module


+ 17
- 8
Scan/MatrixARM/matrix_scan.c View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal




// Matrix ghosting check and elimination // Matrix ghosting check and elimination
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
#ifdef GHOSTING_MATRIX #ifdef GHOSTING_MATRIX
// strobe = column, sense = row // strobe = column, sense = row


row_use[row] = used; row_use[row] = used;
row_ghost[row] = 0; // clear row_ghost[row] = 0; // clear
} }
// Check if matrix has ghost // Check if matrix has ghost
// Happens when key is pressed and some other key is pressed in same row and another in same column // Happens when key is pressed and some other key is pressed in same row and another in same column
//print(" G "); //print(" G ");
uint8_t key = Matrix_colsNum * row + col; uint8_t key = Matrix_colsNum * row + col;
KeyState *state = &Matrix_scanArray[ key ]; KeyState *state = &Matrix_scanArray[ key ];
KeyGhost *st = &Matrix_ghostArray[ key ]; KeyGhost *st = &Matrix_ghostArray[ key ];
// col or row is ghosting (crossed) // col or row is ghosting (crossed)
uint8_t ghost = (col_ghost[col] > 0 || row_ghost[row] > 0) ? 1 : 0; uint8_t ghost = (col_ghost[col] > 0 || row_ghost[row] > 0) ? 1 : 0;
st->prev = st->cur; // previous st->prev = st->cur; // previous
// save state if no ghost or outside ghosted area // save state if no ghost or outside ghosted area
if ( ghost == 0 ) if ( ghost == 0 )
// final // final
// use saved state if ghosting, or current if not // use saved state if ghosting, or current if not
st->cur = ghost > 0 ? st->saved : state->curState; st->cur = ghost > 0 ? st->saved : state->curState;
// Send keystate to macro module // Send keystate to macro module
KeyPosition k = !st->cur
KeyPosition k = !st->cur
? (!st->prev ? KeyState_Off : KeyState_Release) ? (!st->prev ? KeyState_Off : KeyState_Release)
: ( st->prev ? KeyState_Hold : KeyState_Press); : ( st->prev ? KeyState_Hold : KeyState_Press);
//if (!st->cur && !st->prev) k = KeyState_Off; else //if (!st->cur && !st->prev) k = KeyState_Off; else
} }
} }
#endif #endif
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .




// State Table Output Debug // State Table Output Debug
} }




// 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 ----- // ----- CLI Command Functions -----


void cliFunc_matrixDebug ( char* args ) void cliFunc_matrixDebug ( char* args )

+ 3
- 1
Scan/MatrixARM/matrix_scan.h View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
void Matrix_setup(); void Matrix_setup();
void Matrix_scan( uint16_t scanNum ); void Matrix_scan( uint16_t scanNum );


void Matrix_currentChange( unsigned int current );


+ 9
- 1
Scan/STLcd/lcd_scan.c View File

/* 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 * 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 * it under the terms of the GNU General Public License as published by
} }




// Signal from parent Scan Module that available current has changed
// current - mA
void LCD_currentChange( unsigned int current )
{
// TODO - Power savings?
}




// ----- Capabilities ----- // ----- Capabilities -----



+ 3
- 1
Scan/STLcd/lcd_scan.h View File

/* 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 * 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 * it under the terms of the GNU General Public License as published by
void LCD_setup(); void LCD_setup();
uint8_t LCD_scan(); uint8_t LCD_scan();


void LCD_currentChange( unsigned int current );


+ 30
- 1
Scan/UARTConnect/connect_scan.c View File

/* 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 * 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 * it under the terms of the GNU General Public License as published by
} }
else 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_cableFaultsMaster++;
Connect_cableOkMaster = 0; Connect_cableOkMaster = 0;
print(" Master "); print(" Master ");
} }
else 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++; Connect_cableChecksMaster++;
} }
} }
// Send reponse back to master // Send reponse back to master
Connect_send_IdReport( id ); 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 // Propogate next Id if the connection is ok
if ( Connect_cableOkSlave ) if ( Connect_cableOkSlave )
{ {
} }




// 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 ----- // ----- CLI Command Functions -----



+ 3
- 1
Scan/UARTConnect/connect_scan.h View File

/* 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 * 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 * it under the terms of the GNU General Public License as published by
void Connect_send_ScanCode( uint8_t id, TriggerGuide *scanCodeStateList, uint8_t numScanCodes ); 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_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 );


+ 11
- 1
Scan/WhiteFox/scan_loop.c View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
Scan_scanCount = 0; 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 );
}


+ 3
- 1
Scan/WhiteFox/scan_loop.h View File

/* 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 * Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal * of this software and associated documentation files (the "Software"), to deal
void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module void Scan_finishedWithMacro( uint8_t sentKeys ); // Called by Macro Module
void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module void Scan_finishedWithOutput( uint8_t sentKeys ); // Called by Output Module


void Scan_currentChange( unsigned int current ); // Called by Output Module