KISS receive works, transmit in early phase of development.

master
marcel 3 years ago
parent 64877d828e
commit fcaf1e7d1d
  1. 3
      CHANGELOG.md
  2. BIN
      build/src/CMakeFiles/KISS.dir/kiss.cpp.obj
  3. BIN
      build/src/CMakeFiles/main.dir/main.cpp.obj
  4. BIN
      build/src/libKISS.a
  5. BIN
      build/src/main.bin
  6. 51923
      build/src/main.dis
  7. BIN
      build/src/main.elf
  8. 1448
      build/src/main.elf.map
  9. 8342
      build/src/main.hex
  10. BIN
      build/src/main.uf2
  11. 85
      src/kiss.cpp
  12. 4
      src/kiss.h
  13. 47
      src/main.cpp

@ -29,4 +29,7 @@ First (more or less) working version.
- All settings (LoRa and APRS) can now be saved to FLASH. - All settings (LoRa and APRS) can now be saved to FLASH.
- Command added for restarting LoRa radio when settings are alterred: "restart lora" - 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) - 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.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

@ -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) digi_cnt = 1; // Start at position 1 as position 0 contains destination (which we already encoded)
while (aprsframe->number_of_digipeaters-- != 0) { while (aprsframe->number_of_digipeaters-- != 0) {
while (cnt < 7) {
encoded_call = EncodeCall(aprsframe->digis[digi_cnt]); encoded_call = EncodeCall(aprsframe->digis[digi_cnt]);
while (cnt < 7) {
ax25frame->complete[position] = *(encoded_call+cnt); ax25frame->complete[position] = *(encoded_call+cnt);
////printf("0x%X ", *(encoded_call+cnt)); ////printf("0x%X ", *(encoded_call+cnt));
//printf("0x%X ", ax25frame->complete[position]); //printf("0x%X ", ax25frame->complete[position]);
@ -101,21 +101,88 @@ uint16_t KissClass::EncodeFrame(struct aprs_frame *aprsframe, struct ax25_frame
cnt++; cnt++;
position++; position++;
} }
printf( "\n"); //printf( "\n");
// Store length of AX25 frame // Store length of AX25 frame
ax25frame->lenght = position; ax25frame->lenght = position;
/*cnt=0; // Encapsulate AX.25 frame in KISS frame (including escaping FEND codes)
while (ax25frame->lenght-- != 0) 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++; cnt++;
} }
printf("\n"); putchar(FEND);
//printf("\n");
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
//fwrite(ax25frame->complete, 1, ax25frame->lenght, stdout);
return 0; return 0;
} }
@ -137,11 +204,13 @@ uint8_t * KissClass::EncodeCall(uint8_t string[])
// extract call // extract call
while( string[position] != 0 || cnt < 6) while( string[position] != 0 || cnt < 6)
{ {
call[cnt++] = string[position] << 1;
if ( string[position] == '-') { if ( string[position] == '-') {
position++; position++;
break; break;
} else {
call[cnt] = string[position] << 1;
} }
cnt++;
position++; position++;
} }
// pad with spaces to a length of 6 // pad with spaces to a length of 6

@ -39,13 +39,15 @@
struct ax25_frame { struct ax25_frame {
uint8_t complete[512]; uint8_t complete[512];
uint16_t lenght = 0; uint16_t lenght = 0;
uint8_t kiss_frame[512]; uint8_t decoded_kiss_frame[512];
uint16_t kiss_length = 0;
}; };
class KissClass class KissClass
{ {
public: public:
uint16_t EncodeFrame(struct aprs_frame *frame, struct ax25_frame *ax25frame); uint16_t EncodeFrame(struct aprs_frame *frame, struct ax25_frame *ax25frame);
uint16_t DecodeFrame(uint8_t string[], struct ax25_frame *ax25frame);
private: private:
uint8_t * EncodeCall(uint8_t string[]); uint8_t * EncodeCall(uint8_t string[]);
}; };

@ -11,6 +11,7 @@
#include "hardware/claim.h" #include "hardware/claim.h"
KissClass Kiss; KissClass Kiss;
struct ax25_frame AX25Frame; //defined in kiss.h
bool startRadio(); bool startRadio();
void getPacketData(int packetLength); void getPacketData(int packetLength);
@ -429,10 +430,11 @@ void ProcessSerialInput(char string[])
} }
void ReadUSBSerial(void) void ReadUSBSerial(void)
{ {
static char strg[100]; static char strg[512];
int chr; int chr;
static int lp = 0; static int lp = 0;
if (Status.KissMode == OFF) {
// Read serial port (USB) - non-blocking! // Read serial port (USB) - non-blocking!
chr = getchar_timeout_us(0); chr = getchar_timeout_us(0);
while(chr != PICO_ERROR_TIMEOUT) while(chr != PICO_ERROR_TIMEOUT)
@ -455,6 +457,46 @@ void ReadUSBSerial(void)
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() { int main() {
@ -641,7 +683,6 @@ uint16_t decode_packet ()
int cnt = 0; int cnt = 0;
struct aprs_frame AprsFrame; //defined in kiss.h 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.source_address, 0, sizeof(AprsFrame.source_address));
memset(AprsFrame.digi_path, 0, sizeof(AprsFrame.digi_path)); 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); 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 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); Kiss.EncodeFrame(&AprsFrame, &AX25Frame);
if (AprsFrame.message[0]) if (AprsFrame.message[0])

Loading…
Cancel
Save