Created a folder to hold the Arduino script. This should allow the project to build under Arduino IDE without the user needing to create a new folder.
Dev1
DigitalConfections 2020-05-26 08:50:47 -04:00
rodzic d5210b08b3
commit b156b5fa2e
6 zmienionych plików z 1029 dodań i 1029 usunięć

Wyświetl plik

@ -1,335 +1,335 @@
/********************************************************************************************** /**********************************************************************************************
* Copyright <EFBFBD> 2017 Digital Confections LLC * Copyright <EFBFBD> 2017 Digital Confections LLC
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in the * this software and associated documentation files (the "Software"), to deal in the
* Software without restriction, including without limitation the rights to use, copy, * Software without restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the * and to permit persons to whom the Software is furnished to do so, subject to the
* following conditions: * following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
**********************************************************************************************/ **********************************************************************************************/
#ifndef DEFS_H #ifndef DEFS_H
#define DEFS_H #define DEFS_H
#include <Arduino.h> #include <Arduino.h>
/* #define F_CPU 16000000UL / * gets declared in makefile * / */ /* #define F_CPU 16000000UL / * gets declared in makefile * / */
/****************************************************** /******************************************************
* Set the text that gets displayed to the user */ * Set the text that gets displayed to the user */
#define SW_REVISION "0.1" #define SW_REVISION "0.1"
//#define TRANQUILIZE_WATCHDOG //#define TRANQUILIZE_WATCHDOG
#define PRODUCT_NAME_SHORT "ARDF Tx" #define PRODUCT_NAME_SHORT "ARDF Tx"
#define PRODUCT_NAME_LONG "WB8WFK ARDF Transmitter" #define PRODUCT_NAME_LONG "WB8WFK ARDF Transmitter"
/*******************************************************/ /*******************************************************/
#ifndef uint16_t_defined #ifndef uint16_t_defined
#define uint16_t_defined #define uint16_t_defined
typedef unsigned int uint16_t; typedef unsigned int uint16_t;
#endif #endif
#ifndef uint32_t_defined #ifndef uint32_t_defined
#define uint32_t_defined #define uint32_t_defined
typedef unsigned long uint32_t; typedef unsigned long uint32_t;
#endif #endif
#ifndef unit8_t_defined #ifndef unit8_t_defined
#define unit8_t_defined #define unit8_t_defined
typedef unsigned char uint8_t; typedef unsigned char uint8_t;
#endif #endif
#ifndef null #ifndef null
#define null 0 #define null 0
#endif #endif
#ifdef INCLUDE_DAC081C085_SUPPORT #ifdef INCLUDE_DAC081C085_SUPPORT
#define PA_DAC DAC081C_I2C_SLAVE_ADDR_A0 #define PA_DAC DAC081C_I2C_SLAVE_ADDR_A0
#define AM_DAC DAC081C_I2C_SLAVE_ADDR_A1 #define AM_DAC DAC081C_I2C_SLAVE_ADDR_A1
#define BIAS_DAC DAC081C_I2C_SLAVE_ADDR_A2 #define BIAS_DAC DAC081C_I2C_SLAVE_ADDR_A2
#endif #endif
typedef enum { typedef enum {
// TX1 = 0xA4, // TX1 = 0xA4,
// TX2 = 0xA3, // TX2 = 0xA3,
// TX3 = 0xA2, // TX3 = 0xA2,
// TX4 = 0xA1, // TX4 = 0xA1,
TX5 = 0xA0 TX5 = 0xA0
} Tx_t; } Tx_t;
/*******************************************************/ /*******************************************************/
/* Error Codes */ /* Error Codes */
/*******************************************************/ /*******************************************************/
typedef enum { typedef enum {
ERROR_CODE_NO_ERROR = 0x00, ERROR_CODE_NO_ERROR = 0x00,
ERROR_CODE_REPORT_NO_ERROR = 0x01, ERROR_CODE_REPORT_NO_ERROR = 0x01,
ERROR_CODE_2M_BIAS_SM_NOT_READY = 0xC6, ERROR_CODE_2M_BIAS_SM_NOT_READY = 0xC6,
ERROR_CODE_EVENT_STATION_ID_ERROR = 0xC7, ERROR_CODE_EVENT_STATION_ID_ERROR = 0xC7,
ERROR_CODE_EVENT_PATTERN_CODE_SPEED_NOT_SPECIFIED = 0xC8, ERROR_CODE_EVENT_PATTERN_CODE_SPEED_NOT_SPECIFIED = 0xC8,
ERROR_CODE_EVENT_PATTERN_NOT_SPECIFIED = 0xC9, ERROR_CODE_EVENT_PATTERN_NOT_SPECIFIED = 0xC9,
ERROR_CODE_EVENT_TIMING_ERROR = 0xCA, ERROR_CODE_EVENT_TIMING_ERROR = 0xCA,
ERROR_CODE_EVENT_MISSING_TRANSMIT_DURATION = 0xCB, ERROR_CODE_EVENT_MISSING_TRANSMIT_DURATION = 0xCB,
ERROR_CODE_EVENT_MISSING_START_TIME = 0xCC, ERROR_CODE_EVENT_MISSING_START_TIME = 0xCC,
ERROR_CODE_EVENT_NOT_CONFIGURED = 0xCD, ERROR_CODE_EVENT_NOT_CONFIGURED = 0xCD,
ERROR_CODE_ILLEGAL_COMMAND_RCVD = 0xCE, ERROR_CODE_ILLEGAL_COMMAND_RCVD = 0xCE,
ERROR_CODE_SW_LOGIC_ERROR = 0xCF, ERROR_CODE_SW_LOGIC_ERROR = 0xCF,
ERROR_CODE_POWER_LEVEL_NOT_SUPPORTED = 0xF5, ERROR_CODE_POWER_LEVEL_NOT_SUPPORTED = 0xF5,
ERROR_CODE_NO_ANTENNA_PREVENTS_POWER_SETTING = 0xF6, ERROR_CODE_NO_ANTENNA_PREVENTS_POWER_SETTING = 0xF6,
ERROR_CODE_NO_ANTENNA_FOR_BAND = 0xF7, ERROR_CODE_NO_ANTENNA_FOR_BAND = 0xF7,
ERROR_CODE_WD_TIMEOUT = 0xF8, ERROR_CODE_WD_TIMEOUT = 0xF8,
ERROR_CODE_SUPPLY_VOLTAGE_ERROR = 0xF9, ERROR_CODE_SUPPLY_VOLTAGE_ERROR = 0xF9,
ERROR_CODE_BUCK_REG_OUTOFSPEC = 0xFA, ERROR_CODE_BUCK_REG_OUTOFSPEC = 0xFA,
ERROR_CODE_CLKGEN_NONRESPONSIVE = 0xFB, ERROR_CODE_CLKGEN_NONRESPONSIVE = 0xFB,
ERROR_CODE_RTC_NONRESPONSIVE = 0xFC, ERROR_CODE_RTC_NONRESPONSIVE = 0xFC,
ERROR_CODE_DAC3_NONRESPONSIVE = 0xFD, ERROR_CODE_DAC3_NONRESPONSIVE = 0xFD,
ERROR_CODE_DAC2_NONRESPONSIVE = 0xFE, ERROR_CODE_DAC2_NONRESPONSIVE = 0xFE,
ERROR_CODE_DAC1_NONRESPONSIVE = 0xFF ERROR_CODE_DAC1_NONRESPONSIVE = 0xFF
} EC; } EC;
/*******************************************************/ /*******************************************************/
/* Status Codes */ /* Status Codes */
/*******************************************************/ /*******************************************************/
typedef enum { typedef enum {
STATUS_CODE_IDLE = 0x00, STATUS_CODE_IDLE = 0x00,
STATUS_CODE_REPORT_IDLE = 0x01, STATUS_CODE_REPORT_IDLE = 0x01,
STATUS_CODE_NO_ANT_ATTACHED = 0xE9, STATUS_CODE_NO_ANT_ATTACHED = 0xE9,
STATUS_CODE_2M_ANT_ATTACHED = 0xEA, STATUS_CODE_2M_ANT_ATTACHED = 0xEA,
STATUS_CODE_80M_ANT_ATTACHED = 0xEB, STATUS_CODE_80M_ANT_ATTACHED = 0xEB,
STATUS_CODE_RECEIVING_EVENT_DATA = 0xEC, STATUS_CODE_RECEIVING_EVENT_DATA = 0xEC,
STATUS_CODE_RETURNED_FROM_SLEEP = 0xED, STATUS_CODE_RETURNED_FROM_SLEEP = 0xED,
STATUS_CODE_BEGINNING_XMSN_THIS_CYCLE = 0xEE, STATUS_CODE_BEGINNING_XMSN_THIS_CYCLE = 0xEE,
STATUS_CODE_SENDING_ID = 0xEF, STATUS_CODE_SENDING_ID = 0xEF,
STATUS_CODE_EVENT_NEVER_ENDS = 0xFB, STATUS_CODE_EVENT_NEVER_ENDS = 0xFB,
STATUS_CODE_EVENT_FINISHED = 0xFC, STATUS_CODE_EVENT_FINISHED = 0xFC,
STATUS_CODE_EVENT_STARTED_NOW_TRANSMITTING = 0xFD, STATUS_CODE_EVENT_STARTED_NOW_TRANSMITTING = 0xFD,
STATUS_CODE_EVENT_STARTED_WAITING_FOR_TIME_SLOT = 0xFE, STATUS_CODE_EVENT_STARTED_WAITING_FOR_TIME_SLOT = 0xFE,
STATUS_CODE_WAITING_FOR_EVENT_START = 0xFF STATUS_CODE_WAITING_FOR_EVENT_START = 0xFF
} SC; } SC;
/*******************************************************/ /*******************************************************/
/******************************************************* /*******************************************************
* ADC Scale Factors */ * ADC Scale Factors */
/* Battery voltage should be read when +12V supply is enabled and all transmitters are fully powered off */ /* Battery voltage should be read when +12V supply is enabled and all transmitters are fully powered off */
#define ADC_REF_VOLTAGE_mV 1100UL #define ADC_REF_VOLTAGE_mV 1100UL
#define ADC_MAX_VOLTAGE_MV 4200L /* maximum voltage the ADC can read */ #define ADC_MAX_VOLTAGE_MV 4200L /* maximum voltage the ADC can read */
#define BATTERY_VOLTAGE_MAX_MV 4200L /* voltage at which the battery is considered to be fully charged */ #define BATTERY_VOLTAGE_MAX_MV 4200L /* voltage at which the battery is considered to be fully charged */
#define BATTERY_DROP 320L /* voltage drop between the battery terminals and the ADC input while powering the ESP8266 */ #define BATTERY_DROP 320L /* voltage drop between the battery terminals and the ADC input while powering the ESP8266 */
#define BATTERY_DROP_OFFSET (BATTERY_DROP * 1023L) #define BATTERY_DROP_OFFSET (BATTERY_DROP * 1023L)
#define VBAT(x) (BATTERY_DROP + (x * ADC_MAX_VOLTAGE_MV) / 1023L) #define VBAT(x) (BATTERY_DROP + (x * ADC_MAX_VOLTAGE_MV) / 1023L)
#define BATTERY_PERCENTAGE(x, y) ( ( 100L * ((x * ADC_MAX_VOLTAGE_MV + BATTERY_DROP_OFFSET) - (1023L * y)) ) / ((BATTERY_VOLTAGE_MAX_MV - y) * 1023L)) #define BATTERY_PERCENTAGE(x, y) ( ( 100L * ((x * ADC_MAX_VOLTAGE_MV + BATTERY_DROP_OFFSET) - (1023L * y)) ) / ((BATTERY_VOLTAGE_MAX_MV - y) * 1023L))
#define SUPPLY_VOLTAGE_MAX_MV 14100L #define SUPPLY_VOLTAGE_MAX_MV 14100L
#define VSUPPLY(x)((x * SUPPLY_VOLTAGE_MAX_MV) / 1023L) #define VSUPPLY(x)((x * SUPPLY_VOLTAGE_MAX_MV) / 1023L)
#define PA_VOLTAGE_MAX_MV 14100L #define PA_VOLTAGE_MAX_MV 14100L
#define VPA(x)((x * PA_VOLTAGE_MAX_MV) / 1023L) #define VPA(x)((x * PA_VOLTAGE_MAX_MV) / 1023L)
typedef uint16_t BatteryLevel; /* in milliVolts */ typedef uint16_t BatteryLevel; /* in milliVolts */
#define VOLTS_5 (((5000L - BATTERY_DROP) * 1023L) / BATTERY_VOLTAGE_MAX_MV) #define VOLTS_5 (((5000L - BATTERY_DROP) * 1023L) / BATTERY_VOLTAGE_MAX_MV)
#define VOLTS_3_19 (((3190L - BATTERY_DROP) * 1023L) / BATTERY_VOLTAGE_MAX_MV) #define VOLTS_3_19 (((3190L - BATTERY_DROP) * 1023L) / BATTERY_VOLTAGE_MAX_MV)
#define VOLTS_3_0 (((3000L - BATTERY_DROP) * 1023L) / BATTERY_VOLTAGE_MAX_MV) #define VOLTS_3_0 (((3000L - BATTERY_DROP) * 1023L) / BATTERY_VOLTAGE_MAX_MV)
#define VOLTS_2_4 (((2400L - BATTERY_DROP) * 1023L) / BATTERY_VOLTAGE_MAX_MV) #define VOLTS_2_4 (((2400L - BATTERY_DROP) * 1023L) / BATTERY_VOLTAGE_MAX_MV)
#define POWER_OFF_VOLT_THRESH_MV VOLTS_2_4 /* 2.4 V = 2400 mV */ #define POWER_OFF_VOLT_THRESH_MV VOLTS_2_4 /* 2.4 V = 2400 mV */
#define POWER_ON_VOLT_THRESH_MV VOLTS_3_0 /* 3.0 V = 3000 mV */ #define POWER_ON_VOLT_THRESH_MV VOLTS_3_0 /* 3.0 V = 3000 mV */
#define ANTENNA_DETECT_THRESH 20 #define ANTENNA_DETECT_THRESH 20
#define ANTENNA_DETECT_DEBOUNCE 50 #define ANTENNA_DETECT_DEBOUNCE 50
#define NUMBER_OF_ESSENTIAL_EVENT_PARAMETERS 14 #define NUMBER_OF_ESSENTIAL_EVENT_PARAMETERS 14
/*******************************************************/ /*******************************************************/
#ifndef SELECTIVELY_DISABLE_OPTIMIZATION #ifndef SELECTIVELY_DISABLE_OPTIMIZATION
#define SELECTIVELY_DISABLE_OPTIMIZATION #define SELECTIVELY_DISABLE_OPTIMIZATION
#endif #endif
/****************************************************** /******************************************************
* EEPROM definitions */ * EEPROM definitions */
#define EEPROM_INITIALIZED_FLAG 0xAD #define EEPROM_INITIALIZED_FLAG 0xAD
#define EEPROM_UNINITIALIZED 0x00 #define EEPROM_UNINITIALIZED 0x00
#define EEPROM_STATION_ID_DEFAULT "FOXBOX" #define EEPROM_STATION_ID_DEFAULT "FOXBOX"
#define EEPROM_PATTERN_TEXT_DEFAULT "PARIS|" #define EEPROM_PATTERN_TEXT_DEFAULT "PARIS|"
#define EEPROM_START_TIME_DEFAULT 0 #define EEPROM_START_TIME_DEFAULT 0
#define EEPROM_FINISH_TIME_DEFAULT 0 #define EEPROM_FINISH_TIME_DEFAULT 0
#define EEPROM_EVENT_ENABLED_DEFAULT FALSE #define EEPROM_EVENT_ENABLED_DEFAULT FALSE
#define EEPROM_ID_CODE_SPEED_DEFAULT 20 #define EEPROM_ID_CODE_SPEED_DEFAULT 20
#define EEPROM_PATTERN_CODE_SPEED_DEFAULT 8 #define EEPROM_PATTERN_CODE_SPEED_DEFAULT 8
#define EEPROM_ON_AIR_TIME_DEFAULT 60 #define EEPROM_ON_AIR_TIME_DEFAULT 60
#define EEPROM_OFF_AIR_TIME_DEFAULT 240 #define EEPROM_OFF_AIR_TIME_DEFAULT 240
#define EEPROM_INTRA_CYCLE_DELAY_TIME_DEFAULT 0 #define EEPROM_INTRA_CYCLE_DELAY_TIME_DEFAULT 0
#define EEPROM_ID_TIME_INTERVAL_DEFAULT 300 #define EEPROM_ID_TIME_INTERVAL_DEFAULT 300
#define EEPROM_CLOCK_CALIBRATION_DEFAULT 15629 #define EEPROM_CLOCK_CALIBRATION_DEFAULT 15629
#define EEPROM_OVERRIDE_DIP_SW_DEFAULT 0 #define EEPROM_OVERRIDE_DIP_SW_DEFAULT 0
#define EEPROM_ENABLE_LEDS_DEFAULT 1 #define EEPROM_ENABLE_LEDS_DEFAULT 1
#define EEPROM_ENABLE_SYNC_DEFAULT 1 #define EEPROM_ENABLE_SYNC_DEFAULT 1
#define EEPROM_SI5351_CALIBRATION_DEFAULT 0x00 #define EEPROM_SI5351_CALIBRATION_DEFAULT 0x00
#define EEPROM_CLK0_OUT_DEFAULT 133000000 #define EEPROM_CLK0_OUT_DEFAULT 133000000
#define EEPROM_CLK1_OUT_DEFAULT 70000000 #define EEPROM_CLK1_OUT_DEFAULT 70000000
#define EEPROM_CLK2_OUT_DEFAULT 10700000 #define EEPROM_CLK2_OUT_DEFAULT 10700000
#define EEPROM_CLK0_ONOFF_DEFAULT OFF #define EEPROM_CLK0_ONOFF_DEFAULT OFF
#define EEPROM_CLK1_ONOFF_DEFAULT OFF #define EEPROM_CLK1_ONOFF_DEFAULT OFF
#define EEPROM_CLK2_ONOFF_DEFAULT OFF #define EEPROM_CLK2_ONOFF_DEFAULT OFF
#define EEPROM_BATTERY_EMPTY_MV 3430 #define EEPROM_BATTERY_EMPTY_MV 3430
/****************************************************** /******************************************************
* General definitions for making the code easier to understand */ * General definitions for making the code easier to understand */
#define SDA_PIN (1 << PINC4) #define SDA_PIN (1 << PINC4)
#define SCL_PIN (1 << PINC5) #define SCL_PIN (1 << PINC5)
#define I2C_PINS (SCL_PIN | SDA_PIN) #define I2C_PINS (SCL_PIN | SDA_PIN)
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
#endif #endif
#ifndef TRUE #ifndef TRUE
#define TRUE !FALSE #define TRUE !FALSE
#endif #endif
#ifndef BOOL #ifndef BOOL
typedef uint8_t BOOL; typedef uint8_t BOOL;
#endif #endif
#ifndef Frequency_Hz #ifndef Frequency_Hz
typedef unsigned long Frequency_Hz; typedef unsigned long Frequency_Hz;
#endif #endif
#ifndef UINT16_MAX #ifndef UINT16_MAX
#define UINT16_MAX __INT16_MAX__ #define UINT16_MAX __INT16_MAX__
#endif #endif
#define ON 1 #define ON 1
#define OFF 0 #define OFF 0
#define TOGGLE 2 #define TOGGLE 2
#define UNDETERMINED 3 #define UNDETERMINED 3
#define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; }) #define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
#define MAX(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; }) #define MAX(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __b : __a; })
#define CLAMP(low, x, high) ({\ #define CLAMP(low, x, high) ({\
__typeof__(x) __x = (x); \ __typeof__(x) __x = (x); \
__typeof__(low) __low = (low);\ __typeof__(low) __low = (low);\
__typeof__(high) __high = (high);\ __typeof__(high) __high = (high);\
__x > __high ? __high : (__x < __low ? __low : __x);\ __x > __high ? __high : (__x < __low ? __low : __x);\
}) })
#define MAX_TIME 4294967295L #define MAX_TIME 4294967295L
#define MAX_UINT16 65535 #define MAX_UINT16 65535
#define MAX_INT16 32767 #define MAX_INT16 32767
typedef enum typedef enum
{ {
DOWN = -1, DOWN = -1,
NOCHANGE = 0, NOCHANGE = 0,
UP = 1, UP = 1,
SETTOVALUE SETTOVALUE
} IncrType; } IncrType;
typedef enum typedef enum
{ {
ANT_CONNECTION_UNDETERMINED, ANT_CONNECTION_UNDETERMINED,
ANT_ALL_DISCONNECTED, ANT_ALL_DISCONNECTED,
ANT_2M_CONNECTED, ANT_2M_CONNECTED,
ANT_80M_CONNECTED, ANT_80M_CONNECTED,
ANT_2M_AND_80M_CONNECTED ANT_2M_AND_80M_CONNECTED
} AntConnType; } AntConnType;
typedef enum typedef enum
{ {
POWER_UP, POWER_UP,
POWER_SLEEP POWER_SLEEP
} InitActionType; } InitActionType;
#define QUAD_MASK 0xC0 #define QUAD_MASK 0xC0
#define QUAD_A 7 #define QUAD_A 7
#define QUAD_B 6 #define QUAD_B 6
#define MAX_TONE_VOLUME_SETTING 15 #define MAX_TONE_VOLUME_SETTING 15
#define TONE_POT_VAL(x) (255 - (x*17)) #define TONE_POT_VAL(x) (255 - (x*17))
#define MAX_MAIN_VOLUME_SETTING 15 #define MAX_MAIN_VOLUME_SETTING 15
#define POWER_OFF_DELAY 5000 #define POWER_OFF_DELAY 5000
#define BACKLIGHT_OFF_DELAY 5000 #define BACKLIGHT_OFF_DELAY 5000
#define BACKLIGHT_ALWAYS_ON 65535 #define BACKLIGHT_ALWAYS_ON 65535
#define HEADPHONE_REMOVED_DELAY 100 #define HEADPHONE_REMOVED_DELAY 100
#define POWERUP_LOW_VOLTAGE_DELAY 900 /* A short delay at first power up before declaring battery is too low */ #define POWERUP_LOW_VOLTAGE_DELAY 900 /* A short delay at first power up before declaring battery is too low */
#define LOW_VOLTAGE_DELAY 9000 /* A longer delay if the receiver has been running and the battery starts to sag */ #define LOW_VOLTAGE_DELAY 9000 /* A longer delay if the receiver has been running and the battery starts to sag */
#define CURSOR_EXPIRATION_DELAY 5000 /* Keep cursor displayed this long without user action */ #define CURSOR_EXPIRATION_DELAY 5000 /* Keep cursor displayed this long without user action */
#define LONG_PRESS_TICK_COUNT 1200 /* Press a button for this many ticks in order to access a long-press function */ #define LONG_PRESS_TICK_COUNT 1200 /* Press a button for this many ticks in order to access a long-press function */
#define SEND_ID_DELAY 4100 #define SEND_ID_DELAY 4100
/* Periodic TIMER2 interrupt timing definitions */ /* Periodic TIMER2 interrupt timing definitions */
#define TIMER2_57HZ 10 #define TIMER2_57HZ 10
#define TIMER2_20HZ 49 #define TIMER2_20HZ 49
#define TIMER2_5_8HZ 100 #define TIMER2_5_8HZ 100
#define TIMER2_0_5HZ 1000 #define TIMER2_0_5HZ 1000
#define BEEP_SHORT 100 #define BEEP_SHORT 100
#define BEEP_LONG 65535 #define BEEP_LONG 65535
/****************************************************** /******************************************************
* UI Hardware-related definitions */ * UI Hardware-related definitions */
typedef enum typedef enum
{ {
FrequencyFormat, FrequencyFormat,
HourMinuteSecondFormat, HourMinuteSecondFormat,
HourMinuteSecondDateFormat HourMinuteSecondDateFormat
} TextFormat; } TextFormat;
#define DISPLAY_WIDTH_STRING_SIZE (NUMBER_OF_LCD_COLS + 1) #define DISPLAY_WIDTH_STRING_SIZE (NUMBER_OF_LCD_COLS + 1)
typedef enum batteryType typedef enum batteryType
{ {
BATTERY_9V, BATTERY_9V,
BATTERY_4r2V, BATTERY_4r2V,
BATTERY_EXTERNAL, BATTERY_EXTERNAL,
BATTERY_UNKNOWN BATTERY_UNKNOWN
} BatteryType; } BatteryType;
typedef enum typedef enum
{ {
Minutes_Seconds, /* minutes up to 59 */ Minutes_Seconds, /* minutes up to 59 */
Hours_Minutes_Seconds, /* hours up to 23 */ Hours_Minutes_Seconds, /* hours up to 23 */
Day_Month_Year_Hours_Minutes_Seconds, /* Year up to 99 */ Day_Month_Year_Hours_Minutes_Seconds, /* Year up to 99 */
Minutes_Seconds_Elapsed, /* minutes up to 99 */ Minutes_Seconds_Elapsed, /* minutes up to 99 */
Time_Format_Not_Specified Time_Format_Not_Specified
} TimeFormat; } TimeFormat;
#define NO_TIME_SPECIFIED (-1) #define NO_TIME_SPECIFIED (-1)
#define SecondsFromHours(hours) ((hours) * 3600) #define SecondsFromHours(hours) ((hours) * 3600)
#define SecondsFromMinutes(min) ((min) * 60) #define SecondsFromMinutes(min) ((min) * 60)
typedef enum typedef enum
{ {
PATTERN_TEXT, PATTERN_TEXT,
STATION_ID STATION_ID
} TextIndex; } TextIndex;
#endif /* DEFS_H */ #endif /* DEFS_H */

Wyświetl plik

@ -1,442 +1,442 @@
/********************************************************************************************** /**********************************************************************************************
* Copyright © 2017 Digital Confections LLC * Copyright © 2017 Digital Confections LLC
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in the * this software and associated documentation files (the "Software"), to deal in the
* Software without restriction, including without limitation the rights to use, copy, * Software without restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the * and to permit persons to whom the Software is furnished to do so, subject to the
* following conditions: * following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
********************************************************************************************** **********************************************************************************************
* linkbus.c * linkbus.c
* *
*/ */
#include "linkbus.h" #include "linkbus.h"
#include "defs.h" #include "defs.h"
//#include "util.h" //#include "util.h"
//#include <string.h> //#include <string.h>
//#include <stdio.h> //#include <stdio.h>
//#include <avr/wdt.h> //#include <avr/wdt.h>
/* Global Variables */ /* Global Variables */
static volatile BOOL g_bus_disabled = TRUE; static volatile BOOL g_bus_disabled = TRUE;
static const char crlf[] = "\n"; static const char crlf[] = "\n";
static char lineTerm[8] = "\n"; static char lineTerm[8] = "\n";
static const char textPrompt[] = "> "; static const char textPrompt[] = "> ";
static const char textHelp[][LINKBUS_MAX_TX_MSG_LENGTH] = { "\nCommands:\n", static const char textHelp[][LINKBUS_MAX_TX_MSG_LENGTH] = { "\nCommands:\n",
" CAL - Calibrate\n", " CAL - Calibrate\n",
" DIP - Override DIP\n", " DIP - Override DIP\n",
" FAC - Factory reset\n", " FAC - Factory reset\n",
" GO - Sync clock\n", " GO - Sync clock\n",
" ID - Set callsign\n", " ID - Set callsign\n",
" LED - LED on/off\n", " LED - LED on/off\n",
" RST - Reset\n", " RST - Reset\n",
" SYN - Sync on/off\n", " SYN - Sync on/off\n",
" VER - S/W version\n" }; " VER - S/W version\n" };
static char g_tempMsgBuff[LINKBUS_MAX_MSG_LENGTH]; static char g_tempMsgBuff[LINKBUS_MAX_MSG_LENGTH];
/* Local function prototypes */ /* Local function prototypes */
BOOL linkbus_start_tx(void); BOOL linkbus_start_tx(void);
/* Module global variables */ /* Module global variables */
static volatile BOOL linkbus_tx_active = FALSE; /* volatile is required to ensure optimizer handles this properly */ static volatile BOOL linkbus_tx_active = FALSE; /* volatile is required to ensure optimizer handles this properly */
static LinkbusTxBuffer tx_buffer[LINKBUS_NUMBER_OF_TX_MSG_BUFFERS]; static LinkbusTxBuffer tx_buffer[LINKBUS_NUMBER_OF_TX_MSG_BUFFERS];
static LinkbusRxBuffer rx_buffer[LINKBUS_NUMBER_OF_RX_MSG_BUFFERS]; static LinkbusRxBuffer rx_buffer[LINKBUS_NUMBER_OF_RX_MSG_BUFFERS];
LinkbusTxBuffer* nextFullTxBuffer(void) LinkbusTxBuffer* nextFullTxBuffer(void)
{ {
BOOL found = TRUE; BOOL found = TRUE;
static uint8_t bufferIndex = 0; static uint8_t bufferIndex = 0;
uint8_t count = 0; uint8_t count = 0;
while(tx_buffer[bufferIndex][0] == '\0') while(tx_buffer[bufferIndex][0] == '\0')
{ {
if(++count >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS) if(++count >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
{ {
found = FALSE; found = FALSE;
break; break;
} }
bufferIndex++; bufferIndex++;
if(bufferIndex >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS) if(bufferIndex >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
{ {
bufferIndex = 0; bufferIndex = 0;
} }
} }
if(found) if(found)
{ {
return( &tx_buffer[bufferIndex]); return( &tx_buffer[bufferIndex]);
} }
return(null); return(null);
} }
LinkbusTxBuffer* nextEmptyTxBuffer(void) LinkbusTxBuffer* nextEmptyTxBuffer(void)
{ {
BOOL found = TRUE; BOOL found = TRUE;
static uint8_t bufferIndex = 0; static uint8_t bufferIndex = 0;
uint8_t count = 0; uint8_t count = 0;
while(tx_buffer[bufferIndex][0] != '\0') while(tx_buffer[bufferIndex][0] != '\0')
{ {
if(++count >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS) if(++count >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
{ {
found = FALSE; found = FALSE;
break; break;
} }
bufferIndex++; bufferIndex++;
if(bufferIndex >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS) if(bufferIndex >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
{ {
bufferIndex = 0; bufferIndex = 0;
} }
} }
if(found) if(found)
{ {
return( &tx_buffer[bufferIndex]); return( &tx_buffer[bufferIndex]);
} }
return(null); return(null);
} }
LinkbusRxBuffer* nextEmptyRxBuffer(void) LinkbusRxBuffer* nextEmptyRxBuffer(void)
{ {
BOOL found = TRUE; BOOL found = TRUE;
static uint8_t bufferIndex = 0; static uint8_t bufferIndex = 0;
uint8_t count = 0; uint8_t count = 0;
while(rx_buffer[bufferIndex].id != MESSAGE_EMPTY) while(rx_buffer[bufferIndex].id != MESSAGE_EMPTY)
{ {
if(++count >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS) if(++count >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
{ {
found = FALSE; found = FALSE;
break; break;
} }
bufferIndex++; bufferIndex++;
if(bufferIndex >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS) if(bufferIndex >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
{ {
bufferIndex = 0; bufferIndex = 0;
} }
} }
if(found) if(found)
{ {
return( &rx_buffer[bufferIndex]); return( &rx_buffer[bufferIndex]);
} }
return(null); return(null);
} }
LinkbusRxBuffer* nextFullRxBuffer(void) LinkbusRxBuffer* nextFullRxBuffer(void)
{ {
BOOL found = TRUE; BOOL found = TRUE;
static uint8_t bufferIndex = 0; static uint8_t bufferIndex = 0;
uint8_t count = 0; uint8_t count = 0;
while(rx_buffer[bufferIndex].id == MESSAGE_EMPTY) while(rx_buffer[bufferIndex].id == MESSAGE_EMPTY)
{ {
if(++count >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS) if(++count >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
{ {
found = FALSE; found = FALSE;
break; break;
} }
bufferIndex++; bufferIndex++;
if(bufferIndex >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS) if(bufferIndex >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
{ {
bufferIndex = 0; bufferIndex = 0;
} }
} }
if(found) if(found)
{ {
return( &rx_buffer[bufferIndex]); return( &rx_buffer[bufferIndex]);
} }
return(null); return(null);
} }
/*********************************************************************** /***********************************************************************
* linkbusTxInProgress(void) * linkbusTxInProgress(void)
************************************************************************/ ************************************************************************/
BOOL linkbusTxInProgress(void) BOOL linkbusTxInProgress(void)
{ {
return(linkbus_tx_active); return(linkbus_tx_active);
} }
BOOL linkbus_start_tx(void) BOOL linkbus_start_tx(void)
{ {
BOOL success = !linkbus_tx_active; BOOL success = !linkbus_tx_active;
if(success) /* message will be lost if transmit is busy */ if(success) /* message will be lost if transmit is busy */
{ {
linkbus_tx_active = TRUE; linkbus_tx_active = TRUE;
UCSR0B |= (1 << UDRIE0); UCSR0B |= (1 << UDRIE0);
} }
return(success); return(success);
} }
void linkbus_end_tx(void) void linkbus_end_tx(void)
{ {
if(linkbus_tx_active) if(linkbus_tx_active)
{ {
UCSR0B &= ~(1 << UDRIE0); UCSR0B &= ~(1 << UDRIE0);
linkbus_tx_active = FALSE; linkbus_tx_active = FALSE;
} }
} }
void linkbus_reset_rx(void) void linkbus_reset_rx(void)
{ {
if(UCSR0B & (1 << RXEN0)) /* perform only if rx is currently enabled */ if(UCSR0B & (1 << RXEN0)) /* perform only if rx is currently enabled */
{ {
UCSR0B &= ~(1 << RXEN0); UCSR0B &= ~(1 << RXEN0);
/* uint16_t s = sizeof(rx_buffer); // test */ /* uint16_t s = sizeof(rx_buffer); // test */
memset(rx_buffer, 0, sizeof(rx_buffer)); memset(rx_buffer, 0, sizeof(rx_buffer));
/* if(s) s = 0; // test */ /* if(s) s = 0; // test */
UCSR0B |= (1 << RXEN0); UCSR0B |= (1 << RXEN0);
} }
} }
void linkbus_init(uint32_t baud) void linkbus_init(uint32_t baud)
{ {
memset(rx_buffer, 0, sizeof(rx_buffer)); memset(rx_buffer, 0, sizeof(rx_buffer));
for(int bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++) for(int bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++)
{ {
tx_buffer[bufferIndex][0] = '\0'; tx_buffer[bufferIndex][0] = '\0';
} }
/*Set baud rate */ /*Set baud rate */
uint16_t myubrr = MYUBRR(baud); uint16_t myubrr = MYUBRR(baud);
UBRR0H = (uint8_t)(myubrr >> 8); UBRR0H = (uint8_t)(myubrr >> 8);
UBRR0L = (uint8_t)myubrr; UBRR0L = (uint8_t)myubrr;
/* Enable receiver and transmitter and related interrupts */ /* Enable receiver and transmitter and related interrupts */
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
/* UCSR0B = (1<<RXEN0) | (1<<TXEN0); /* UCSR0B = (1<<RXEN0) | (1<<TXEN0);
* Set frame format: 8data, 2stop bit */ * Set frame format: 8data, 2stop bit */
UCSR0C = (1 << USBS0) | (3 << UCSZ00); UCSR0C = (1 << USBS0) | (3 << UCSZ00);
g_bus_disabled = FALSE; g_bus_disabled = FALSE;
} }
void linkbus_disable(void) void linkbus_disable(void)
{ {
uint8_t bufferIndex; uint8_t bufferIndex;
g_bus_disabled = TRUE; g_bus_disabled = TRUE;
UCSR0B = 0; UCSR0B = 0;
linkbus_end_tx(); linkbus_end_tx();
memset(rx_buffer, 0, sizeof(rx_buffer)); memset(rx_buffer, 0, sizeof(rx_buffer));
for(bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++) for(bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++)
{ {
tx_buffer[bufferIndex][0] = '\0'; tx_buffer[bufferIndex][0] = '\0';
} }
} }
void linkbus_enable(void) void linkbus_enable(void)
{ {
uint8_t bufferIndex; uint8_t bufferIndex;
g_bus_disabled = FALSE; g_bus_disabled = FALSE;
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0); UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
memset(rx_buffer, 0, sizeof(rx_buffer)); memset(rx_buffer, 0, sizeof(rx_buffer));
for(bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++) for(bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++)
{ {
tx_buffer[bufferIndex][0] = '\0'; tx_buffer[bufferIndex][0] = '\0';
} }
} }
BOOL linkbus_send_text(char* text) BOOL linkbus_send_text(char* text)
{ {
BOOL err = TRUE; BOOL err = TRUE;
uint16_t tries = 200; uint16_t tries = 200;
if(g_bus_disabled) if(g_bus_disabled)
{ {
return( err); return( err);
} }
if(text) if(text)
{ {
LinkbusTxBuffer* buff = nextEmptyTxBuffer(); LinkbusTxBuffer* buff = nextEmptyTxBuffer();
while(!buff && tries) while(!buff && tries)
{ {
while(linkbusTxInProgress() && tries) while(linkbusTxInProgress() && tries)
{ {
if(tries) if(tries)
{ {
tries--; /* wait until transmit finishes */ tries--; /* wait until transmit finishes */
} }
} }
buff = nextEmptyTxBuffer(); buff = nextEmptyTxBuffer();
} }
if(buff) if(buff)
{ {
sprintf(*buff, text); sprintf(*buff, text);
linkbus_start_tx(); linkbus_start_tx();
err = FALSE; err = FALSE;
} }
} }
return(err); return(err);
} }
/*********************************************************************************** /***********************************************************************************
* Support for creating and sending various Linkbus messages is provided below. * Support for creating and sending various Linkbus messages is provided below.
************************************************************************************/ ************************************************************************************/
void lb_send_msg(LBMessageType msgType, char* msgLabel, char* msgStr) void lb_send_msg(LBMessageType msgType, char* msgLabel, char* msgStr)
{ {
char prefix = '$'; char prefix = '$';
char terminus = ';'; char terminus = ';';
if(msgType == LINKBUS_MSG_REPLY) if(msgType == LINKBUS_MSG_REPLY)
{ {
prefix = '!'; prefix = '!';
} }
else if(msgType == LINKBUS_MSG_QUERY) else if(msgType == LINKBUS_MSG_QUERY)
{ {
terminus = '?'; terminus = '?';
} }
sprintf(g_tempMsgBuff, "%c%s,%s%c", prefix, msgLabel, msgStr, terminus); sprintf(g_tempMsgBuff, "%c%s,%s%c", prefix, msgLabel, msgStr, terminus);
linkbus_send_text(g_tempMsgBuff); linkbus_send_text(g_tempMsgBuff);
} }
void lb_send_sync(void) void lb_send_sync(void)
{ {
sprintf(g_tempMsgBuff, "....."); sprintf(g_tempMsgBuff, ".....");
linkbus_send_text(g_tempMsgBuff); linkbus_send_text(g_tempMsgBuff);
} }
void lb_broadcast_num(uint16_t data, char* str) void lb_broadcast_num(uint16_t data, char* str)
{ {
char t[6] = "\0"; char t[6] = "\0";
sprintf(t, "%u", data); sprintf(t, "%u", data);
g_tempMsgBuff[0] = '\0'; g_tempMsgBuff[0] = '\0';
if(str) if(str)
{ {
sprintf(g_tempMsgBuff, "%s,%s;", str, t); sprintf(g_tempMsgBuff, "%s,%s;", str, t);
} }
if(g_tempMsgBuff[0]) if(g_tempMsgBuff[0])
{ {
linkbus_send_text(g_tempMsgBuff); linkbus_send_text(g_tempMsgBuff);
} }
} }
/*********************************************************************************** /***********************************************************************************
* Support for creating and sending various Terminal Mode Linkbus messages is provided below. * Support for creating and sending various Terminal Mode Linkbus messages is provided below.
************************************************************************************/ ************************************************************************************/
void lb_send_NewPrompt(void) void lb_send_NewPrompt(void)
{ {
linkbus_send_text((char*)textPrompt); linkbus_send_text((char*)textPrompt);
} }
void lb_send_NewLine(void) void lb_send_NewLine(void)
{ {
linkbus_send_text((char*)crlf); linkbus_send_text((char*)crlf);
} }
void linkbus_setLineTerm(char* term) void linkbus_setLineTerm(char* term)
{ {
sprintf(lineTerm, term); sprintf(lineTerm, term);
} }
void lb_echo_char(uint8_t c) void lb_echo_char(uint8_t c)
{ {
g_tempMsgBuff[0] = c; g_tempMsgBuff[0] = c;
g_tempMsgBuff[1] = '\0'; g_tempMsgBuff[1] = '\0';
linkbus_send_text(g_tempMsgBuff); linkbus_send_text(g_tempMsgBuff);
} }
BOOL lb_send_string(char* str) BOOL lb_send_string(char* str)
{ {
if(str == NULL) if(str == NULL)
{ {
return( TRUE); return( TRUE);
} }
if(strlen(str) > LINKBUS_MAX_MSG_LENGTH) if(strlen(str) > LINKBUS_MAX_MSG_LENGTH)
{ {
return( TRUE); return( TRUE);
} }
strncpy(g_tempMsgBuff, str, LINKBUS_MAX_MSG_LENGTH); strncpy(g_tempMsgBuff, str, LINKBUS_MAX_MSG_LENGTH);
linkbus_send_text(g_tempMsgBuff); linkbus_send_text(g_tempMsgBuff);
return( FALSE); return( FALSE);
} }
void lb_send_value(uint16_t value, char* label) void lb_send_value(uint16_t value, char* label)
{ {
sprintf(g_tempMsgBuff, "> %s=%d%s", label, value, lineTerm); sprintf(g_tempMsgBuff, "> %s=%d%s", label, value, lineTerm);
linkbus_send_text(g_tempMsgBuff); linkbus_send_text(g_tempMsgBuff);
} }
/*********************************************************************** /***********************************************************************
* lb_send_Help(void) * lb_send_Help(void)
************************************************************************/ ************************************************************************/
void lb_send_Help(void) void lb_send_Help(void)
{ {
if(g_bus_disabled) if(g_bus_disabled)
{ {
return; return;
} }
sprintf(g_tempMsgBuff, "\n*** %s Ver. %s ***", PRODUCT_NAME_LONG, SW_REVISION); sprintf(g_tempMsgBuff, "\n*** %s Ver. %s ***", PRODUCT_NAME_LONG, SW_REVISION);
while(linkbus_send_text(g_tempMsgBuff)) while(linkbus_send_text(g_tempMsgBuff))
{ {
; ;
} }
while(linkbusTxInProgress()) while(linkbusTxInProgress())
{ {
; ;
} }
size_t n = sizeof(textHelp) / sizeof(textHelp[0]); size_t n = sizeof(textHelp) / sizeof(textHelp[0]);
for(uint8_t i = 0; i < n; i++) for(uint8_t i = 0; i < n; i++)
{ {
while(linkbus_send_text((char*)textHelp[i])) while(linkbus_send_text((char*)textHelp[i]))
{ {
; ;
} }
while(linkbusTxInProgress()) while(linkbusTxInProgress())
{ {
; ;
} }
} }
lb_send_NewLine(); lb_send_NewLine();
} }

Wyświetl plik

@ -1,252 +1,252 @@
/********************************************************************************************** /**********************************************************************************************
* Copyright <EFBFBD> 2017 Digital Confections LLC * Copyright <EFBFBD> 2017 Digital Confections LLC
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of * Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in the * this software and associated documentation files (the "Software"), to deal in the
* Software without restriction, including without limitation the rights to use, copy, * Software without restriction, including without limitation the rights to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, * modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the * and to permit persons to whom the Software is furnished to do so, subject to the
* following conditions: * following conditions:
* *
* The above copyright notice and this permission notice shall be included in all * The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software. * copies or substantial portions of the Software.
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
********************************************************************************************** **********************************************************************************************
* *
* linkbus.h - a simple serial inter-processor communication protocol. * linkbus.h - a simple serial inter-processor communication protocol.
*/ */
#ifndef LINKBUS_H_ #ifndef LINKBUS_H_
#define LINKBUS_H_ #define LINKBUS_H_
#include "defs.h" #include "defs.h"
//#include "transmitter.h" //#include "transmitter.h"
//#include "si5351.h" //#include "si5351.h"
#define LINKBUS_MAX_MSG_LENGTH 50 #define LINKBUS_MAX_MSG_LENGTH 50
#define LINKBUS_MIN_MSG_LENGTH 3 /* shortest message: $TTY; */ #define LINKBUS_MIN_MSG_LENGTH 3 /* shortest message: $TTY; */
#define LINKBUS_MAX_MSG_FIELD_LENGTH 21 #define LINKBUS_MAX_MSG_FIELD_LENGTH 21
#define LINKBUS_MAX_MSG_NUMBER_OF_FIELDS 3 #define LINKBUS_MAX_MSG_NUMBER_OF_FIELDS 3
#define LINKBUS_NUMBER_OF_RX_MSG_BUFFERS 2 #define LINKBUS_NUMBER_OF_RX_MSG_BUFFERS 2
#define LINKBUS_MAX_TX_MSG_LENGTH 40 #define LINKBUS_MAX_TX_MSG_LENGTH 40
#define LINKBUS_NUMBER_OF_TX_MSG_BUFFERS 10 #define LINKBUS_NUMBER_OF_TX_MSG_BUFFERS 10
#define LINKBUS_POWERUP_DELAY_SECONDS 6 #define LINKBUS_POWERUP_DELAY_SECONDS 6
#define LINKBUS_MIN_TX_INTERVAL_MS 100 #define LINKBUS_MIN_TX_INTERVAL_MS 100
#define FOSC 16000000 /* Clock Speed */ #define FOSC 16000000 /* Clock Speed */
#define BAUD 57600 #define BAUD 57600
#define MYUBRR(b) (FOSC / 16 / (b) - 1) #define MYUBRR(b) (FOSC / 16 / (b) - 1)
typedef enum typedef enum
{ {
EMPTY_BUFF, EMPTY_BUFF,
FULL_BUFF FULL_BUFF
} BufferState; } BufferState;
/* Linkbus Messages /* Linkbus Messages
* Message formats: * Message formats:
* $id,f1,f2... fn; * $id,f1,f2... fn;
* !id,f1,f2,... fn; * !id,f1,f2,... fn;
* $id,f1,f2,... fn? * $id,f1,f2,... fn?
* *
* where * where
* $ = command - ! indicates a response or broadcast to subscribers * $ = command - ! indicates a response or broadcast to subscribers
* id = linkbus MessageID * id = linkbus MessageID
* fn = variable length fields * fn = variable length fields
* ; = end of message flag - ? = end of query * ; = end of message flag - ? = end of query
* Null fields in settings commands indicates no change should be applied * Null fields in settings commands indicates no change should be applied
* All null fields indicates a polling request for current settings * All null fields indicates a polling request for current settings
* ? terminator indicates subscription request to value changes * ? terminator indicates subscription request to value changes
* Sending a query with fields containing data, is the equivalent of sending * Sending a query with fields containing data, is the equivalent of sending
* a command followed by a query (i.e., a response is requested). * a command followed by a query (i.e., a response is requested).
* *
* TEST EQUIPMENT MESSAGE FAMILY (DEVICE MESSAGING) * TEST EQUIPMENT MESSAGE FAMILY (DEVICE MESSAGING)
* $TST - Test message * $TST - Test message
* !ACK - Simple acknowledgment to a command (sent when required) * !ACK - Simple acknowledgment to a command (sent when required)
* $CK0 - Set Si5351 CLK0: field1 = freq (Hz); field2 = enable (BOOL) * $CK0 - Set Si5351 CLK0: field1 = freq (Hz); field2 = enable (BOOL)
* $CK1 - Set Si5351 CLK1: field1 = freq (Hz); field2 = enable (BOOL) * $CK1 - Set Si5351 CLK1: field1 = freq (Hz); field2 = enable (BOOL)
* $CK2 - Set Si5351 CLK2: field1 = freq (Hz); field2 = enable (BOOL) * $CK2 - Set Si5351 CLK2: field1 = freq (Hz); field2 = enable (BOOL)
* $VOL - Set audio volume: field1 = inc/decr (BOOL); field2 = % (int) * $VOL - Set audio volume: field1 = inc/decr (BOOL); field2 = % (int)
* $BAT? - Subscribe to battery voltage reports * $BAT? - Subscribe to battery voltage reports
* *
* DUAL-BAND RX MESSAGE FAMILY (FUNCTIONAL MESSAGING) * DUAL-BAND RX MESSAGE FAMILY (FUNCTIONAL MESSAGING)
* $BND - Set/Get radio band to 2m or 80m * $BND - Set/Get radio band to 2m or 80m
* $S? - Subscribe to signal strength reports * $S? - Subscribe to signal strength reports
* - Subscribe to gain setting reports * - Subscribe to gain setting reports
* - * -
*/ */
typedef enum typedef enum
{ {
MESSAGE_EMPTY = 0, MESSAGE_EMPTY = 0,
/* TEST EQUIPMENT MESSAGE FAMILY (TEST DEVICE MESSAGING) */ /* TEST EQUIPMENT MESSAGE FAMILY (TEST DEVICE MESSAGING) */
MESSAGE_BAND = 'B' * 100 + 'N' * 10 + 'D', /* $BND,; / $BND? / !BND,; // Set band; field1 = RadioBand */ MESSAGE_BAND = 'B' * 100 + 'N' * 10 + 'D', /* $BND,; / $BND? / !BND,; // Set band; field1 = RadioBand */
MESSAGE_TTY = 'T' * 100 + 'T' * 10 + 'Y', /* Adjust for PC communications interface (add crlf, etc.) */ MESSAGE_TTY = 'T' * 100 + 'T' * 10 + 'Y', /* Adjust for PC communications interface (add crlf, etc.) */
/* DUAL-BAND TX MESSAGE FAMILY (FUNCTIONAL MESSAGING) */ /* DUAL-BAND TX MESSAGE FAMILY (FUNCTIONAL MESSAGING) */
MESSAGE_CLOCK_CAL = 'C' * 100 + 'A' * 10 + 'L', /* Set Jerry's clock calibration value */ MESSAGE_CLOCK_CAL = 'C' * 100 + 'A' * 10 + 'L', /* Set Jerry's clock calibration value */
MESSAGE_FACTORY_RESET = 'F' * 100 + 'A' * 10 + 'C', /* Sets EEPROM back to defaults */ MESSAGE_FACTORY_RESET = 'F' * 100 + 'A' * 10 + 'C', /* Sets EEPROM back to defaults */
MESSAGE_OVERRIDE_DIP = 'D' *100 + 'I' * 10 + 'P', /* Override DIP switch settings using this value */ MESSAGE_OVERRIDE_DIP = 'D' *100 + 'I' * 10 + 'P', /* Override DIP switch settings using this value */
MESSAGE_LEDS = 'L' * 100 + 'E' * 10 + 'D', /* Turn on or off LEDs - accepts 1 or 0 or ON or OFF */ MESSAGE_LEDS = 'L' * 100 + 'E' * 10 + 'D', /* Turn on or off LEDs - accepts 1 or 0 or ON or OFF */
MESSAGE_SYNC_ENABLE = 'S' * 100 + 'Y' * 10 + 'N', /* Enable or disable transmitter syncing */ MESSAGE_SYNC_ENABLE = 'S' * 100 + 'Y' * 10 + 'N', /* Enable or disable transmitter syncing */
MESSAGE_TEMP = 'T' * 100 + 'E' * 10 + 'M', /* Temperature data */ MESSAGE_TEMP = 'T' * 100 + 'E' * 10 + 'M', /* Temperature data */
MESSAGE_SET_STATION_ID = 'I' * 10 + 'D', /* Sets amateur radio callsign text */ MESSAGE_SET_STATION_ID = 'I' * 10 + 'D', /* Sets amateur radio callsign text */
MESSAGE_GO = 'G' * 10 + 'O', /* Synchronizes clock */ MESSAGE_GO = 'G' * 10 + 'O', /* Synchronizes clock */
/* UTILITY MESSAGES */ /* UTILITY MESSAGES */
MESSAGE_RESET = 'R' * 100 + 'S' * 10 + 'T', /* Processor reset */ MESSAGE_RESET = 'R' * 100 + 'S' * 10 + 'T', /* Processor reset */
MESSAGE_VERSION = 'V' * 100 + 'E' * 10 + + 'R', /* S/W version number */ MESSAGE_VERSION = 'V' * 100 + 'E' * 10 + + 'R', /* S/W version number */
INVALID_MESSAGE = UINT16_MAX /* This value must never overlap a valid message ID */ INVALID_MESSAGE = UINT16_MAX /* This value must never overlap a valid message ID */
} LBMessageID; } LBMessageID;
typedef enum typedef enum
{ {
LINKBUS_MSG_UNKNOWN = 0, LINKBUS_MSG_UNKNOWN = 0,
LINKBUS_MSG_COMMAND, LINKBUS_MSG_COMMAND,
LINKBUS_MSG_QUERY, LINKBUS_MSG_QUERY,
LINKBUS_MSG_REPLY, LINKBUS_MSG_REPLY,
LINKBUS_MSG_INVALID LINKBUS_MSG_INVALID
} LBMessageType; } LBMessageType;
typedef enum typedef enum
{ {
FIELD1 = 0, FIELD1 = 0,
FIELD2 = 1, FIELD2 = 1,
FIELD3 = 2 FIELD3 = 2
} LBMessageField; } LBMessageField;
typedef enum typedef enum
{ {
BATTERY_BROADCAST = 0x0001, BATTERY_BROADCAST = 0x0001,
RSSI_BROADCAST = 0x0002, RSSI_BROADCAST = 0x0002,
RF_BROADCAST = 0x0004, RF_BROADCAST = 0x0004,
UPC_TEMP_BROADCAST = 0x0008, UPC_TEMP_BROADCAST = 0x0008,
ALL_BROADCASTS = 0x000FF ALL_BROADCASTS = 0x000FF
} LBbroadcastType; } LBbroadcastType;
typedef enum typedef enum
{ {
NO_ID = 0, NO_ID = 0,
CONTROL_HEAD_ID = 1, CONTROL_HEAD_ID = 1,
RECEIVER_ID = 2, RECEIVER_ID = 2,
TRANSMITTER_ID = 3 TRANSMITTER_ID = 3
} DeviceID; } DeviceID;
typedef char LinkbusTxBuffer[LINKBUS_MAX_TX_MSG_LENGTH]; typedef char LinkbusTxBuffer[LINKBUS_MAX_TX_MSG_LENGTH];
typedef struct typedef struct
{ {
LBMessageType type; LBMessageType type;
LBMessageID id; LBMessageID id;
char fields[LINKBUS_MAX_MSG_NUMBER_OF_FIELDS][LINKBUS_MAX_MSG_FIELD_LENGTH]; char fields[LINKBUS_MAX_MSG_NUMBER_OF_FIELDS][LINKBUS_MAX_MSG_FIELD_LENGTH];
} LinkbusRxBuffer; } LinkbusRxBuffer;
#define WAITING_FOR_UPDATE -1 #define WAITING_FOR_UPDATE -1
/** /**
*/ */
void linkbus_init(uint32_t baud); void linkbus_init(uint32_t baud);
/** /**
* Immediately turns off receiver and flushes receive buffer * Immediately turns off receiver and flushes receive buffer
*/ */
void linkbus_disable(void); void linkbus_disable(void);
/** /**
* Undoes linkbus_disable() * Undoes linkbus_disable()
*/ */
void linkbus_enable(void); void linkbus_enable(void);
/** /**
*/ */
void linkbus_end_tx(void); void linkbus_end_tx(void);
/** /**
*/ */
void linkbus_reset_rx(void); void linkbus_reset_rx(void);
/** /**
*/ */
LinkbusTxBuffer* nextEmptyTxBuffer(void); LinkbusTxBuffer* nextEmptyTxBuffer(void);
/** /**
*/ */
LinkbusTxBuffer* nextFullTxBuffer(void); LinkbusTxBuffer* nextFullTxBuffer(void);
/** /**
*/ */
BOOL linkbusTxInProgress(void); BOOL linkbusTxInProgress(void);
/** /**
*/ */
LinkbusRxBuffer* nextEmptyRxBuffer(void); LinkbusRxBuffer* nextEmptyRxBuffer(void);
/** /**
*/ */
LinkbusRxBuffer* nextFullRxBuffer(void); LinkbusRxBuffer* nextFullRxBuffer(void);
/** /**
*/ */
void lb_send_sync(void); void lb_send_sync(void);
/** /**
*/ */
BOOL linkbus_send_text(char* text); BOOL linkbus_send_text(char* text);
/** /**
*/ */
void lb_send_ESP(LBMessageType msgType, char* msg); void lb_send_ESP(LBMessageType msgType, char* msg);
/** /**
*/ */
void lb_send_msg(LBMessageType msgType, char* msgLabel, char* msgStr); void lb_send_msg(LBMessageType msgType, char* msgLabel, char* msgStr);
/** /**
*/ */
void lb_broadcast_num(uint16_t data, char* str); void lb_broadcast_num(uint16_t data, char* str);
/** /**
*/ */
void lb_send_Help(void); void lb_send_Help(void);
/** /**
*/ */
void lb_send_NewPrompt(void); void lb_send_NewPrompt(void);
/** /**
*/ */
void lb_send_NewLine(void); void lb_send_NewLine(void);
/** /**
*/ */
void linkbus_setLineTerm(char* term); void linkbus_setLineTerm(char* term);
/** /**
*/ */
void lb_echo_char(uint8_t c); void lb_echo_char(uint8_t c);
/** /**
*/ */
BOOL lb_send_string(char* str); BOOL lb_send_string(char* str);
/** /**
*/ */
void lb_send_value(uint16_t value, char* label); void lb_send_value(uint16_t value, char* label);
/** /**
*/ */
void lb_send_Help(void); void lb_send_Help(void);
#endif /* LINKBUS_H_ */ #endif /* LINKBUS_H_ */