Added software timers
Accessory state machine framework functional
This commit is contained in:
464
source/ports.c
464
source/ports.c
@@ -30,6 +30,7 @@
|
||||
#include "pwm.h"
|
||||
#include "pwr_level.h"
|
||||
#include "System/system.h"
|
||||
#include "usbComms.h"
|
||||
|
||||
ACCESSORY_t accy1;
|
||||
ACCESSORY_t accy2;
|
||||
@@ -54,43 +55,112 @@ static int handleBroadcast(ACCESSORY_t *accy)
|
||||
switch (accy->state)
|
||||
{
|
||||
case PORT_STATE_INIT:
|
||||
{
|
||||
if (accy->initState)
|
||||
{
|
||||
USB_SendString("Broadcast initializing...");
|
||||
accy->stateTimer = sys.systemTime + 2000;
|
||||
}
|
||||
|
||||
if (sys.systemTime >= accy->stateTimer)
|
||||
{
|
||||
accy->state = PORT_STATE_RUNNING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PORT_STATE_DEINIT:
|
||||
break;
|
||||
{
|
||||
if (accy->initState)
|
||||
{
|
||||
USB_SendString("Broadcast deinitializing...");
|
||||
accy->stateTimer = sys.systemTime + 2000;
|
||||
}
|
||||
|
||||
if (sys.systemTime >= accy->stateTimer)
|
||||
{
|
||||
accy->state = PORT_STATE_STANDBY;
|
||||
USB_SendString("Broadcast in standby!");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case PORT_STATE_RUNNING:
|
||||
{
|
||||
if (accy->initState)
|
||||
{
|
||||
USB_SendString("Broadcast running!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handleClamp(ACCESSORY_t *accy)
|
||||
{
|
||||
|
||||
switch (accy->state)
|
||||
{
|
||||
case PORT_STATE_INIT:
|
||||
{
|
||||
if (accy->initState)
|
||||
{
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PORT_STATE_DEINIT:
|
||||
accy->state = PORT_STATE_STANDBY;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handleDirect(ACCESSORY_t *accy)
|
||||
static int handleDirectConnect(ACCESSORY_t *accy)
|
||||
{
|
||||
switch (accy->state)
|
||||
{
|
||||
case PORT_STATE_INIT:
|
||||
{
|
||||
if (accy->initState)
|
||||
{
|
||||
accy->stateTimer = sys.systemTime + 2000;
|
||||
|
||||
USB_SendString("Direct connect initializing...");
|
||||
}
|
||||
|
||||
if (sys.systemTime >= accy->stateTimer)
|
||||
{
|
||||
accy->state = PORT_STATE_RUNNING;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case PORT_STATE_DEINIT:
|
||||
accy->state = PORT_STATE_STANDBY;
|
||||
break;
|
||||
|
||||
case PORT_STATE_STANDBY:
|
||||
break;
|
||||
|
||||
case PORT_STATE_RUNNING:
|
||||
{
|
||||
if (accy->initState)
|
||||
{
|
||||
USB_SendString("Direct connect running!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
@@ -101,44 +171,184 @@ static int initAccessory(ACCESSORY_t *accy)
|
||||
{
|
||||
accy->state = PORT_STATE_INIT;
|
||||
accy->initState = true;
|
||||
accy->handler(accy);
|
||||
//accy->handler(accy);
|
||||
}
|
||||
|
||||
static int deinitAccessory(ACCESSORY_t *accy)
|
||||
{
|
||||
accy->state = PORT_STATE_DEINIT;
|
||||
accy->initState = true;
|
||||
accy->handler(accy);
|
||||
if (accy->isConnected)
|
||||
{
|
||||
accy->state = PORT_STATE_DEINIT;
|
||||
accy->initState = true;
|
||||
}
|
||||
//accy->handler(accy);
|
||||
}
|
||||
|
||||
void ACCY_Connect(ACCESSORY_t *accy, ACCY_ID_t id)
|
||||
void ACCY_service(void)
|
||||
{
|
||||
ACCY_Update();
|
||||
|
||||
ACCESSORY_t *active = sys.activeAccessory;
|
||||
|
||||
// if there is an accessory waiting to be switched, check that the current active is in standby before initializing
|
||||
if (active != NULL)
|
||||
{
|
||||
if (active->isConnected)
|
||||
{
|
||||
// service the current accessory
|
||||
PortState_t prevState = active->state;
|
||||
active->handler(active);
|
||||
active->initState = (prevState != active->state);
|
||||
}
|
||||
else
|
||||
{
|
||||
// active accessory was disconnected
|
||||
// fall back to induction for now
|
||||
ACCY_setActive(&sys.ports[ACCY_PORT_INDUCTION], CHANNEL_A);
|
||||
}
|
||||
|
||||
|
||||
if ((sys.nextAccessory) != NULL)
|
||||
{
|
||||
// wait until current accessory has been deinitialized before switching
|
||||
if (active->state == PORT_STATE_STANDBY)
|
||||
{
|
||||
sys.activeAccessory = sys.nextAccessory;
|
||||
sys.nextAccessory = NULL;
|
||||
initAccessory(active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ACCY_next(void)
|
||||
{
|
||||
// cycle through accessories and channels to find the next available
|
||||
AccessoryPortId_t currentPort = sys.activeAccessory->portId;
|
||||
AccyChannelId_t currentChannel = sys.activeAccessory->activeChannel;
|
||||
|
||||
|
||||
AccessoryPortId_t port = currentPort;
|
||||
AccyChannelId_t channel = currentChannel + 1;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
if (channel >= NUM_CHANNELS)
|
||||
{
|
||||
port++;
|
||||
|
||||
if (port >= NUM_PORTS)
|
||||
{
|
||||
port = 0;
|
||||
}
|
||||
|
||||
channel = CHANNEL_A;
|
||||
}
|
||||
|
||||
AccessoryChannel_t *ch = &sys.ports[port].channels[channel];
|
||||
|
||||
if (ch->connected)
|
||||
{
|
||||
ACCY_setActive(&sys.ports[port], channel);
|
||||
break;
|
||||
}
|
||||
|
||||
channel++;
|
||||
|
||||
} while ((port != currentPort) || (channel != currentChannel));
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ACCY_setActive(ACCESSORY_t *accy, AccyChannelId_t channel)
|
||||
{
|
||||
accy->activeChannel = channel;
|
||||
// deinitialize current accessory
|
||||
if (sys.activeAccessory != NULL)
|
||||
{
|
||||
deinitAccessory(sys.activeAccessory);
|
||||
|
||||
// initialize the accessory to switch when complete
|
||||
sys.nextAccessory = accy;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// nothing active, switch now
|
||||
sys.activeAccessory = accy;
|
||||
initAccessory(sys.activeAccessory);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void ACCY_Disconnect(ACCESSORY_t *accy)
|
||||
{
|
||||
|
||||
sprintf(sys.tmpString, "Accessory disconnected: %d", accy->connected);
|
||||
USB_SendString(sys.tmpString);
|
||||
|
||||
accy->connected = ID_NONE;
|
||||
accy->isConnected = false;
|
||||
|
||||
accy->handler = NULL;
|
||||
|
||||
accy->state = PORT_STATE_STANDBY;
|
||||
|
||||
accy->channels[CHANNEL_A].id = CHANNEL_A;
|
||||
accy->channels[CHANNEL_A].connected = false;
|
||||
|
||||
accy->channels[CHANNEL_B].id = CHANNEL_B;
|
||||
accy->channels[CHANNEL_B].connected = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// setup the accessory as connected but do not initialize it until set as active
|
||||
bool ACCY_Connect(ACCESSORY_t *accy, ACCY_ID_t id)
|
||||
{
|
||||
accy->connected = id;
|
||||
accy->isConnected = true;
|
||||
|
||||
accy->state = PORT_STATE_INIT;
|
||||
accy->state = PORT_STATE_STANDBY;
|
||||
|
||||
accy->channels[0] = 0;
|
||||
accy->channels[1] = 0;
|
||||
accy->channels[CHANNEL_A].id = CHANNEL_A;
|
||||
accy->channels[CHANNEL_A].connected = false;
|
||||
|
||||
accy->channels[CHANNEL_B].id = CHANNEL_B;
|
||||
accy->channels[CHANNEL_B].connected = false;
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case ID_TX_SINGLE_DIRECT:
|
||||
case ID_TX_DUAL_DIRECT:
|
||||
{
|
||||
accy->handler = handleDirect;
|
||||
accy->channels[CHANNEL_B].connected = true;
|
||||
// intentional fall through
|
||||
}
|
||||
case ID_TX_SINGLE_DIRECT:
|
||||
{
|
||||
accy->channels[CHANNEL_A].connected = true;
|
||||
accy->handler = handleDirectConnect;
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_CLAMP:
|
||||
case ID_CLAMP2:
|
||||
{
|
||||
accy->channels[CHANNEL_A].connected = true;
|
||||
accy->handler = handleClamp;
|
||||
break;
|
||||
}
|
||||
|
||||
case ID_BROADCAST:
|
||||
{
|
||||
accy->channels[CHANNEL_A].connected = true;
|
||||
accy->handler = handleBroadcast;
|
||||
break;
|
||||
}
|
||||
@@ -150,6 +360,11 @@ void ACCY_Connect(ACCESSORY_t *accy, ACCY_ID_t id)
|
||||
accy->isConnected = false;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(sys.tmpString, "New accessory connected: %d", accy->connected);
|
||||
USB_SendString(sys.tmpString);
|
||||
|
||||
return accy->isConnected;
|
||||
}
|
||||
|
||||
static ACCY_ID_t ReadAccessory(uint8_t port)
|
||||
@@ -237,7 +452,7 @@ void Disconnect(uint8_t port) // called when you disconnect
|
||||
//Configure frequency to make sure things are setup correctly
|
||||
// Tx_ConfigureFrequency();
|
||||
}
|
||||
void ACCY_Init(void)
|
||||
void ACCY_Init(void)
|
||||
{
|
||||
|
||||
for (int i=0; i<NUM_PORTS; ++i)
|
||||
@@ -245,6 +460,8 @@ void ACCY_Init(void)
|
||||
sys.ports[i].connected = ID_NONE;
|
||||
sys.ports[i].consecutiveScans = 0;
|
||||
sys.ports[i].isConnected = false;
|
||||
|
||||
sys.ports[i].portId = i;
|
||||
}
|
||||
|
||||
sys.ports[ACCY_PORT_1].idVoltage = &sys.adc.V_ID1;
|
||||
@@ -267,20 +484,23 @@ void ACCY_Init(void)
|
||||
void ACCY_Update(void)
|
||||
{
|
||||
|
||||
for (int i=0; i<NUM_PORTS; ++i)
|
||||
for (int i=ACCY_PORT_1; i<NUM_PORTS; ++i)
|
||||
{
|
||||
ACCESSORY_t *accy = &sys.ports[i];
|
||||
ACCY_ID_t detected = ReadAccessory(i);
|
||||
|
||||
if(accy->connected == ID_NONE) //Nothing connected. Look for accessory to connect
|
||||
if(!accy->isConnected) //Nothing connected. Look for accessory to connect
|
||||
{
|
||||
|
||||
if((detected == accy->lastDetected) && (detected != ID_NONE)) //If detected same as last time and not ID_NONE
|
||||
{
|
||||
|
||||
if(++accy->consecutiveScans == AC_NUM_SCANS_TO_CONNECT) //Connect on 3rd consecutive scan of same accessory
|
||||
{
|
||||
ACCY_Connect(accy, detected);
|
||||
// we found a newly connected accessory. switch to it.
|
||||
if (ACCY_Connect(accy, detected))
|
||||
{
|
||||
ACCY_setActive(accy, CHANNEL_A);
|
||||
}
|
||||
}
|
||||
}
|
||||
else //If different than last scan
|
||||
@@ -288,88 +508,17 @@ void ACCY_Update(void)
|
||||
accy->lastDetected = detected; //remember what was scanned last time
|
||||
accy->consecutiveScans = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else if (detected != accy->connected) //If connected and detected reads different, disconnect
|
||||
{
|
||||
Disconnect(i);
|
||||
ACCY_Disconnect(accy);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//Call @ 10Hz to detect, connect, and disconnect accessories
|
||||
void ACCY_Update1(void)
|
||||
{
|
||||
//read ID voltage and determine connected accessory *for each port*
|
||||
|
||||
//Require same accessory detected 3 consecutive updates (to de-glitch)
|
||||
|
||||
//Read accessory voltage and identify accessory
|
||||
|
||||
ACCY_ID_t detected = ReadAccessory(1);
|
||||
|
||||
if(accy1.connected == ID_NONE) //Nothing connected. Look for accessory to connect
|
||||
{
|
||||
|
||||
if((detected == accy1.lastDetected) && (detected != ID_NONE)) //If detected same as last time and not ID_NONE
|
||||
{
|
||||
|
||||
if(++accy1.consecutiveScans == AC_NUM_SCANS_TO_CONNECT) //Connect on 3rd consecutive scan of same accessory
|
||||
{
|
||||
ACCY_Connect1(accy1.lastDetected); //CONNECT
|
||||
}
|
||||
}
|
||||
else //If different than last scan
|
||||
{
|
||||
accy1.lastDetected = detected; //remember what was scanned last time
|
||||
accy1.consecutiveScans = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else if (detected != accy1.connected) //If connected and detected reads different, disconnect
|
||||
{
|
||||
Disconnect(ACCY_PORT_1);
|
||||
}
|
||||
|
||||
}
|
||||
//Call @ 10Hz to detect, connect, and disconnect accessories
|
||||
void ACCY_Update2(void)
|
||||
{
|
||||
//read ID voltage and determine connected accessory *for each port*
|
||||
|
||||
//Require same accessory detected 3 consecutive updates (to de-glitch)
|
||||
|
||||
//Read accessory voltage and identify accessory
|
||||
|
||||
ACCY_ID_t detected = ReadAccessory(2);
|
||||
|
||||
whatever = ReadAccessory(2);
|
||||
|
||||
if(accy2.connected == ID_NONE) //Nothing connected. Look for accessory to connect
|
||||
{
|
||||
|
||||
if((detected == accy2.lastDetected) && (detected != ID_NONE)) //If detected same as last time and not ID_NONE
|
||||
{
|
||||
|
||||
if(++accy2.consecutiveScans == AC_NUM_SCANS_TO_CONNECT) //Connect on 3rd consecutive scan of same accessory
|
||||
{
|
||||
ACCY_Connect2(accy2.lastDetected); //CONNECT
|
||||
}
|
||||
}
|
||||
else //If different than last scan
|
||||
{
|
||||
accy2.lastDetected = detected; //remember what was scanned last time
|
||||
accy2.consecutiveScans = 0;
|
||||
}
|
||||
|
||||
}
|
||||
else if (detected != accy2.connected) //If connected and detected reads different, disconnect
|
||||
{
|
||||
Disconnect(ACCY_PORT_2);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Connect accessory
|
||||
*/
|
||||
@@ -390,83 +539,10 @@ bool ACCY_isKnown(ACCY_ID_t id)
|
||||
return known;
|
||||
}
|
||||
|
||||
void ACCY_Connect1(ACCY_ID_t id)
|
||||
{
|
||||
accy1.connected = id;
|
||||
accy1.isConnected = true;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case ID_TX_SINGLE_DIRECT:
|
||||
Port_changed_flag = true; //connect it
|
||||
break;
|
||||
case ID_TX_DUAL_DIRECT:
|
||||
Port_changed_flag = true; //connect it
|
||||
break;
|
||||
case ID_CLAMP:
|
||||
Port_changed_flag = true; //connect it
|
||||
break;
|
||||
case ID_CLAMP2:
|
||||
Port_changed_flag = true; //connect it
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
accy1.connected = ID_NONE;
|
||||
accy1.isConnected = false;
|
||||
}
|
||||
|
||||
|
||||
//Configure frequency to make sure things are setup correctly
|
||||
// Tx_ConfigureFrequency();
|
||||
|
||||
}
|
||||
void ACCY_Connect2(ACCY_ID_t id)
|
||||
{
|
||||
accy2.connected = id;
|
||||
accy2.isConnected = true;
|
||||
|
||||
switch(id)
|
||||
{
|
||||
case ID_TX_SINGLE_DIRECT:
|
||||
Port_changed_flag = true;//connect it
|
||||
break;
|
||||
case ID_TX_DUAL_DIRECT:
|
||||
Port_changed_flag = true;//connect it
|
||||
break;
|
||||
case ID_CLAMP:
|
||||
Port_changed_flag = true;//connect it
|
||||
break;
|
||||
case ID_CLAMP2:
|
||||
Port_changed_flag = true;//connect it
|
||||
break;
|
||||
|
||||
default:
|
||||
accy2.connected = ID_NONE;
|
||||
accy2.isConnected = false;
|
||||
}
|
||||
|
||||
|
||||
//Configure frequency to make sure things are setup correctly
|
||||
// Tx_ConfigureFrequency();
|
||||
|
||||
}
|
||||
bool ACCY_IsConnected1(uint8_t port)
|
||||
{
|
||||
if(port == 1)
|
||||
return accy1.isConnected;
|
||||
else
|
||||
return accy2.isConnected;
|
||||
|
||||
}
|
||||
|
||||
ACCY_ID_t ACCY_GetConnectedAccessory(uint8_t port)
|
||||
{
|
||||
if(port == 1)
|
||||
return accy1.connected;
|
||||
else
|
||||
return accy2.connected;
|
||||
|
||||
return ID_NONE;
|
||||
}
|
||||
|
||||
ACCY_ID_t ACCY_GetActive(void)
|
||||
@@ -492,64 +568,6 @@ void Read_Tx_Ports(void) // check for whats plugged in at the ports every 100mS.
|
||||
|
||||
ACCY_Update();
|
||||
|
||||
//ACCY_Update1();
|
||||
|
||||
if((mode_Array[PORT1_A].Selected == false) && (mode_Array[PORT1_B].Selected == false) && (accy1.isConnected)) //new bit here
|
||||
Cur_Mode = PORT1_A; // Something is connected to PORT1
|
||||
|
||||
switch(accy1.connected) // Find out what it is
|
||||
{
|
||||
case ID_TX_DUAL_DIRECT: //Transmitter accessory
|
||||
mode_Array[PORT1_A].Selected = accy1.isConnected;
|
||||
mode_Array[PORT1_B].Selected = accy1.isConnected;
|
||||
break;
|
||||
|
||||
case ID_TX_SINGLE_DIRECT:
|
||||
mode_Array[PORT1_A].Selected = accy1.isConnected;
|
||||
break;
|
||||
|
||||
case ID_CLAMP:
|
||||
mode_Array[PORT1_A].Selected = accy1.isConnected;
|
||||
break;
|
||||
|
||||
case ID_CLAMP2:
|
||||
mode_Array[PORT1_A].Selected = accy1.isConnected;
|
||||
break;
|
||||
|
||||
default: //empty
|
||||
mode_Array[PORT1_A].Selected = accy1.isConnected;
|
||||
mode_Array[PORT1_B].Selected = accy1.isConnected;
|
||||
}
|
||||
|
||||
|
||||
//ACCY_Update2();
|
||||
if((mode_Array[PORT2_A].Selected == false) && (mode_Array[PORT2_B].Selected == false) && (accy2.isConnected)) //new bit here
|
||||
Cur_Mode = PORT2_A;
|
||||
|
||||
switch(accy2.connected)
|
||||
{
|
||||
case ID_TX_DUAL_DIRECT: //Transmitter accessory
|
||||
mode_Array[PORT2_A].Selected = accy2.isConnected;
|
||||
mode_Array[PORT2_B].Selected = accy2.isConnected;
|
||||
break;
|
||||
|
||||
case ID_TX_SINGLE_DIRECT:
|
||||
mode_Array[PORT2_A].Selected = accy2.isConnected;
|
||||
break;
|
||||
|
||||
case ID_CLAMP:
|
||||
mode_Array[PORT2_A].Selected = accy2.isConnected;
|
||||
break;
|
||||
case ID_CLAMP2:
|
||||
mode_Array[PORT2_A].Selected = accy2.isConnected;
|
||||
break;
|
||||
|
||||
default: //empty
|
||||
mode_Array[PORT2_A].Selected = accy2.isConnected;
|
||||
mode_Array[PORT2_B].Selected = accy2.isConnected;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -573,7 +591,7 @@ void Select_Output_Port(void) // which DC Out port, to switch on
|
||||
}
|
||||
|
||||
// HACK
|
||||
Select_Estop(OFF); // Ensure output is not ISOLATED from connections
|
||||
Select_Estop(CONNECTED); // Ensure output is not ISOLATED from connections
|
||||
|
||||
switch (Cur_Mode)
|
||||
{
|
||||
@@ -602,7 +620,7 @@ void Select_Output_Port(void) // which DC Out port, to switch on
|
||||
else
|
||||
{ // Assumes broadcast mode has just been selected
|
||||
Disable_DC(); // Shut down Direct connect circuitry
|
||||
Select_Estop(ON); // Ensure output is ISOLATED from connections
|
||||
Select_Estop(ISOLATED); // Ensure output is ISOLATED from connections
|
||||
|
||||
Tx_ConfigureFrequency(); // Select correct frequency
|
||||
Enable_BC(); // Enable BCAST circuitry using either Minimum or previously selected freq
|
||||
|
||||
Reference in New Issue
Block a user