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,35 +408,40 @@ 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)) {
 | 
				
			||||||
 | 
							          TRACE_ERROR("IMG  > Failed on re-send of image %i", image_id);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
				  packetRepeats[i].n_done = false; // Set done
 | 
									  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,9 +58,8 @@ 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,
 | 
				
			||||||
| 
						 | 
					@ -68,6 +67,7 @@ THD_FUNCTION(logThread, arg)
 | 
				
			||||||
                                  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,
 | 
					              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);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
			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,
 | 
					              transmitOnRadio(pp,
 | 
				
			||||||
                              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);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// 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,9 +79,8 @@ 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,
 | 
					                      transmitOnRadio(packet,
 | 
				
			||||||
                                      conf->radio_conf.freq,
 | 
					                                      conf->radio_conf.freq,
 | 
				
			||||||
                                      conf->radio_conf.step,
 | 
					                                      conf->radio_conf.step,
 | 
				
			||||||
| 
						 | 
					@ -89,6 +88,7 @@ THD_FUNCTION(posThread, arg)
 | 
				
			||||||
                                      conf->radio_conf.pwr,
 | 
					                                      conf->radio_conf.pwr,
 | 
				
			||||||
                                      conf->radio_conf.mod);
 | 
					                                      conf->radio_conf.mod);
 | 
				
			||||||
                      chThdSleep(TIME_S2I(5));
 | 
					                      chThdSleep(TIME_S2I(5));
 | 
				
			||||||
 | 
							            }
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				last_conf_transmission += conf->tel_enc_cycle;
 | 
									last_conf_transmission += conf->tel_enc_cycle;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Ładowanie…
	
		Reference in New Issue