APRS settings can be saved in FLASH.
This commit is contained in:
		
							
								
								
									
										10
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								CHANGELOG.md
									
									
									
									
									
								
							@@ -9,10 +9,16 @@ All notable changes to this project will be documented in this file.
 | 
				
			|||||||
    Fixed     : for any bug fixes.
 | 
					    Fixed     : for any bug fixes.
 | 
				
			||||||
    Security  : in case of vulnerabilities.
 | 
					    Security  : in case of vulnerabilities.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [1.0.0] - pre 2022-05-12
 | 
					## [1.0.0] - pre 2022-05-10
 | 
				
			||||||
First (more or less) working version.
 | 
					First (more or less) working version.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## [1.0.1] - 2022-05-12
 | 
					## [1.0.1] - 2022-05-10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Added
 | 
					### Added
 | 
				
			||||||
- Support for saving settings to internal FLASH
 | 
					- Support for saving settings to internal FLASH
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## [1.0.2] - 2022-05-11
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Added
 | 
				
			||||||
 | 
					- APRS settings can now be saved in FLASH
 | 
				
			||||||
 | 
					- logging to serial USB is disabled when in KISS mode (but KISS mode still needs to be implemented)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -251,6 +251,8 @@ string.h
 | 
				
			|||||||
-
 | 
					-
 | 
				
			||||||
time.h
 | 
					time.h
 | 
				
			||||||
-
 | 
					-
 | 
				
			||||||
 | 
					stdarg.h
 | 
				
			||||||
 | 
					-
 | 
				
			||||||
pico/stdlib.h
 | 
					pico/stdlib.h
 | 
				
			||||||
/home/marcel/Documents/electronische_projecten/lora_aprs_node_pico/src/pico/stdlib.h
 | 
					/home/marcel/Documents/electronische_projecten/lora_aprs_node_pico/src/pico/stdlib.h
 | 
				
			||||||
pico/binary_info.h
 | 
					pico/binary_info.h
 | 
				
			||||||
 
 | 
				
			|||||||
										
											Binary file not shown.
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										50017
									
								
								build/src/main.dis
									
									
									
									
									
								
							
							
						
						
									
										50017
									
								
								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
											
										
									
								
							
							
								
								
									
										7974
									
								
								build/src/main.hex
									
									
									
									
									
								
							
							
						
						
									
										7974
									
								
								build/src/main.hex
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										46
									
								
								src/Config.h
									
									
									
									
									
								
							
							
						
						
									
										46
									
								
								src/Config.h
									
									
									
									
									
								
							@@ -21,20 +21,13 @@
 | 
				
			|||||||
  #define OFF 0
 | 
					  #define OFF 0
 | 
				
			||||||
  #define ON 1
 | 
					  #define ON 1
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					  #define CR		13
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
  const long serialBaudRate   = 38400;
 | 
					  const long serialBaudRate   = 38400;
 | 
				
			||||||
  const int  rssiOffset      = 292;
 | 
					  const int  rssiOffset      = 292;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const int  loraRxTurnaround = 50;
 | 
					  const int  loraRxTurnaround = 50;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Default LoRa settings
 | 
					 | 
				
			||||||
  int       loraSpreadingFactor = 12;
 | 
					 | 
				
			||||||
  int       loraPreamble        = 8;
 | 
					 | 
				
			||||||
  int       loraCodingRate      = 5;
 | 
					 | 
				
			||||||
  int       loraTxPower         = 17;
 | 
					 | 
				
			||||||
  int       LoRaPaSelect        = 1;
 | 
					 | 
				
			||||||
  uint32_t  loraBandwidth       = 125E3;
 | 
					 | 
				
			||||||
  uint32_t  loraFrequency       = 433775000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  uint8_t txBuffer[MTU];
 | 
					  uint8_t txBuffer[MTU];
 | 
				
			||||||
  uint8_t rxBuffer[MTU];
 | 
					  uint8_t rxBuffer[MTU];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -60,18 +53,31 @@
 | 
				
			|||||||
  const uint8_t SIG_SYNCED = 0x02;
 | 
					  const uint8_t SIG_SYNCED = 0x02;
 | 
				
			||||||
  const uint8_t RX_ONGOING = 0x04;
 | 
					  const uint8_t RX_ONGOING = 0x04;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  // The size of this struc should be a exactly 256 bytes, which is the FLASH_PAGE_SIZE of the RPi pico's flash memory
 | 
					  // The size of this struc should be a exactly 256 bytes (or a multiple), which is the FLASH_PAGE_SIZE of the RPi pico's flash memory
 | 
				
			||||||
 | 
					  // Struct can not be bigger than 4kbyte
 | 
				
			||||||
  struct aprssettings {
 | 
					  struct aprssettings {
 | 
				
			||||||
      uint8_t ValidFlashData = 0x5A;  // Indicates flash contains valid data - 1 bytes
 | 
					      uint8_t ValidFlashData = 0x5A;  // Indicates flash contains valid data - 1 bytes
 | 
				
			||||||
      uint8_t MyCall[10] = { 'N','O','C','A','L','L','-','2', 0} ;      // 10 bytes
 | 
					      uint8_t MyCall[10] = { 'P','E','1','R','X','F','-','5', 0, 0} ;      // 10 bytes
 | 
				
			||||||
      uint8_t ServerCall[10] = { 'N','O','C','A','L','L','-','1', 0} ;  // 10 bytes
 | 
					      uint8_t ServerCall[10] = { 'P','E','1','R','X','F','-','3', 0, 0} ;  // 10 bytes
 | 
				
			||||||
      uint8_t Destination[10] = { 'A','P','Z','M','D','M', 0} ;         // 10 bytes
 | 
					      uint8_t Destination[10] = { 'A','P','Z','M','D','M', 0, 0, 0 ,0} ;   // 10 bytes
 | 
				
			||||||
      uint8_t Path1[10] = { 0,'I','D','E','1','-', '1', 0} ;            // 10 bytes
 | 
					      uint8_t Path1[10] = { 0,'I','D','E','1','-', '1', 0, 0, 0} ;         // 10 bytes
 | 
				
			||||||
      uint8_t Path2[10] = { 0,'I','D','E','2','-', '2', 0} ;            // 10 bytes
 | 
					      uint8_t Path2[10] = { 0,'I','D','E','2','-', '2', 0, 0 ,0} ;         // 10 bytes
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
      uint8_t FirmwareVersion[20] = { 'V','1',',','C','o','n','t','r', 'o','l','l','e','r',' ','0','1', 0} ;    // 20 bytes
 | 
					      uint8_t FirmwareVersion[20] = { 'V','1',',','C','o','n','t','r', 'o','l','l','e','r',' ','0','1', 0, 0, 0, 0} ;
 | 
				
			||||||
                                                                        // 71 bytes total
 | 
					                                                                        // 20 bytes
 | 
				
			||||||
      uint8_t FillerData[256-71];
 | 
					                                                                       
 | 
				
			||||||
 | 
					      // Default LoRa settings
 | 
				
			||||||
 | 
					      uint16_t  loraSpreadingFactor = 12;                               // 2 bytes
 | 
				
			||||||
 | 
					      uint16_t  loraPreamble        = 8;                                // 2 bytes
 | 
				
			||||||
 | 
					      uint16_t  loraCodingRate      = 5;                                // 2 bytes
 | 
				
			||||||
 | 
					      uint16_t  loraTxPower         = 17;                               // 2 bytes
 | 
				
			||||||
 | 
					      uint16_t  loraPaSelect        = 1;                                // 2 bytes
 | 
				
			||||||
 | 
					      uint32_t  loraBandwidth       = 125E3;                            // 4 bytes
 | 
				
			||||||
 | 
					      uint32_t  loraFrequency       = 433775000;                        // 4 bytes
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					                                                                // Total 89 bytes
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      uint8_t   FillerData[163];
 | 
				
			||||||
  } AprsSettings;
 | 
					  } AprsSettings;
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  struct status {
 | 
					  struct status {
 | 
				
			||||||
@@ -81,6 +87,10 @@
 | 
				
			|||||||
      bool ControlRelay;
 | 
					      bool ControlRelay;
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      uint8_t StatusString[6] = { '0','0','0','0','0',0};
 | 
					      uint8_t StatusString[6] = { '0','0','0','0','0',0};
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      uint8_t DescriptionString[20] ={ 'N','C',',','C','n','t','r',',','5','V',',','1','2','V',',','2','4','V',0,0};
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      uint8_t KissMode = OFF;
 | 
				
			||||||
  } Status;
 | 
					  } Status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										333
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										333
									
								
								src/main.cpp
									
									
									
									
									
								
							@@ -1,6 +1,7 @@
 | 
				
			|||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <time.h>
 | 
					#include <time.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
#include "pico/stdlib.h"
 | 
					#include "pico/stdlib.h"
 | 
				
			||||||
#include "pico/binary_info.h"
 | 
					#include "pico/binary_info.h"
 | 
				
			||||||
#include "hardware/flash.h"
 | 
					#include "hardware/flash.h"
 | 
				
			||||||
@@ -34,36 +35,88 @@ const uint RelayOnControl        = 3;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const uint8_t *flash_target_contents = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET);
 | 
					const uint8_t *flash_target_contents = (const uint8_t *) (XIP_BASE + FLASH_TARGET_OFFSET);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uint8_t ReadSettingsFromFlash(void)
 | 
					void log_out(const char *fmt, ...)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					        char buf[256];
 | 
				
			||||||
 | 
					        va_list args;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    // If byte zero of flash contains 0x5A we assume the data to be valid, otherwise we fill the flash with default values.
 | 
					        if (Status.KissMode == OFF) {
 | 
				
			||||||
    if (flash_target_contents[0] != 0x5A)
 | 
					            va_start(args, fmt);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            vsnprintf(buf, sizeof buf, fmt, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            va_end( args);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            printf("%s", buf);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Saves settings in struct AprsSettings to FLASH memory
 | 
				
			||||||
 | 
					 * Struct AprsSettings should be exactly a multiple of FLASH_PAGE_SIZE in size.
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * Returns: 0 when successfull
 | 
				
			||||||
 | 
					 *          1 when error
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t SaveSettingsToFlash(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
        printf( "No valid data found in FLASH memory.\n" );
 | 
					 | 
				
			||||||
        memset(AprsSettings.FillerData, 0, sizeof(AprsSettings.FillerData));
 | 
					 | 
				
			||||||
    uint32_t ints = save_and_disable_interrupts();
 | 
					    uint32_t ints = save_and_disable_interrupts();
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    // First we erase the FLASH sector we need. After that we can store new values.
 | 
					    // First we erase the FLASH sector we need. After that we can store new values.
 | 
				
			||||||
    // Note that a whole number of sectors must be erased at a time.
 | 
					    // Note that a whole number of sectors must be erased at a time.
 | 
				
			||||||
        // Sector size is 4kB, so this is way bigger than the needed 256 bytes for storing the settings.
 | 
					    // Sector size is 4kB, so this is way bigger than the 256 bytes PAGE_SIZE for storing the settings.
 | 
				
			||||||
        printf("Erasing FLASH region...");
 | 
					    // We can therefore store up to 16 blocks of 256 bytes per sector
 | 
				
			||||||
 | 
					    log_out("Erasing FLASH region...");
 | 
				
			||||||
    flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE);
 | 
					    flash_range_erase(FLASH_TARGET_OFFSET, FLASH_SECTOR_SIZE);
 | 
				
			||||||
        printf("done\n");
 | 
					    log_out("done\n");
 | 
				
			||||||
        printf("Writing default values to FLASH...");    
 | 
					    log_out("Writing settings to FLASH...");    
 | 
				
			||||||
        flash_range_program(FLASH_TARGET_OFFSET, (uint8_t*)&AprsSettings, FLASH_PAGE_SIZE);
 | 
					    flash_range_program(FLASH_TARGET_OFFSET, (uint8_t*)&AprsSettings, sizeof(AprsSettings) );
 | 
				
			||||||
        printf("done\n");
 | 
					    log_out("done\n");
 | 
				
			||||||
    restore_interrupts (ints);
 | 
					    restore_interrupts (ints);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return(0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShowSettings(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    log_out("LoRa APRS remote switcher with build in KISS TNC.\n"); 
 | 
				
			||||||
 | 
					    log_out(" Firmware version : %s\n",AprsSettings.FirmwareVersion);
 | 
				
			||||||
 | 
					    log_out(" Size of struct   : %u.\n\n", sizeof(AprsSettings));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    log_out("APRS settings\n");
 | 
				
			||||||
 | 
					    log_out("  My call         : %s\n", AprsSettings.MyCall);
 | 
				
			||||||
 | 
					    log_out("  Server call     : %s\n", AprsSettings.ServerCall);
 | 
				
			||||||
 | 
					    log_out("  Destination     : %s\n", AprsSettings.Destination);
 | 
				
			||||||
 | 
					    log_out("  Path 1          : %s\n", AprsSettings.Path1);
 | 
				
			||||||
 | 
					    log_out("  Path 2          : %s\n\n", AprsSettings.Path2);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    log_out("LoRa settings\n");
 | 
				
			||||||
 | 
					    log_out("  Frequency       : %u\n", AprsSettings.loraFrequency);    
 | 
				
			||||||
 | 
					    log_out("  SpreadingFactor : %i\n", AprsSettings.loraSpreadingFactor);    
 | 
				
			||||||
 | 
					    log_out("  Preamble        : %i\n", AprsSettings.loraPreamble);    
 | 
				
			||||||
 | 
					    log_out("  CodingRate      : %i\n", AprsSettings.loraCodingRate);    
 | 
				
			||||||
 | 
					    log_out("  TxPower         : %i\n", AprsSettings.loraTxPower);    
 | 
				
			||||||
 | 
					    log_out("  PaSelect        : %i\n", AprsSettings.loraPaSelect);    
 | 
				
			||||||
 | 
					    log_out("  Bandwidth       : %u\n", AprsSettings.loraBandwidth); 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t ReadSettingsFromFlash(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    // If byte zero of flash contains 0x5A we assume the data to be valid, otherwise we fill the flash with default values.
 | 
				
			||||||
 | 
					    if (flash_target_contents[0] != 0x5A)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        log_out( "No valid data found in FLASH memory. Using default values.\n" );
 | 
				
			||||||
 | 
					        memset(AprsSettings.FillerData, 0, sizeof(AprsSettings.FillerData));
 | 
				
			||||||
 | 
					        SaveSettingsToFlash();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        // Read settings stored in flash memory
 | 
					        // Read settings stored in flash memory
 | 
				
			||||||
        printf("Found valid settings in FLASH memory.\n");
 | 
					        log_out("Found valid settings in FLASH memory.\n");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    memcpy((uint8_t*)&AprsSettings, flash_target_contents, FLASH_PAGE_SIZE);
 | 
					    memcpy((uint8_t*)&AprsSettings, flash_target_contents, sizeof(AprsSettings));
 | 
				
			||||||
        
 | 
					    ShowSettings();
 | 
				
			||||||
    printf("APRS settings:\n");
 | 
					 | 
				
			||||||
    printf("My call: %s\n", AprsSettings.MyCall);
 | 
					 | 
				
			||||||
    printf("Server call: %s\n", AprsSettings.ServerCall);
 | 
					 | 
				
			||||||
    printf("Firmware: %s\n",AprsSettings.FirmwareVersion);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void setup(void)
 | 
					void setup(void)
 | 
				
			||||||
@@ -107,6 +160,191 @@ void setup(void)
 | 
				
			|||||||
   startRadio();
 | 
					   startRadio();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void print_help(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    log_out("Unknown command.\n\n");
 | 
				
			||||||
 | 
					    log_out("kiss\n");
 | 
				
			||||||
 | 
					    log_out("   Enter KISS mode.\n");
 | 
				
			||||||
 | 
					    log_out("save\n");
 | 
				
			||||||
 | 
					    log_out("   Save settings to flash.\n");
 | 
				
			||||||
 | 
					    log_out("read <flash/ram>\n");
 | 
				
			||||||
 | 
					    log_out("   Read settings from FLASH or RAM.\n");
 | 
				
			||||||
 | 
					    log_out("mycall/servercall/destination/path1/path2\n");
 | 
				
			||||||
 | 
					    log_out("   APRS settings.\n");
 | 
				
			||||||
 | 
					    log_out("freq/spread/pre/rate/power/pa/band.\n");
 | 
				
			||||||
 | 
					    log_out("   LoRa settings.\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ProcessSerialInput(char string[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    uint8_t cnt;
 | 
				
			||||||
 | 
					    uint8_t position=0;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    char command[100];
 | 
				
			||||||
 | 
					    char parameter[100];
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    //log_out("You wrote - %s (%u).\n", string, strlen(string));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Command cannot be any shorter than 3 characters
 | 
				
			||||||
 | 
					    if (strlen(string) > 2) {
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Extract command (part before space)
 | 
				
			||||||
 | 
					        cnt = 0;    
 | 
				
			||||||
 | 
					        while( string[position] != 0 )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            command[cnt++] = string[position];
 | 
				
			||||||
 | 
					            if ( string[position] == ' ' ) {
 | 
				
			||||||
 | 
					                command[cnt-1] = 0;  // terminate command string
 | 
				
			||||||
 | 
					                position++;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            position++;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Extract parameter (part after space)
 | 
				
			||||||
 | 
					        cnt = 0;    
 | 
				
			||||||
 | 
					        while( string[position] != 0 )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            parameter[cnt++] = string[position++];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        parameter[cnt] = 0; //terminate string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //log_out("Command - %s.\n", command);
 | 
				
			||||||
 | 
					        //log_out("Parameter - %s.\n", parameter);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Read settings
 | 
				
			||||||
 | 
					        if (strcmp(command, "read") == 0) {
 | 
				
			||||||
 | 
					            if (strcmp(parameter, "flash") == 0) {
 | 
				
			||||||
 | 
					                ReadSettingsFromFlash();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (strcmp(parameter, "ram") == 0) {
 | 
				
			||||||
 | 
					                ShowSettings();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Save settings to FLASH
 | 
				
			||||||
 | 
					        else if (strcmp(command, "save") == 0)
 | 
				
			||||||
 | 
					            SaveSettingsToFlash();
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // Enter KISS mode
 | 
				
			||||||
 | 
					        else if (strcmp(command, "kiss") == 0) {
 | 
				
			||||||
 | 
					            log_out("Entering KISS mode.\n");
 | 
				
			||||||
 | 
					            log_out("You can exit KISS mode via KISS command <0xC0 0xFF 0xC0>\n");
 | 
				
			||||||
 | 
					            Status.KissMode = ON;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Set mycall (cannot be longer than 9 characters)
 | 
				
			||||||
 | 
					        else if (strcmp(command, "mycall") == 0) {
 | 
				
			||||||
 | 
					            if (sizeof(AprsSettings.MyCall) > strlen(parameter)) {
 | 
				
			||||||
 | 
					                position = 0;
 | 
				
			||||||
 | 
					                while( parameter[position] != 0 )
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    AprsSettings.MyCall[position] = parameter[position];
 | 
				
			||||||
 | 
					                    position++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                AprsSettings.MyCall[position] = 0;
 | 
				
			||||||
 | 
					                log_out("MyCall set to %s.\n", AprsSettings.MyCall);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Set servercall (cannot be longer than 9 characters)
 | 
				
			||||||
 | 
					        else if (strcmp(command, "servercall") == 0) {
 | 
				
			||||||
 | 
					            if (sizeof(AprsSettings.ServerCall) > strlen(parameter)) {
 | 
				
			||||||
 | 
					                position = 0;
 | 
				
			||||||
 | 
					                while( parameter[position] != 0 )
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    AprsSettings.ServerCall[position] = parameter[position];
 | 
				
			||||||
 | 
					                    position++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                AprsSettings.ServerCall[position] = 0;
 | 
				
			||||||
 | 
					                log_out("ServerCall set to %s.\n", AprsSettings.ServerCall);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Set path 1 (cannot be longer than 9 characters)
 | 
				
			||||||
 | 
					        else if (strcmp(command, "path1") == 0) {
 | 
				
			||||||
 | 
					            // Set path to nothing
 | 
				
			||||||
 | 
					            if (parameter[0] == '0') {
 | 
				
			||||||
 | 
					                AprsSettings.Path1[0] = 0;
 | 
				
			||||||
 | 
					                log_out("Path1 cleared.\n");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (sizeof(AprsSettings.Path1) > strlen(parameter)) {
 | 
				
			||||||
 | 
					                position = 0;
 | 
				
			||||||
 | 
					                while( parameter[position] != 0 )
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    AprsSettings.Path1[position] = parameter[position];
 | 
				
			||||||
 | 
					                    position++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                AprsSettings.Path1[position] = 0;
 | 
				
			||||||
 | 
					                log_out("Path1 set to %s.\n", AprsSettings.Path1);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Set path 2 (cannot be longer than 9 characters)
 | 
				
			||||||
 | 
					        else if (strcmp(command, "path2") == 0) {
 | 
				
			||||||
 | 
					            // Set path to nothing
 | 
				
			||||||
 | 
					            if (parameter[0] == '0') {
 | 
				
			||||||
 | 
					                AprsSettings.Path2[0] = 0;
 | 
				
			||||||
 | 
					                log_out("Path2 cleared.\n");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else if (sizeof(AprsSettings.Path2) > strlen(parameter)) {
 | 
				
			||||||
 | 
					                position = 0;
 | 
				
			||||||
 | 
					                while( parameter[position] != 0 )
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    AprsSettings.Path2[position] = parameter[position];
 | 
				
			||||||
 | 
					                    position++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                AprsSettings.Path2[position] = 0;
 | 
				
			||||||
 | 
					                log_out("Path2 set to %s.\n", AprsSettings.Path2);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // Set destination (cannot be longer than 9 characters)
 | 
				
			||||||
 | 
					        else if (strcmp(command, "dest") == 0) {
 | 
				
			||||||
 | 
					            if (sizeof(AprsSettings.Destination) > strlen(parameter)) {
 | 
				
			||||||
 | 
					                position = 0;
 | 
				
			||||||
 | 
					                while( parameter[position] != 0 )
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    AprsSettings.Destination[position] = parameter[position];
 | 
				
			||||||
 | 
					                    position++;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                AprsSettings.Destination[position] = 0;
 | 
				
			||||||
 | 
					                log_out("Destination set to %s.\n", AprsSettings.Destination);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
 | 
					            print_help();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        print_help();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					void ReadUSBSerial(void)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    static char strg[100];
 | 
				
			||||||
 | 
					    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
 | 
				
			||||||
 | 
								
 | 
				
			||||||
 | 
								ProcessSerialInput(strg);
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							chr = getchar_timeout_us(0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main() {
 | 
					int main() {
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    uint16_t ServerCommand = 0;
 | 
					    uint16_t ServerCommand = 0;
 | 
				
			||||||
@@ -118,7 +356,7 @@ int main() {
 | 
				
			|||||||
      int packetSize = LoRa.parsePacket();
 | 
					      int packetSize = LoRa.parsePacket();
 | 
				
			||||||
      if (packetSize) {
 | 
					      if (packetSize) {
 | 
				
			||||||
         // received a packet
 | 
					         // received a packet
 | 
				
			||||||
         printf("Received packet (RSSI = %idBm)\n",LoRa.packetRssi());
 | 
					         log_out("Received packet (RSSI = %idBm)\n",LoRa.packetRssi());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
         getPacketData(packetSize);
 | 
					         getPacketData(packetSize);
 | 
				
			||||||
         
 | 
					         
 | 
				
			||||||
@@ -129,10 +367,10 @@ int main() {
 | 
				
			|||||||
                 rxBuffer[cnt-3] = rxBuffer[cnt];
 | 
					                 rxBuffer[cnt-3] = rxBuffer[cnt];
 | 
				
			||||||
             }
 | 
					             }
 | 
				
			||||||
             rxBuffer[packetSize-3] = 0;
 | 
					             rxBuffer[packetSize-3] = 0;
 | 
				
			||||||
             printf("%s\n", rxBuffer);
 | 
					             log_out("%s\n", rxBuffer);
 | 
				
			||||||
             ServerCommand = decode_packet();
 | 
					             ServerCommand = decode_packet();
 | 
				
			||||||
         } else {
 | 
					         } else {
 | 
				
			||||||
             printf("ERROR: No or corrupted APRS frame.\n");
 | 
					             log_out("ERROR: No or corrupted APRS frame.\n");
 | 
				
			||||||
         }
 | 
					         }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
@@ -169,6 +407,10 @@ int main() {
 | 
				
			|||||||
                  
 | 
					                  
 | 
				
			||||||
                  break;
 | 
					                  break;
 | 
				
			||||||
                  
 | 
					                  
 | 
				
			||||||
 | 
					              // Send description digital outputs
 | 
				
			||||||
 | 
					              case 7 :
 | 
				
			||||||
 | 
					                  ComposeAprsFrame(Status.DescriptionString);
 | 
				
			||||||
 | 
					                  
 | 
				
			||||||
              // Switch off 24V power supply
 | 
					              // Switch off 24V power supply
 | 
				
			||||||
              case 30 :
 | 
					              case 30 :
 | 
				
			||||||
                  gpio_put(PowerSupply24VControl, 0);
 | 
					                  gpio_put(PowerSupply24VControl, 0);
 | 
				
			||||||
@@ -235,6 +477,9 @@ int main() {
 | 
				
			|||||||
              TransmitRequest = false;
 | 
					              TransmitRequest = false;
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // Read serial input and process it
 | 
				
			||||||
 | 
					    ReadUSBSerial();
 | 
				
			||||||
  }    
 | 
					  }    
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  return 0;
 | 
					  return 0;
 | 
				
			||||||
@@ -247,29 +492,19 @@ bool startRadio()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  // override the default CS, reset, and IRQ pins (optional)
 | 
					  // override the default CS, reset, and IRQ pins (optional)
 | 
				
			||||||
  // LoRa.setPins(7, 6, 1); // set CS, reset, IRQ pin
 | 
					  // LoRa.setPins(7, 6, 1); // set CS, reset, IRQ pin
 | 
				
			||||||
    
 | 
					  log_out("Starting LoRa radio");
 | 
				
			||||||
  printf("LoRa settings:\n");
 | 
					  if (!LoRa.begin(AprsSettings.loraFrequency)) {
 | 
				
			||||||
  printf("loraFrequency       = %u\n", loraFrequency);    
 | 
					    log_out("  [ FAILED ]\n");
 | 
				
			||||||
  printf("loraSpreadingFactor = %i\n", loraSpreadingFactor);    
 | 
					 | 
				
			||||||
  printf("loraPreamble        = %i\n", loraPreamble);    
 | 
					 | 
				
			||||||
  printf("loraCodingRate      = %i\n", loraCodingRate);    
 | 
					 | 
				
			||||||
  printf("loraTxPower         = %i\n", loraTxPower);    
 | 
					 | 
				
			||||||
  printf("LoRaPaSelect        = %i\n", LoRaPaSelect);    
 | 
					 | 
				
			||||||
  printf("loraBandwidth       = %u\n", loraBandwidth);    
 | 
					 | 
				
			||||||
   
 | 
					 | 
				
			||||||
  printf("Starting LoRa radio");
 | 
					 | 
				
			||||||
  if (!LoRa.begin(loraFrequency)) {
 | 
					 | 
				
			||||||
    printf("  [ FAILED ]\n");
 | 
					 | 
				
			||||||
    while(1);
 | 
					    while(1);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  else {
 | 
					  else {
 | 
				
			||||||
    LoRa.setPreambleLength(loraPreamble);
 | 
					    LoRa.setPreambleLength(AprsSettings.loraPreamble);
 | 
				
			||||||
    LoRa.setSignalBandwidth(loraBandwidth);
 | 
					    LoRa.setSignalBandwidth(AprsSettings.loraBandwidth);
 | 
				
			||||||
    LoRa.setTxPower(loraTxPower,LoRaPaSelect);
 | 
					    LoRa.setTxPower(AprsSettings.loraTxPower,AprsSettings.loraPaSelect);
 | 
				
			||||||
    LoRa.setSpreadingFactor(loraSpreadingFactor);
 | 
					    LoRa.setSpreadingFactor(AprsSettings.loraSpreadingFactor);
 | 
				
			||||||
    LoRa.setCodingRate4(loraCodingRate);
 | 
					    LoRa.setCodingRate4(AprsSettings.loraCodingRate);
 | 
				
			||||||
    LoRa.enableCrc();
 | 
					    LoRa.enableCrc();
 | 
				
			||||||
    printf("  [ DONE ]\n");
 | 
					    log_out("  [ DONE ]\n");
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -318,13 +553,12 @@ uint16_t decode_packet ()
 | 
				
			|||||||
        if ( rxBuffer[position] == '>' && position < 10 ) {
 | 
					        if ( rxBuffer[position] == '>' && position < 10 ) {
 | 
				
			||||||
            aprs_source_address[cnt-1] = 0;
 | 
					            aprs_source_address[cnt-1] = 0;
 | 
				
			||||||
            valid_apsr_data = true;
 | 
					            valid_apsr_data = true;
 | 
				
			||||||
 | 
					                position++;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        position++;
 | 
					        position++;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    position++;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (valid_apsr_data == true)
 | 
					    if (valid_apsr_data == true)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Extract digi path
 | 
					        // Extract digi path
 | 
				
			||||||
@@ -336,6 +570,7 @@ uint16_t decode_packet ()
 | 
				
			|||||||
            if ( rxBuffer[position] == ':' ) {
 | 
					            if ( rxBuffer[position] == ':' ) {
 | 
				
			||||||
                aprs_digi_path[cnt-1] = 0;
 | 
					                aprs_digi_path[cnt-1] = 0;
 | 
				
			||||||
                valid_apsr_data = true;
 | 
					                valid_apsr_data = true;
 | 
				
			||||||
 | 
					                    position++;
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            position++;
 | 
					            position++;
 | 
				
			||||||
@@ -343,8 +578,6 @@ uint16_t decode_packet ()
 | 
				
			|||||||
        
 | 
					        
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    position++;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (valid_apsr_data == true)
 | 
					    if (valid_apsr_data == true)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        // Extract data field
 | 
					        // Extract data field
 | 
				
			||||||
@@ -372,8 +605,6 @@ uint16_t decode_packet ()
 | 
				
			|||||||
                    valid_apsr_data = false;
 | 
					                    valid_apsr_data = false;
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                //position++;
 | 
					 | 
				
			||||||
                cnt = 0;
 | 
					                cnt = 0;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            position++;
 | 
					            position++;
 | 
				
			||||||
@@ -424,20 +655,20 @@ uint16_t decode_packet ()
 | 
				
			|||||||
            
 | 
					            
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        printf("Source address: %s\nDigipeaters (%u): %s %s %s %s\nData: %s\n", aprs_source_address, number_of_digipeaters+1, aprs_digis[0], aprs_digis[1], aprs_digis[2], aprs_digis[3], aprs_data_field);
 | 
					        log_out("Source address: %s\nDigipeaters (%u): %s %s %s %s\nData: %s\n", aprs_source_address, number_of_digipeaters+1, aprs_digis[0], aprs_digis[1], aprs_digis[2], aprs_digis[3], aprs_data_field);
 | 
				
			||||||
        if (aprs_message[0])
 | 
					        if (aprs_message[0])
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            printf("Message from server: %s (command %u)\n", aprs_message, aprs_server_command);
 | 
					            log_out("Message from server: %s (command %u)\n", aprs_message, aprs_server_command);
 | 
				
			||||||
            if (aprs_acknowledge_request) {
 | 
					            if (aprs_acknowledge_request) {
 | 
				
			||||||
                ComposeAprsFrame(aprs_acknowledge_number);
 | 
					                ComposeAprsFrame(aprs_acknowledge_number);
 | 
				
			||||||
                printf("Acknowledge request: %s\n", aprs_acknowledge_number);
 | 
					                log_out("Acknowledge request: %s\n", aprs_acknowledge_number);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }    
 | 
					    }    
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        printf("Error decoding APRS frame.");
 | 
					        log_out("Error decoding APRS frame.");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return (aprs_server_command);
 | 
					    return (aprs_server_command);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -570,7 +801,7 @@ void ComposeAprsFrame(uint8_t payload[])
 | 
				
			|||||||
    
 | 
					    
 | 
				
			||||||
    // Set variable to indicate a send request
 | 
					    // Set variable to indicate a send request
 | 
				
			||||||
    TransmitRequest = true; 
 | 
					    TransmitRequest = true; 
 | 
				
			||||||
    printf("%s\n", txBuffer);
 | 
					    log_out("%s\n", txBuffer);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void transmit() {
 | 
					void transmit() {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user