KISS receive works, transmit in early phase of development.
This commit is contained in:
@@ -29,4 +29,7 @@ First (more or less) working version.
|
||||
- All settings (LoRa and APRS) can now be saved to FLASH.
|
||||
- Command added for restarting LoRa radio when settings are alterred: "restart lora"
|
||||
- Received LoRa frames can now be converted to propper AX25 frames (needed for KISS TNC functionality)
|
||||
- KISS mode works for receiving (LoRa -> USB port)
|
||||
- KISS mode for transmitting in early phase of development
|
||||
- Can enter KISS mode with command "kiss 1" and exit KISS mode with command "sudo kissparms -p ax0 -x"
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
51433
build/src/main.dis
51433
build/src/main.dis
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
8342
build/src/main.hex
8342
build/src/main.hex
File diff suppressed because it is too large
Load Diff
Binary file not shown.
87
src/kiss.cpp
87
src/kiss.cpp
@@ -70,8 +70,8 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
|
||||
digi_cnt = 1; // Start at position 1 as position 0 contains destination (which we already encoded)
|
||||
while (aprsframe->number_of_digipeaters-- != 0) {
|
||||
|
||||
encoded_call = EncodeCall(aprsframe->digis[digi_cnt]);
|
||||
while (cnt < 7) {
|
||||
encoded_call = EncodeCall(aprsframe->digis[digi_cnt]);
|
||||
ax25frame->complete[position] = *(encoded_call+cnt);
|
||||
////printf("0x%X ", *(encoded_call+cnt));
|
||||
//printf("0x%X ", ax25frame->complete[position]);
|
||||
@@ -101,21 +101,88 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
|
||||
cnt++;
|
||||
position++;
|
||||
}
|
||||
printf( "\n");
|
||||
//printf( "\n");
|
||||
|
||||
// Store length of AX25 frame
|
||||
ax25frame->lenght = position;
|
||||
|
||||
/*cnt=0;
|
||||
while (ax25frame->lenght-- != 0)
|
||||
// Encapsulate AX.25 frame in KISS frame (including escaping FEND codes)
|
||||
putchar(FEND);
|
||||
putchar(CMD_DATA);
|
||||
cnt=0;
|
||||
position=ax25frame->lenght;
|
||||
while (position-- != 0)
|
||||
{
|
||||
printf("0x%X ", ax25frame->complete[cnt]);
|
||||
// Escape FESC and TFEND
|
||||
if (ax25frame->complete[cnt] == FEND) {
|
||||
putchar(FESC);
|
||||
putchar(TFEND);
|
||||
} else if (ax25frame->complete[cnt] == FESC) {
|
||||
putchar(FESC);
|
||||
putchar(TFESC);
|
||||
} else {
|
||||
putchar(ax25frame->complete[cnt]);
|
||||
}
|
||||
cnt++;
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
putchar(FEND);
|
||||
//printf("\n");
|
||||
|
||||
|
||||
//fwrite(ax25frame->complete, 1, ax25frame->lenght, stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Decodes a KISS frame from the usb serial port
|
||||
*
|
||||
* Input : string starting with FEND and ending with FEND
|
||||
* Output: ax25frame->decoded_kiss_frame terminated with NULL
|
||||
* Return: 0 = OK, 1 = ERROR, 2 = EXIT KISS MODE
|
||||
*/
|
||||
uint16_t KissClass::DecodeFrame(uint8_t string[], struct ax25_frame *ax25frame)
|
||||
{
|
||||
uint16_t position =0 ;
|
||||
uint16_t cnt =0 ;
|
||||
|
||||
// Not a valid frame
|
||||
if (string[position] != FEND)
|
||||
return 1;
|
||||
|
||||
position++;
|
||||
|
||||
// Is data frame: we de-escape the string and put it back in the same string with a NULL at the end as terminator.
|
||||
if (string[position] == CMD_DATA)
|
||||
{
|
||||
position++;
|
||||
while (string[position] != FEND)
|
||||
{
|
||||
// De-escape codes
|
||||
if (string[position] == FESC && string[position+1] == TFEND)
|
||||
{
|
||||
string[cnt] = FEND;
|
||||
position++;
|
||||
}
|
||||
else if (string[position] == FESC && string[position+1] == TFESC)
|
||||
{
|
||||
string[cnt] = FESC;
|
||||
position++;
|
||||
}
|
||||
else {
|
||||
string[cnt] = string[position];
|
||||
}
|
||||
cnt++;
|
||||
position++;
|
||||
}
|
||||
string[cnt] = 0; //Terminate string
|
||||
|
||||
}
|
||||
// Is command to exit KISS MODE
|
||||
else if (string[position] == CMD_EXIT_KISS) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
// If we are here we have a valid AX.25 frame in 'string' which is decapsulated from its KISS frame
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -137,11 +204,13 @@ uint8_t * KissClass::EncodeCall(uint8_t string[])
|
||||
// extract call
|
||||
while( string[position] != 0 || cnt < 6)
|
||||
{
|
||||
call[cnt++] = string[position] << 1;
|
||||
if ( string[position] == '-') {
|
||||
position++;
|
||||
break;
|
||||
} else {
|
||||
call[cnt] = string[position] << 1;
|
||||
}
|
||||
cnt++;
|
||||
position++;
|
||||
}
|
||||
// pad with spaces to a length of 6
|
||||
|
@@ -39,13 +39,15 @@
|
||||
struct ax25_frame {
|
||||
uint8_t complete[512];
|
||||
uint16_t lenght = 0;
|
||||
uint8_t kiss_frame[512];
|
||||
uint8_t decoded_kiss_frame[512];
|
||||
uint16_t kiss_length = 0;
|
||||
};
|
||||
|
||||
class KissClass
|
||||
{
|
||||
public:
|
||||
uint16_t EncodeFrame(struct aprs_frame *frame, struct ax25_frame *ax25frame);
|
||||
uint16_t DecodeFrame(uint8_t string[], struct ax25_frame *ax25frame);
|
||||
private:
|
||||
uint8_t * EncodeCall(uint8_t string[]);
|
||||
};
|
||||
|
85
src/main.cpp
85
src/main.cpp
@@ -11,6 +11,7 @@
|
||||
#include "hardware/claim.h"
|
||||
|
||||
KissClass Kiss;
|
||||
struct ax25_frame AX25Frame; //defined in kiss.h
|
||||
|
||||
bool startRadio();
|
||||
void getPacketData(int packetLength);
|
||||
@@ -429,31 +430,72 @@ void ProcessSerialInput(char string[])
|
||||
}
|
||||
void ReadUSBSerial(void)
|
||||
{
|
||||
static char strg[100];
|
||||
static char strg[512];
|
||||
int chr;
|
||||
static int lp = 0;
|
||||
|
||||
// Read serial port (USB) - non-blocking!
|
||||
chr = getchar_timeout_us(0);
|
||||
while(chr != PICO_ERROR_TIMEOUT)
|
||||
{
|
||||
log_out("%c", chr);
|
||||
|
||||
strg[lp++] = chr;
|
||||
if(chr == CR || lp == (sizeof(strg) - 1))
|
||||
{
|
||||
strg[lp-1] = 0; //terminate string by overwriting <CR> with NULL
|
||||
//log_out("You wrote - %s\n", strg);
|
||||
lp = 0; //reset string buffer pointer
|
||||
log_out("\n");
|
||||
|
||||
ProcessSerialInput(strg);
|
||||
if (Status.KissMode == OFF) {
|
||||
// Read serial port (USB) - non-blocking!
|
||||
chr = getchar_timeout_us(0);
|
||||
while(chr != PICO_ERROR_TIMEOUT)
|
||||
{
|
||||
log_out("%c", chr);
|
||||
|
||||
break;
|
||||
}
|
||||
strg[lp++] = chr;
|
||||
if(chr == CR || lp == (sizeof(strg) - 1))
|
||||
{
|
||||
strg[lp-1] = 0; //terminate string by overwriting <CR> with NULL
|
||||
//log_out("You wrote - %s\n", strg);
|
||||
lp = 0; //reset string buffer pointer
|
||||
log_out("\n");
|
||||
|
||||
ProcessSerialInput(strg);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
chr = getchar_timeout_us(0);
|
||||
}
|
||||
chr = getchar_timeout_us(0);
|
||||
}
|
||||
}
|
||||
// We are in KISS mode
|
||||
else
|
||||
{
|
||||
// Read serial port (USB) - non-blocking!
|
||||
chr = getchar_timeout_us(0);
|
||||
while(chr != PICO_ERROR_TIMEOUT)
|
||||
{
|
||||
strg[lp++] = chr;
|
||||
// Receive buffer buffer full
|
||||
if( lp == (sizeof(strg) - 1)) {
|
||||
lp=0;
|
||||
}
|
||||
// Received FEND (=begin or end frame)
|
||||
if(chr == FEND)
|
||||
{
|
||||
// Valid FISS frame received
|
||||
if (strg[0] == FEND && lp > 1)
|
||||
{
|
||||
if (Kiss.DecodeFrame((uint8_t *) strg, &AX25Frame) == 2)
|
||||
{
|
||||
//exit KISS MODE
|
||||
stdio_set_translate_crlf(&stdio_usb, true);
|
||||
Status.KissMode = OFF;
|
||||
}
|
||||
lp = 0; //reset string buffer pointer
|
||||
}
|
||||
// We received a FEND byte,so we are probably between two KISS frames. Let's assume the latest FEND is the beginning of a new frame
|
||||
else
|
||||
{
|
||||
strg[0] = chr;
|
||||
lp = 1; // set string buffer pointer to second position
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
chr = getchar_timeout_us(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -641,7 +683,6 @@ uint16_t decode_packet ()
|
||||
int cnt = 0;
|
||||
|
||||
struct aprs_frame AprsFrame; //defined in kiss.h
|
||||
struct ax25_frame AX25Frame; //defined in kiss.h
|
||||
|
||||
memset(AprsFrame.source_address, 0, sizeof(AprsFrame.source_address));
|
||||
memset(AprsFrame.digi_path, 0, sizeof(AprsFrame.digi_path));
|
||||
@@ -768,7 +809,7 @@ uint16_t decode_packet ()
|
||||
log_out("Source address: %s\nDigipeaters (%u): %s %s %s %s\nData: %s\n", AprsFrame.source_address, AprsFrame.number_of_digipeaters+1, AprsFrame.digis[0], AprsFrame.digis[1], AprsFrame.digis[2], AprsFrame.digis[3], AprsFrame.data_field);
|
||||
|
||||
// If in KISS mode the struct AprsFrame is handed over to the KISS encoder
|
||||
if (Status.KissMode == 0)
|
||||
if (Status.KissMode == ON)
|
||||
Kiss.EncodeFrame(&AprsFrame, &AX25Frame);
|
||||
|
||||
if (AprsFrame.message[0])
|
||||
|
Reference in New Issue
Block a user