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 | ||||
| 		}, | ||||
| 
 | ||||
| 		.call				= "VK2GJ-15", | ||||
| 		.call				= "VK2GJ-12", | ||||
| 		.path				= "WIDE2-1", | ||||
| 		.symbol				= SYM_DIGIPEATER, | ||||
| 
 | ||||
|  | @ -63,9 +63,9 @@ const conf_t conf_flash_default = { | |||
| 		}, | ||||
| 		.radio_conf = { | ||||
| 			.pwr			= 0x7F, | ||||
|             .freq           = 144800000, | ||||
|             .freq           = 144000000, | ||||
|             .step           = 12500, | ||||
|             .chan           = 0, | ||||
|             .chan           = 64, | ||||
| 			.mod			= MOD_2FSK, | ||||
| 			.preamble		= 200, | ||||
| 			.redundantTx	= true | ||||
|  | @ -135,7 +135,7 @@ const conf_t conf_flash_default = { | |||
| 			.preamble		= 200 | ||||
| 		}, | ||||
| 
 | ||||
| 		.call				= "VK2GJ-15", | ||||
| 		.call				= "VK2GJ-4", | ||||
| 		.path				= "WIDE2-1", | ||||
| 		.symbol				= SYM_DIGIPEATER | ||||
| 	}, | ||||
|  |  | |||
|  | @ -599,8 +599,6 @@ static bool Si446x_transmit(radio_unit_t radio, | |||
|     // Transmit
 | ||||
|     TRACE_INFO("SI   > Tune Si446x (TX)"); | ||||
|     Si446x_setReadyState(radio); | ||||
|     /* Set band parameters back to normal TX. */ | ||||
|     //Si446x_setBandParameters(radio, freq, step);     // Set frequency
 | ||||
|     Si446x_setPowerLevel(power);        // Set power level
 | ||||
|     Si446x_setTXState(radio, chan, size); | ||||
| 
 | ||||
|  | @ -727,119 +725,14 @@ void Si446x_pauseReceive(radio_unit_t radio) { | |||
| 
 | ||||
| /* ==================================================================== 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 packet_pos;             // Next bit to be sent out
 | ||||
| static uint32_t current_sample_in_baud; // 1 bit = SAMPLES_PER_BAUD samples
 | ||||
| static uint8_t current_byte; | ||||
| //static uint8_t ctone = 0;
 | ||||
| static uint8_t current_byte;*/ | ||||
| 
 | ||||
| /*static bool Si446x_getBitAsNRZI(bool bit) {
 | ||||
|     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;
 | ||||
| /*static uint8_t __attribute__((unused)) Si446x_getUpsampledAFSKbits(uint8_t* buf) {
 | ||||
| 
 | ||||
|     uint8_t b = 0; | ||||
|     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)
 | ||||
|         phase_delta = (current_byte & 1) ? PHASE_DELTA_1200 : PHASE_DELTA_2200; | ||||
|         /* Add delta-phase (bit count within SAMPLES_PER_BAUD). */ | ||||
| 
 | ||||
|         phase += phase_delta; | ||||
|         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; | ||||
| }*/ | ||||
| 
 | ||||
| /*
 | ||||
|  * | ||||
|  */ | ||||
| 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 upsample_rate) { | ||||
|   uint8_t b = 0, i = 0, usr; | ||||
|  | @ -876,7 +803,7 @@ static void __attribute__((unused)) Si446x_upsampleNRZIstream(uint8_t current_by | |||
|     do { | ||||
|       // Toggle tone (1200 <> 2200)
 | ||||
|       phase_delta = (current_byte & 1) ? PHASE_DELTA_1200 : PHASE_DELTA_2200; | ||||
|       /* Add delta-phase (bit count within SAMPLES_PER_BAUD). */ | ||||
| 
 | ||||
|       phase += phase_delta; | ||||
|       b |= ((phase >> 16) & 1) << i;  // Set modulation bit
 | ||||
|       current_byte >>= (usr / upsample_rate) * 8; | ||||
|  | @ -884,13 +811,13 @@ static void __attribute__((unused)) Si446x_upsampleNRZIstream(uint8_t current_by | |||
|     i = 0; | ||||
|     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) { | ||||
|   /* 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) { | ||||
|       /* Nothing encoded. Release packet send object. */ | ||||
| 
 | ||||
| 
 | ||||
|       TRACE_DEBUG("SI   > AFSK TX no NRZI data encoded"); | ||||
|       TRACE_ERROR("SI   > AFSK TX no NRZI data encoded"); | ||||
| 
 | ||||
|       // Free packet object memory
 | ||||
|       pktReleaseSendObject(pp); | ||||
|  | @ -964,12 +890,15 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | |||
|     const uint8_t reset_fifo[] = {0x15, 0x01}; | ||||
|     Si446x_write(reset_fifo, 2); | ||||
| 
 | ||||
|     up_iterator_t upsampler = {0}; | ||||
|     upsampler.phase_delta = PHASE_DELTA_1200; | ||||
| 
 | ||||
|     /* Initialize variables for up sampler. */ | ||||
|     phase_delta = PHASE_DELTA_1200; | ||||
| /*    phase_delta = PHASE_DELTA_1200;
 | ||||
|     phase = 0; | ||||
|     packet_pos = 0; | ||||
|     current_sample_in_baud = 0; | ||||
|     current_byte = 0; | ||||
|     current_byte = 0;*/ | ||||
| 
 | ||||
|     /* Maximum amount of FIFO data when using combined TX+RX (safe size). */ | ||||
|     uint8_t localBuffer[Si446x_FIFO_COMBINED_SIZE]; | ||||
|  | @ -992,7 +921,8 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | |||
| 
 | ||||
|     /* Initial FIFO load. */ | ||||
|     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); | ||||
| 
 | ||||
|     uint8_t lower = 0; | ||||
|  | @ -1018,7 +948,8 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | |||
| 
 | ||||
|         /* Load the FIFO. */ | ||||
|         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
 | ||||
|         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. | ||||
|          * 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)); | ||||
|         if(evt) { | ||||
|           /* Force 446x out of TX state. */ | ||||
|  | @ -1052,9 +983,10 @@ THD_FUNCTION(min_si_fifo_feeder_afsk, arg) { | |||
|       continue; | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     TRACE_INFO("SI   > AFSK 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
 | ||||
|     pktReleaseSendObject(pp); | ||||
|  | @ -1147,8 +1079,7 @@ THD_FUNCTION(min_si_fifo_feeder_fsk, arg) { | |||
|   if(all == 0) { | ||||
|     /* Nothing encoded. Release packet send object. */ | ||||
| 
 | ||||
| 
 | ||||
|     TRACE_DEBUG("SI   > 2FSK TX no NRZI data encoded"); | ||||
|     TRACE_ERROR("SI   > 2FSK TX no NRZI data encoded"); | ||||
| 
 | ||||
|     // Free packet object memory
 | ||||
|     pktReleaseSendObject(pp); | ||||
|  | @ -1220,7 +1151,7 @@ THD_FUNCTION(min_si_fifo_feeder_fsk, arg) { | |||
|        * Time delay allows ~10 bytes to be consumed from 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)); | ||||
|       if(evt) { | ||||
|         /* Force 446x out of TX state. */ | ||||
|  | @ -1245,7 +1176,10 @@ THD_FUNCTION(min_si_fifo_feeder_fsk, arg) { | |||
|     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
 | ||||
|   pktReleaseSendObject(pp); | ||||
|  |  | |||
|  | @ -1,9 +1,9 @@ | |||
| #ifndef __si446x__H__ | ||||
| #define __si446x__H__ | ||||
| 
 | ||||
| //#include "ch.h"
 | ||||
| //#include "hal.h"
 | ||||
| //#include "types.h"
 | ||||
| /*===========================================================================*/ | ||||
| /* Module constants.                                                         */ | ||||
| /*===========================================================================*/ | ||||
| 
 | ||||
| #define Si446x_LOCK_BY_SEMAPHORE    TRUE | ||||
| 
 | ||||
|  | @ -192,12 +192,31 @@ | |||
| #define SI_AFSK_FIFO_MIN_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 { | ||||
|   RADIO_RX, | ||||
|   RADIO_TX, | ||||
|   RADIO_CCA | ||||
| } 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
 | ||||
| 
 | ||||
| int16_t Si446x_getLastTemperature(radio_unit_t radio); | ||||
|  |  | |||
|  | @ -50,10 +50,10 @@ eventmask_t evt = chEvtGetAndClearEvents(EVENT_MASK(1)); | |||
|       TRACE_ERROR("PKT  > Decoder error"); | ||||
|     } | ||||
|     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) { | ||||
|       TRACE_WARN("PKT  > PWM ICU overflow"); | ||||
|       TRACE_DEBUG("PKT  > PWM ICU overflow"); | ||||
|     } | ||||
|     if(flags & EVT_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) { | ||||
|       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_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; | ||||
| 	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) | ||||
| 			{ | ||||
| 				TRACE_ERROR("SSDV > Premature end of file"); | ||||
| 				break; | ||||
| 				return false; | ||||
| 			} | ||||
| 			ssdv_enc_feed(&ssdv, b, r); | ||||
| 		} | ||||
| 
 | ||||
| 		if(c == SSDV_EOI) { | ||||
| 			break; | ||||
| 			return true; | ||||
| 		} else if(c != SSDV_OK) { | ||||
| 			return; | ||||
| 			return false; | ||||
| 		} | ||||
| 
 | ||||
| 		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); | ||||
| 		    /* TODO: Check for failure to get packet (NULL). */ | ||||
| 			packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'I', pkt_base91); | ||||
|             if(packet == NULL) { | ||||
|               TRACE_WARN("SSDV > No free packet objects"); | ||||
|               break; | ||||
|               TRACE_WARN("IMG  > No free packet objects for transmission"); | ||||
|               return false; | ||||
|             } | ||||
|             transmitOnRadio(packet, | ||||
|             if(!transmitOnRadio(packet, | ||||
|                             conf->radio_conf.freq, | ||||
|                             conf->radio_conf.step, | ||||
|                             conf->radio_conf.chan, | ||||
|                             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
 | ||||
|  | @ -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; | ||||
| 	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) { | ||||
| 			packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'I', pkt_base91); | ||||
|             if(packet == NULL) { | ||||
|               TRACE_WARN("SSDV > No free packet objects"); | ||||
|               break; | ||||
|               TRACE_WARN("IMG  > No free packet objects for redundant TX"); | ||||
|               return false; | ||||
|             } | ||||
|             transmitOnRadio(packet, | ||||
|             if(!transmitOnRadio(packet, | ||||
|                             conf->radio_conf.freq, | ||||
|                             conf->radio_conf.step, | ||||
|                             conf->radio_conf.chan, | ||||
|                             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
 | ||||
|  | @ -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) | ||||
| 		{ | ||||
| 			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; | ||||
| 
 | ||||
| 			if(r <= 0) | ||||
| 			{ | ||||
| 				TRACE_ERROR("SSDV > Premature end of file"); | ||||
| 				break; | ||||
| 				return false; | ||||
| 			} | ||||
| 			ssdv_enc_feed(&ssdv, b, r); | ||||
| 		} | ||||
|  | @ -399,35 +408,40 @@ static void transmit_image_packets(const uint8_t *image, uint32_t image_len, thd | |||
| 		if(c == SSDV_EOI) | ||||
| 		{ | ||||
| 			TRACE_INFO("SSDV > ssdv_enc_get_packet said EOI"); | ||||
| 			break; | ||||
| 			return true; | ||||
| 		} else if(c != SSDV_OK) { | ||||
| 			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); | ||||
| 
 | ||||
| 		packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'I', pkt_base91); | ||||
|         if(packet == NULL) { | ||||
|           TRACE_WARN("SSDV > No free packet objects"); | ||||
|           break; | ||||
|           TRACE_WARN("IMG  > No free packet objects for normal TX"); | ||||
|           return false; | ||||
|         } | ||||
|         transmitOnRadio(packet, | ||||
|         if(!transmitOnRadio(packet, | ||||
|                         conf->radio_conf.freq, | ||||
|                         conf->radio_conf.step, | ||||
|                         conf->radio_conf.chan, | ||||
|                         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
 | ||||
| 
 | ||||
| 		// Repeat packets
 | ||||
| 		for(uint8_t i=0; i<16; i++) { | ||||
| 			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)) { | ||||
| 		          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
 | ||||
| 		} | ||||
| 
 | ||||
|  | @ -438,11 +452,11 @@ static void transmit_image_packets(const uint8_t *image, uint32_t image_len, thd | |||
| 		// Handle image rejection flag
 | ||||
| 		if(conf == &conf_sram.img_pri && reject_pri) { // Image rejected
 | ||||
| 			reject_pri = false; | ||||
| 			return; | ||||
| 			return true; | ||||
| 		} | ||||
| 		if(conf == &conf_sram.img_sec && reject_sec) { // Image rejected
 | ||||
| 			reject_sec = false; | ||||
| 			return; | ||||
| 			return true; | ||||
| 		} | ||||
| 
 | ||||
| 		i++; | ||||
|  | @ -599,21 +613,25 @@ THD_FUNCTION(imgThread, arg) | |||
| 
 | ||||
| 					// Find 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) | ||||
| 							break; | ||||
| 					} | ||||
| 					TRACE_DEBUG("IMG  > SOI at byte %d"); | ||||
| 
 | ||||
| 					writeBufferToFile(filename, &buffer[soi], size_sampled-soi); | ||||
| 				} | ||||
| 
 | ||||
| 				// Encode and transmit picture
 | ||||
| 				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
 | ||||
| 				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) | ||||
| { | ||||
| 	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,9 +58,8 @@ THD_FUNCTION(logThread, arg) | |||
| 				// Encode and transmit log packet
 | ||||
| 				packet_t packet = aprs_encode_data_packet(conf->call, conf->path, 'L', pkt_base91); // Encode packet
 | ||||
| 	            if(packet == NULL) { | ||||
| 	              TRACE_WARN("LOG  > No free packet objects"); | ||||
| 	              break; | ||||
| 	            } | ||||
| 	              TRACE_WARN("LOG  > No free packet objects for log transmission"); | ||||
| 	            } else { | ||||
| 				// Transmit packet
 | ||||
|                   transmitOnRadio(packet, | ||||
|                                   conf->radio_conf.freq, | ||||
|  | @ -68,6 +67,7 @@ THD_FUNCTION(logThread, arg) | |||
|                                   conf->radio_conf.chan, | ||||
|                                   conf->radio_conf.pwr, | ||||
|                                   conf->radio_conf.mod); | ||||
| 	            } | ||||
| 			} else { | ||||
| 				TRACE_INFO("LOG  > No log point in memory"); | ||||
| 			} | ||||
|  |  | |||
|  | @ -43,29 +43,29 @@ THD_FUNCTION(posThread, arg) | |||
| 			// Encode/Transmit position packet
 | ||||
| 			packet_t packet = aprs_encode_position(conf->call, conf->path, conf->symbol, dataPoint); | ||||
|             if(packet == NULL) { | ||||
|               TRACE_WARN("POS  > No free packet objects"); | ||||
|               break; | ||||
|             } | ||||
|               TRACE_WARN("POS  > No free packet objects for position transmission"); | ||||
|             } 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)); | ||||
| 
 | ||||
| 			// Encode/Transmit APRSD packet
 | ||||
| 			packet_t pp = aprs_encode_query_answer_aprsd(conf->call, conf->path, conf->call); | ||||
|             if(packet == NULL) { | ||||
|               TRACE_WARN("POS  > No free packet objects"); | ||||
|               break; | ||||
|             } | ||||
|               TRACE_WARN("POS  > No free packet objects for APRSD transmission"); | ||||
|             } else { | ||||
|               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
 | ||||
| 			if(conf->tel_enc_cycle != 0 && last_conf_transmission + conf->tel_enc_cycle < chVTGetSystemTime()) | ||||
|  | @ -79,9 +79,8 @@ THD_FUNCTION(posThread, arg) | |||
| 				{ | ||||
| 					packet = aprs_encode_telemetry_configuration(conf->call, conf->path, type); | ||||
| 		            if(packet == NULL) { | ||||
| 		              TRACE_WARN("POS  > No free packet objects"); | ||||
| 		              break; | ||||
| 		            } | ||||
| 		              TRACE_WARN("POS  > No free packet objects for telemetry transmission"); | ||||
| 		            } else { | ||||
|                       transmitOnRadio(packet, | ||||
|                                       conf->radio_conf.freq, | ||||
|                                       conf->radio_conf.step, | ||||
|  | @ -89,6 +88,7 @@ THD_FUNCTION(posThread, arg) | |||
|                                       conf->radio_conf.pwr, | ||||
|                                       conf->radio_conf.mod); | ||||
|                       chThdSleep(TIME_S2I(5)); | ||||
| 		            } | ||||
| 				} | ||||
| 
 | ||||
| 				last_conf_transmission += conf->tel_enc_cycle; | ||||
|  |  | |||
		Ładowanie…
	
		Reference in New Issue
	
	 CInsights
						CInsights