commit
d00a5c4e7e
Plik diff jest za duży
Load Diff
|
@ -24,14 +24,40 @@
|
|||
#ifndef DEFS_H
|
||||
#define DEFS_H
|
||||
|
||||
#include <Arduino.h>
|
||||
// #define COMPILE_FOR_ATMELSTUDIO7
|
||||
|
||||
#ifdef COMPILE_FOR_ATMELSTUDIO7
|
||||
#include <avr/io.h>
|
||||
#include <util/delay.h>
|
||||
#include <avr/interrupt.h>
|
||||
#else
|
||||
#include "Arduino.h"
|
||||
#endif // COMPILE_FOR_ATMELSTUDIO7
|
||||
|
||||
#ifndef HIGH
|
||||
#define HIGH 0x1
|
||||
#endif
|
||||
|
||||
#ifndef LOW
|
||||
#define LOW 0x0
|
||||
#endif
|
||||
|
||||
#ifndef INPUT
|
||||
#define INPUT 0x0
|
||||
#endif
|
||||
|
||||
#ifndef OUTPUT
|
||||
#define OUTPUT 0x1
|
||||
#endif
|
||||
|
||||
#define bit_iz_set(sfr, bit) ((*(volatile uint8_t *)((uint16_t) &(sfr))) & (1 << bit))
|
||||
|
||||
/* #define F_CPU 16000000UL / * gets declared in makefile * / */
|
||||
|
||||
|
||||
/******************************************************
|
||||
* Set the text that gets displayed to the user */
|
||||
#define SW_REVISION "0.1"
|
||||
#define SW_REVISION "0.2"
|
||||
|
||||
//#define TRANQUILIZE_WATCHDOG
|
||||
|
||||
|
@ -66,94 +92,17 @@ typedef unsigned char uint8_t;
|
|||
#define PIN_NANO_DIP_1 5
|
||||
#define PIN_NANO_DIP_2 6
|
||||
|
||||
#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
|
||||
|
||||
/*******************************************************/
|
||||
/* 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
|
||||
BEACON = 0,
|
||||
FOX_1,
|
||||
FOX_2,
|
||||
FOX_3,
|
||||
FOX_4,
|
||||
FOX_5,
|
||||
FOX_DEMO,
|
||||
FOXORING,
|
||||
INVALID_FOX
|
||||
} FoxType;
|
||||
|
||||
|
||||
/*******************************************************/
|
||||
|
@ -288,8 +237,8 @@ typedef enum
|
|||
#define TIMER2_5_8HZ 100
|
||||
#define TIMER2_0_5HZ 1000
|
||||
|
||||
#define BEEP_SHORT 100
|
||||
#define BEEP_LONG 65535
|
||||
#define BLINK_SHORT 100
|
||||
#define BLINK_LONG 500
|
||||
|
||||
/******************************************************
|
||||
* UI Hardware-related definitions */
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
|
||||
#include "linkbus.h"
|
||||
#include "defs.h"
|
||||
//#include "util.h"
|
||||
//#include <string.h>
|
||||
//#include <stdio.h>
|
||||
//#include <avr/wdt.h>
|
||||
|
||||
#ifdef COMPILE_FOR_ATMELSTUDIO7
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#endif /* COMPILE_FOR_ATMELSTUDIO7 */
|
||||
|
||||
/* Global Variables */
|
||||
static volatile BOOL g_bus_disabled = TRUE;
|
||||
|
@ -36,17 +37,18 @@ 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",
|
||||
" TEM - Temperature\n",
|
||||
" VER - S/W version\n" };
|
||||
static const char textHelp[][23] = { "\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",
|
||||
" SPD - Code speed\n",
|
||||
" SYN - Sync on/off\n",
|
||||
" TEM - Temperature\n",
|
||||
" VER - S/W version\n" };
|
||||
|
||||
static char g_tempMsgBuff[LINKBUS_MAX_MSG_LENGTH];
|
||||
|
||||
|
@ -308,62 +310,16 @@ BOOL linkbus_send_text(char* text)
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************************
|
||||
* 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);
|
||||
while(linkbus_send_text((char*)textPrompt))
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
void lb_send_NewLine(void)
|
||||
|
@ -371,11 +327,6 @@ 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;
|
||||
|
@ -383,19 +334,37 @@ void lb_echo_char(uint8_t c)
|
|||
linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
BOOL lb_send_string(char* str)
|
||||
BOOL lb_send_string(char* str, BOOL wait)
|
||||
{
|
||||
BOOL err;
|
||||
|
||||
if(str == NULL)
|
||||
{
|
||||
return( TRUE);
|
||||
}
|
||||
if(strlen(str) > LINKBUS_MAX_MSG_LENGTH)
|
||||
if(strlen(str) > LINKBUS_MAX_TX_MSG_LENGTH)
|
||||
{
|
||||
return( TRUE);
|
||||
}
|
||||
strncpy(g_tempMsgBuff, str, LINKBUS_MAX_MSG_LENGTH);
|
||||
linkbus_send_text(g_tempMsgBuff);
|
||||
return( FALSE);
|
||||
strncpy(g_tempMsgBuff, str, LINKBUS_MAX_TX_MSG_LENGTH);
|
||||
|
||||
if(wait)
|
||||
{
|
||||
while(linkbus_send_text(g_tempMsgBuff))
|
||||
{
|
||||
;
|
||||
}
|
||||
while(linkbusTxInProgress())
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = linkbus_send_text(g_tempMsgBuff);
|
||||
}
|
||||
|
||||
return( err);
|
||||
}
|
||||
|
||||
void lb_send_value(uint16_t value, char* label)
|
||||
|
|
|
@ -35,8 +35,8 @@
|
|||
#define LINKBUS_MAX_MSG_FIELD_LENGTH 10
|
||||
#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_MAX_TX_MSG_LENGTH 30
|
||||
#define LINKBUS_NUMBER_OF_TX_MSG_BUFFERS 4
|
||||
|
||||
#define LINKBUS_POWERUP_DELAY_SECONDS 6
|
||||
|
||||
|
@ -89,10 +89,6 @@ 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 */
|
||||
|
@ -102,6 +98,7 @@ typedef enum
|
|||
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 */
|
||||
MESSAGE_CODE_SPEED = 'S' * 100 + 'P' * 10 + 'D', /* Set Morse code speeds */
|
||||
|
||||
/* UTILITY MESSAGES */
|
||||
MESSAGE_RESET = 'R' * 100 + 'S' * 10 + 'T', /* Processor reset */
|
||||
|
@ -197,10 +194,6 @@ LinkbusRxBuffer* nextEmptyRxBuffer(void);
|
|||
*/
|
||||
LinkbusRxBuffer* nextFullRxBuffer(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
void lb_send_sync(void);
|
||||
|
||||
/**
|
||||
*/
|
||||
BOOL linkbus_send_text(char* text);
|
||||
|
@ -209,14 +202,6 @@ 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);
|
||||
|
@ -229,18 +214,13 @@ 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);
|
||||
|
||||
BOOL lb_send_string(char* str, BOOL wait);
|
||||
/**
|
||||
*/
|
||||
void lb_send_value(uint16_t value, char* label);
|
||||
|
|
|
@ -0,0 +1,700 @@
|
|||
/*
|
||||
* morse.c
|
||||
*
|
||||
* Created: 3/19/2018 3:15:40 PM
|
||||
* Author: charl
|
||||
*/
|
||||
|
||||
#include "morse.h"
|
||||
#include <stddef.h>
|
||||
|
||||
MorseCharacter getMorseChar(char c);
|
||||
|
||||
#define SOLID_KEYDOWN 0xFF
|
||||
#define INTER_CHAR_SPACE 0xFE
|
||||
#define INTER_WORD_SPACE 0xFD
|
||||
|
||||
/*
|
||||
* Load a string to send by passing in a pointer via the first argument.
|
||||
* Call this function with a NULL argument at intervals of 1 element of time to generate Morse code.
|
||||
* Once loaded with a string each call to this function returns a BOOL indicating whether a CW carrier should be sent
|
||||
* Pass in a pointer to a BOOL in the second and third arguments:
|
||||
*/
|
||||
BOOL makeMorse(char* s, BOOL* repeating, BOOL* finished)
|
||||
{
|
||||
static char* str = NULL;
|
||||
static char c = ' ';
|
||||
static BOOL repeat = TRUE;
|
||||
static MorseCharacter morseInProgress;
|
||||
static uint8_t charIndex; /* letters, numbers, punctuation */
|
||||
static uint8_t symbolIndex; /* dits and dahs */
|
||||
static uint8_t elementIndex; /* units of time: dit = 1, dah = 3, intersymbol = 1, intercharacter = 3, etc. */
|
||||
static uint8_t addedSpace; /* adds additional time to make an inter-character space */
|
||||
static BOOL completedString = FALSE;
|
||||
static BOOL carrierOn = FALSE;
|
||||
static BOOL holdKeyDown = FALSE;
|
||||
|
||||
if(s) /* load a new NULL-terminated string to send */
|
||||
{
|
||||
holdKeyDown = FALSE;
|
||||
|
||||
if(repeating)
|
||||
{
|
||||
repeat = *repeating;
|
||||
}
|
||||
|
||||
if(*s)
|
||||
{
|
||||
str = s;
|
||||
c = ' ';
|
||||
morseInProgress = getMorseChar(*str);
|
||||
charIndex = 0;
|
||||
symbolIndex = 0;
|
||||
elementIndex = 0;
|
||||
addedSpace = 0;
|
||||
completedString = FALSE;
|
||||
}
|
||||
else /* a zero-length string shuts down makeMorse */
|
||||
{
|
||||
str = NULL;
|
||||
completedString = TRUE;
|
||||
if(finished)
|
||||
{
|
||||
*finished = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
carrierOn = OFF;
|
||||
return( OFF);
|
||||
}
|
||||
else if(str)
|
||||
{
|
||||
if(repeating)
|
||||
{
|
||||
*repeating = repeat;
|
||||
}
|
||||
|
||||
if(completedString)
|
||||
{
|
||||
if(finished)
|
||||
{
|
||||
*finished = TRUE;
|
||||
holdKeyDown = FALSE;
|
||||
}
|
||||
return( OFF);
|
||||
}
|
||||
|
||||
if(elementIndex)
|
||||
{
|
||||
elementIndex--;
|
||||
}
|
||||
else if(carrierOn && !holdKeyDown) /* carrier is on, so turn it off and wait appropriate amount of space */
|
||||
{
|
||||
carrierOn = FALSE;
|
||||
/* wait one element = inter-symbol space */
|
||||
if(addedSpace)
|
||||
{
|
||||
elementIndex = addedSpace;
|
||||
addedSpace = 0;
|
||||
}
|
||||
/* wait inter-character space */
|
||||
}
|
||||
else /* carrier is off, so turn it on and get next symbol */
|
||||
{
|
||||
if(symbolIndex >= morseInProgress.lengthInSymbols)
|
||||
{
|
||||
c = (*(str + ++charIndex));
|
||||
|
||||
if(!c) /* wrap to beginning of text */
|
||||
{
|
||||
if(repeat)
|
||||
{
|
||||
c = *str;
|
||||
charIndex = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
str = NULL;
|
||||
carrierOn = OFF;
|
||||
completedString = TRUE;
|
||||
if(finished)
|
||||
{
|
||||
*finished = TRUE;
|
||||
}
|
||||
holdKeyDown = FALSE;
|
||||
return( OFF );
|
||||
}
|
||||
}
|
||||
|
||||
morseInProgress = getMorseChar(c);
|
||||
symbolIndex = 0;
|
||||
}
|
||||
|
||||
if(morseInProgress.pattern < INTER_WORD_SPACE)
|
||||
{
|
||||
BOOL isDah = morseInProgress.pattern & (1 << symbolIndex++);
|
||||
|
||||
if(isDah)
|
||||
{
|
||||
elementIndex = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
elementIndex = 0;
|
||||
}
|
||||
|
||||
carrierOn = TRUE;
|
||||
|
||||
if(symbolIndex >= morseInProgress.lengthInSymbols)
|
||||
{
|
||||
addedSpace = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint8_t sym = morseInProgress.lengthInSymbols;
|
||||
symbolIndex = 255; /* ensure the next character gets read */
|
||||
carrierOn = FALSE;
|
||||
if(sym >= 4 )
|
||||
{
|
||||
elementIndex = morseInProgress.lengthInSymbols - 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
elementIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Overrides for key on and key off special characters */
|
||||
if(c == '<') /* constant tone */
|
||||
{
|
||||
holdKeyDown = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
holdKeyDown = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if(finished)
|
||||
{
|
||||
*finished = completedString;
|
||||
}
|
||||
|
||||
if(holdKeyDown)
|
||||
{
|
||||
return(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return( carrierOn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of milliseconds required to send the string pointed to by the first argument at the WPM code speed
|
||||
* passed in the second argument.
|
||||
*/
|
||||
uint16_t timeRequiredToSendStrAtWPM(char* str, uint16_t spd)
|
||||
{
|
||||
uint8_t elements = 0;
|
||||
MorseCharacter m;
|
||||
char c;
|
||||
|
||||
for(int i = 0; i < 20; i++)
|
||||
{
|
||||
c = str[i];
|
||||
if(!c)
|
||||
{
|
||||
break;
|
||||
}
|
||||
m = getMorseChar(c);
|
||||
if(m.pattern < INTER_WORD_SPACE)
|
||||
{
|
||||
elements += 3;
|
||||
}
|
||||
elements += m.lengthInElements;
|
||||
}
|
||||
|
||||
return(elements * WPM_TO_MS_PER_DOT(spd));
|
||||
}
|
||||
|
||||
/**
|
||||
* Morse Code characters are defined as having three attributes:
|
||||
* pattern = a sequence of up to 8 dit and dah symbols contained in an unsigned byte, sequentially read from LSB to MSB (first symbol is bit 0)
|
||||
* lengthInSymbols = how many symbols (dits and dahs) the character contains; this is how many pattern bits are used to represent the character
|
||||
* lengthInElements = how long (measured in "dit lengths") is the total character including all inter-symbol spaces.
|
||||
*/
|
||||
MorseCharacter getMorseChar(char c)
|
||||
{
|
||||
MorseCharacter morse;
|
||||
|
||||
switch( c )
|
||||
{
|
||||
case 'A':
|
||||
{
|
||||
morse.pattern = 0x02; /* 0000 0010; */
|
||||
morse.lengthInSymbols = 2;
|
||||
morse.lengthInElements = 5;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
{
|
||||
morse.pattern = 0x01; /* 0000 0001; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
{
|
||||
morse.pattern = 0x05; /* 0000 0101; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 11;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
{
|
||||
morse.pattern = 0x01; /* 0000 0001; */
|
||||
morse.lengthInSymbols = 3;
|
||||
morse.lengthInElements = 7;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'E':
|
||||
{
|
||||
morse.pattern = 0x00; /* 0000 0000; */
|
||||
morse.lengthInSymbols = 1;
|
||||
morse.lengthInElements = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
{
|
||||
morse.pattern = 0x04; /* 0000 0100; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'G':
|
||||
{
|
||||
morse.pattern = 0x03; /* 0000 0011; */
|
||||
morse.lengthInSymbols = 3;
|
||||
morse.lengthInElements = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
{
|
||||
morse.pattern = 0x00; /* 0000 0000; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 7;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
{
|
||||
morse.pattern = 0x00; /* 0000 0000; */
|
||||
morse.lengthInSymbols = 2;
|
||||
morse.lengthInElements = 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'J':
|
||||
{
|
||||
morse.pattern = 0x0e; /* 0000 1110; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
{
|
||||
morse.pattern = 0x05; /* 0000 0101; */
|
||||
morse.lengthInSymbols = 3;
|
||||
morse.lengthInElements = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
{
|
||||
morse.pattern = 0x02; /* 0000 0010; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
{
|
||||
morse.pattern = 0x03; /* 0000 0011; */
|
||||
morse.lengthInSymbols = 2;
|
||||
morse.lengthInElements = 7;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
{
|
||||
morse.pattern = 0x01; /* 0000 0001; */
|
||||
morse.lengthInSymbols = 2;
|
||||
morse.lengthInElements = 5;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
{
|
||||
morse.pattern = 0x07; /* 0000 0111; */
|
||||
morse.lengthInSymbols = 3;
|
||||
morse.lengthInElements = 11;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'P':
|
||||
{
|
||||
morse.pattern = 0x06; /* 0000 0110; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 11;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Q':
|
||||
{
|
||||
morse.pattern = 0x0b; /* 0000 1011; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'R':
|
||||
{
|
||||
morse.pattern = 0x02; /* 0000 0010; */
|
||||
morse.lengthInSymbols = 3;
|
||||
morse.lengthInElements = 7;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
{
|
||||
morse.pattern = 0x00; /* 0000 0000; */
|
||||
morse.lengthInSymbols = 3;
|
||||
morse.lengthInElements = 5;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
{
|
||||
morse.pattern = 0x01; /* 0000 0001; */
|
||||
morse.lengthInSymbols = 1;
|
||||
morse.lengthInElements = 3;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
{
|
||||
morse.pattern = 0x04; /* 0000 0100; */
|
||||
morse.lengthInSymbols = 3;
|
||||
morse.lengthInElements = 7;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'V':
|
||||
{
|
||||
morse.pattern = 0x08; /* 0000 1000; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
{
|
||||
morse.pattern = 0x06; /* 0000 0110; */
|
||||
morse.lengthInSymbols = 3;
|
||||
morse.lengthInElements = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
{
|
||||
morse.pattern = 0x09; /* 0000 1001; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 11;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
{
|
||||
morse.pattern = 0x0d; /* 0000 1101; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Z':
|
||||
{
|
||||
morse.pattern = 0x03; /* 0000 0011; */
|
||||
morse.lengthInSymbols = 4;
|
||||
morse.lengthInElements = 11;
|
||||
}
|
||||
break;
|
||||
|
||||
case '0':
|
||||
{
|
||||
morse.pattern = 0x1f; /* 0001 1111; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 19;
|
||||
}
|
||||
break;
|
||||
|
||||
case '1':
|
||||
{
|
||||
morse.pattern = 0x1e; /* 0001 1110; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 17;
|
||||
}
|
||||
break;
|
||||
|
||||
case '2':
|
||||
{
|
||||
morse.pattern = 0x1c; /* 0001 1100; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 15;
|
||||
}
|
||||
break;
|
||||
|
||||
case '3':
|
||||
{
|
||||
morse.pattern = 0x18; /* 0001 1000; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case '4':
|
||||
{
|
||||
morse.pattern = 0x10; /* 0001 0000; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 11;
|
||||
}
|
||||
break;
|
||||
|
||||
case '5':
|
||||
{
|
||||
morse.pattern = 0x00; /* 0000 0000; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 9;
|
||||
}
|
||||
break;
|
||||
|
||||
case '6':
|
||||
{
|
||||
morse.pattern = 0x01; /* 0000 0001; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 11;
|
||||
}
|
||||
break;
|
||||
|
||||
case '7':
|
||||
{
|
||||
morse.pattern = 0x03; /* 0000 0011; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case '8':
|
||||
{
|
||||
morse.pattern = 0x07; /* 0000 0111; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 15;
|
||||
}
|
||||
break;
|
||||
|
||||
case '9':
|
||||
{
|
||||
morse.pattern = 0x0f; /* 0000 1111; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 17;
|
||||
}
|
||||
break;
|
||||
|
||||
case '.':
|
||||
{
|
||||
morse.pattern = 0x2a; /* 0010 1010; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 17;
|
||||
}
|
||||
break;
|
||||
|
||||
case ',':
|
||||
{
|
||||
morse.pattern = 0x33; /* 0011 0011; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 19;
|
||||
}
|
||||
break;
|
||||
|
||||
case '?':
|
||||
{
|
||||
morse.pattern = 0x0c; /* 0000 1100; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 15;
|
||||
}
|
||||
break;
|
||||
|
||||
case '\'':
|
||||
{
|
||||
morse.pattern = 0x1e; /* 0001 1110; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 19;
|
||||
}
|
||||
break;
|
||||
|
||||
case '!':
|
||||
{
|
||||
morse.pattern = 0x35; /* 0011 0101; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 19;
|
||||
}
|
||||
break;
|
||||
|
||||
case '/':
|
||||
{
|
||||
morse.pattern = 0x09; /* 0000 1001; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case '(':
|
||||
{
|
||||
morse.pattern = 0x0d; /* 0000 1101; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 15;
|
||||
}
|
||||
break;
|
||||
|
||||
case ')':
|
||||
{
|
||||
morse.pattern = 0x2d; /* 0010 1101; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 19;
|
||||
}
|
||||
break;
|
||||
|
||||
case '&':
|
||||
{
|
||||
morse.pattern = 0x02; /* 0000 0010; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 11;
|
||||
}
|
||||
break;
|
||||
|
||||
case ':':
|
||||
{
|
||||
morse.pattern = 0x07; /* 0000 0111; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 17;
|
||||
}
|
||||
break;
|
||||
|
||||
case ';':
|
||||
{
|
||||
morse.pattern = 0x15; /* 0001 0101; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 12;
|
||||
}
|
||||
break;
|
||||
|
||||
case '=':
|
||||
{
|
||||
morse.pattern = 0x11; /* 0001 0001; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case '+':
|
||||
{
|
||||
morse.pattern = 0x0a; /* 0000 1010; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 13;
|
||||
}
|
||||
break;
|
||||
|
||||
case '-':
|
||||
{
|
||||
morse.pattern = 0x21; /* 0010 0001; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 15;
|
||||
}
|
||||
break;
|
||||
|
||||
case '_':
|
||||
{
|
||||
morse.pattern = 0x2c; /* 0010 1100; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 17;
|
||||
}
|
||||
break;
|
||||
|
||||
case '"':
|
||||
{
|
||||
morse.pattern = 0x12; /* 0001 0010; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 15;
|
||||
}
|
||||
break;
|
||||
|
||||
case '$':
|
||||
{
|
||||
morse.pattern = 0x48; /* 0100 1000; */
|
||||
morse.lengthInSymbols = 7;
|
||||
morse.lengthInElements = 17;
|
||||
}
|
||||
break;
|
||||
|
||||
case '@':
|
||||
{
|
||||
morse.pattern = 0x16; /* 0001 0110; */
|
||||
morse.lengthInSymbols = 6;
|
||||
morse.lengthInElements = 17;
|
||||
}
|
||||
break;
|
||||
|
||||
case '|': /* inter-word space */
|
||||
{ morse.pattern = 0xff; /* 1000 0000; */
|
||||
morse.lengthInSymbols = 7;
|
||||
morse.lengthInElements = 4; /* adjusted by -3 to account for inter-character space */
|
||||
}
|
||||
break;
|
||||
|
||||
case ' ': /* inter-word space */
|
||||
{ morse.pattern = 0xfe; /* 1000 0000; */
|
||||
morse.lengthInSymbols = 7;
|
||||
morse.lengthInElements = 7; /* 4 + 3 (character space) = 7 */
|
||||
}
|
||||
break;
|
||||
|
||||
case '<': /* long keydown */
|
||||
{
|
||||
morse.pattern = 0x1f; /* 0001 1111; */
|
||||
morse.lengthInSymbols = 5;
|
||||
morse.lengthInElements = 19;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
morse.pattern = 0x0000; /* 0000 0000; */
|
||||
morse.lengthInSymbols = 0;
|
||||
morse.lengthInElements = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return( morse);
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* morse.h
|
||||
*
|
||||
* Created: 3/19/2018 3:16:02 PM
|
||||
* Author: charl
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MORSE_H_
|
||||
#define MORSE_H_
|
||||
|
||||
#include "defs.h"
|
||||
|
||||
#define PROCESSSOR_CLOCK_HZ (16000000L)
|
||||
#define WPM_TO_MS_PER_DOT(w) (1200/(w))
|
||||
#define THROTTLE_VAL_FROM_WPM(w) (PROCESSSOR_CLOCK_HZ / 8000000L) * ((7042 / (w)) / 10)
|
||||
|
||||
/*
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t pattern;
|
||||
uint8_t lengthInSymbols;
|
||||
uint8_t lengthInElements;
|
||||
} MorseCharacter;
|
||||
|
||||
/**
|
||||
Load a string to send by passing in a pointer to the string in the argument.
|
||||
Call this function with a NULL argument at intervals of 1 element of time to generate Morse code.
|
||||
Once loaded with a string each call to this function returns a BOOL indicating whether a CW carrier should be sent
|
||||
*/
|
||||
BOOL makeMorse(char* s, BOOL* repeating, BOOL* finished);
|
||||
|
||||
/**
|
||||
Returns the number of milliseconds required to send the string pointed to by the first argument at the WPM code speed
|
||||
passed in the second argument.
|
||||
*/
|
||||
uint16_t timeRequiredToSendStrAtWPM(char* str, uint16_t spd);
|
||||
|
||||
#endif /* MORSE_H_ */
|
Ładowanie…
Reference in New Issue