diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index 4827031..c884f98 100644 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -4,7 +4,7 @@ - + @@ -15,7 +15,7 @@ - + diff --git a/.vscode/settings.json b/.vscode/settings.json index bdd00a8..284fa29 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,6 +20,7 @@ "dds.h": "c", "frq.h": "c", "driver.h": "c", - "pwm.h": "c" + "pwm.h": "c", + "direct.h": "c" } } \ No newline at end of file diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..85276f4 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,108 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +This is an embedded C application for the LPC54114 microcontroller (ARM Cortex-M4) running on the LPCXpresso54114 development board. The project appears to be a transmitter device (TX) with signal generation, display, USB communication, and power management capabilities. + +**Hardware Target:** NXP LPC54114 dual-core Cortex-M4/M0+ microcontroller +**Software Version:** 1.10A (defined in source/System/system.h:18) + +## Build System + +### Build Commands +```bash +# Build debug version +cd Debug +make all + +# Build release version +cd Release +make all + +# Clean build artifacts +make clean +``` + +### Build Artifacts +- **Target executable:** `TX_App.axf` (ARM executable format) +- **Binary output:** `TX_App.bin` (generated post-build) +- **Memory map:** `TX_App.map` +- **Linker scripts:** `TX_App_Debug.ld`, `TX_App_Release.ld` + +### Toolchain +- **Compiler:** arm-none-eabi-gcc +- **Target:** Cortex-M4 with hardware floating point (fpv4-sp-d16) +- **IDE Support:** MCUXpresso, IAR, Keil MDK + +## Code Architecture + +### Core System Structure + +**Main Application Flow:** +- Entry point: `source/main.c` +- System initialization: `source/System/system.c` +- Hardware initialization: `source/init.c` + +**Key Subsystems:** + +1. **Signal Generation (`source/dds.c`, `source/fgen.c`)** + - DDS (Direct Digital Synthesis) for frequency generation + - Function generator capabilities + - Frequency range: 3.14kHz - 200kHz for broadcast mode + - System clock: 12MHz + +2. **Display System (`source/display.c`, `source/lcd.c`)** + - Graphics library in `source/Graphics/` + - Font rendering system in `source/Fonts/` + - Multi-language support with translations + - Icon and bitmap handling + +3. **Power Management (`source/battery.c`, `source/ports.c`)** + - Battery type detection (Lithium/Alkaline/External DC) + - Power limits: 10W (Lithium/Ext), 5W (Alkaline) + - Clamp control and regulation + +4. **Communication (`source/USB/`, `source/broadcast.c`)** + - USB CDC (Virtual COM) interface + - Broadcast transmission capabilities + - Flash update support via USB + +5. **Hardware Drivers (`source/driver.c`, `source/io.c`)** + - SPI communication for external components + - ADC for measurements + - Timer and PWM control + - GPIO port management + +### Directory Structure + +- `source/` - Main application code +- `source/System/` - System-level configuration and data structures +- `source/USB/` - USB device implementation +- `source/Graphics/` - Display graphics and UI +- `source/Fonts/` - Font data and localization +- `source/Loader/` - Bootloader and flash update functionality +- `drivers/` - NXP SDK peripheral drivers +- `CMSIS/` - ARM CMSIS headers +- `usb/` - USB middleware stack +- `Debug/`, `Release/` - Build output directories + +### Key Data Structures + +**ClampData_t** (`source/System/system.h:35`): Core control structure containing: +- Slope, voltage, current, impedance measurements +- Power regulation parameters +- Digital potentiometer settings + +### Development Notes + +- The project uses NXP's MCUXpresso SDK for peripheral drivers +- Hardware-specific fixes are isolated in `source/hwFixes.c` +- Comprehensive change log maintained in `source/AppChangeLog.txt` +- Flash memory layout: Application starts at 0x10000 (64KB offset for bootloader) +- Maximum application size: 192KB + +### Testing + +Connect via USB (J7 connector) at 115200 baud for debug console output. The application supports firmware updates through the bootloader system. \ No newline at end of file diff --git a/source/System/system.h b/source/System/system.h index 379f015..e6e90bf 100644 --- a/source/System/system.h +++ b/source/System/system.h @@ -12,6 +12,8 @@ #include "ports.h" #include "adc.h" +#include "driver.h" +#include "battery.h" #define SW_VERSION "1.10A" @@ -86,6 +88,7 @@ typedef struct ACCESSORY_t *nextAccessory; float32_t maxPowerLimit; + Battery_t batteryType; ADC_t adc; diff --git a/source/battery.c b/source/battery.c index 9c3d42b..1d58458 100644 --- a/source/battery.c +++ b/source/battery.c @@ -55,43 +55,40 @@ bool result; + void battery_checkId(void) { - -} - -void Check_Bat_Id(void) -{ -float32_t Battery; -float32_t Bat_Mid_Point; + float32_t Battery; + float32_t Bat_Mid_Point; if(sys.adc.V_BID > LITHIUM_MID_POINT) // BAT_ID = 0V for lithium, mid point for Alkaline { if(Compare_With_Limit(sys.adc.V_BID,sys.adc.V_BAT,5.0)) { - Bat_Type = EXT_DC; + + sys.batteryType = EXT_DC; sys.maxPowerLimit = POWER_LIMIT_EXT_DC; // Limit max power to 5W. } else { - Bat_Type = ALKALINE; + sys.batteryType = ALKALINE; sys.maxPowerLimit = POWER_LIMIT_ALKALINE; // Limit max power to 5W. Battery = sys.adc.V_BAT; // Calculate mid-point for alkaline Bat_Mid_Point = Battery / 2; if ((sys.adc.V_BID > (Bat_Mid_Point * 1.1)) || (sys.adc.V_BID < (Bat_Mid_Point * 0.9)) ) // Check if not at mid-point - Bat_Type = BAT_ERROR; // indicate battery insertion error + sys.batteryType = BAT_ERROR; // indicate battery insertion error } } else { - Bat_Type = LITHIUM; + sys.batteryType = LITHIUM; sys.maxPowerLimit = POWER_LIMIT_LITHIUM; // Limit max power to 5W. 1.7 = 10.0 1.7X = 25.0 } - if(Bat_Type == BAT_ERROR) + if(sys.batteryType == BAT_ERROR) { LCD_Clear(); Task=BAT_INSERTION_ERROR; diff --git a/source/battery.h b/source/battery.h index 2384295..80de75f 100644 --- a/source/battery.h +++ b/source/battery.h @@ -70,9 +70,11 @@ typedef enum { LITHIUM, BAT_ERROR, EXT_DC -}BAT_STACK_t; +} Battery_t; -void Check_Bat_Id(void); +void battery_checkId(void); + +//void Check_Bat_Id(void); void Chk_Bat_Level(void); void Test_Bat_Level(float32_t Bat_Cut_Off); float32_t Adjust_Battery_For_Load(); diff --git a/source/broadcast.c b/source/broadcast.c index 175d367..bfa4148 100644 --- a/source/broadcast.c +++ b/source/broadcast.c @@ -69,9 +69,14 @@ static void _stateInit(ACCESSORY_t *accy) accy->setFrequency = setFrequency; accy->setPower = setPower; + accy->signalPath = SIGNAL_PATH_ANT; + + accy->driveVoltage[LOW_FREQ] = V_27V; + accy->driveVoltage[HIGH_FREQ] = V_27V; + driver_setFrequency(freq); - driver_broadcastOn(true); + ACCY_setTimeout(accy, 500); } @@ -100,15 +105,7 @@ int broadcast_service(ACCESSORY_t *accy) { //USB_SendString("Broadcast deinitializing..."); - // turn off the amp and antenna - driver_broadcastOn(false); - delayms(50); - // turn off PWM - driver_setDuty(0); - - // set PSU to minimum - driver_setPSUVoltage(V_24V); accy->stateTimer = sys.systemTime + 500; } diff --git a/source/clamp.c b/source/clamp.c new file mode 100644 index 0000000..9b60f79 --- /dev/null +++ b/source/clamp.c @@ -0,0 +1,92 @@ +#include "clamp.h" + +#include "driver.h" +#include "ports.h" +#include "fgen.h" +#include "utils.h" +#include "System/system.h" + +extern SYSTEM_DATA_t sys; + +static FREQUENCY_t * setFrequency(ACCESSORY_t *accy, FREQUENCY_t *freq) +{ + + accy->setPower(accy, sys.driver->powerLevel); + + return freq; +} + +static int setPower(ACCESSORY_t *accy, PowerLevel_t power) +{ + FREQUENCY_t *f = driver_getFrequency(); + + return 0; +} + +static void _stateInit(ACCESSORY_t *accy) +{ + FREQUENCY_t *freq = driver_getFrequency(); + + if (accy->initState) + { + accy->setFrequency = setFrequency; + accy->setPower = setPower; + + accy->signalPath = SIGNAL_PATH_AMP; + + accy->driveVoltage[LOW_FREQ] = V_27V; + accy->driveVoltage[HIGH_FREQ] = V_42V; + + driver_setFrequency(freq); + + driver_broadcastOn(true); + + ACCY_setTimeout(accy, 500); + } + + if (ACCY_timedOut(accy)) + { + accy->state = PORT_STATE_RUNNING; + } +} + + +int clamp_service(ACCESSORY_t *accy) +{ + switch (accy->state) + { + case PORT_STATE_INIT: + { + _stateInit(accy); + break; + } + + case PORT_STATE_DEINIT: + { + if (accy->initState) + { + + accy->stateTimer = sys.systemTime + 500; + } + + if (sys.systemTime >= accy->stateTimer) + { + accy->state = PORT_STATE_STANDBY; + } + + break; + } + + case PORT_STATE_RUNNING: + { + if (accy->initState) + { + } + break; + } + default: + return -1; + } + + return 0; +} \ No newline at end of file diff --git a/source/clamp.h b/source/clamp.h new file mode 100644 index 0000000..ccd2aba --- /dev/null +++ b/source/clamp.h @@ -0,0 +1,8 @@ +#ifndef _CLAMP_H +#define _CLAMP_H + +#include "ports.h" + +int clamp_service(ACCESSORY_t *accy); + +#endif \ No newline at end of file diff --git a/source/dds.c b/source/dds.c index a29c13d..d634848 100644 --- a/source/dds.c +++ b/source/dds.c @@ -49,10 +49,10 @@ void dds_setFrequency(dds_t *dds, uint32_t frequency) data[3] = (uint8_t)(freq_hi & 0x00ff); // send Control word to hold setup - sendCommand(dds, FRQ_CTRL_WORD1, data, sizeof(data)); + sendCommand(dds, FRQ_CTRL_WORD1 | (dds->ddsMode == DDS_TRIANGLE ? 0x0002 : 0x0000), data, sizeof(data)); // send Control word to release setup - sendCommand(dds, FRQ_CTRL_WORD2, NULL, 0); + sendCommand(dds, FRQ_CTRL_WORD2 | (dds->ddsMode == DDS_TRIANGLE ? 0x0002 : 0x0000), NULL, 0); } else @@ -62,10 +62,11 @@ void dds_setFrequency(dds_t *dds, uint32_t frequency) } -void dds_init(dds_t *dds, SPI_MODE_t mode, gpio_pin_t resetPin) +void dds_init(dds_t *dds, SPI_MODE_t mode, gpio_pin_t resetPin, dds_mode_t ddsMode) { dds->mode = mode; dds->resetPin = resetPin; + dds->ddsMode = ddsMode; dds_reset(dds, true); } diff --git a/source/dds.h b/source/dds.h index d108199..e6adbbd 100644 --- a/source/dds.h +++ b/source/dds.h @@ -45,6 +45,12 @@ #define FREQ_LD_MAX_FREQUENCY 10000 //LD runs at or below this frequency #define FREQ_LD_SWITCH_POINT 1500 //At or below this freq, f2 is f1 * 2. above this f2 = f1 / 2 +typedef enum +{ + DDS_SINE = 0, + DDS_TRIANGLE +} dds_mode_t; + typedef struct { SPI_MODE_t mode; @@ -54,9 +60,14 @@ typedef struct // reset pin gpio_pin_t resetPin; + dds_mode_t ddsMode; + } dds_t; -void dds_init(dds_t *dds, SPI_MODE_t mode, gpio_pin_t resetPin); + + +void dds_init(dds_t *dds, SPI_MODE_t mode, gpio_pin_t resetPin, dds_mode_t ddsMode); void dds_reset(dds_t *dds, bool reset); void dds_sleep(dds_t *dds, bool sleep, bool disableDAC); +void dds_setFrequency(dds_t *dds, uint32_t frequency); #endif diff --git a/source/direct.c b/source/direct.c new file mode 100644 index 0000000..56633b1 --- /dev/null +++ b/source/direct.c @@ -0,0 +1,294 @@ +#include "direct.h" +#include "driver.h" +#include "ports.h" +#include "fgen.h" +#include "utils.h" +#include "System/system.h" + +extern SYSTEM_DATA_t sys; + +enum +{ + SET_ALKALINE = 0, + SET_LITHIUM, + SET_HF, + NUM_SETPOINTS +}; + + + +static float _setpoints[NUM_SETPOINTS][POWER_LEVEL_COUNT] = { + { 0.010, 0.050, 0.100, 0.150, 0.200 }, // Alkaline + { 0.010, 0.050, 0.150, 0.400, 1.000 }, // Lithium + { 0.010, 0.050, 0.100, 0.150, 0.200 } // HF +}; + +static const float DIRECT_KP = 10.1f; +static const float DIRECT_KI = 10.5f; +static const float DIRECT_KD = 0.0f; + +enum +{ + KP = 0, + KI, + KD, + TERM_COUNT +}; + +typedef struct +{ + float k[TERM_COUNT]; + float err; + float output; + float err_int; + float setpoint; + bool enabled; +} Controller_t; + + +static FREQUENCY_t * setFrequency(ACCESSORY_t *accy, FREQUENCY_t *freq) +{ + // is this an appropriate frequency? if not, return one that is + + return freq; +} + +static int setPower(ACCESSORY_t *accy, PowerLevel_t power) +{ + FREQUENCY_t *f = driver_getFrequency(); + PowerLevel_t prevPower = driver_getPowerLevel(); + + Controller_t *controller = (Controller_t*)accy->data; + + if (prevPower == POWER_LEVEL_0 && power > POWER_LEVEL_0) + { + driver_bypass(true); + driver_isolateOutput(false); + + + controller->enabled = true; + + } + else + if (prevPower > POWER_LEVEL_0 && power == POWER_LEVEL_0) + { + driver_bypass(false); + driver_isolateOutput(true); + + driver_setAmplitude(0); + controller->enabled = false; + } + + if (driver_isLowFreq()) + { + if (sys.batteryType == ALKALINE) + { + controller->setpoint = _setpoints[SET_ALKALINE][power]; + } + else + { + controller->setpoint = _setpoints[SET_LITHIUM][power]; + } + } + else + { + controller->setpoint = _setpoints[SET_HF][power]; + } + +#if 0 + driver_setAmplitude(power * 20); + + if (prevPower == POWER_LEVEL_0 && power > POWER_LEVEL_0) + { + driver_bypass(true); + driver_isolateOutput(false); + } + else + if (prevPower > POWER_LEVEL_0 && power == POWER_LEVEL_0) + { + driver_bypass(false); + driver_isolateOutput(true); + } +#endif + return 0; +} + + + + +static void regulate(ACCESSORY_t *accy) +{ + Controller_t *c = (Controller_t*)accy->data; + + // check for disconnect + if (accy->loadConnected) + { + if (sys.adc.Ohms_slowfilt > 10000) + { + driver_setAmplitude(20); + accy->loadConnected = false; + c->enabled = false; + } + } + else + { + if (sys.adc.Ohms_slowfilt < 3000) + { + driver_setAmplitude(20); + accy->loadConnected = true; + c->enabled = true; + } + } + + if (!c->enabled) + { + return; + } + +#if 0 + + float err = c->setpoint - sys.adc.I_OUT_SlowFilt; + float err_int = c->err_int + err; + + c->output = err * c->k[KP] + err_int * c->k[KI]; + + if (c->output > 180.0f) + { + c->output = 180.0f; + } + else + { + c->err_int = err_int; + } + + driver_setAmplitude((uint8_t)(c->output + 0.5f)); +#endif + + float targetCurrent = driver_maxLoadCurrent(); + + if (c->setpoint < targetCurrent) + { + targetCurrent = c->setpoint; + } + + int pot = driver_getAmplitude(); + int newPot = 3; + + if (pot > 0) + { + newPot = (targetCurrent / sys.adc.I_OUT_SlowFilt) * pot; // Request divided by Pot current contents + } + + + // limit change to 20 + if (newPot - pot > 20) + { + newPot = pot + 20; + } + else + if (newPot - pot < -20) + { + newPot = pot - 20; + } + + if (newPot > 255) + { + newPot = 255; + } + + // limit if the estimated voltage is over the maximum + + driver_setAmplitude((uint8_t)newPot); + +} + +static void _stateInit(ACCESSORY_t *accy) +{ + FREQUENCY_t *freq = driver_getFrequency(); + + if (accy->initState) + { + accy->setFrequency = setFrequency; + accy->setPower = setPower; + + accy->signalPath = SIGNAL_PATH_AMP; + + accy->driveVoltage[LOW_FREQ] = V_36V; + accy->driveVoltage[HIGH_FREQ] = V_24V; + + driver_setFrequency(freq); + + driver_broadcastOn(true); + + ACCY_setTimeout(accy, 500); + } + + if (ACCY_timedOut(accy)) + { + accy->state = PORT_STATE_WAIT_FOR_DRIVER; + } +} + + +int direct_service(ACCESSORY_t *accy) +{ + switch (accy->state) + { + case PORT_STATE_INIT: + { + _stateInit(accy); + break; + } + + case PORT_STATE_DEINIT: + { + if (accy->initState) + { + + accy->stateTimer = sys.systemTime + 500; + } + + if (sys.systemTime >= accy->stateTimer) + { + accy->state = PORT_STATE_STANDBY; + } + + break; + } + + case PORT_STATE_WAIT_FOR_DRIVER: + { + if (driver_outputReady()) + { + accy->state = PORT_STATE_RUNNING; + } + break; + } + + case PORT_STATE_RUNNING: + { + if (accy->initState) + { + Controller_t *controller = (Controller_t*)accy->data; + controller->k[KP] = DIRECT_KP; + controller->k[KI] = DIRECT_KI; + controller->k[KD] = DIRECT_KD; + + controller->err_int = 0.0f; + + controller->enabled = false; + + setPower(accy, driver_getPowerLevel()); + + } + + regulate(accy); + break; + } + + default: + return -1; + } + + return 0; +} diff --git a/source/direct.h b/source/direct.h new file mode 100644 index 0000000..cb7c26f --- /dev/null +++ b/source/direct.h @@ -0,0 +1,10 @@ +#ifndef _DIRECT_H +#define _DIRECT_H + +// handle the direct connect accessories + +#include "ports.h" + +int direct_service(ACCESSORY_t *accy); + +#endif \ No newline at end of file diff --git a/source/display.c b/source/display.c index a39b8d9..4a7a62e 100644 --- a/source/display.c +++ b/source/display.c @@ -71,7 +71,7 @@ void Display_Bcast(void) } } -void Display_USB(void) +static void displayUSB(void) { GL_DrawMonoBitmap(usbIconSmall, LCD_X_MIN + 30, LCD_Y_MAX - usbIconSmall[1], LCD_DRAW_SET); } @@ -158,7 +158,7 @@ void Display_Line_Voltage(void) if(Volts < 0) Volts = 0; - sprintf(tempString,"%.0fVa",Volts); + sprintf(tempString,"%.0fV",Volts); FL_DrawString( tempString, X_POS_MA+90, 48, font16Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); GL_DrawLine( X_POS_MA+90, 74, X_POS_MA+130, 74, 3, LCD_DRAW_SET); @@ -188,7 +188,7 @@ void Display_Clamp_Volts(void) if(Volts < 0) Volts = 0; - sprintf(tempString,"%.0fVb",Volts); + sprintf(tempString,"%.0fV",Volts); FL_DrawString( tempString, LCD_X_MID -10, 60, font18Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); } @@ -686,15 +686,6 @@ void Display_Line_Measurements(void) } - -void Display_USB_Status(void) -{ - if(GPIO_PinRead(GPIO,1,6)) - Display_USB(); -// GL_DrawMonoBitmap(usbIconSmall, LCD_X_MID, 30, LCD_DRAW_SET); - -} - void Display_Over_Voltage_Status(void) { static uint32_t county = 0; @@ -717,11 +708,30 @@ void Display_Fatal_Error(void) FL_DrawString(tempString, 80, 90, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); } -void Display_OnScreen_Diagnostics(void) +static void displayDiagnostics(void) { - sprintf(tempString, "POT %d", Dds_Pot_Val[1]); + //TxDriver_t *d = driver_getDriver(); + + sprintf(tempString, "Pot: %d", driver_getAmplitude()); + FL_DrawString(tempString, 0, 20, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + sprintf(tempString, "Tap: %d", driver_getTap()); FL_DrawString(tempString, 0, 30, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + sprintf(tempString, "Amp: %d", driver_getAmplifier()); + FL_DrawString(tempString, 0, 40, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + sprintf(tempString, "PSU: %.1fV", sys.adc.V_PSU); + FL_DrawString(tempString, 0, 50, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + sprintf(tempString, " F: %c%c%c", + (sys.status[ESTOP] ? 'E' : ' '), + (sys.status[BYPASS] ? 'B' : ' '), + (sys.status[USB_CONNECTED] ? 'U' : ' ') + ); + FL_DrawString(tempString, 0, 60, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + + #if 0 if((Port_State[MID_SR] & 0x40) > 0) sprintf(tempString, "HI", Dds_Pot_Val[1]); else @@ -736,8 +746,7 @@ void Display_OnScreen_Diagnostics(void) FL_DrawString(tempString, 0, 0, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); - sprintf(tempString,"Taps %d", Display_Taps()); - FL_DrawString(tempString, 0, 20, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); + sprintf(tempString,"B %.2fV",sys.adc.V_BAT); FL_DrawString(tempString, 0, 60, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); @@ -763,6 +772,7 @@ void Display_OnScreen_Diagnostics(void) // sprintf(tempString,"R %.2f",sys.adc.IRawFilt); // FL_DrawString(tempString, 0, 80, font10Bold, LCD_DRAW_SET, FL_ALIGN_LEFT); +#endif } @@ -805,6 +815,7 @@ static void displayMode(void) SYSTEM_DATA_t * sys = system_getSys(); ACCESSORY_t *active = sys->activeAccessory; + char *tmpString = sys->tmpString; if (active != NULL) { @@ -812,15 +823,26 @@ static void displayMode(void) { case ID_BROADCAST: { + + // display icon GL_DrawMonoBitmap(inductionIcon, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); + + // display power percentage + sprintf(tmpString, "%d%%", (int)driver_getPowerLevel() * 25); + FL_DrawString( tmpString, LCD_X_MID, 60, font18Bold, LCD_DRAW_SET, FL_ALIGN_CENTER); + break; } case ID_TX_SINGLE_DIRECT: { + // display icon / port GL_DrawMonoBitmap(directConnectIcon5, LCD_X_MAX-60,LCD_Y_MIN + 2, LCD_DRAW_SET); - sprintf(sys->tmpString, "%d", active->portId); - FL_DrawString(sys->tmpString, LCD_X_MAX-40, LCD_Y_MIN, font12Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + sprintf(tmpString, "%d", active->portId); + FL_DrawString(tmpString, LCD_X_MAX-40, LCD_Y_MIN, font12Bold, LCD_DRAW_SET, FL_ALIGN_RIGHT); + + // display measurements + Display_Line_Measurements(); break; } @@ -855,17 +877,27 @@ static void displayMode(void) void Display_Update(void) { - LCD_Clear(); //clear the frameBuffer + // clear the frameBuffer + LCD_Clear(); - Display_USB_Status(); + // display if USB is connected + if (isUsbConnected()) + { + displayUSB(); + } // display current mode information displayMode(); + // display power level bars displayLevel(); + // display current frequency displayFrequency(); + displayDiagnostics(); + + // write to the LCD LCD_Update(); } diff --git a/source/display.h b/source/display.h index a2fa726..f30b509 100644 --- a/source/display.h +++ b/source/display.h @@ -84,7 +84,7 @@ void Display_Clamp_Volts(void); void Display_Clamp_Power(void); void Display_Line_Voltage(void); void Display_Clamp_Volts(void); -void Display_USB(void); + uint8_t Display_Taps(void); void Display_Bat_Frame_Flash(void); void Display_Currently_Selected(void); @@ -92,7 +92,7 @@ void Display_Line_Measurements(void); void Display_Fatal_Error(void); void Display_OnScreen_Diagnostics(void); void Display_Over_Voltage_Status(void); -void Display_USB_Status(void); + void Draw_Battery(uint8_t stacks); uint8_t Read_Model_type(); void Display_EXT_DC(void); diff --git a/source/driver.c b/source/driver.c index 250faff..c62c7db 100644 --- a/source/driver.c +++ b/source/driver.c @@ -13,11 +13,137 @@ static bool powerChangeAllowed(void) return ((_sys->systemTime - _driver.lastPowerChangeTime) > POWER_CHANGE_TIME); } +static void setTapLF(TransformerTap_t tap, bool update) +{ + + TransformerTap_t prevTap = _driver.tap; + + EXPANDER_CLEAR(TAPS_OFF, NO_UPDATE); + + switch (tap) + { + case TAP_2: + { + EXPANDER_SET(_TAP2_LF_ON, update); + break; + } + case TAP_3: + { + EXPANDER_SET(_TAP3_LF_ON, update); + break; + } + case TAP_4: + { + EXPANDER_SET(_TAP4_LF_ON, update); + break; + } + default: + { + EXPANDER_SET(_TAP1_LF_ON, update); + break; + } + } + + if (update) io_update(); + + _driver.tap = tap; + +} + +static void setAmplifier(Amplifier_t amp) +{ + Amplifier_t prevAmp = _driver.amplifier; + + switch (amp) + { + case AMPLIFIER_D: + { + io_ampABOn(false, UPDATE); + delayms(5); + + io_connectAmpAB(false, UPDATE); + delayms(5); + + io_selectAmpD(UPDATE); + + io_ampDOn(true, UPDATE); + delayms(10); + + io_ampDEnable(true, UPDATE); + + + break; + } + + case AMPLIFIER_AB: + { + // turn off AB + io_ampABOn(false, NO_UPDATE); + io_connectAmpAB(false, NO_UPDATE); + io_update(); + + // set the voltage appropriate for the accessory + driver_setPSUVoltage(_sys->activeAccessory->driveVoltage[HIGH_FREQ]); + + _driver.state = DRIVER_STATE_SWITCH_AMP; + break; + } + + default: + { + // turn off all amplifiers + + io_ampABOn(false, NO_UPDATE); + io_ampDOn(false, NO_UPDATE); + io_ampDEnable(false, NO_UPDATE); + + io_connectAmpAB(false, NO_UPDATE); + io_broadcastOn(false, NO_UPDATE); + + // update values at the same time + io_update(); + + amp = AMPLIFIER_NONE; + } + } + + _driver.amplifier = amp; +} + +static void allAmpsOff(void) +{ + setAmplifier(AMPLIFIER_NONE); +} + +float driver_maxLoadCurrent(void) +{ + // get max current based on load and frquency and battery + float targetPower = _sys->maxPowerLimit; + + if (!driver_isLowFreq()) + { + targetPower = 1.0f; + } + + return (sqrtf(targetPower / _sys->adc.Ohms_slowfilt)); +} + +bool driver_isLowFreq(void) +{ + return (_driver.frequency->frequency <= MAX_D_FREQ); +} + TxDriver_t * driver_getDriver(void) { return &_driver; } +void driver_optimizeTransformer(void) +{ + // update the tap settings based on the load + // must be requested by the accessory +} + void driver_setPSUVoltage(uint8_t value) { uint8_t data[2]; @@ -29,11 +155,7 @@ void driver_setPSUVoltage(uint8_t value) void driver_setAmplitude(uint8_t value) { - uint8_t data[2]; - data[0] = 0x0; - data[1] = value; - - SPI0_SendBytes(data, 2, AMPLITUDE); // Update the Pot + fgen_setAmplitude(value); } void driver_isolateOutput(bool isolate) @@ -76,6 +198,7 @@ void driver_init(void) _driver.state = DRIVER_STATE_INIT; _driver.initState = true; + _driver.signalPath = SIGNAL_PATH_NONE; // initialize amplitude pot driver_setAmplitude(0); @@ -86,8 +209,9 @@ void driver_init(void) driver_enablePower(true); + _driver.prevAccy = NULL; - fgen_init(); + _driver.fgen = fgen_init(); // HACK: pick the first frequency for now _driver.powerLevel = POWER_LEVEL_0; @@ -95,27 +219,40 @@ void driver_init(void) _driver.lastPowerChangeTime = _sys->systemTime; + setTapLF(TAP_2, UPDATE); + } + + void driver_broadcastOn(bool on) { // turn off all amplifiers - io_broadcastOn(false, NO_UPDATE); - io_connectAmpAB(false, NO_UPDATE); - io_ampDOn(false, NO_UPDATE); + io_broadcastOn(!on, NO_UPDATE); + io_connectAmpAB(!on, NO_UPDATE); + io_ampDOn(!on, NO_UPDATE); // update values at the same time io_update(); delayms(10); - driver_setPSUVoltage(V_27V); + + driver_setPSUVoltage((on ? V_27V : V_24V)); // turn on broadcast amp - io_broadcastOn(true, UPDATE); + io_broadcastOn(on, UPDATE); delayms(5); // turn on the amplifier power supply - io_ampPsuOn(true, UPDATE); + io_ampPsuOn(on, UPDATE); + + _driver.amplifier = AMPLIFIER_NONE; + + if (!on) + { + // turn off PWM + driver_setDuty(0); + } } void driver_setDuty(uint32_t duty) @@ -146,6 +283,8 @@ void driver_setFrequency(FREQUENCY_t *freq) // accessory may select a different frequency _driver.frequency = freq; + fgen_setFrequency(freq); + driver_setPower(_driver.powerLevel); } } @@ -214,11 +353,92 @@ void driver_setSafe(bool safe) io_expanderSetSafe(); delayms(10); - dds_t *dds = fgen_getDDS(DDS_SIGNAL); - dds_sleep(dds, true, true); + //dds_t *dds = fgen_getDDS(DDS_SIGNAL); + //dds_sleep(dds, true, true); } } +static void processSwitchAmp(void) +{ + +} + + + +bool driver_outputReady(void) +{ + return (_driver.state == DRIVER_STATE_RUNNING); +} + +void driver_bypass(bool bypass) +{ + _sys->status[BYPASS] = bypass; + io_bypassProtection(bypass, UPDATE); + +} + +void driver_setSignalPath(SignalPath_t path) +{ + SignalPath_t prevPath = _driver.signalPath; + + if (path == prevPath) return; + + // disconnect external outputs + driver_isolateOutput(true); + + driver_bypass(false); + + // turn off all amplifiers + setAmplifier(AMPLIFIER_NONE); + + switch (path) + { + case SIGNAL_PATH_ANT: + { + + delayms(10); + + driver_setPSUVoltage(V_27V); + + // turn on broadcast amp + io_broadcastOn(true, UPDATE); + delayms(5); + + // turn on the amplifier power supply + io_ampPsuOn(true, UPDATE); + + // turn off PWM + driver_setDuty(0); + + break; + } + + case SIGNAL_PATH_AMP: + { + // set the frequency generator + driver_setFrequency(_driver.frequency); + + // select amplifier + if (driver_isLowFreq()) + { + setAmplifier(AMPLIFIER_D); + } + else + { + setAmplifier(AMPLIFIER_AB); + } + + break; + } + + default: + { + } + } + + _driver.signalPath = path; +} + FREQUENCY_t* driver_getFrequency(void) { return _driver.frequency; @@ -229,24 +449,99 @@ PowerLevel_t driver_getPowerLevel(void) return _driver.powerLevel; } +uint8_t driver_getAmplitude(void) +{ + return _driver.fgen->amplitude; +} + +TransformerTap_t driver_getTap(void) +{ + return _driver.tap; +} + +Amplifier_t driver_getAmplifier(void) +{ + return _driver.amplifier; +} + // safety monitor run from interrupt void driver_monitor(void) { } +static void checkAccessory(void) +{ + ACCESSORY_t *accy = _sys->activeAccessory; + + // do we need to swtich the signal path? + if (accy != NULL) + { + if (accy->state == PORT_STATE_RUNNING) + { + // new accessory attached + if (_driver.prevAccy != accy) + { + if (_driver.signalPath != accy->signalPath) + { + // change the signal path + driver_setSignalPath(accy->signalPath); + } + + io_setOutputPort(accy->portId, accy->activeChannel); + + _driver.prevAccy = accy; + } + } + } +} + void driver_service(void) { + DriverState_t prevState = _driver.state; + switch (_driver.state) { case DRIVER_STATE_INIT: { - + _driver.state = DRIVER_STATE_RUNNING; break; } - case DRIVER_STATE_WAIT_PSU: + case DRIVER_STATE_RUNNING: { + // has the accessory / signal path changed? + checkAccessory(); + break; + } + + case DRIVER_STATE_SWITCH_AMP: + { + if (_driver.initState) + { + + } + + if (_driver.amplifier == AMPLIFIER_AB) + { + if (_sys->adc.V_PSU < MAX_AB_VOLTAGE) + { + // disable D amp + io_ampDEnable(false, UPDATE); + delayms(5); + + io_ampDOn(false, UPDATE); + delayms(5); + + // select AB amp + // turn on AB amp + io_ampABOn(true, UPDATE); + + _driver.state = DRIVER_STATE_RUNNING; + } + } + + break; } @@ -255,4 +550,9 @@ void driver_service(void) break; } } + + if (prevState != _driver.state) + { + _driver.initState = true; + } } diff --git a/source/driver.h b/source/driver.h index 761b121..6caf469 100644 --- a/source/driver.h +++ b/source/driver.h @@ -5,6 +5,7 @@ #include #include "fgen.h" +#include "ports.h" #define MAIN_PSU_ENBL 0b00000100 // Active Low U13 D2 #define V_18V 0 @@ -17,26 +18,25 @@ #define V_42V 250 #define V_55V 255 #define MAX_AB_PSU V_24V //TODO - +#define MAX_AB_VOLTAGE 32.0f #define MAX_D_PSU V_36V +#define MAX_D_FREQ 44500 + + + #define MAX_CLAMP_PSU 255 #define POWER_CHANGE_TIME 500 //m sec -typedef enum -{ - POWER_LEVEL_0 = 0, - POWER_LEVEL_1, - POWER_LEVEL_2, - POWER_LEVEL_3, - POWER_LEVEL_4, -} PowerLevel_t; + typedef enum { DRIVER_STATE_INIT = 0, DRIVER_STATE_WAIT_PSU, + DRIVER_STATE_SWITCH_AMP, DRIVER_STATE_SWITCH_FREQUENCY, + DRIVER_STATE_RUNNING, } DriverState_t; typedef struct @@ -54,8 +54,17 @@ typedef struct uint32_t lastPowerChangeTime; + Amplifier_t amplifier; + SignalPath_t signalPath; + TransformerTap_t tap; + uint8_t amplitude; + fgen_t *fgen; + ACCESSORY_t *prevAccy; + } TxDriver_t; +bool driver_isLowFreq(void); +float driver_maxLoadCurrent(void); TxDriver_t * driver_getDriver(void); void driver_setPSUVoltage(uint8_t value); void driver_setAmplitude(uint8_t value); @@ -71,8 +80,16 @@ void driver_setPower(PowerLevel_t powerLevel); FREQUENCY_t *driver_getFrequency(void); void driver_setSafe(bool safe); PowerLevel_t driver_getPowerLevel(); +void driver_setSignalPath(SignalPath_t path); +uint8_t driver_getAmplitude(void); +TransformerTap_t driver_getTap(void); +Amplifier_t driver_getAmplifier(void); +bool driver_outputReady(void); +void driver_bypass(bool bypass); void driver_powerUp(void); void driver_powerDown(void); + + #endif diff --git a/source/fgen.c b/source/fgen.c index 4f0428a..3ce1ea8 100644 --- a/source/fgen.c +++ b/source/fgen.c @@ -374,29 +374,53 @@ static bool loadFrequencies(void) return success; } +void fgen_setAmplitude(uint8_t amplitude) +{ + uint8_t data[2]; + + data[0] = 0; + data[1] = (uint8_t)amplitude; + SPI0_SendBytes(data, 2, AMPLITUDE); + + _fgen.amplitude = amplitude; +} + void fgen_setFrequency(FREQUENCY_t *freq) { - + if (freq->ldFrequency > 0) + { + dds_setFrequency(&_fgen.dds[DDS_DIRECTION], freq->ldFrequency); + } + else + { + // disable the signal direction DDS + dds_sleep(&_fgen.dds[DDS_DIRECTION], true, false); + } + + dds_setFrequency(&_fgen.dds[DDS_SIGNAL], freq->frequency); + } -void fgen_init(void) +fgen_t* fgen_init(void) { uint32_t tmp; gpio_pin_t resetPin; + fgen_setAmplitude(0); + // init sets reset resetPin.port = PORT(PIN_SIG_RESET); resetPin.pin = PIN (PIN_SIG_RESET); - dds_init(&_fgen.dds[DDS_SIGNAL], SIGNAL, resetPin); + dds_init(&_fgen.dds[DDS_SIGNAL], SIGNAL, resetPin, DDS_SINE); resetPin.port = PORT(PIN_SD_RESET); resetPin.pin = PIN (PIN_SD_RESET); - dds_init(&_fgen.dds[DDS_DIRECTION], SDSIGNAL, resetPin); + dds_init(&_fgen.dds[DDS_DIRECTION], SDSIGNAL, resetPin, DDS_SINE); resetPin.port = PORT(PIN_RAMP_RST); resetPin.pin = PIN (PIN_RAMP_RST); - dds_init(&_fgen.dds[DDS_RAMP], RAMP, resetPin); + dds_init(&_fgen.dds[DDS_RAMP], RAMP, resetPin, DDS_TRIANGLE); delayms(10); @@ -408,11 +432,17 @@ void fgen_init(void) _fgen.numFrequencies = 0; + // load available frequencies from EEPROM loadFrequencies(); + // disable the signal direction DDS dds_sleep(&_fgen.dds[DDS_DIRECTION], true, false); + // set the ramp DDS frequency dds_setFrequency(&_fgen.dds[DDS_RAMP], RAMP_300KHZ); + + + return &_fgen; } diff --git a/source/fgen.h b/source/fgen.h index cea01f8..0727c77 100644 --- a/source/fgen.h +++ b/source/fgen.h @@ -52,17 +52,20 @@ typedef struct dds_t dds[NUM_DDS]; + uint8_t amplitude; + } fgen_t; -void fgen_init(void); +fgen_t* fgen_init(void); FREQUENCY_t* fgen_findNearest(uint32_t freq); FREQUENCY_t *fgen_getByIndex(int index); void fgen_getFrequencyName(FREQUENCY_t *freq, uint8_t *string); uint32_t fgen_getNumFrequencies(void); void fgen_addFrequency(uint32_t frequency, uint8_t enabled, uint8_t inMenu, FREQ_TYPE_t type); void fgen_clearFrequencies(void); - +void fgen_setFrequency(FREQUENCY_t *freq); void fgen_enableDDS(dds_type_t dds, bool enable); dds_t* fgen_getDDS(dds_type_t dds); +void fgen_setAmplitude(uint8_t amplitude); #endif diff --git a/source/io.c b/source/io.c index 9447302..5f8eda3 100644 --- a/source/io.c +++ b/source/io.c @@ -1,5 +1,6 @@ #include "io.h" #include "spi.h" +#include "ports.h" @@ -41,6 +42,20 @@ void io_expanderSetSafe(void) io_update(); } +void io_ampABOn(bool on, bool update) +{ + if (on) + { + EXPANDER_SET(AMP_AB_ON, NO_UPDATE); + } + else + { + EXPANDER_CLEAR(AMP_AB_ON, NO_UPDATE); + } + + if (update) io_update(); +} + void io_connectAmpAB(bool connect, bool update) { if (connect) @@ -78,10 +93,9 @@ void io_backlightOn(bool on, bool update) if (update) io_update(); } - -void io_ampDOn(bool on, bool update) +void io_ampDEnable(bool enable, bool update) { - if (on) + if (enable) { EXPANDER_SET(AMP_D_EN, NO_UPDATE); } @@ -93,6 +107,20 @@ void io_ampDOn(bool on, bool update) if (update) io_update(); } +void io_ampDOn(bool on, bool update) +{ + if (on) + { + EXPANDER_SET(AMP_D_ON, NO_UPDATE); + } + else + { + EXPANDER_CLEAR(AMP_D_ON, NO_UPDATE); + } + + if (update) io_update(); +} + void io_broadcastOn(bool on, bool update) { if (on) @@ -109,10 +137,19 @@ void io_broadcastOn(bool on, bool update) if (update) io_update(); } +void io_selectAmpAB(bool update) +{ + EXPANDER_SET(SELECT_AB_AMP, update); +} + +void io_selectAmpD(bool update) +{ + EXPANDER_CLEAR(SELECT_AB_AMP, update); +} void io_ampPsuOn(bool on, bool update) { - if (on) + if (on) { EXPANDER_CLEAR( _AMP_PSU_ON, NO_UPDATE); } @@ -123,3 +160,52 @@ void io_ampPsuOn(bool on, bool update) if (update) io_update(); } + +void io_setOutputPort(AccessoryPortId_t port, AccyChannelId_t channel) +{ + + if (port == ACCY_PORT_1) + { + EXPANDER_CLEAR(OUT_RELAY_OFF, NO_UPDATE); + if (channel == CHANNEL_A) + { + EXPANDER_SET(PORT1A_ON, NO_UPDATE); + } + else + if (channel == CHANNEL_B) + { + EXPANDER_SET(PORT1B_ON, NO_UPDATE); + } + } + else + if (port == ACCY_PORT_2) + { + EXPANDER_CLEAR(OUT_RELAY_OFF, NO_UPDATE); + if (channel == CHANNEL_A) + { + EXPANDER_SET(PORT2A_ON, NO_UPDATE); + } + else + if (channel == CHANNEL_B) + { + EXPANDER_SET(PORT2B_ON, NO_UPDATE); + } + } + + io_update(); +} + +void io_bypassProtection(bool bypass, bool update) +{ + if (bypass) + { + //if ((freqArray[frequency].frequency1 < MIN_BLOCK_FREQ) && (!Over_Voltage_Flag)) + EXPANDER_SET(BYPASS_ON, NO_UPDATE); + } + else + { + EXPANDER_CLEAR(BYPASS_ON, NO_UPDATE); + } + + if (update) io_update(); +} \ No newline at end of file diff --git a/source/io.h b/source/io.h index bf5b731..0c6b043 100644 --- a/source/io.h +++ b/source/io.h @@ -3,6 +3,8 @@ #include "fsl_gpio.h" #include +#include "utils.h" + void io_expanderSet(uint8_t port, uint8_t pins, bool update); void io_expanderClear(uint8_t port, uint8_t pins, bool update); @@ -52,10 +54,11 @@ void io_update(void); #define BOT_SR 2 #define TAPS_OFF_MASK 0b11100111 +#define OUT_RELAY_OFF_MASK 0b11100111 // Bottom Shift Register (U35) #define AMP_AB_SW 0b00000001 -#define AMP_D_ON 0b00000010 +#define AMP_D_ON_ 0b00000010 #define AMP_PSU 0b00000100 #define TAP_204_LF 0b00001000 #define TAP_102_LF 0b00010000 @@ -88,17 +91,28 @@ void io_update(void); #define _TAP3_LF_ON (BOT_SR, TAP_204_LF) #define _TAP4_LF_ON (BOT_SR, 0) -#define BYPASS_ON (MID_SR , LF_BYPASS) -#define BACKLIGHT_ON (BOT_SR, BKLITE_ON) -#define DISCONNECT_AB (TOP_SR, MUX_AB_AMP) -#define BROADCAST_AMP_EN (MID_SR, ANT_AMP_EN) -#define BROADCAST_AMP_PWR (TOP_SR, ANT_AMP_SW) +#define TAPS_OFF (BOT_SR, (uint8_t)~TAPS_OFF_MASK) +#define OUT_RELAY_OFF (MID_SR, (uint8_t)~OUT_RELAY_OFF_MASK) +#define BYPASS_ON (MID_SR, LF_BYPASS) +#define BACKLIGHT_ON (BOT_SR, BKLITE_ON) +#define DISCONNECT_AB (TOP_SR, MUX_AB_AMP) +#define BROADCAST_AMP_EN (MID_SR, ANT_AMP_EN) +#define BROADCAST_AMP_PWR (TOP_SR, ANT_AMP_SW) -#define AMP_D_EN (MID_SR, DAMP_EN) +#define AMP_AB_ON (BOT_SR, AMP_AB_SW) +#define AMP_D_EN (MID_SR, DAMP_EN) +#define AMP_D_ON (BOT_SR, AMP_D_ON_) + +#define PORT1A_ON (MID_SR, SLCT_GRP) +#define PORT1B_ON (MID_SR, SLCT_GRP | SLCT_OUTPUT) +#define PORT2A_ON (MID_SR, 0) +#define PORT2B_ON (MID_SR, SLCT_OUTPUT) #define _AMP_PSU_ON (BOT_SR, AMP_PSU) +#define SELECT_AB_AMP (BOT_SR, SLCT_AMP) + #define EXPANDER_SET(port_pins, update) io_expanderSet (_P1 port_pins, _P2 port_pins, update) @@ -114,10 +128,15 @@ typedef struct void io_expanderClearAll(bool update); void io_backlightOn(bool on, bool update); void io_ampDOn(bool on, bool update); +void io_ampDEnable(bool enable, bool update); +void io_ampABOn(bool on, bool update); void io_broadcastOn(bool on, bool update); void io_ampPsuOn(bool on, bool update); void io_connectAmpAB(bool connect, bool update); void io_expanderSetSafe(void); - +void io_setOutputPort(AccessoryPortId_t port, AccyChannelId_t channel); +void io_selectAmpAB(bool update); +void io_selectAmpD(bool update); +void io_bypassProtection(bool bypass, bool update); #endif diff --git a/source/main.c b/source/main.c index 4b75d9c..3a6900a 100644 --- a/source/main.c +++ b/source/main.c @@ -78,10 +78,7 @@ ClampData_t clampData; -bool isUsbConnected(void) -{ - return GPIO_READ(PIN_VBUS); -} + static char tmpString[32]; static bool _firstInit = true; @@ -142,7 +139,7 @@ static void init(void) //Safety_Check(); // Check all voltages are safe to continue in DC. - Check_Bat_Id(); // Check for Alkaline or Lithium and battery insertion error. + battery_checkId(); // Check for Alkaline or Lithium and battery insertion error. @@ -173,6 +170,7 @@ int main(void) static uint32_t tickCount = 0; sys.usbConnected = isUsbConnected(); + sys.status[USB_CONNECTED] = isUsbConnected(); USB_Update(); //Update USB here so we're outside the ISR @@ -186,7 +184,6 @@ int main(void) //setSafeMode(true); } - Display_USB(); } else { @@ -233,6 +230,7 @@ int main(void) // check for accessories ACCY_service(); + driver_service(); uint32_t pressed = 0; @@ -277,11 +275,9 @@ int main(void) case MODE_KEY: { - //mode_menu(); - // test accessory state machine ACCY_next(); - //ACCY_setActive(&sys.ports[ACCY_PORT_INDUCTION], CHANNEL_A); + //io_setOutputPort(ACCY_PORT_2, CHANNEL_B); break; } @@ -297,20 +293,7 @@ int main(void) break; } -#if 0 - case PWR_DN_KEY: - { - if(Key_Lock_Out_tmr == 0) - { - Vchktmr = LOCK_OUT_DELAY; - dec_pwr();// decrement the power output - Key_Lock_Out_tmr = KEY_LOCK_TIME; - Suspend_Step_Chk = false; - step_count = 0; - } - break; - } -#endif + } Display_Update(); diff --git a/source/ports.c b/source/ports.c index 5e9a128..9ab891b 100644 --- a/source/ports.c +++ b/source/ports.c @@ -32,6 +32,7 @@ #include "usbComms.h" #include "driver.h" #include "broadcast.h" +#include "direct.h" uint16_t Port_timer; uint16_t Taps_adjust_timer; @@ -172,7 +173,7 @@ void ACCY_service(void) { sys.activeAccessory = sys.nextAccessory; sys.nextAccessory = NULL; - initAccessory(active); + initAccessory(sys.activeAccessory); } } } @@ -316,7 +317,7 @@ bool ACCY_Connect(ACCESSORY_t *accy, ACCY_ID_t id) case ID_TX_SINGLE_DIRECT: { accy->channels[CHANNEL_A].connected = true; - accy->handler = handleDirectConnect; + accy->handler = direct_service; break; } diff --git a/source/ports.h b/source/ports.h index c905cb8..247399e 100644 --- a/source/ports.h +++ b/source/ports.h @@ -10,7 +10,8 @@ #include "fgen.h" -#include "driver.h" +//#include "driver.h" +#include "utils.h" typedef struct ACCESSORY_s ACCESSORY_t; @@ -42,29 +43,11 @@ typedef enum PORT_STATE_DEINIT, PORT_STATE_STANDBY, PORT_STATE_RUNNING, + PORT_STATE_WAIT_FOR_DRIVER, } PortState_t; -typedef enum -{ - ACCY_PORT_INDUCTION = 0, - ACCY_PORT_1 = 1, - ACCY_PORT_2 = 2, - NUM_PORTS -} AccessoryPortId_t; -typedef enum -{ - CHANNEL_A = 0, - CHANNEL_B, - NUM_CHANNELS -} AccyChannelId_t; - -typedef struct -{ - AccyChannelId_t id; - bool connected; -} AccessoryChannel_t; struct ACCESSORY_s { @@ -82,12 +65,18 @@ struct ACCESSORY_s uint32_t stateTimer; AccessoryPortId_t portId; + bool loadConnected; AccessorySetFrequency_t setFrequency; AccessorySetPower_t setPower; uint8_t powerLevel; + + SignalPath_t signalPath; + uint8_t driveVoltage[NUM_FREQ_RANGES]; + + uint8_t data[64]; }; diff --git a/source/timer.c b/source/timer.c index 82a36de..e8dfa1b 100644 --- a/source/timer.c +++ b/source/timer.c @@ -92,6 +92,7 @@ void ctimer_match0_callback(uint32_t flags) // ISR every 1mS } system_monitor(); + driver_monitor(); if (Sys_Timer > 0) Sys_Timer--; diff --git a/source/utils.c b/source/utils.c index c05754b..18734d2 100644 --- a/source/utils.c +++ b/source/utils.c @@ -418,7 +418,7 @@ void Power_Down() if (flasher) { LCD_Clear(); - Display_USB(); + //Display_USB(); count_down = 0; LCD_Update(); } @@ -833,3 +833,8 @@ void delayms(uint32_t msec) { stimer_delay(msec); } + +bool isUsbConnected(void) +{ + return GPIO_READ(PIN_VBUS); +} diff --git a/source/utils.h b/source/utils.h index 5bbe3e7..c575cf6 100644 --- a/source/utils.h +++ b/source/utils.h @@ -24,12 +24,8 @@ #define DDC_MIN 270 #define DDC_MAX 300 #define TGT_NOT_USED 330 -#define OUT_RELAY_OFF_MASK 0b11100111 +//#define OUT_RELAY_OFF_MASK 0b11100111 -#define PORT1A_ON 0b00001000 -#define PORT1B_ON 0b00011000 -#define PORT2A_ON 0b00000000 -#define PORT2B_ON 0b00010000 #define XFRMR_HF_ON 0b00000010 #define HF_AMP_ON 0b01000000 @@ -94,6 +90,65 @@ typedef enum { } RELAY_SELECT_t; +typedef enum +{ + ACCY_PORT_INDUCTION = 0, + ACCY_PORT_1 = 1, + ACCY_PORT_2 = 2, + NUM_PORTS +} AccessoryPortId_t; + +typedef enum +{ + CHANNEL_A = 0, + CHANNEL_B, + NUM_CHANNELS +} AccyChannelId_t; + +typedef struct +{ + AccyChannelId_t id; + bool connected; +} AccessoryChannel_t; + +typedef enum { + LOW_FREQ = 0, + HIGH_FREQ, + NUM_FREQ_RANGES, +} FrequencyRange_t; + +typedef enum +{ + POWER_LEVEL_0 = 0, + POWER_LEVEL_1, + POWER_LEVEL_2, + POWER_LEVEL_3, + POWER_LEVEL_4, + POWER_LEVEL_COUNT +} PowerLevel_t; + +typedef enum +{ + SIGNAL_PATH_NONE = 0, + SIGNAL_PATH_ANT, + SIGNAL_PATH_AMP, +} SignalPath_t; + +typedef enum +{ + AMPLIFIER_NONE = 0, + AMPLIFIER_D, + AMPLIFIER_AB, +} Amplifier_t; + + +typedef enum +{ + TAP_1 = 1, + TAP_2, + TAP_3, + TAP_4, +} TransformerTap_t; void Select_Estop(ESTOP_SELECT_t); void Send_Pot_Data(uint16_t Data, SPI_MODE_t destination); @@ -135,6 +190,7 @@ float32_t Get_Power_Limit(void); bool Check_For_Clamp_New(); void delayms(uint32_t msec); +bool isUsbConnected(void); #endif /* UTILS_H_ */