New Folder
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
rodzic
d5210b08b3
commit
b156b5fa2e
|
@ -1,335 +1,335 @@
|
|||
|
||||
/**********************************************************************************************
|
||||
* Copyright <EFBFBD> 2017 Digital Confections LLC
|
||||
*
|
||||
* 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
|
||||
* Software without restriction, including without limitation the rights to use, copy,
|
||||
* 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
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef DEFS_H
|
||||
#define DEFS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
/* #define F_CPU 16000000UL / * gets declared in makefile * / */
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Set the text that gets displayed to the user */
|
||||
#define SW_REVISION "0.1"
|
||||
|
||||
//#define TRANQUILIZE_WATCHDOG
|
||||
|
||||
#define PRODUCT_NAME_SHORT "ARDF Tx"
|
||||
#define PRODUCT_NAME_LONG "WB8WFK ARDF Transmitter"
|
||||
|
||||
/*******************************************************/
|
||||
|
||||
#ifndef uint16_t_defined
|
||||
#define uint16_t_defined
|
||||
typedef unsigned int uint16_t;
|
||||
#endif
|
||||
|
||||
#ifndef uint32_t_defined
|
||||
#define uint32_t_defined
|
||||
typedef unsigned long uint32_t;
|
||||
#endif
|
||||
|
||||
#ifndef unit8_t_defined
|
||||
#define unit8_t_defined
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
|
||||
#ifndef null
|
||||
#define null 0
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_DAC081C085_SUPPORT
|
||||
#define PA_DAC DAC081C_I2C_SLAVE_ADDR_A0
|
||||
#define AM_DAC DAC081C_I2C_SLAVE_ADDR_A1
|
||||
#define BIAS_DAC DAC081C_I2C_SLAVE_ADDR_A2
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
// TX1 = 0xA4,
|
||||
// TX2 = 0xA3,
|
||||
// TX3 = 0xA2,
|
||||
// TX4 = 0xA1,
|
||||
TX5 = 0xA0
|
||||
} Tx_t;
|
||||
|
||||
/*******************************************************/
|
||||
/* Error Codes */
|
||||
/*******************************************************/
|
||||
typedef enum {
|
||||
ERROR_CODE_NO_ERROR = 0x00,
|
||||
ERROR_CODE_REPORT_NO_ERROR = 0x01,
|
||||
ERROR_CODE_2M_BIAS_SM_NOT_READY = 0xC6,
|
||||
ERROR_CODE_EVENT_STATION_ID_ERROR = 0xC7,
|
||||
ERROR_CODE_EVENT_PATTERN_CODE_SPEED_NOT_SPECIFIED = 0xC8,
|
||||
ERROR_CODE_EVENT_PATTERN_NOT_SPECIFIED = 0xC9,
|
||||
ERROR_CODE_EVENT_TIMING_ERROR = 0xCA,
|
||||
ERROR_CODE_EVENT_MISSING_TRANSMIT_DURATION = 0xCB,
|
||||
ERROR_CODE_EVENT_MISSING_START_TIME = 0xCC,
|
||||
ERROR_CODE_EVENT_NOT_CONFIGURED = 0xCD,
|
||||
ERROR_CODE_ILLEGAL_COMMAND_RCVD = 0xCE,
|
||||
ERROR_CODE_SW_LOGIC_ERROR = 0xCF,
|
||||
ERROR_CODE_POWER_LEVEL_NOT_SUPPORTED = 0xF5,
|
||||
ERROR_CODE_NO_ANTENNA_PREVENTS_POWER_SETTING = 0xF6,
|
||||
ERROR_CODE_NO_ANTENNA_FOR_BAND = 0xF7,
|
||||
ERROR_CODE_WD_TIMEOUT = 0xF8,
|
||||
ERROR_CODE_SUPPLY_VOLTAGE_ERROR = 0xF9,
|
||||
ERROR_CODE_BUCK_REG_OUTOFSPEC = 0xFA,
|
||||
ERROR_CODE_CLKGEN_NONRESPONSIVE = 0xFB,
|
||||
ERROR_CODE_RTC_NONRESPONSIVE = 0xFC,
|
||||
ERROR_CODE_DAC3_NONRESPONSIVE = 0xFD,
|
||||
ERROR_CODE_DAC2_NONRESPONSIVE = 0xFE,
|
||||
ERROR_CODE_DAC1_NONRESPONSIVE = 0xFF
|
||||
} EC;
|
||||
|
||||
/*******************************************************/
|
||||
/* Status Codes */
|
||||
/*******************************************************/
|
||||
typedef enum {
|
||||
STATUS_CODE_IDLE = 0x00,
|
||||
STATUS_CODE_REPORT_IDLE = 0x01,
|
||||
STATUS_CODE_NO_ANT_ATTACHED = 0xE9,
|
||||
STATUS_CODE_2M_ANT_ATTACHED = 0xEA,
|
||||
STATUS_CODE_80M_ANT_ATTACHED = 0xEB,
|
||||
STATUS_CODE_RECEIVING_EVENT_DATA = 0xEC,
|
||||
STATUS_CODE_RETURNED_FROM_SLEEP = 0xED,
|
||||
STATUS_CODE_BEGINNING_XMSN_THIS_CYCLE = 0xEE,
|
||||
STATUS_CODE_SENDING_ID = 0xEF,
|
||||
STATUS_CODE_EVENT_NEVER_ENDS = 0xFB,
|
||||
STATUS_CODE_EVENT_FINISHED = 0xFC,
|
||||
STATUS_CODE_EVENT_STARTED_NOW_TRANSMITTING = 0xFD,
|
||||
STATUS_CODE_EVENT_STARTED_WAITING_FOR_TIME_SLOT = 0xFE,
|
||||
STATUS_CODE_WAITING_FOR_EVENT_START = 0xFF
|
||||
} SC;
|
||||
|
||||
/*******************************************************/
|
||||
/*******************************************************
|
||||
* ADC Scale Factors */
|
||||
/* 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_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_DROP 320L /* voltage drop between the battery terminals and the ADC input while powering the ESP8266 */
|
||||
#define BATTERY_DROP_OFFSET (BATTERY_DROP * 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 SUPPLY_VOLTAGE_MAX_MV 14100L
|
||||
#define VSUPPLY(x)((x * SUPPLY_VOLTAGE_MAX_MV) / 1023L)
|
||||
|
||||
#define PA_VOLTAGE_MAX_MV 14100L
|
||||
#define VPA(x)((x * PA_VOLTAGE_MAX_MV) / 1023L)
|
||||
|
||||
typedef uint16_t BatteryLevel; /* in milliVolts */
|
||||
|
||||
#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_0 (((3000L - 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_ON_VOLT_THRESH_MV VOLTS_3_0 /* 3.0 V = 3000 mV */
|
||||
|
||||
#define ANTENNA_DETECT_THRESH 20
|
||||
#define ANTENNA_DETECT_DEBOUNCE 50
|
||||
|
||||
#define NUMBER_OF_ESSENTIAL_EVENT_PARAMETERS 14
|
||||
|
||||
|
||||
/*******************************************************/
|
||||
|
||||
#ifndef SELECTIVELY_DISABLE_OPTIMIZATION
|
||||
#define SELECTIVELY_DISABLE_OPTIMIZATION
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* EEPROM definitions */
|
||||
#define EEPROM_INITIALIZED_FLAG 0xAD
|
||||
#define EEPROM_UNINITIALIZED 0x00
|
||||
|
||||
#define EEPROM_STATION_ID_DEFAULT "FOXBOX"
|
||||
#define EEPROM_PATTERN_TEXT_DEFAULT "PARIS|"
|
||||
|
||||
#define EEPROM_START_TIME_DEFAULT 0
|
||||
#define EEPROM_FINISH_TIME_DEFAULT 0
|
||||
#define EEPROM_EVENT_ENABLED_DEFAULT FALSE
|
||||
#define EEPROM_ID_CODE_SPEED_DEFAULT 20
|
||||
#define EEPROM_PATTERN_CODE_SPEED_DEFAULT 8
|
||||
#define EEPROM_ON_AIR_TIME_DEFAULT 60
|
||||
#define EEPROM_OFF_AIR_TIME_DEFAULT 240
|
||||
#define EEPROM_INTRA_CYCLE_DELAY_TIME_DEFAULT 0
|
||||
#define EEPROM_ID_TIME_INTERVAL_DEFAULT 300
|
||||
#define EEPROM_CLOCK_CALIBRATION_DEFAULT 15629
|
||||
#define EEPROM_OVERRIDE_DIP_SW_DEFAULT 0
|
||||
#define EEPROM_ENABLE_LEDS_DEFAULT 1
|
||||
#define EEPROM_ENABLE_SYNC_DEFAULT 1
|
||||
|
||||
#define EEPROM_SI5351_CALIBRATION_DEFAULT 0x00
|
||||
#define EEPROM_CLK0_OUT_DEFAULT 133000000
|
||||
#define EEPROM_CLK1_OUT_DEFAULT 70000000
|
||||
#define EEPROM_CLK2_OUT_DEFAULT 10700000
|
||||
#define EEPROM_CLK0_ONOFF_DEFAULT OFF
|
||||
#define EEPROM_CLK1_ONOFF_DEFAULT OFF
|
||||
#define EEPROM_CLK2_ONOFF_DEFAULT OFF
|
||||
|
||||
#define EEPROM_BATTERY_EMPTY_MV 3430
|
||||
|
||||
/******************************************************
|
||||
* General definitions for making the code easier to understand */
|
||||
#define SDA_PIN (1 << PINC4)
|
||||
#define SCL_PIN (1 << PINC5)
|
||||
#define I2C_PINS (SCL_PIN | SDA_PIN)
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE !FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BOOL
|
||||
typedef uint8_t BOOL;
|
||||
#endif
|
||||
|
||||
#ifndef Frequency_Hz
|
||||
typedef unsigned long Frequency_Hz;
|
||||
#endif
|
||||
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX __INT16_MAX__
|
||||
#endif
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#define TOGGLE 2
|
||||
|
||||
#define UNDETERMINED 3
|
||||
|
||||
#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 CLAMP(low, x, high) ({\
|
||||
__typeof__(x) __x = (x); \
|
||||
__typeof__(low) __low = (low);\
|
||||
__typeof__(high) __high = (high);\
|
||||
__x > __high ? __high : (__x < __low ? __low : __x);\
|
||||
})
|
||||
|
||||
#define MAX_TIME 4294967295L
|
||||
#define MAX_UINT16 65535
|
||||
#define MAX_INT16 32767
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DOWN = -1,
|
||||
NOCHANGE = 0,
|
||||
UP = 1,
|
||||
SETTOVALUE
|
||||
} IncrType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ANT_CONNECTION_UNDETERMINED,
|
||||
ANT_ALL_DISCONNECTED,
|
||||
ANT_2M_CONNECTED,
|
||||
ANT_80M_CONNECTED,
|
||||
ANT_2M_AND_80M_CONNECTED
|
||||
} AntConnType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
POWER_UP,
|
||||
POWER_SLEEP
|
||||
} InitActionType;
|
||||
|
||||
#define QUAD_MASK 0xC0
|
||||
#define QUAD_A 7
|
||||
#define QUAD_B 6
|
||||
|
||||
#define MAX_TONE_VOLUME_SETTING 15
|
||||
#define TONE_POT_VAL(x) (255 - (x*17))
|
||||
#define MAX_MAIN_VOLUME_SETTING 15
|
||||
|
||||
#define POWER_OFF_DELAY 5000
|
||||
#define BACKLIGHT_OFF_DELAY 5000
|
||||
#define BACKLIGHT_ALWAYS_ON 65535
|
||||
#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 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 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
|
||||
|
||||
/* Periodic TIMER2 interrupt timing definitions */
|
||||
#define TIMER2_57HZ 10
|
||||
#define TIMER2_20HZ 49
|
||||
#define TIMER2_5_8HZ 100
|
||||
#define TIMER2_0_5HZ 1000
|
||||
|
||||
#define BEEP_SHORT 100
|
||||
#define BEEP_LONG 65535
|
||||
|
||||
/******************************************************
|
||||
* UI Hardware-related definitions */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FrequencyFormat,
|
||||
HourMinuteSecondFormat,
|
||||
HourMinuteSecondDateFormat
|
||||
} TextFormat;
|
||||
|
||||
#define DISPLAY_WIDTH_STRING_SIZE (NUMBER_OF_LCD_COLS + 1)
|
||||
|
||||
typedef enum batteryType
|
||||
{
|
||||
BATTERY_9V,
|
||||
BATTERY_4r2V,
|
||||
BATTERY_EXTERNAL,
|
||||
BATTERY_UNKNOWN
|
||||
} BatteryType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Minutes_Seconds, /* minutes up to 59 */
|
||||
Hours_Minutes_Seconds, /* hours up to 23 */
|
||||
Day_Month_Year_Hours_Minutes_Seconds, /* Year up to 99 */
|
||||
Minutes_Seconds_Elapsed, /* minutes up to 99 */
|
||||
Time_Format_Not_Specified
|
||||
} TimeFormat;
|
||||
|
||||
#define NO_TIME_SPECIFIED (-1)
|
||||
|
||||
#define SecondsFromHours(hours) ((hours) * 3600)
|
||||
#define SecondsFromMinutes(min) ((min) * 60)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PATTERN_TEXT,
|
||||
STATION_ID
|
||||
} TextIndex;
|
||||
|
||||
#endif /* DEFS_H */
|
||||
|
||||
/**********************************************************************************************
|
||||
* Copyright <EFBFBD> 2017 Digital Confections LLC
|
||||
*
|
||||
* 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
|
||||
* Software without restriction, including without limitation the rights to use, copy,
|
||||
* 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
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef DEFS_H
|
||||
#define DEFS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
/* #define F_CPU 16000000UL / * gets declared in makefile * / */
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Set the text that gets displayed to the user */
|
||||
#define SW_REVISION "0.1"
|
||||
|
||||
//#define TRANQUILIZE_WATCHDOG
|
||||
|
||||
#define PRODUCT_NAME_SHORT "ARDF Tx"
|
||||
#define PRODUCT_NAME_LONG "WB8WFK ARDF Transmitter"
|
||||
|
||||
/*******************************************************/
|
||||
|
||||
#ifndef uint16_t_defined
|
||||
#define uint16_t_defined
|
||||
typedef unsigned int uint16_t;
|
||||
#endif
|
||||
|
||||
#ifndef uint32_t_defined
|
||||
#define uint32_t_defined
|
||||
typedef unsigned long uint32_t;
|
||||
#endif
|
||||
|
||||
#ifndef unit8_t_defined
|
||||
#define unit8_t_defined
|
||||
typedef unsigned char uint8_t;
|
||||
#endif
|
||||
|
||||
#ifndef null
|
||||
#define null 0
|
||||
#endif
|
||||
|
||||
#ifdef INCLUDE_DAC081C085_SUPPORT
|
||||
#define PA_DAC DAC081C_I2C_SLAVE_ADDR_A0
|
||||
#define AM_DAC DAC081C_I2C_SLAVE_ADDR_A1
|
||||
#define BIAS_DAC DAC081C_I2C_SLAVE_ADDR_A2
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
// TX1 = 0xA4,
|
||||
// TX2 = 0xA3,
|
||||
// TX3 = 0xA2,
|
||||
// TX4 = 0xA1,
|
||||
TX5 = 0xA0
|
||||
} Tx_t;
|
||||
|
||||
/*******************************************************/
|
||||
/* Error Codes */
|
||||
/*******************************************************/
|
||||
typedef enum {
|
||||
ERROR_CODE_NO_ERROR = 0x00,
|
||||
ERROR_CODE_REPORT_NO_ERROR = 0x01,
|
||||
ERROR_CODE_2M_BIAS_SM_NOT_READY = 0xC6,
|
||||
ERROR_CODE_EVENT_STATION_ID_ERROR = 0xC7,
|
||||
ERROR_CODE_EVENT_PATTERN_CODE_SPEED_NOT_SPECIFIED = 0xC8,
|
||||
ERROR_CODE_EVENT_PATTERN_NOT_SPECIFIED = 0xC9,
|
||||
ERROR_CODE_EVENT_TIMING_ERROR = 0xCA,
|
||||
ERROR_CODE_EVENT_MISSING_TRANSMIT_DURATION = 0xCB,
|
||||
ERROR_CODE_EVENT_MISSING_START_TIME = 0xCC,
|
||||
ERROR_CODE_EVENT_NOT_CONFIGURED = 0xCD,
|
||||
ERROR_CODE_ILLEGAL_COMMAND_RCVD = 0xCE,
|
||||
ERROR_CODE_SW_LOGIC_ERROR = 0xCF,
|
||||
ERROR_CODE_POWER_LEVEL_NOT_SUPPORTED = 0xF5,
|
||||
ERROR_CODE_NO_ANTENNA_PREVENTS_POWER_SETTING = 0xF6,
|
||||
ERROR_CODE_NO_ANTENNA_FOR_BAND = 0xF7,
|
||||
ERROR_CODE_WD_TIMEOUT = 0xF8,
|
||||
ERROR_CODE_SUPPLY_VOLTAGE_ERROR = 0xF9,
|
||||
ERROR_CODE_BUCK_REG_OUTOFSPEC = 0xFA,
|
||||
ERROR_CODE_CLKGEN_NONRESPONSIVE = 0xFB,
|
||||
ERROR_CODE_RTC_NONRESPONSIVE = 0xFC,
|
||||
ERROR_CODE_DAC3_NONRESPONSIVE = 0xFD,
|
||||
ERROR_CODE_DAC2_NONRESPONSIVE = 0xFE,
|
||||
ERROR_CODE_DAC1_NONRESPONSIVE = 0xFF
|
||||
} EC;
|
||||
|
||||
/*******************************************************/
|
||||
/* Status Codes */
|
||||
/*******************************************************/
|
||||
typedef enum {
|
||||
STATUS_CODE_IDLE = 0x00,
|
||||
STATUS_CODE_REPORT_IDLE = 0x01,
|
||||
STATUS_CODE_NO_ANT_ATTACHED = 0xE9,
|
||||
STATUS_CODE_2M_ANT_ATTACHED = 0xEA,
|
||||
STATUS_CODE_80M_ANT_ATTACHED = 0xEB,
|
||||
STATUS_CODE_RECEIVING_EVENT_DATA = 0xEC,
|
||||
STATUS_CODE_RETURNED_FROM_SLEEP = 0xED,
|
||||
STATUS_CODE_BEGINNING_XMSN_THIS_CYCLE = 0xEE,
|
||||
STATUS_CODE_SENDING_ID = 0xEF,
|
||||
STATUS_CODE_EVENT_NEVER_ENDS = 0xFB,
|
||||
STATUS_CODE_EVENT_FINISHED = 0xFC,
|
||||
STATUS_CODE_EVENT_STARTED_NOW_TRANSMITTING = 0xFD,
|
||||
STATUS_CODE_EVENT_STARTED_WAITING_FOR_TIME_SLOT = 0xFE,
|
||||
STATUS_CODE_WAITING_FOR_EVENT_START = 0xFF
|
||||
} SC;
|
||||
|
||||
/*******************************************************/
|
||||
/*******************************************************
|
||||
* ADC Scale Factors */
|
||||
/* 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_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_DROP 320L /* voltage drop between the battery terminals and the ADC input while powering the ESP8266 */
|
||||
#define BATTERY_DROP_OFFSET (BATTERY_DROP * 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 SUPPLY_VOLTAGE_MAX_MV 14100L
|
||||
#define VSUPPLY(x)((x * SUPPLY_VOLTAGE_MAX_MV) / 1023L)
|
||||
|
||||
#define PA_VOLTAGE_MAX_MV 14100L
|
||||
#define VPA(x)((x * PA_VOLTAGE_MAX_MV) / 1023L)
|
||||
|
||||
typedef uint16_t BatteryLevel; /* in milliVolts */
|
||||
|
||||
#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_0 (((3000L - 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_ON_VOLT_THRESH_MV VOLTS_3_0 /* 3.0 V = 3000 mV */
|
||||
|
||||
#define ANTENNA_DETECT_THRESH 20
|
||||
#define ANTENNA_DETECT_DEBOUNCE 50
|
||||
|
||||
#define NUMBER_OF_ESSENTIAL_EVENT_PARAMETERS 14
|
||||
|
||||
|
||||
/*******************************************************/
|
||||
|
||||
#ifndef SELECTIVELY_DISABLE_OPTIMIZATION
|
||||
#define SELECTIVELY_DISABLE_OPTIMIZATION
|
||||
#endif
|
||||
|
||||
/******************************************************
|
||||
* EEPROM definitions */
|
||||
#define EEPROM_INITIALIZED_FLAG 0xAD
|
||||
#define EEPROM_UNINITIALIZED 0x00
|
||||
|
||||
#define EEPROM_STATION_ID_DEFAULT "FOXBOX"
|
||||
#define EEPROM_PATTERN_TEXT_DEFAULT "PARIS|"
|
||||
|
||||
#define EEPROM_START_TIME_DEFAULT 0
|
||||
#define EEPROM_FINISH_TIME_DEFAULT 0
|
||||
#define EEPROM_EVENT_ENABLED_DEFAULT FALSE
|
||||
#define EEPROM_ID_CODE_SPEED_DEFAULT 20
|
||||
#define EEPROM_PATTERN_CODE_SPEED_DEFAULT 8
|
||||
#define EEPROM_ON_AIR_TIME_DEFAULT 60
|
||||
#define EEPROM_OFF_AIR_TIME_DEFAULT 240
|
||||
#define EEPROM_INTRA_CYCLE_DELAY_TIME_DEFAULT 0
|
||||
#define EEPROM_ID_TIME_INTERVAL_DEFAULT 300
|
||||
#define EEPROM_CLOCK_CALIBRATION_DEFAULT 15629
|
||||
#define EEPROM_OVERRIDE_DIP_SW_DEFAULT 0
|
||||
#define EEPROM_ENABLE_LEDS_DEFAULT 1
|
||||
#define EEPROM_ENABLE_SYNC_DEFAULT 1
|
||||
|
||||
#define EEPROM_SI5351_CALIBRATION_DEFAULT 0x00
|
||||
#define EEPROM_CLK0_OUT_DEFAULT 133000000
|
||||
#define EEPROM_CLK1_OUT_DEFAULT 70000000
|
||||
#define EEPROM_CLK2_OUT_DEFAULT 10700000
|
||||
#define EEPROM_CLK0_ONOFF_DEFAULT OFF
|
||||
#define EEPROM_CLK1_ONOFF_DEFAULT OFF
|
||||
#define EEPROM_CLK2_ONOFF_DEFAULT OFF
|
||||
|
||||
#define EEPROM_BATTERY_EMPTY_MV 3430
|
||||
|
||||
/******************************************************
|
||||
* General definitions for making the code easier to understand */
|
||||
#define SDA_PIN (1 << PINC4)
|
||||
#define SCL_PIN (1 << PINC5)
|
||||
#define I2C_PINS (SCL_PIN | SDA_PIN)
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE !FALSE
|
||||
#endif
|
||||
|
||||
#ifndef BOOL
|
||||
typedef uint8_t BOOL;
|
||||
#endif
|
||||
|
||||
#ifndef Frequency_Hz
|
||||
typedef unsigned long Frequency_Hz;
|
||||
#endif
|
||||
|
||||
#ifndef UINT16_MAX
|
||||
#define UINT16_MAX __INT16_MAX__
|
||||
#endif
|
||||
|
||||
#define ON 1
|
||||
#define OFF 0
|
||||
#define TOGGLE 2
|
||||
|
||||
#define UNDETERMINED 3
|
||||
|
||||
#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 CLAMP(low, x, high) ({\
|
||||
__typeof__(x) __x = (x); \
|
||||
__typeof__(low) __low = (low);\
|
||||
__typeof__(high) __high = (high);\
|
||||
__x > __high ? __high : (__x < __low ? __low : __x);\
|
||||
})
|
||||
|
||||
#define MAX_TIME 4294967295L
|
||||
#define MAX_UINT16 65535
|
||||
#define MAX_INT16 32767
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DOWN = -1,
|
||||
NOCHANGE = 0,
|
||||
UP = 1,
|
||||
SETTOVALUE
|
||||
} IncrType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ANT_CONNECTION_UNDETERMINED,
|
||||
ANT_ALL_DISCONNECTED,
|
||||
ANT_2M_CONNECTED,
|
||||
ANT_80M_CONNECTED,
|
||||
ANT_2M_AND_80M_CONNECTED
|
||||
} AntConnType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
POWER_UP,
|
||||
POWER_SLEEP
|
||||
} InitActionType;
|
||||
|
||||
#define QUAD_MASK 0xC0
|
||||
#define QUAD_A 7
|
||||
#define QUAD_B 6
|
||||
|
||||
#define MAX_TONE_VOLUME_SETTING 15
|
||||
#define TONE_POT_VAL(x) (255 - (x*17))
|
||||
#define MAX_MAIN_VOLUME_SETTING 15
|
||||
|
||||
#define POWER_OFF_DELAY 5000
|
||||
#define BACKLIGHT_OFF_DELAY 5000
|
||||
#define BACKLIGHT_ALWAYS_ON 65535
|
||||
#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 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 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
|
||||
|
||||
/* Periodic TIMER2 interrupt timing definitions */
|
||||
#define TIMER2_57HZ 10
|
||||
#define TIMER2_20HZ 49
|
||||
#define TIMER2_5_8HZ 100
|
||||
#define TIMER2_0_5HZ 1000
|
||||
|
||||
#define BEEP_SHORT 100
|
||||
#define BEEP_LONG 65535
|
||||
|
||||
/******************************************************
|
||||
* UI Hardware-related definitions */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FrequencyFormat,
|
||||
HourMinuteSecondFormat,
|
||||
HourMinuteSecondDateFormat
|
||||
} TextFormat;
|
||||
|
||||
#define DISPLAY_WIDTH_STRING_SIZE (NUMBER_OF_LCD_COLS + 1)
|
||||
|
||||
typedef enum batteryType
|
||||
{
|
||||
BATTERY_9V,
|
||||
BATTERY_4r2V,
|
||||
BATTERY_EXTERNAL,
|
||||
BATTERY_UNKNOWN
|
||||
} BatteryType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
Minutes_Seconds, /* minutes up to 59 */
|
||||
Hours_Minutes_Seconds, /* hours up to 23 */
|
||||
Day_Month_Year_Hours_Minutes_Seconds, /* Year up to 99 */
|
||||
Minutes_Seconds_Elapsed, /* minutes up to 99 */
|
||||
Time_Format_Not_Specified
|
||||
} TimeFormat;
|
||||
|
||||
#define NO_TIME_SPECIFIED (-1)
|
||||
|
||||
#define SecondsFromHours(hours) ((hours) * 3600)
|
||||
#define SecondsFromMinutes(min) ((min) * 60)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PATTERN_TEXT,
|
||||
STATION_ID
|
||||
} TextIndex;
|
||||
|
||||
#endif /* DEFS_H */
|
|
@ -1,442 +1,442 @@
|
|||
/**********************************************************************************************
|
||||
* Copyright © 2017 Digital Confections LLC
|
||||
*
|
||||
* 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
|
||||
* Software without restriction, including without limitation the rights to use, copy,
|
||||
* 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
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************
|
||||
* linkbus.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "linkbus.h"
|
||||
#include "defs.h"
|
||||
//#include "util.h"
|
||||
//#include <string.h>
|
||||
//#include <stdio.h>
|
||||
//#include <avr/wdt.h>
|
||||
|
||||
/* Global Variables */
|
||||
static volatile BOOL g_bus_disabled = TRUE;
|
||||
static const char crlf[] = "\n";
|
||||
static char lineTerm[8] = "\n";
|
||||
static const char textPrompt[] = "> ";
|
||||
|
||||
static const char textHelp[][LINKBUS_MAX_TX_MSG_LENGTH] = { "\nCommands:\n",
|
||||
" CAL - Calibrate\n",
|
||||
" DIP - Override DIP\n",
|
||||
" FAC - Factory reset\n",
|
||||
" GO - Sync clock\n",
|
||||
" ID - Set callsign\n",
|
||||
" LED - LED on/off\n",
|
||||
" RST - Reset\n",
|
||||
" SYN - Sync on/off\n",
|
||||
" VER - S/W version\n" };
|
||||
|
||||
static char g_tempMsgBuff[LINKBUS_MAX_MSG_LENGTH];
|
||||
|
||||
/* Local function prototypes */
|
||||
BOOL linkbus_start_tx(void);
|
||||
|
||||
/* Module global variables */
|
||||
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 LinkbusRxBuffer rx_buffer[LINKBUS_NUMBER_OF_RX_MSG_BUFFERS];
|
||||
|
||||
LinkbusTxBuffer* nextFullTxBuffer(void)
|
||||
{
|
||||
BOOL found = TRUE;
|
||||
static uint8_t bufferIndex = 0;
|
||||
uint8_t count = 0;
|
||||
|
||||
while(tx_buffer[bufferIndex][0] == '\0')
|
||||
{
|
||||
if(++count >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
bufferIndex++;
|
||||
if(bufferIndex >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
return( &tx_buffer[bufferIndex]);
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
LinkbusTxBuffer* nextEmptyTxBuffer(void)
|
||||
{
|
||||
BOOL found = TRUE;
|
||||
static uint8_t bufferIndex = 0;
|
||||
uint8_t count = 0;
|
||||
|
||||
while(tx_buffer[bufferIndex][0] != '\0')
|
||||
{
|
||||
if(++count >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
bufferIndex++;
|
||||
if(bufferIndex >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
return( &tx_buffer[bufferIndex]);
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
LinkbusRxBuffer* nextEmptyRxBuffer(void)
|
||||
{
|
||||
BOOL found = TRUE;
|
||||
static uint8_t bufferIndex = 0;
|
||||
uint8_t count = 0;
|
||||
|
||||
while(rx_buffer[bufferIndex].id != MESSAGE_EMPTY)
|
||||
{
|
||||
if(++count >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
bufferIndex++;
|
||||
if(bufferIndex >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
return( &rx_buffer[bufferIndex]);
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
LinkbusRxBuffer* nextFullRxBuffer(void)
|
||||
{
|
||||
BOOL found = TRUE;
|
||||
static uint8_t bufferIndex = 0;
|
||||
uint8_t count = 0;
|
||||
|
||||
while(rx_buffer[bufferIndex].id == MESSAGE_EMPTY)
|
||||
{
|
||||
if(++count >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
bufferIndex++;
|
||||
if(bufferIndex >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
return( &rx_buffer[bufferIndex]);
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* linkbusTxInProgress(void)
|
||||
************************************************************************/
|
||||
BOOL linkbusTxInProgress(void)
|
||||
{
|
||||
return(linkbus_tx_active);
|
||||
}
|
||||
|
||||
BOOL linkbus_start_tx(void)
|
||||
{
|
||||
BOOL success = !linkbus_tx_active;
|
||||
|
||||
if(success) /* message will be lost if transmit is busy */
|
||||
{
|
||||
linkbus_tx_active = TRUE;
|
||||
UCSR0B |= (1 << UDRIE0);
|
||||
}
|
||||
|
||||
return(success);
|
||||
}
|
||||
|
||||
void linkbus_end_tx(void)
|
||||
{
|
||||
if(linkbus_tx_active)
|
||||
{
|
||||
UCSR0B &= ~(1 << UDRIE0);
|
||||
linkbus_tx_active = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void linkbus_reset_rx(void)
|
||||
{
|
||||
if(UCSR0B & (1 << RXEN0)) /* perform only if rx is currently enabled */
|
||||
{
|
||||
UCSR0B &= ~(1 << RXEN0);
|
||||
/* uint16_t s = sizeof(rx_buffer); // test */
|
||||
memset(rx_buffer, 0, sizeof(rx_buffer));
|
||||
/* if(s) s = 0; // test */
|
||||
UCSR0B |= (1 << RXEN0);
|
||||
}
|
||||
}
|
||||
|
||||
void linkbus_init(uint32_t baud)
|
||||
{
|
||||
memset(rx_buffer, 0, sizeof(rx_buffer));
|
||||
|
||||
for(int bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++)
|
||||
{
|
||||
tx_buffer[bufferIndex][0] = '\0';
|
||||
}
|
||||
|
||||
/*Set baud rate */
|
||||
uint16_t myubrr = MYUBRR(baud);
|
||||
UBRR0H = (uint8_t)(myubrr >> 8);
|
||||
UBRR0L = (uint8_t)myubrr;
|
||||
/* Enable receiver and transmitter and related interrupts */
|
||||
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
|
||||
/* UCSR0B = (1<<RXEN0) | (1<<TXEN0);
|
||||
* Set frame format: 8data, 2stop bit */
|
||||
UCSR0C = (1 << USBS0) | (3 << UCSZ00);
|
||||
g_bus_disabled = FALSE;
|
||||
}
|
||||
|
||||
void linkbus_disable(void)
|
||||
{
|
||||
uint8_t bufferIndex;
|
||||
|
||||
g_bus_disabled = TRUE;
|
||||
UCSR0B = 0;
|
||||
linkbus_end_tx();
|
||||
memset(rx_buffer, 0, sizeof(rx_buffer));
|
||||
|
||||
for(bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++)
|
||||
{
|
||||
tx_buffer[bufferIndex][0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void linkbus_enable(void)
|
||||
{
|
||||
uint8_t bufferIndex;
|
||||
|
||||
g_bus_disabled = FALSE;
|
||||
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
|
||||
|
||||
memset(rx_buffer, 0, sizeof(rx_buffer));
|
||||
|
||||
for(bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++)
|
||||
{
|
||||
tx_buffer[bufferIndex][0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL linkbus_send_text(char* text)
|
||||
{
|
||||
BOOL err = TRUE;
|
||||
uint16_t tries = 200;
|
||||
|
||||
if(g_bus_disabled)
|
||||
{
|
||||
return( err);
|
||||
}
|
||||
|
||||
if(text)
|
||||
{
|
||||
LinkbusTxBuffer* buff = nextEmptyTxBuffer();
|
||||
|
||||
while(!buff && tries)
|
||||
{
|
||||
while(linkbusTxInProgress() && tries)
|
||||
{
|
||||
if(tries)
|
||||
{
|
||||
tries--; /* wait until transmit finishes */
|
||||
}
|
||||
}
|
||||
buff = nextEmptyTxBuffer();
|
||||
}
|
||||
|
||||
if(buff)
|
||||
{
|
||||
sprintf(*buff, text);
|
||||
|
||||
linkbus_start_tx();
|
||||
err = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
* Support for creating and sending various Linkbus messages is provided below.
|
||||
************************************************************************************/
|
||||
|
||||
void lb_send_msg(LBMessageType msgType, char* msgLabel, char* msgStr)
|
||||
{
|
||||
char prefix = '$';
|
||||
char terminus = ';';
|
||||
|
||||
if(msgType == LINKBUS_MSG_REPLY)
|
||||
{
|
||||
prefix = '!';
|
||||
}
|
||||
else if(msgType == LINKBUS_MSG_QUERY)
|
||||
{
|
||||
terminus = '?';
|
||||
}
|
||||
|
||||
sprintf(g_tempMsgBuff, "%c%s,%s%c", prefix, msgLabel, msgStr, terminus);
|
||||
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
|
||||
void lb_send_sync(void)
|
||||
{
|
||||
sprintf(g_tempMsgBuff, ".....");
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
|
||||
void lb_broadcast_num(uint16_t data, char* str)
|
||||
{
|
||||
char t[6] = "\0";
|
||||
|
||||
sprintf(t, "%u", data);
|
||||
g_tempMsgBuff[0] = '\0';
|
||||
|
||||
if(str)
|
||||
{
|
||||
sprintf(g_tempMsgBuff, "%s,%s;", str, t);
|
||||
}
|
||||
|
||||
if(g_tempMsgBuff[0])
|
||||
{
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
* Support for creating and sending various Terminal Mode Linkbus messages is provided below.
|
||||
************************************************************************************/
|
||||
|
||||
void lb_send_NewPrompt(void)
|
||||
{
|
||||
linkbus_send_text((char*)textPrompt);
|
||||
}
|
||||
|
||||
void lb_send_NewLine(void)
|
||||
{
|
||||
linkbus_send_text((char*)crlf);
|
||||
}
|
||||
|
||||
void linkbus_setLineTerm(char* term)
|
||||
{
|
||||
sprintf(lineTerm, term);
|
||||
}
|
||||
|
||||
void lb_echo_char(uint8_t c)
|
||||
{
|
||||
g_tempMsgBuff[0] = c;
|
||||
g_tempMsgBuff[1] = '\0';
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
BOOL lb_send_string(char* str)
|
||||
{
|
||||
if(str == NULL)
|
||||
{
|
||||
return( TRUE);
|
||||
}
|
||||
if(strlen(str) > LINKBUS_MAX_MSG_LENGTH)
|
||||
{
|
||||
return( TRUE);
|
||||
}
|
||||
strncpy(g_tempMsgBuff, str, LINKBUS_MAX_MSG_LENGTH);
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
return( FALSE);
|
||||
}
|
||||
|
||||
void lb_send_value(uint16_t value, char* label)
|
||||
{
|
||||
sprintf(g_tempMsgBuff, "> %s=%d%s", label, value, lineTerm);
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* lb_send_Help(void)
|
||||
************************************************************************/
|
||||
void lb_send_Help(void)
|
||||
{
|
||||
if(g_bus_disabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(g_tempMsgBuff, "\n*** %s Ver. %s ***", PRODUCT_NAME_LONG, SW_REVISION);
|
||||
|
||||
while(linkbus_send_text(g_tempMsgBuff))
|
||||
{
|
||||
;
|
||||
}
|
||||
while(linkbusTxInProgress())
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
size_t n = sizeof(textHelp) / sizeof(textHelp[0]);
|
||||
for(uint8_t i = 0; i < n; i++)
|
||||
{
|
||||
while(linkbus_send_text((char*)textHelp[i]))
|
||||
{
|
||||
;
|
||||
}
|
||||
while(linkbusTxInProgress())
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
lb_send_NewLine();
|
||||
}
|
||||
|
||||
/**********************************************************************************************
|
||||
* Copyright © 2017 Digital Confections LLC
|
||||
*
|
||||
* 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
|
||||
* Software without restriction, including without limitation the rights to use, copy,
|
||||
* 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
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************
|
||||
* linkbus.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "linkbus.h"
|
||||
#include "defs.h"
|
||||
//#include "util.h"
|
||||
//#include <string.h>
|
||||
//#include <stdio.h>
|
||||
//#include <avr/wdt.h>
|
||||
|
||||
/* Global Variables */
|
||||
static volatile BOOL g_bus_disabled = TRUE;
|
||||
static const char crlf[] = "\n";
|
||||
static char lineTerm[8] = "\n";
|
||||
static const char textPrompt[] = "> ";
|
||||
|
||||
static const char textHelp[][LINKBUS_MAX_TX_MSG_LENGTH] = { "\nCommands:\n",
|
||||
" CAL - Calibrate\n",
|
||||
" DIP - Override DIP\n",
|
||||
" FAC - Factory reset\n",
|
||||
" GO - Sync clock\n",
|
||||
" ID - Set callsign\n",
|
||||
" LED - LED on/off\n",
|
||||
" RST - Reset\n",
|
||||
" SYN - Sync on/off\n",
|
||||
" VER - S/W version\n" };
|
||||
|
||||
static char g_tempMsgBuff[LINKBUS_MAX_MSG_LENGTH];
|
||||
|
||||
/* Local function prototypes */
|
||||
BOOL linkbus_start_tx(void);
|
||||
|
||||
/* Module global variables */
|
||||
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 LinkbusRxBuffer rx_buffer[LINKBUS_NUMBER_OF_RX_MSG_BUFFERS];
|
||||
|
||||
LinkbusTxBuffer* nextFullTxBuffer(void)
|
||||
{
|
||||
BOOL found = TRUE;
|
||||
static uint8_t bufferIndex = 0;
|
||||
uint8_t count = 0;
|
||||
|
||||
while(tx_buffer[bufferIndex][0] == '\0')
|
||||
{
|
||||
if(++count >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
bufferIndex++;
|
||||
if(bufferIndex >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
return( &tx_buffer[bufferIndex]);
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
LinkbusTxBuffer* nextEmptyTxBuffer(void)
|
||||
{
|
||||
BOOL found = TRUE;
|
||||
static uint8_t bufferIndex = 0;
|
||||
uint8_t count = 0;
|
||||
|
||||
while(tx_buffer[bufferIndex][0] != '\0')
|
||||
{
|
||||
if(++count >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
bufferIndex++;
|
||||
if(bufferIndex >= LINKBUS_NUMBER_OF_TX_MSG_BUFFERS)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
return( &tx_buffer[bufferIndex]);
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
LinkbusRxBuffer* nextEmptyRxBuffer(void)
|
||||
{
|
||||
BOOL found = TRUE;
|
||||
static uint8_t bufferIndex = 0;
|
||||
uint8_t count = 0;
|
||||
|
||||
while(rx_buffer[bufferIndex].id != MESSAGE_EMPTY)
|
||||
{
|
||||
if(++count >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
bufferIndex++;
|
||||
if(bufferIndex >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
return( &rx_buffer[bufferIndex]);
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
LinkbusRxBuffer* nextFullRxBuffer(void)
|
||||
{
|
||||
BOOL found = TRUE;
|
||||
static uint8_t bufferIndex = 0;
|
||||
uint8_t count = 0;
|
||||
|
||||
while(rx_buffer[bufferIndex].id == MESSAGE_EMPTY)
|
||||
{
|
||||
if(++count >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
|
||||
{
|
||||
found = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
bufferIndex++;
|
||||
if(bufferIndex >= LINKBUS_NUMBER_OF_RX_MSG_BUFFERS)
|
||||
{
|
||||
bufferIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(found)
|
||||
{
|
||||
return( &rx_buffer[bufferIndex]);
|
||||
}
|
||||
|
||||
return(null);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* linkbusTxInProgress(void)
|
||||
************************************************************************/
|
||||
BOOL linkbusTxInProgress(void)
|
||||
{
|
||||
return(linkbus_tx_active);
|
||||
}
|
||||
|
||||
BOOL linkbus_start_tx(void)
|
||||
{
|
||||
BOOL success = !linkbus_tx_active;
|
||||
|
||||
if(success) /* message will be lost if transmit is busy */
|
||||
{
|
||||
linkbus_tx_active = TRUE;
|
||||
UCSR0B |= (1 << UDRIE0);
|
||||
}
|
||||
|
||||
return(success);
|
||||
}
|
||||
|
||||
void linkbus_end_tx(void)
|
||||
{
|
||||
if(linkbus_tx_active)
|
||||
{
|
||||
UCSR0B &= ~(1 << UDRIE0);
|
||||
linkbus_tx_active = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void linkbus_reset_rx(void)
|
||||
{
|
||||
if(UCSR0B & (1 << RXEN0)) /* perform only if rx is currently enabled */
|
||||
{
|
||||
UCSR0B &= ~(1 << RXEN0);
|
||||
/* uint16_t s = sizeof(rx_buffer); // test */
|
||||
memset(rx_buffer, 0, sizeof(rx_buffer));
|
||||
/* if(s) s = 0; // test */
|
||||
UCSR0B |= (1 << RXEN0);
|
||||
}
|
||||
}
|
||||
|
||||
void linkbus_init(uint32_t baud)
|
||||
{
|
||||
memset(rx_buffer, 0, sizeof(rx_buffer));
|
||||
|
||||
for(int bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++)
|
||||
{
|
||||
tx_buffer[bufferIndex][0] = '\0';
|
||||
}
|
||||
|
||||
/*Set baud rate */
|
||||
uint16_t myubrr = MYUBRR(baud);
|
||||
UBRR0H = (uint8_t)(myubrr >> 8);
|
||||
UBRR0L = (uint8_t)myubrr;
|
||||
/* Enable receiver and transmitter and related interrupts */
|
||||
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
|
||||
/* UCSR0B = (1<<RXEN0) | (1<<TXEN0);
|
||||
* Set frame format: 8data, 2stop bit */
|
||||
UCSR0C = (1 << USBS0) | (3 << UCSZ00);
|
||||
g_bus_disabled = FALSE;
|
||||
}
|
||||
|
||||
void linkbus_disable(void)
|
||||
{
|
||||
uint8_t bufferIndex;
|
||||
|
||||
g_bus_disabled = TRUE;
|
||||
UCSR0B = 0;
|
||||
linkbus_end_tx();
|
||||
memset(rx_buffer, 0, sizeof(rx_buffer));
|
||||
|
||||
for(bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++)
|
||||
{
|
||||
tx_buffer[bufferIndex][0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void linkbus_enable(void)
|
||||
{
|
||||
uint8_t bufferIndex;
|
||||
|
||||
g_bus_disabled = FALSE;
|
||||
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
|
||||
|
||||
memset(rx_buffer, 0, sizeof(rx_buffer));
|
||||
|
||||
for(bufferIndex = 0; bufferIndex < LINKBUS_NUMBER_OF_TX_MSG_BUFFERS; bufferIndex++)
|
||||
{
|
||||
tx_buffer[bufferIndex][0] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL linkbus_send_text(char* text)
|
||||
{
|
||||
BOOL err = TRUE;
|
||||
uint16_t tries = 200;
|
||||
|
||||
if(g_bus_disabled)
|
||||
{
|
||||
return( err);
|
||||
}
|
||||
|
||||
if(text)
|
||||
{
|
||||
LinkbusTxBuffer* buff = nextEmptyTxBuffer();
|
||||
|
||||
while(!buff && tries)
|
||||
{
|
||||
while(linkbusTxInProgress() && tries)
|
||||
{
|
||||
if(tries)
|
||||
{
|
||||
tries--; /* wait until transmit finishes */
|
||||
}
|
||||
}
|
||||
buff = nextEmptyTxBuffer();
|
||||
}
|
||||
|
||||
if(buff)
|
||||
{
|
||||
sprintf(*buff, text);
|
||||
|
||||
linkbus_start_tx();
|
||||
err = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
* Support for creating and sending various Linkbus messages is provided below.
|
||||
************************************************************************************/
|
||||
|
||||
void lb_send_msg(LBMessageType msgType, char* msgLabel, char* msgStr)
|
||||
{
|
||||
char prefix = '$';
|
||||
char terminus = ';';
|
||||
|
||||
if(msgType == LINKBUS_MSG_REPLY)
|
||||
{
|
||||
prefix = '!';
|
||||
}
|
||||
else if(msgType == LINKBUS_MSG_QUERY)
|
||||
{
|
||||
terminus = '?';
|
||||
}
|
||||
|
||||
sprintf(g_tempMsgBuff, "%c%s,%s%c", prefix, msgLabel, msgStr, terminus);
|
||||
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
|
||||
void lb_send_sync(void)
|
||||
{
|
||||
sprintf(g_tempMsgBuff, ".....");
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
|
||||
void lb_broadcast_num(uint16_t data, char* str)
|
||||
{
|
||||
char t[6] = "\0";
|
||||
|
||||
sprintf(t, "%u", data);
|
||||
g_tempMsgBuff[0] = '\0';
|
||||
|
||||
if(str)
|
||||
{
|
||||
sprintf(g_tempMsgBuff, "%s,%s;", str, t);
|
||||
}
|
||||
|
||||
if(g_tempMsgBuff[0])
|
||||
{
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************************
|
||||
* Support for creating and sending various Terminal Mode Linkbus messages is provided below.
|
||||
************************************************************************************/
|
||||
|
||||
void lb_send_NewPrompt(void)
|
||||
{
|
||||
linkbus_send_text((char*)textPrompt);
|
||||
}
|
||||
|
||||
void lb_send_NewLine(void)
|
||||
{
|
||||
linkbus_send_text((char*)crlf);
|
||||
}
|
||||
|
||||
void linkbus_setLineTerm(char* term)
|
||||
{
|
||||
sprintf(lineTerm, term);
|
||||
}
|
||||
|
||||
void lb_echo_char(uint8_t c)
|
||||
{
|
||||
g_tempMsgBuff[0] = c;
|
||||
g_tempMsgBuff[1] = '\0';
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
BOOL lb_send_string(char* str)
|
||||
{
|
||||
if(str == NULL)
|
||||
{
|
||||
return( TRUE);
|
||||
}
|
||||
if(strlen(str) > LINKBUS_MAX_MSG_LENGTH)
|
||||
{
|
||||
return( TRUE);
|
||||
}
|
||||
strncpy(g_tempMsgBuff, str, LINKBUS_MAX_MSG_LENGTH);
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
return( FALSE);
|
||||
}
|
||||
|
||||
void lb_send_value(uint16_t value, char* label)
|
||||
{
|
||||
sprintf(g_tempMsgBuff, "> %s=%d%s", label, value, lineTerm);
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* lb_send_Help(void)
|
||||
************************************************************************/
|
||||
void lb_send_Help(void)
|
||||
{
|
||||
if(g_bus_disabled)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
sprintf(g_tempMsgBuff, "\n*** %s Ver. %s ***", PRODUCT_NAME_LONG, SW_REVISION);
|
||||
|
||||
while(linkbus_send_text(g_tempMsgBuff))
|
||||
{
|
||||
;
|
||||
}
|
||||
while(linkbusTxInProgress())
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
size_t n = sizeof(textHelp) / sizeof(textHelp[0]);
|
||||
for(uint8_t i = 0; i < n; i++)
|
||||
{
|
||||
while(linkbus_send_text((char*)textHelp[i]))
|
||||
{
|
||||
;
|
||||
}
|
||||
while(linkbusTxInProgress())
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
lb_send_NewLine();
|
||||
}
|
||||
|
|
@ -1,252 +1,252 @@
|
|||
/**********************************************************************************************
|
||||
* Copyright <EFBFBD> 2017 Digital Confections LLC
|
||||
*
|
||||
* 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
|
||||
* Software without restriction, including without limitation the rights to use, copy,
|
||||
* 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
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************
|
||||
*
|
||||
* linkbus.h - a simple serial inter-processor communication protocol.
|
||||
*/
|
||||
|
||||
#ifndef LINKBUS_H_
|
||||
#define LINKBUS_H_
|
||||
|
||||
#include "defs.h"
|
||||
//#include "transmitter.h"
|
||||
//#include "si5351.h"
|
||||
|
||||
#define LINKBUS_MAX_MSG_LENGTH 50
|
||||
#define LINKBUS_MIN_MSG_LENGTH 3 /* shortest message: $TTY; */
|
||||
#define LINKBUS_MAX_MSG_FIELD_LENGTH 21
|
||||
#define LINKBUS_MAX_MSG_NUMBER_OF_FIELDS 3
|
||||
#define LINKBUS_NUMBER_OF_RX_MSG_BUFFERS 2
|
||||
#define LINKBUS_MAX_TX_MSG_LENGTH 40
|
||||
#define LINKBUS_NUMBER_OF_TX_MSG_BUFFERS 10
|
||||
|
||||
#define LINKBUS_POWERUP_DELAY_SECONDS 6
|
||||
|
||||
#define LINKBUS_MIN_TX_INTERVAL_MS 100
|
||||
|
||||
#define FOSC 16000000 /* Clock Speed */
|
||||
#define BAUD 57600
|
||||
#define MYUBRR(b) (FOSC / 16 / (b) - 1)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EMPTY_BUFF,
|
||||
FULL_BUFF
|
||||
} BufferState;
|
||||
|
||||
/* Linkbus Messages
|
||||
* Message formats:
|
||||
* $id,f1,f2... fn;
|
||||
* !id,f1,f2,... fn;
|
||||
* $id,f1,f2,... fn?
|
||||
*
|
||||
* where
|
||||
* $ = command - ! indicates a response or broadcast to subscribers
|
||||
* id = linkbus MessageID
|
||||
* fn = variable length fields
|
||||
* ; = end of message flag - ? = end of query
|
||||
* Null fields in settings commands indicates no change should be applied
|
||||
* All null fields indicates a polling request for current settings
|
||||
* ? terminator indicates subscription request to value changes
|
||||
* Sending a query with fields containing data, is the equivalent of sending
|
||||
* a command followed by a query (i.e., a response is requested).
|
||||
*
|
||||
* TEST EQUIPMENT MESSAGE FAMILY (DEVICE MESSAGING)
|
||||
* $TST - Test message
|
||||
* !ACK - Simple acknowledgment to a command (sent when required)
|
||||
* $CK0 - Set Si5351 CLK0: 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)
|
||||
* $VOL - Set audio volume: field1 = inc/decr (BOOL); field2 = % (int)
|
||||
* $BAT? - Subscribe to battery voltage reports
|
||||
*
|
||||
* DUAL-BAND RX MESSAGE FAMILY (FUNCTIONAL MESSAGING)
|
||||
* $BND - Set/Get radio band to 2m or 80m
|
||||
* $S? - Subscribe to signal strength reports
|
||||
* - Subscribe to gain setting reports
|
||||
* -
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MESSAGE_EMPTY = 0,
|
||||
|
||||
/* TEST EQUIPMENT MESSAGE FAMILY (TEST DEVICE MESSAGING) */
|
||||
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.) */
|
||||
|
||||
/* DUAL-BAND TX MESSAGE FAMILY (FUNCTIONAL MESSAGING) */
|
||||
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_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_SYNC_ENABLE = 'S' * 100 + 'Y' * 10 + 'N', /* Enable or disable transmitter syncing */
|
||||
MESSAGE_TEMP = 'T' * 100 + 'E' * 10 + 'M', /* Temperature data */
|
||||
MESSAGE_SET_STATION_ID = 'I' * 10 + 'D', /* Sets amateur radio callsign text */
|
||||
MESSAGE_GO = 'G' * 10 + 'O', /* Synchronizes clock */
|
||||
|
||||
/* UTILITY MESSAGES */
|
||||
MESSAGE_RESET = 'R' * 100 + 'S' * 10 + 'T', /* Processor reset */
|
||||
MESSAGE_VERSION = 'V' * 100 + 'E' * 10 + + 'R', /* S/W version number */
|
||||
|
||||
INVALID_MESSAGE = UINT16_MAX /* This value must never overlap a valid message ID */
|
||||
} LBMessageID;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LINKBUS_MSG_UNKNOWN = 0,
|
||||
LINKBUS_MSG_COMMAND,
|
||||
LINKBUS_MSG_QUERY,
|
||||
LINKBUS_MSG_REPLY,
|
||||
LINKBUS_MSG_INVALID
|
||||
} LBMessageType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FIELD1 = 0,
|
||||
FIELD2 = 1,
|
||||
FIELD3 = 2
|
||||
} LBMessageField;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BATTERY_BROADCAST = 0x0001,
|
||||
RSSI_BROADCAST = 0x0002,
|
||||
RF_BROADCAST = 0x0004,
|
||||
UPC_TEMP_BROADCAST = 0x0008,
|
||||
ALL_BROADCASTS = 0x000FF
|
||||
} LBbroadcastType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NO_ID = 0,
|
||||
CONTROL_HEAD_ID = 1,
|
||||
RECEIVER_ID = 2,
|
||||
TRANSMITTER_ID = 3
|
||||
} DeviceID;
|
||||
|
||||
typedef char LinkbusTxBuffer[LINKBUS_MAX_TX_MSG_LENGTH];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LBMessageType type;
|
||||
LBMessageID id;
|
||||
char fields[LINKBUS_MAX_MSG_NUMBER_OF_FIELDS][LINKBUS_MAX_MSG_FIELD_LENGTH];
|
||||
} LinkbusRxBuffer;
|
||||
|
||||
#define WAITING_FOR_UPDATE -1
|
||||
|
||||
/**
|
||||
*/
|
||||
void linkbus_init(uint32_t baud);
|
||||
|
||||
/**
|
||||
* Immediately turns off receiver and flushes receive buffer
|
||||
*/
|
||||
void linkbus_disable(void);
|
||||
|
||||
/**
|
||||
* Undoes linkbus_disable()
|
||||
*/
|
||||
void linkbus_enable(void);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
void linkbus_end_tx(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void linkbus_reset_rx(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
LinkbusTxBuffer* nextEmptyTxBuffer(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
LinkbusTxBuffer* nextFullTxBuffer(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
BOOL linkbusTxInProgress(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
LinkbusRxBuffer* nextEmptyRxBuffer(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
LinkbusRxBuffer* nextFullRxBuffer(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_sync(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
BOOL linkbus_send_text(char* text);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_ESP(LBMessageType msgType, char* msg);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_msg(LBMessageType msgType, char* msgLabel, char* msgStr);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_broadcast_num(uint16_t data, char* str);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_Help(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_NewPrompt(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_NewLine(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void linkbus_setLineTerm(char* term);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_echo_char(uint8_t c);
|
||||
|
||||
/**
|
||||
*/
|
||||
BOOL lb_send_string(char* str);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_value(uint16_t value, char* label);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_Help(void);
|
||||
|
||||
#endif /* LINKBUS_H_ */
|
||||
/**********************************************************************************************
|
||||
* Copyright <EFBFBD> 2017 Digital Confections LLC
|
||||
*
|
||||
* 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
|
||||
* Software without restriction, including without limitation the rights to use, copy,
|
||||
* 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
|
||||
* following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* 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
|
||||
* 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
|
||||
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
**********************************************************************************************
|
||||
*
|
||||
* linkbus.h - a simple serial inter-processor communication protocol.
|
||||
*/
|
||||
|
||||
#ifndef LINKBUS_H_
|
||||
#define LINKBUS_H_
|
||||
|
||||
#include "defs.h"
|
||||
//#include "transmitter.h"
|
||||
//#include "si5351.h"
|
||||
|
||||
#define LINKBUS_MAX_MSG_LENGTH 50
|
||||
#define LINKBUS_MIN_MSG_LENGTH 3 /* shortest message: $TTY; */
|
||||
#define LINKBUS_MAX_MSG_FIELD_LENGTH 21
|
||||
#define LINKBUS_MAX_MSG_NUMBER_OF_FIELDS 3
|
||||
#define LINKBUS_NUMBER_OF_RX_MSG_BUFFERS 2
|
||||
#define LINKBUS_MAX_TX_MSG_LENGTH 40
|
||||
#define LINKBUS_NUMBER_OF_TX_MSG_BUFFERS 10
|
||||
|
||||
#define LINKBUS_POWERUP_DELAY_SECONDS 6
|
||||
|
||||
#define LINKBUS_MIN_TX_INTERVAL_MS 100
|
||||
|
||||
#define FOSC 16000000 /* Clock Speed */
|
||||
#define BAUD 57600
|
||||
#define MYUBRR(b) (FOSC / 16 / (b) - 1)
|
||||
|
||||
typedef enum
|
||||
{
|
||||
EMPTY_BUFF,
|
||||
FULL_BUFF
|
||||
} BufferState;
|
||||
|
||||
/* Linkbus Messages
|
||||
* Message formats:
|
||||
* $id,f1,f2... fn;
|
||||
* !id,f1,f2,... fn;
|
||||
* $id,f1,f2,... fn?
|
||||
*
|
||||
* where
|
||||
* $ = command - ! indicates a response or broadcast to subscribers
|
||||
* id = linkbus MessageID
|
||||
* fn = variable length fields
|
||||
* ; = end of message flag - ? = end of query
|
||||
* Null fields in settings commands indicates no change should be applied
|
||||
* All null fields indicates a polling request for current settings
|
||||
* ? terminator indicates subscription request to value changes
|
||||
* Sending a query with fields containing data, is the equivalent of sending
|
||||
* a command followed by a query (i.e., a response is requested).
|
||||
*
|
||||
* TEST EQUIPMENT MESSAGE FAMILY (DEVICE MESSAGING)
|
||||
* $TST - Test message
|
||||
* !ACK - Simple acknowledgment to a command (sent when required)
|
||||
* $CK0 - Set Si5351 CLK0: 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)
|
||||
* $VOL - Set audio volume: field1 = inc/decr (BOOL); field2 = % (int)
|
||||
* $BAT? - Subscribe to battery voltage reports
|
||||
*
|
||||
* DUAL-BAND RX MESSAGE FAMILY (FUNCTIONAL MESSAGING)
|
||||
* $BND - Set/Get radio band to 2m or 80m
|
||||
* $S? - Subscribe to signal strength reports
|
||||
* - Subscribe to gain setting reports
|
||||
* -
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
MESSAGE_EMPTY = 0,
|
||||
|
||||
/* TEST EQUIPMENT MESSAGE FAMILY (TEST DEVICE MESSAGING) */
|
||||
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.) */
|
||||
|
||||
/* DUAL-BAND TX MESSAGE FAMILY (FUNCTIONAL MESSAGING) */
|
||||
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_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_SYNC_ENABLE = 'S' * 100 + 'Y' * 10 + 'N', /* Enable or disable transmitter syncing */
|
||||
MESSAGE_TEMP = 'T' * 100 + 'E' * 10 + 'M', /* Temperature data */
|
||||
MESSAGE_SET_STATION_ID = 'I' * 10 + 'D', /* Sets amateur radio callsign text */
|
||||
MESSAGE_GO = 'G' * 10 + 'O', /* Synchronizes clock */
|
||||
|
||||
/* UTILITY MESSAGES */
|
||||
MESSAGE_RESET = 'R' * 100 + 'S' * 10 + 'T', /* Processor reset */
|
||||
MESSAGE_VERSION = 'V' * 100 + 'E' * 10 + + 'R', /* S/W version number */
|
||||
|
||||
INVALID_MESSAGE = UINT16_MAX /* This value must never overlap a valid message ID */
|
||||
} LBMessageID;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
LINKBUS_MSG_UNKNOWN = 0,
|
||||
LINKBUS_MSG_COMMAND,
|
||||
LINKBUS_MSG_QUERY,
|
||||
LINKBUS_MSG_REPLY,
|
||||
LINKBUS_MSG_INVALID
|
||||
} LBMessageType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FIELD1 = 0,
|
||||
FIELD2 = 1,
|
||||
FIELD3 = 2
|
||||
} LBMessageField;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
BATTERY_BROADCAST = 0x0001,
|
||||
RSSI_BROADCAST = 0x0002,
|
||||
RF_BROADCAST = 0x0004,
|
||||
UPC_TEMP_BROADCAST = 0x0008,
|
||||
ALL_BROADCASTS = 0x000FF
|
||||
} LBbroadcastType;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
NO_ID = 0,
|
||||
CONTROL_HEAD_ID = 1,
|
||||
RECEIVER_ID = 2,
|
||||
TRANSMITTER_ID = 3
|
||||
} DeviceID;
|
||||
|
||||
typedef char LinkbusTxBuffer[LINKBUS_MAX_TX_MSG_LENGTH];
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LBMessageType type;
|
||||
LBMessageID id;
|
||||
char fields[LINKBUS_MAX_MSG_NUMBER_OF_FIELDS][LINKBUS_MAX_MSG_FIELD_LENGTH];
|
||||
} LinkbusRxBuffer;
|
||||
|
||||
#define WAITING_FOR_UPDATE -1
|
||||
|
||||
/**
|
||||
*/
|
||||
void linkbus_init(uint32_t baud);
|
||||
|
||||
/**
|
||||
* Immediately turns off receiver and flushes receive buffer
|
||||
*/
|
||||
void linkbus_disable(void);
|
||||
|
||||
/**
|
||||
* Undoes linkbus_disable()
|
||||
*/
|
||||
void linkbus_enable(void);
|
||||
|
||||
|
||||
/**
|
||||
*/
|
||||
void linkbus_end_tx(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void linkbus_reset_rx(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
LinkbusTxBuffer* nextEmptyTxBuffer(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
LinkbusTxBuffer* nextFullTxBuffer(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
BOOL linkbusTxInProgress(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
LinkbusRxBuffer* nextEmptyRxBuffer(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
LinkbusRxBuffer* nextFullRxBuffer(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_sync(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
BOOL linkbus_send_text(char* text);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_ESP(LBMessageType msgType, char* msg);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_msg(LBMessageType msgType, char* msgLabel, char* msgStr);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_broadcast_num(uint16_t data, char* str);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_Help(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_NewPrompt(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_NewLine(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void linkbus_setLineTerm(char* term);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_echo_char(uint8_t c);
|
||||
|
||||
/**
|
||||
*/
|
||||
BOOL lb_send_string(char* str);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_value(uint16_t value, char* label);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_Help(void);
|
||||
|
||||
#endif /* LINKBUS_H_ */
|
Ładowanie…
Reference in New Issue