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

Wyświetl plik

@ -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();
}

Wyświetl plik

@ -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_ */