kopia lustrzana https://github.com/DL7AD/pecanpico10
				
				
				
			Improve error checking for packet buffers. Improve 446x driver.
							rodzic
							
								
									e329bbb2bf
								
							
						
					
					
						commit
						b33c2ebe46
					
				|  | @ -24,7 +24,7 @@ const conf_t conf_flash_default = { | ||||||
| 			.preamble		= 200 | 			.preamble		= 200 | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		.call				= "VK2GJ-15", | 		.call				= "VK2GJ-12", | ||||||
| 		.path				= "WIDE2-1", | 		.path				= "WIDE2-1", | ||||||
| 		.symbol				= SYM_DIGIPEATER, | 		.symbol				= SYM_DIGIPEATER, | ||||||
| 
 | 
 | ||||||
|  | @ -63,9 +63,9 @@ const conf_t conf_flash_default = { | ||||||
| 		}, | 		}, | ||||||
| 		.radio_conf = { | 		.radio_conf = { | ||||||
| 			.pwr			= 0x7F, | 			.pwr			= 0x7F, | ||||||
|             .freq           = 144800000, |             .freq           = 144000000, | ||||||
|             .step           = 12500, |             .step           = 12500, | ||||||
|             .chan           = 0, |             .chan           = 64, | ||||||
| 			.mod			= MOD_2FSK, | 			.mod			= MOD_2FSK, | ||||||
| 			.preamble		= 200, | 			.preamble		= 200, | ||||||
| 			.redundantTx	= true | 			.redundantTx	= true | ||||||
|  | @ -135,7 +135,7 @@ const conf_t conf_flash_default = { | ||||||
| 			.preamble		= 200 | 			.preamble		= 200 | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		.call				= "VK2GJ-15", | 		.call				= "VK2GJ-4", | ||||||
| 		.path				= "WIDE2-1", | 		.path				= "WIDE2-1", | ||||||
| 		.symbol				= SYM_DIGIPEATER | 		.symbol				= SYM_DIGIPEATER | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
|  | @ -599,8 +599,6 @@ static bool Si446x_transmit(radio_unit_t radio, | ||||||
|     // Transmit
 |     // Transmit
 | ||||||
|     TRACE_INFO("SI   > Tune Si446x (TX)"); |     TRACE_INFO("SI   > Tune Si446x (TX)"); | ||||||
|     Si446x_setReadyState(radio); |     Si446x_setReadyState(radio); | ||||||
|     /* Set band parameters back to normal TX. */ |  | ||||||
|     //Si446x_setBandParameters(radio, freq, step);     // Set frequency
 |  | ||||||
|     Si446x_setPowerLevel(power);        // Set power level
 |     Si446x_setPowerLevel(power);        // Set power level
 | ||||||
|     Si446x_setTXState(radio, chan, size); |     Si446x_setTXState(radio, chan, size); | ||||||
| 
 | 
 | ||||||
|  | @ -727,119 +725,14 @@ void Si446x_pauseReceive(radio_unit_t radio) { | ||||||
| 
 | 
 | ||||||
| /* ==================================================================== AFSK Transmitter ==================================================================== */ | /* ==================================================================== AFSK Transmitter ==================================================================== */ | ||||||
| 
 | 
 | ||||||
| #define PLAYBACK_RATE       13200 |  | ||||||
| #define BAUD_RATE           1200                                    /* APRS AFSK baudrate */ |  | ||||||
| #define SAMPLES_PER_BAUD    (PLAYBACK_RATE / BAUD_RATE)             /* Samples per baud (13200Hz / 1200baud = 11samp/baud) */ |  | ||||||
| #define PHASE_DELTA_1200    (((2 * 1200) << 16) / PLAYBACK_RATE)    /* Delta-phase per sample for 1200Hz tone */ |  | ||||||
| #define PHASE_DELTA_2200    (((2 * 2200) << 16) / PLAYBACK_RATE)    /* Delta-phase per sample for 2200Hz tone */ |  | ||||||
| 
 | 
 | ||||||
| static uint32_t phase_delta;            // 1200/2200 for standard AX.25
 | /*static uint32_t phase_delta;            // 1200/2200 for standard AX.25
 | ||||||
| static uint32_t phase;                  // Fixed point 9.7 (2PI = TABLE_SIZE)
 | static uint32_t phase;                  // Fixed point 9.7 (2PI = TABLE_SIZE)
 | ||||||
| static uint32_t packet_pos;             // Next bit to be sent out
 | static uint32_t packet_pos;             // Next bit to be sent out
 | ||||||
| static uint32_t current_sample_in_baud; // 1 bit = SAMPLES_PER_BAUD samples
 | static uint32_t current_sample_in_baud; // 1 bit = SAMPLES_PER_BAUD samples
 | ||||||
| static uint8_t current_byte; | static uint8_t current_byte;*/ | ||||||
| //static uint8_t ctone = 0;
 |  | ||||||
| 
 | 
 | ||||||
| /*static bool Si446x_getBitAsNRZI(bool bit) {
 | /*static uint8_t __attribute__((unused)) Si446x_getUpsampledAFSKbits(uint8_t* buf) {
 | ||||||
|     if((bit & 0x1) == 0) |  | ||||||
|         ctone = !ctone; |  | ||||||
|     return ctone; |  | ||||||
| }*/ |  | ||||||
| 
 |  | ||||||
| /*
 |  | ||||||
|  * Create a bit stream of AFSK (NRZI & HDLC) encoded packet data. |  | ||||||
|  */ |  | ||||||
| /*static uint32_t Si446x_encodeDataToAFSK(uint8_t *inbuf, uint32_t inlen,
 |  | ||||||
|                      uint8_t* buf, uint32_t buf_len, uint8_t pre_len) { |  | ||||||
|     memset(buf, 0, buf_len); // Clear buffer
 |  | ||||||
|     uint32_t blen = 0; |  | ||||||
| 
 |  | ||||||
|     // Preamble (HDLC flags)
 |  | ||||||
|     for(uint8_t i = 0; i < pre_len; i++) { |  | ||||||
|         for(uint8_t j = 0; j < 8; j++) { |  | ||||||
| 
 |  | ||||||
|             if(blen >> 3 >= buf_len) { // Buffer overflow
 |  | ||||||
| 
 |  | ||||||
|                 TRACE_ERROR("SI   > Preamble too long"); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|                 return 0; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             buf[blen >> 3] |= Si446x_getBitAsNRZI((0x7E >> j) & 0x1) << (blen % 8); |  | ||||||
|             blen++; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Insert CRC to buffer
 |  | ||||||
|     uint16_t crc = calc_crc16(inbuf, 0, inlen); |  | ||||||
|     inbuf[inlen++] = crc & 0xFF; |  | ||||||
|     inbuf[inlen++] = crc >> 8; |  | ||||||
| 
 |  | ||||||
|     uint32_t pos = 0; |  | ||||||
|     uint8_t bitstuff_cntr = 0; |  | ||||||
| 
 |  | ||||||
|     while(pos < inlen*8) |  | ||||||
|     { |  | ||||||
|         if(blen >> 3 >= buf_len) { // Buffer overflow
 |  | ||||||
| 
 |  | ||||||
|           TRACE_ERROR("SI   > Packet too long"); |  | ||||||
| 
 |  | ||||||
|             return 0; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         bool bit; |  | ||||||
|         if(bitstuff_cntr < 5) { // Normal bit
 |  | ||||||
| 
 |  | ||||||
|             bit = (inbuf[pos >> 3] >> (pos%8)) & 0x1; |  | ||||||
|             if(bit == 1) { |  | ||||||
|                 bitstuff_cntr++; |  | ||||||
|             } else { |  | ||||||
|                 bitstuff_cntr = 0; |  | ||||||
|             } |  | ||||||
|             pos++; |  | ||||||
| 
 |  | ||||||
|         } else { // Fill stuffing bit
 |  | ||||||
| 
 |  | ||||||
|             bit = 0; |  | ||||||
|             bitstuff_cntr = 0; |  | ||||||
| 
 |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         // NRZ-I encode bit
 |  | ||||||
|         bool nrzi = Si446x_getBitAsNRZI(bit); |  | ||||||
| 
 |  | ||||||
|         buf[blen >> 3] |= nrzi << (blen % 8); |  | ||||||
|         blen++; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     // Final flag
 |  | ||||||
|     for(uint8_t i=0; i<10; i++) |  | ||||||
|         for(uint8_t j=0; j<8; j++) { |  | ||||||
| 
 |  | ||||||
|             if(blen >> 3 >= buf_len) { // Buffer overflow
 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
|                 TRACE_ERROR("SI   > Packet too long"); |  | ||||||
| 
 |  | ||||||
|                 return 0; |  | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             buf[blen >> 3] |= Si446x_getBitAsNRZI((0x7E >> j) & 0x1) << (blen % 8); |  | ||||||
|             blen++; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|     return blen; |  | ||||||
| }*/ |  | ||||||
| 
 |  | ||||||
| static uint8_t Si446x_getUpsampledAFSKbits(uint8_t* buf/*, uint32_t blen*/) |  | ||||||
| { |  | ||||||
|   /* This function may be called with different bit stream sources.
 |  | ||||||
|    * These will have their own blen so checking is not valid. |  | ||||||
|    */ |  | ||||||
|     //if(packet_pos == blen)
 |  | ||||||
|       /* Packet transmission finished already so just return a zero. */ |  | ||||||
|       //return 0;
 |  | ||||||
| 
 | 
 | ||||||
|     uint8_t b = 0; |     uint8_t b = 0; | ||||||
|     for(uint8_t i = 0; i < 8; i++) |     for(uint8_t i = 0; i < 8; i++) | ||||||
|  | @ -854,7 +747,7 @@ static uint8_t Si446x_getUpsampledAFSKbits(uint8_t* buf/*, uint32_t blen*/) | ||||||
| 
 | 
 | ||||||
|         // Toggle tone (1200 <> 2200)
 |         // Toggle tone (1200 <> 2200)
 | ||||||
|         phase_delta = (current_byte & 1) ? PHASE_DELTA_1200 : PHASE_DELTA_2200; |         phase_delta = (current_byte & 1) ? PHASE_DELTA_1200 : PHASE_DELTA_2200; | ||||||
|         /* Add delta-phase (bit count within SAMPLES_PER_BAUD). */ | 
 | ||||||
|         phase += phase_delta; |         phase += phase_delta; | ||||||
|         b |= ((phase >> 16) & 1) << i;  // Set modulation bit
 |         b |= ((phase >> 16) & 1) << i;  // Set modulation bit
 | ||||||
| 
 | 
 | ||||||
|  | @ -866,9 +759,43 @@ static uint8_t Si446x_getUpsampledAFSKbits(uint8_t* buf/*, uint32_t blen*/) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return b; |     return b; | ||||||
|  | }*/ | ||||||
|  | 
 | ||||||
|  | /*
 | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | static uint8_t Si446x_getUpsampledNRZIbits(up_iterator_t *upsampler, | ||||||
|  |                                            uint8_t *buf) { | ||||||
|  |   uint8_t b = 0; | ||||||
|  |   for(uint8_t i = 0; i < 8; i++) { | ||||||
|  |     if(upsampler->current_sample_in_baud == 0) { | ||||||
|  |       if((upsampler->packet_pos & 7) == 0) { // Load up next byte
 | ||||||
|  |         upsampler->current_byte = buf[upsampler->packet_pos >> 3]; | ||||||
|  |       } else { // Load up next bit
 | ||||||
|  |         upsampler->current_byte >>= 1; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     // Toggle tone (1200 <> 2200)
 | ||||||
|  |     upsampler->phase_delta = (upsampler->current_byte & 1) ? PHASE_DELTA_1200 : PHASE_DELTA_2200; | ||||||
|  |     /* Add delta-phase (position within SAMPLES_PER_BAUD). */ | ||||||
|  |     upsampler->phase += upsampler->phase_delta; | ||||||
|  |     b |= ((upsampler->phase >> 16) & 1) << i;  // Set modulation bit
 | ||||||
|  | 
 | ||||||
|  |     //upsampler->current_sample_in_baud++;
 | ||||||
|  | 
 | ||||||
|  |     if(++upsampler->current_sample_in_baud == SAMPLES_PER_BAUD) {    // Old bit consumed, load next bit
 | ||||||
|  |       upsampler->current_sample_in_baud = 0; | ||||||
|  |       upsampler->packet_pos++; | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   return b; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void __attribute__((unused)) Si446x_upsampleNRZIstream(uint8_t current_byte, | /*
 | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | /*static void __attribute__((unused)) Si446x_upsampleNRZIstream(uint8_t current_byte,
 | ||||||
|                                                uint8_t *buf, |                                                uint8_t *buf, | ||||||
|                                                uint8_t upsample_rate) { |                                                uint8_t upsample_rate) { | ||||||
|   uint8_t b = 0, i = 0, usr; |   uint8_t b = 0, i = 0, usr; | ||||||
|  | @ -876,7 +803,7 @@ static void __attribute__((unused)) Si446x_upsampleNRZIstream(uint8_t current_by | ||||||
|     do { |     do { | ||||||
|       // Toggle tone (1200 <> 2200)
 |       // Toggle tone (1200 <> 2200)
 | ||||||
|       phase_delta = (current_byte & 1) ? PHASE_DELTA_1200 : PHASE_DELTA_2200; |       phase_delta = (current_byte & 1) ? PHASE_DELTA_1200 : PHASE_DELTA_2200; | ||||||
|       /* Add delta-phase (bit count within SAMPLES_PER_BAUD). */ | 
 | ||||||
|       phase += phase_delta; |       phase += phase_delta; | ||||||
|       b |= ((phase >> 16) & 1) << i;  // Set modulation bit
 |       b |= ((phase >> 16) & 1) << i;  // Set modulation bit
 | ||||||
|       current_byte >>= (usr / upsample_rate) * 8; |       current_byte >>= (usr / upsample_rate) * 8; | ||||||
|  | @ -884,13 +811,13 @@ static void __attribute__((unused)) Si446x_upsampleNRZIstream(uint8_t current_by | ||||||
|     i = 0; |     i = 0; | ||||||
|     buf[usr] = b; |     buf[usr] = b; | ||||||
|   } |   } | ||||||
| } | }*/ | ||||||
| 
 | 
 | ||||||
| #define SI446X_EVT_AFSK_TX_TIMEOUT      EVENT_MASK(0) | #define SI446X_EVT_TX_TIMEOUT      EVENT_MASK(0) | ||||||
| 
 | 
 | ||||||
| static void Si446x_transmitTimeoutI(thread_t *tp) { | static void Si446x_transmitTimeoutI(thread_t *tp) { | ||||||
|   /* The tell the thread to terminate. */ |   /* The tell the thread to terminate. */ | ||||||
|   chEvtSignal(tp, SI446X_EVT_AFSK_TX_TIMEOUT); |   chEvtSignal(tp, SI446X_EVT_TX_TIMEOUT); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /*
 | /*
 | ||||||
|  | @ -942,8 +869,7 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | ||||||
|     if(all == 0) { |     if(all == 0) { | ||||||
|       /* Nothing encoded. Release packet send object. */ |       /* Nothing encoded. Release packet send object. */ | ||||||
| 
 | 
 | ||||||
| 
 |       TRACE_ERROR("SI   > AFSK TX no NRZI data encoded"); | ||||||
|       TRACE_DEBUG("SI   > AFSK TX no NRZI data encoded"); |  | ||||||
| 
 | 
 | ||||||
|       // Free packet object memory
 |       // Free packet object memory
 | ||||||
|       pktReleaseSendObject(pp); |       pktReleaseSendObject(pp); | ||||||
|  | @ -964,12 +890,15 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | ||||||
|     const uint8_t reset_fifo[] = {0x15, 0x01}; |     const uint8_t reset_fifo[] = {0x15, 0x01}; | ||||||
|     Si446x_write(reset_fifo, 2); |     Si446x_write(reset_fifo, 2); | ||||||
| 
 | 
 | ||||||
|  |     up_iterator_t upsampler = {0}; | ||||||
|  |     upsampler.phase_delta = PHASE_DELTA_1200; | ||||||
|  | 
 | ||||||
|     /* Initialize variables for up sampler. */ |     /* Initialize variables for up sampler. */ | ||||||
|     phase_delta = PHASE_DELTA_1200; | /*    phase_delta = PHASE_DELTA_1200;
 | ||||||
|     phase = 0; |     phase = 0; | ||||||
|     packet_pos = 0; |     packet_pos = 0; | ||||||
|     current_sample_in_baud = 0; |     current_sample_in_baud = 0; | ||||||
|     current_byte = 0; |     current_byte = 0;*/ | ||||||
| 
 | 
 | ||||||
|     /* Maximum amount of FIFO data when using combined TX+RX (safe size). */ |     /* Maximum amount of FIFO data when using combined TX+RX (safe size). */ | ||||||
|     uint8_t localBuffer[Si446x_FIFO_COMBINED_SIZE]; |     uint8_t localBuffer[Si446x_FIFO_COMBINED_SIZE]; | ||||||
|  | @ -992,7 +921,8 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | ||||||
| 
 | 
 | ||||||
|     /* Initial FIFO load. */ |     /* Initial FIFO load. */ | ||||||
|     for(uint16_t i = 0;  i < c; i++) |     for(uint16_t i = 0;  i < c; i++) | ||||||
|         localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0); |         //localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0);
 | ||||||
|  |       localBuffer[i] = Si446x_getUpsampledNRZIbits(&upsampler, layer0); | ||||||
|     Si446x_writeFIFO(localBuffer, c); |     Si446x_writeFIFO(localBuffer, c); | ||||||
| 
 | 
 | ||||||
|     uint8_t lower = 0; |     uint8_t lower = 0; | ||||||
|  | @ -1018,7 +948,8 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | ||||||
| 
 | 
 | ||||||
|         /* Load the FIFO. */ |         /* Load the FIFO. */ | ||||||
|         for(uint16_t i = 0; i < more; i++) |         for(uint16_t i = 0; i < more; i++) | ||||||
|             localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0); |             //localBuffer[i] = Si446x_getUpsampledAFSKbits(layer0);
 | ||||||
|  |           localBuffer[i] = Si446x_getUpsampledNRZIbits(&upsampler, layer0); | ||||||
|         Si446x_writeFIFO(localBuffer, more); // Write into FIFO
 |         Si446x_writeFIFO(localBuffer, more); // Write into FIFO
 | ||||||
|         c += more; |         c += more; | ||||||
| 
 | 
 | ||||||
|  | @ -1027,7 +958,7 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | ||||||
|          * Time delay allows ~SAMPLES_PER_BAUD bytes to be consumed from FIFO. |          * Time delay allows ~SAMPLES_PER_BAUD bytes to be consumed from FIFO. | ||||||
|          * If no timeout event go back and load more data to FIFO. |          * If no timeout event go back and load more data to FIFO. | ||||||
|          */ |          */ | ||||||
|         eventmask_t evt = chEvtWaitAnyTimeout(SI446X_EVT_AFSK_TX_TIMEOUT, |         eventmask_t evt = chEvtWaitAnyTimeout(SI446X_EVT_TX_TIMEOUT, | ||||||
|                                    chTimeUS2I(833 * 8)); |                                    chTimeUS2I(833 * 8)); | ||||||
|         if(evt) { |         if(evt) { | ||||||
|           /* Force 446x out of TX state. */ |           /* Force 446x out of TX state. */ | ||||||
|  | @ -1052,9 +983,10 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | ||||||
|       continue; |       continue; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| 
 |     if(lower > (free / 2)) { | ||||||
| 
 |       /* Warn when level drops below 50% of FIFO size. */ | ||||||
|     TRACE_INFO("SI   > AFSK TX FIFO lowest free level %i", lower); |       TRACE_DEBUG("SI   > AFSK TX FIFO dropped below safe threshold %i", lower); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     // Free packet object memory
 |     // Free packet object memory
 | ||||||
|     pktReleaseSendObject(pp); |     pktReleaseSendObject(pp); | ||||||
|  | @ -1147,8 +1079,7 @@ THD_FUNCTION(min_si_fifo_feeder_fsk, arg) { | ||||||
|   if(all == 0) { |   if(all == 0) { | ||||||
|     /* Nothing encoded. Release packet send object. */ |     /* Nothing encoded. Release packet send object. */ | ||||||
| 
 | 
 | ||||||
| 
 |     TRACE_ERROR("SI   > 2FSK TX no NRZI data encoded"); | ||||||
|     TRACE_DEBUG("SI   > 2FSK TX no NRZI data encoded"); |  | ||||||
| 
 | 
 | ||||||
|     // Free packet object memory
 |     // Free packet object memory
 | ||||||
|     pktReleaseSendObject(pp); |     pktReleaseSendObject(pp); | ||||||
|  | @ -1220,7 +1151,7 @@ THD_FUNCTION(min_si_fifo_feeder_fsk, arg) { | ||||||
|        * Time delay allows ~10 bytes to be consumed from FIFO. |        * Time delay allows ~10 bytes to be consumed from FIFO. | ||||||
|        * If no timeout event go back and load more data to FIFO. |        * If no timeout event go back and load more data to FIFO. | ||||||
|        */ |        */ | ||||||
|       eventmask_t evt = chEvtWaitAnyTimeout(SI446X_EVT_AFSK_TX_TIMEOUT, |       eventmask_t evt = chEvtWaitAnyTimeout(SI446X_EVT_TX_TIMEOUT, | ||||||
|                                  chTimeUS2I(104 * 8 * 10)); |                                  chTimeUS2I(104 * 8 * 10)); | ||||||
|       if(evt) { |       if(evt) { | ||||||
|         /* Force 446x out of TX state. */ |         /* Force 446x out of TX state. */ | ||||||
|  | @ -1245,7 +1176,10 @@ THD_FUNCTION(min_si_fifo_feeder_fsk, arg) { | ||||||
|     continue; |     continue; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   TRACE_INFO("SI   > 2FSK TX FIFO lowest free level %i", lower); |   if(lower > (free / 2)) { | ||||||
|  |     /* Warn when level drops below 50% of FIFO size. */ | ||||||
|  |     TRACE_DEBUG("SI   > AFSK TX FIFO dropped below safe threshold %i", lower); | ||||||
|  |   } | ||||||
| 
 | 
 | ||||||
|   // Free packet object memory
 |   // Free packet object memory
 | ||||||
|   pktReleaseSendObject(pp); |   pktReleaseSendObject(pp); | ||||||
|  |  | ||||||
|  | @ -1,9 +1,9 @@ | ||||||
| #ifndef __si446x__H__ | #ifndef __si446x__H__ | ||||||
| #define __si446x__H__ | #define __si446x__H__ | ||||||
| 
 | 
 | ||||||
| //#include "ch.h"
 | /*===========================================================================*/ | ||||||
| //#include "hal.h"
 | /* Module constants.                                                         */ | ||||||
| //#include "types.h"
 | /*===========================================================================*/ | ||||||
| 
 | 
 | ||||||
| #define Si446x_LOCK_BY_SEMAPHORE    TRUE | #define Si446x_LOCK_BY_SEMAPHORE    TRUE | ||||||
| 
 | 
 | ||||||
|  | @ -192,12 +192,31 @@ | ||||||
| #define SI_AFSK_FIFO_MIN_FEEDER_WA_SIZE         1024 | #define SI_AFSK_FIFO_MIN_FEEDER_WA_SIZE         1024 | ||||||
| #define SI_FSK_FIFO_FEEDER_WA_SIZE              1024 | #define SI_FSK_FIFO_FEEDER_WA_SIZE              1024 | ||||||
| 
 | 
 | ||||||
|  | /* AFSK NRZI up-sampler definitions. */ | ||||||
|  | #define PLAYBACK_RATE       13200 | ||||||
|  | #define BAUD_RATE           1200                                    /* APRS AFSK baudrate */ | ||||||
|  | #define SAMPLES_PER_BAUD    (PLAYBACK_RATE / BAUD_RATE)             /* Samples per baud (13200Hz / 1200baud = 11samp/baud) */ | ||||||
|  | #define PHASE_DELTA_1200    (((2 * 1200) << 16) / PLAYBACK_RATE)    /* Delta-phase per sample for 1200Hz tone */ | ||||||
|  | #define PHASE_DELTA_2200    (((2 * 2200) << 16) / PLAYBACK_RATE)    /* Delta-phase per sample for 2200Hz tone */ | ||||||
|  | 
 | ||||||
|  | /*===========================================================================*/ | ||||||
|  | /* Module data structures and types.                                         */ | ||||||
|  | /*===========================================================================*/ | ||||||
|  | 
 | ||||||
| typedef enum radioMode { | typedef enum radioMode { | ||||||
|   RADIO_RX, |   RADIO_RX, | ||||||
|   RADIO_TX, |   RADIO_TX, | ||||||
|   RADIO_CCA |   RADIO_CCA | ||||||
| } radio_mode_t; | } radio_mode_t; | ||||||
| 
 | 
 | ||||||
|  | typedef struct { | ||||||
|  |   uint32_t phase_delta;            // 1200/2200 for standard AX.25
 | ||||||
|  |   uint32_t phase;                  // Fixed point 9.7 (2PI = TABLE_SIZE)
 | ||||||
|  |   uint32_t packet_pos;             // Next bit to be sent out
 | ||||||
|  |   uint32_t current_sample_in_baud; // 1 bit = SAMPLES_PER_BAUD samples
 | ||||||
|  |   uint8_t current_byte; | ||||||
|  | } up_iterator_t; | ||||||
|  | 
 | ||||||
| // Public methods
 | // Public methods
 | ||||||
| 
 | 
 | ||||||
| int16_t Si446x_getLastTemperature(radio_unit_t radio); | int16_t Si446x_getLastTemperature(radio_unit_t radio); | ||||||
|  |  | ||||||
|  | @ -50,10 +50,10 @@ eventmask_t evt = chEvtGetAndClearEvents(EVENT_MASK(1)); | ||||||
|       TRACE_ERROR("PKT  > Decoder error"); |       TRACE_ERROR("PKT  > Decoder error"); | ||||||
|     } |     } | ||||||
|     if(flags & EVT_PWM_UNKNOWN_INBAND) { |     if(flags & EVT_PWM_UNKNOWN_INBAND) { | ||||||
|       TRACE_ERROR("PKT  > Unknown PWM inband flag"); |       TRACE_ERROR("PKT  > Unknown PWM in-band flag"); | ||||||
|     } |     } | ||||||
|     if(flags & EVT_ICU_OVERFLOW) { |     if(flags & EVT_ICU_OVERFLOW) { | ||||||
|       TRACE_WARN("PKT  > PWM ICU overflow"); |       TRACE_DEBUG("PKT  > PWM ICU overflow"); | ||||||
|     } |     } | ||||||
|     if(flags & EVT_PWM_STREAM_TIMEOUT) { |     if(flags & EVT_PWM_STREAM_TIMEOUT) { | ||||||
|       TRACE_WARN("PKT  > PWM stream timeout"); |       TRACE_WARN("PKT  > PWM stream timeout"); | ||||||
|  | @ -61,5 +61,14 @@ eventmask_t evt = chEvtGetAndClearEvents(EVENT_MASK(1)); | ||||||
|     if(flags & EVT_PWM_NO_DATA) { |     if(flags & EVT_PWM_NO_DATA) { | ||||||
|       TRACE_WARN("PKT  > PWM data not started from radio"); |       TRACE_WARN("PKT  > PWM data not started from radio"); | ||||||
|     } |     } | ||||||
|  |     if(flags & EVT_AFSK_START_FAIL) { | ||||||
|  |       TRACE_ERROR("PKT  > AFSK decoder failed to start"); | ||||||
|  |     } | ||||||
|  |     if(flags & EVT_PKT_BUFFER_MGR_FAIL) { | ||||||
|  |       TRACE_ERROR("PKT  > Unable to start packet RX buffer"); | ||||||
|  |     } | ||||||
|  |     if(flags & EVT_PKT_CBK_MGR_FAIL) { | ||||||
|  |       TRACE_ERROR("PKT  > Unable to start packet RX callback manager"); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -285,7 +285,7 @@ ssdv_packet_t packetRepeats[16]; | ||||||
| bool reject_pri; | bool reject_pri; | ||||||
| bool reject_sec; | bool reject_sec; | ||||||
| 
 | 
 | ||||||
| static void transmit_image_packet(const uint8_t *image, uint32_t image_len, thd_img_conf_t* conf, uint8_t image_id, uint16_t packet_id) | static bool transmit_image_packet(const uint8_t *image, uint32_t image_len, thd_img_conf_t* conf, uint8_t image_id, uint16_t packet_id) | ||||||
| { | { | ||||||
| 	ssdv_t ssdv; | 	ssdv_t ssdv; | ||||||
| 	uint8_t pkt[SSDV_PKT_SIZE]; | 	uint8_t pkt[SSDV_PKT_SIZE]; | ||||||
|  | @ -311,34 +311,35 @@ static void transmit_image_packet(const uint8_t *image, uint32_t image_len, thd_ | ||||||
| 			if(r <= 0) | 			if(r <= 0) | ||||||
| 			{ | 			{ | ||||||
| 				TRACE_ERROR("SSDV > Premature end of file"); | 				TRACE_ERROR("SSDV > Premature end of file"); | ||||||
| 				break; | 				return false; | ||||||
| 			} | 			} | ||||||
| 			ssdv_enc_feed(&ssdv, b, r); | 			ssdv_enc_feed(&ssdv, b, r); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if(c == SSDV_EOI) { | 		if(c == SSDV_EOI) { | ||||||
| 			break; | 			return true; | ||||||
| 		} else if(c != SSDV_OK) { | 		} else if(c != SSDV_OK) { | ||||||
| 			return; | 			return false; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if(i == packet_id) { | 		if(i == packet_id) { | ||||||
| 			// Sync byte, CRC and FEC of SSDV not transmitted (because its not neccessary inside an APRS packet)
 | 			// Sync byte, CRC and FEC of SSDV not transmitted (because its not necessary inside an APRS packet)
 | ||||||
| 			base91_encode(&pkt[6], pkt_base91, 174); | 			base91_encode(&pkt[6], pkt_base91, 174); | ||||||
| 		    /* TODO: Check for failure to get packet (NULL). */ |  | ||||||
| 			packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'I', pkt_base91); | 			packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'I', pkt_base91); | ||||||
|             if(packet == NULL) { |             if(packet == NULL) { | ||||||
|               TRACE_WARN("SSDV > No free packet objects"); |               TRACE_WARN("IMG  > No free packet objects for transmission"); | ||||||
|               break; |               return false; | ||||||
|             } |             } | ||||||
|             transmitOnRadio(packet, |             if(!transmitOnRadio(packet, | ||||||
|                             conf->radio_conf.freq, |                             conf->radio_conf.freq, | ||||||
|                             conf->radio_conf.step, |                             conf->radio_conf.step, | ||||||
|                             conf->radio_conf.chan, |                             conf->radio_conf.chan, | ||||||
|                             conf->radio_conf.pwr, |                             conf->radio_conf.pwr, | ||||||
|                             conf->radio_conf.mod); |                             conf->radio_conf.mod)) { | ||||||
| 
 | 
 | ||||||
| 			return; |               TRACE_ERROR("IMG  > Unable to send image packet TX on radio"); | ||||||
|  |               return false; | ||||||
|  |             } | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		chThdSleep(TIME_MS2I(10)); // Leave other threads some time
 | 		chThdSleep(TIME_MS2I(10)); // Leave other threads some time
 | ||||||
|  | @ -347,7 +348,11 @@ static void transmit_image_packet(const uint8_t *image, uint32_t image_len, thd_ | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void transmit_image_packets(const uint8_t *image, uint32_t image_len, thd_img_conf_t* conf, uint8_t image_id) | /*
 | ||||||
|  |  * Transmit image packets. | ||||||
|  |  * Return true if success or false on fail. | ||||||
|  |  */ | ||||||
|  | static bool transmit_image_packets(const uint8_t *image, uint32_t image_len, thd_img_conf_t* conf, uint8_t image_id) | ||||||
| { | { | ||||||
| 	ssdv_t ssdv; | 	ssdv_t ssdv; | ||||||
| 	uint8_t pkt[SSDV_PKT_SIZE]; | 	uint8_t pkt[SSDV_PKT_SIZE]; | ||||||
|  | @ -368,15 +373,19 @@ static void transmit_image_packets(const uint8_t *image, uint32_t image_len, thd | ||||||
| 		if(strlen((char*)pkt_base91) && conf->radio_conf.redundantTx) { | 		if(strlen((char*)pkt_base91) && conf->radio_conf.redundantTx) { | ||||||
| 			packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'I', pkt_base91); | 			packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'I', pkt_base91); | ||||||
|             if(packet == NULL) { |             if(packet == NULL) { | ||||||
|               TRACE_WARN("SSDV > No free packet objects"); |               TRACE_WARN("IMG  > No free packet objects for redundant TX"); | ||||||
|               break; |               return false; | ||||||
|             } |             } | ||||||
|             transmitOnRadio(packet, |             if(!transmitOnRadio(packet, | ||||||
|                             conf->radio_conf.freq, |                             conf->radio_conf.freq, | ||||||
|                             conf->radio_conf.step, |                             conf->radio_conf.step, | ||||||
|                             conf->radio_conf.chan, |                             conf->radio_conf.chan, | ||||||
|                             conf->radio_conf.pwr, |                             conf->radio_conf.pwr, | ||||||
|                             conf->radio_conf.mod); |                             conf->radio_conf.mod)) { | ||||||
|  |               TRACE_ERROR("IMG  > Unable to send redundant TX on radio"); | ||||||
|  |               return false; | ||||||
|  |             } | ||||||
|  |             chThdSleep(TIME_MS2I(10)); // Leave other threads some time
 | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Encode packet
 | 		// Encode packet
 | ||||||
|  | @ -385,13 +394,13 @@ static void transmit_image_packets(const uint8_t *image, uint32_t image_len, thd | ||||||
| 		while((c = ssdv_enc_get_packet(&ssdv)) == SSDV_FEED_ME) | 		while((c = ssdv_enc_get_packet(&ssdv)) == SSDV_FEED_ME) | ||||||
| 		{ | 		{ | ||||||
| 			b = &image[bi]; | 			b = &image[bi]; | ||||||
| 			uint8_t r = bi < image_len-128 ? 128 : image_len - bi; | 			int16_t r = bi < image_len-128 ? 128 : image_len - bi; | ||||||
| 			bi += r; | 			bi += r; | ||||||
| 
 | 
 | ||||||
| 			if(r <= 0) | 			if(r <= 0) | ||||||
| 			{ | 			{ | ||||||
| 				TRACE_ERROR("SSDV > Premature end of file"); | 				TRACE_ERROR("SSDV > Premature end of file"); | ||||||
| 				break; | 				return false; | ||||||
| 			} | 			} | ||||||
| 			ssdv_enc_feed(&ssdv, b, r); | 			ssdv_enc_feed(&ssdv, b, r); | ||||||
| 		} | 		} | ||||||
|  | @ -399,34 +408,39 @@ static void transmit_image_packets(const uint8_t *image, uint32_t image_len, thd | ||||||
| 		if(c == SSDV_EOI) | 		if(c == SSDV_EOI) | ||||||
| 		{ | 		{ | ||||||
| 			TRACE_INFO("SSDV > ssdv_enc_get_packet said EOI"); | 			TRACE_INFO("SSDV > ssdv_enc_get_packet said EOI"); | ||||||
| 			break; | 			return true; | ||||||
| 		} else if(c != SSDV_OK) { | 		} else if(c != SSDV_OK) { | ||||||
| 			TRACE_ERROR("SSDV > ssdv_enc_get_packet failed: %i", c); | 			TRACE_ERROR("SSDV > ssdv_enc_get_packet failed: %i", c); | ||||||
| 			return; | 			return false; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		// Sync byte, CRC and FEC of SSDV not transmitted (because its not neccessary inside an APRS packet)
 | 		// Sync byte, CRC and FEC of SSDV not transmitted (because its not necessary inside an APRS packet)
 | ||||||
| 		base91_encode(&pkt[6], pkt_base91, 174); | 		base91_encode(&pkt[6], pkt_base91, 174); | ||||||
| 
 | 
 | ||||||
| 		packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'I', pkt_base91); | 		packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'I', pkt_base91); | ||||||
|         if(packet == NULL) { |         if(packet == NULL) { | ||||||
|           TRACE_WARN("SSDV > No free packet objects"); |           TRACE_WARN("IMG  > No free packet objects for normal TX"); | ||||||
|           break; |           return false; | ||||||
|         } |         } | ||||||
|         transmitOnRadio(packet, |         if(!transmitOnRadio(packet, | ||||||
|                         conf->radio_conf.freq, |                         conf->radio_conf.freq, | ||||||
|                         conf->radio_conf.step, |                         conf->radio_conf.step, | ||||||
|                         conf->radio_conf.chan, |                         conf->radio_conf.chan, | ||||||
|                         conf->radio_conf.pwr, |                         conf->radio_conf.pwr, | ||||||
|                         conf->radio_conf.mod); |                         conf->radio_conf.mod)) { | ||||||
| 
 |           TRACE_ERROR("IMG  > Unable to send normal TX on radio"); | ||||||
|  |           return false; | ||||||
|  |         } | ||||||
| 		chThdSleep(TIME_MS2I(10)); // Leave other threads some time
 | 		chThdSleep(TIME_MS2I(10)); // Leave other threads some time
 | ||||||
| 
 | 
 | ||||||
| 		// Repeat packets
 | 		// Repeat packets
 | ||||||
| 		for(uint8_t i=0; i<16; i++) { | 		for(uint8_t i=0; i<16; i++) { | ||||||
| 			if(packetRepeats[i].n_done && image_id == packetRepeats[i].image_id) { | 			if(packetRepeats[i].n_done && image_id == packetRepeats[i].image_id) { | ||||||
| 				transmit_image_packet(image, image_len, conf, image_id, packetRepeats[i].packet_id); | 				if(!transmit_image_packet(image, image_len, conf, image_id, packetRepeats[i].packet_id)) { | ||||||
| 				packetRepeats[i].n_done = false; // Set done
 | 		          TRACE_ERROR("IMG  > Failed on re-send of image %i", image_id); | ||||||
|  | 				} else { | ||||||
|  | 				  packetRepeats[i].n_done = false; // Set done
 | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 			chThdSleep(TIME_MS2I(100)); // Leave other threads some time
 | 			chThdSleep(TIME_MS2I(100)); // Leave other threads some time
 | ||||||
| 		} | 		} | ||||||
|  | @ -438,11 +452,11 @@ static void transmit_image_packets(const uint8_t *image, uint32_t image_len, thd | ||||||
| 		// Handle image rejection flag
 | 		// Handle image rejection flag
 | ||||||
| 		if(conf == &conf_sram.img_pri && reject_pri) { // Image rejected
 | 		if(conf == &conf_sram.img_pri && reject_pri) { // Image rejected
 | ||||||
| 			reject_pri = false; | 			reject_pri = false; | ||||||
| 			return; | 			return true; | ||||||
| 		} | 		} | ||||||
| 		if(conf == &conf_sram.img_sec && reject_sec) { // Image rejected
 | 		if(conf == &conf_sram.img_sec && reject_sec) { // Image rejected
 | ||||||
| 			reject_sec = false; | 			reject_sec = false; | ||||||
| 			return; | 			return true; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		i++; | 		i++; | ||||||
|  | @ -599,21 +613,25 @@ THD_FUNCTION(imgThread, arg) | ||||||
| 
 | 
 | ||||||
| 					// Find SOI
 | 					// Find SOI
 | ||||||
| 					uint32_t soi; | 					uint32_t soi; | ||||||
| 					for(soi=0; soi<conf->buf_size; soi++) | 					for(soi=0; soi<conf->buf_size; soi++) { | ||||||
| 						if(buffer[soi] == 0xFF && buffer[soi+1] == 0xD8) | 						if(buffer[soi] == 0xFF && buffer[soi+1] == 0xD8) | ||||||
| 							break; | 							break; | ||||||
|  | 					} | ||||||
| 					TRACE_DEBUG("IMG  > SOI at byte %d"); | 					TRACE_DEBUG("IMG  > SOI at byte %d"); | ||||||
| 
 |  | ||||||
| 					writeBufferToFile(filename, &buffer[soi], size_sampled-soi); | 					writeBufferToFile(filename, &buffer[soi], size_sampled-soi); | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				// Encode and transmit picture
 | 				// Encode and transmit picture
 | ||||||
| 				TRACE_INFO("IMG  > Encode/Transmit SSDV ID=%d", gimage_id-1); | 				TRACE_INFO("IMG  > Encode/Transmit SSDV ID=%d", gimage_id-1); | ||||||
| 				transmit_image_packets(buffer, size_sampled, conf, (uint8_t)(gimage_id-1)); | 				if(!transmit_image_packets(buffer, size_sampled, conf, (uint8_t)(gimage_id-1))) { | ||||||
|  |                   TRACE_ERROR("IMG  > Failure in image packet transmit"); | ||||||
|  | 				} | ||||||
| 
 | 
 | ||||||
| 			} else { // No camera found
 | 			} else { // No camera found
 | ||||||
| 				TRACE_INFO("IMG  > Encode/Transmit SSDV (camera error) ID=%d", gimage_id-1); | 				TRACE_INFO("IMG  > Encode/Transmit SSDV (camera error) ID=%d", gimage_id-1); | ||||||
| 				transmit_image_packets(noCameraFound, sizeof(noCameraFound), conf, (uint8_t)(gimage_id-1)); | 				if(!transmit_image_packets(noCameraFound, sizeof(noCameraFound), conf, (uint8_t)(gimage_id-1))) { | ||||||
|  |                   TRACE_ERROR("IMG  > Failure in image packet transmit"); | ||||||
|  | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -621,6 +639,9 @@ THD_FUNCTION(imgThread, arg) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /*
 | ||||||
|  |  * | ||||||
|  |  */ | ||||||
| void start_image_thread(thd_img_conf_t *conf) | void start_image_thread(thd_img_conf_t *conf) | ||||||
| { | { | ||||||
| 	thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE((conf->thread_conf.packet_spacing ? 70:70) * 1024 + conf->buf_size), "IMG", NORMALPRIO, imgThread, conf); | 	thread_t *th = chThdCreateFromHeap(NULL, THD_WORKING_AREA_SIZE((conf->thread_conf.packet_spacing ? 70:70) * 1024 + conf->buf_size), "IMG", NORMALPRIO, imgThread, conf); | ||||||
|  |  | ||||||
|  | @ -58,16 +58,16 @@ THD_FUNCTION(logThread, arg) | ||||||
| 				// Encode and transmit log packet
 | 				// Encode and transmit log packet
 | ||||||
| 				packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'L', pkt_base91); // Encode packet
 | 				packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'L', pkt_base91); // Encode packet
 | ||||||
| 	            if(packet == NULL) { | 	            if(packet == NULL) { | ||||||
| 	              TRACE_WARN("LOG  > No free packet objects"); | 	              TRACE_WARN("LOG  > No free packet objects for log transmission"); | ||||||
| 	              break; | 	            } else { | ||||||
| 	            } |  | ||||||
| 				// Transmit packet
 | 				// Transmit packet
 | ||||||
| 				transmitOnRadio(packet, |                   transmitOnRadio(packet, | ||||||
| 				                conf->radio_conf.freq, |                                   conf->radio_conf.freq, | ||||||
| 	                            conf->radio_conf.step, |                                   conf->radio_conf.step, | ||||||
| 	                            conf->radio_conf.chan, |                                   conf->radio_conf.chan, | ||||||
| 	                            conf->radio_conf.pwr, |                                   conf->radio_conf.pwr, | ||||||
| 	                            conf->radio_conf.mod); |                                   conf->radio_conf.mod); | ||||||
|  | 	            } | ||||||
| 			} else { | 			} else { | ||||||
| 				TRACE_INFO("LOG  > No log point in memory"); | 				TRACE_INFO("LOG  > No log point in memory"); | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | @ -43,29 +43,29 @@ THD_FUNCTION(posThread, arg) | ||||||
| 			// Encode/Transmit position packet
 | 			// Encode/Transmit position packet
 | ||||||
| 			packet_t packet = aprs_encode_position(conf->call, conf->path, conf->symbol, dataPoint); | 			packet_t packet = aprs_encode_position(conf->call, conf->path, conf->symbol, dataPoint); | ||||||
|             if(packet == NULL) { |             if(packet == NULL) { | ||||||
|               TRACE_WARN("POS  > No free packet objects"); |               TRACE_WARN("POS  > No free packet objects for position transmission"); | ||||||
|               break; |             } else { | ||||||
|  |               transmitOnRadio(packet, | ||||||
|  |                               conf->radio_conf.freq, | ||||||
|  |                               conf->radio_conf.step, | ||||||
|  |                               conf->radio_conf.chan, | ||||||
|  |                               conf->radio_conf.pwr, | ||||||
|  |                               conf->radio_conf.mod); | ||||||
|             } |             } | ||||||
| 			transmitOnRadio(packet, |  | ||||||
|                             conf->radio_conf.freq, |  | ||||||
|                             conf->radio_conf.step, |  | ||||||
|                             conf->radio_conf.chan, |  | ||||||
|                             conf->radio_conf.pwr, |  | ||||||
|                             conf->radio_conf.mod); |  | ||||||
| 			chThdSleep(TIME_S2I(5)); | 			chThdSleep(TIME_S2I(5)); | ||||||
| 
 | 
 | ||||||
| 			// Encode/Transmit APRSD packet
 | 			// Encode/Transmit APRSD packet
 | ||||||
| 			packet_t pp = aprs_encode_query_answer_aprsd(conf->call, conf->path, conf->call); | 			packet_t pp = aprs_encode_query_answer_aprsd(conf->call, conf->path, conf->call); | ||||||
|             if(packet == NULL) { |             if(packet == NULL) { | ||||||
|               TRACE_WARN("POS  > No free packet objects"); |               TRACE_WARN("POS  > No free packet objects for APRSD transmission"); | ||||||
|               break; |             } else { | ||||||
|  |               transmitOnRadio(pp, | ||||||
|  |                               conf->radio_conf.freq, | ||||||
|  |                               conf->radio_conf.step, | ||||||
|  |                               conf->radio_conf.chan, | ||||||
|  |                               conf->radio_conf.pwr, | ||||||
|  |                               conf->radio_conf.mod); | ||||||
|             } |             } | ||||||
| 			transmitOnRadio(pp, |  | ||||||
| 			                conf->radio_conf.freq, |  | ||||||
|                             conf->radio_conf.step, |  | ||||||
|                             conf->radio_conf.chan, |  | ||||||
|                             conf->radio_conf.pwr, |  | ||||||
|                             conf->radio_conf.mod); |  | ||||||
| 
 | 
 | ||||||
| 			// Telemetry encoding parameter transmission
 | 			// Telemetry encoding parameter transmission
 | ||||||
| 			if(conf->tel_enc_cycle != 0 && last_conf_transmission + conf->tel_enc_cycle < chVTGetSystemTime()) | 			if(conf->tel_enc_cycle != 0 && last_conf_transmission + conf->tel_enc_cycle < chVTGetSystemTime()) | ||||||
|  | @ -79,16 +79,16 @@ THD_FUNCTION(posThread, arg) | ||||||
| 				{ | 				{ | ||||||
| 					packet = aprs_encode_telemetry_configuration(conf->call, conf->path, type); | 					packet = aprs_encode_telemetry_configuration(conf->call, conf->path, type); | ||||||
| 		            if(packet == NULL) { | 		            if(packet == NULL) { | ||||||
| 		              TRACE_WARN("POS  > No free packet objects"); | 		              TRACE_WARN("POS  > No free packet objects for telemetry transmission"); | ||||||
| 		              break; | 		            } else { | ||||||
|  |                       transmitOnRadio(packet, | ||||||
|  |                                       conf->radio_conf.freq, | ||||||
|  |                                       conf->radio_conf.step, | ||||||
|  |                                       conf->radio_conf.chan, | ||||||
|  |                                       conf->radio_conf.pwr, | ||||||
|  |                                       conf->radio_conf.mod); | ||||||
|  |                       chThdSleep(TIME_S2I(5)); | ||||||
| 		            } | 		            } | ||||||
| 					transmitOnRadio(packet, |  | ||||||
| 		                            conf->radio_conf.freq, |  | ||||||
| 		                            conf->radio_conf.step, |  | ||||||
| 		                            conf->radio_conf.chan, |  | ||||||
| 		                            conf->radio_conf.pwr, |  | ||||||
| 		                            conf->radio_conf.mod); |  | ||||||
| 					chThdSleep(TIME_S2I(5)); |  | ||||||
| 				} | 				} | ||||||
| 
 | 
 | ||||||
| 				last_conf_transmission += conf->tel_enc_cycle; | 				last_conf_transmission += conf->tel_enc_cycle; | ||||||
|  |  | ||||||
		Ładowanie…
	
		Reference in New Issue
	
	 CInsights
						CInsights