void read_therm(RHTresult *result) { DDRB |= (1 << THERM); // Output mode // Drop it low for 10ms THERM_PORT &= ~(1 << THERM); // Pin low _delay_ms(5); // Wait for the sensor to init cli(); THERM_PORT |= (1 << THERM); // Pin high // We're going to read from now on DDRB &= ~(1 << THERM); // Input mode // Keep some state uint8_t bits[5] = { 0, 0, 0, 0, 0 }; uint8_t state = 0; uint8_t bucket; // Ignore 2-bit pre-amble next_bit(&state); next_bit(&state); // Begin scanning for transitions for(int counter=0; counter < BIT_TRANSITIONS; counter++) { next_bit(&state); bucket = counter >> 3; // bit-shift-divide by 8 bits[bucket] = (bits[bucket] << 1) | state; } result->humidity = (bits[0] << 8) | bits[1]; result->temperature = (bits[2] << 8) | bits[3]; result->checksum = (bits[0] + bits[1] + bits[2] + bits[3] == bits[4]) ? 1 : 0; print_debug(result); sei(); }
int decode_envelope (int number_of_regions, float *decoder_standard_deviation, int *absolute_region_power_index, int esf_adjustment) { int index; int i; int envelope_bits = 0; index = 0; for (i = 0; i < 5; i++) index = (index << 1) | next_bit (); envelope_bits = 5; absolute_region_power_index[0] = index - esf_adjustment; decoder_standard_deviation[0] = standard_deviation[absolute_region_power_index[0] + 24]; for (i = 1; i < number_of_regions; i++) { index = 0; do { index = differential_decoder_tree[i - 1][index][next_bit ()]; envelope_bits++; } while (index > 0); absolute_region_power_index[i] = absolute_region_power_index[i - 1] - index - 12; decoder_standard_deviation[i] = standard_deviation[absolute_region_power_index[i] + 24]; } return envelope_bits; }
/*! * \brief Parse a system header structure. * \param *bitstr The bitstream to use. * \param *system_header A pointer to a system_header structure. * \return 1 if succeed, 0 otherwise. * * From 'ISO/IEC 13818-1' specification: * 2.5.3.5 System header. * Table 2-34 – Program Stream system header */ static int parse_system_header(Bitstream_t *bitstr, PesHeader_t *header, SystemHeader_t *packet) { int retcode = SUCCESS; TRACE_INFO(MPS, BLD_GREEN "parse_system_header()" CLR_RESET " @ %lli", header->offset_start); MARKER_BIT packet->rate_bound = read_bits(bitstr, 22); MARKER_BIT packet->audio_bound = read_bits(bitstr, 6); packet->fixed_flag = read_bits(bitstr, 1); packet->CSPS_flag = read_bits(bitstr, 1); packet->system_audio_lock_flag = read_bits(bitstr, 1); packet->system_video_lock_flag = read_bits(bitstr, 1); MARKER_BIT packet->video_bound = read_bits(bitstr, 5); packet->packet_rate_restriction_flag = read_bits(bitstr, 1); /*unsigned reserved_bits =*/ read_bits(bitstr, 7); // stack it? while (next_bit(bitstr) == 1) { packet->stream_id = read_bits(bitstr, 8); MARKER_BIT MARKER_BIT packet->PSTD_buffer_bound_scale = read_bits(bitstr, 1); packet->PSTD_buffer_size_bound = read_bits(bitstr, 13); } return retcode; }
/* different to next_bit, returns the next > n, not >=. */ static uint32_t next_n(uint32_t subseq, uint32_t n) { uint32_t m; assert(n % subseq_Q == SUBSEQ[subseq].d); m = n / subseq_Q; assert(m >= m_low); assert(m <= m_high); m = next_bit(SUBSEQ[subseq].M,m-m_low+1)+m_low; if (m > m_high) return UINT32_MAX; return m*subseq_Q + SUBSEQ[subseq].d; }
/*! * \brief Parse a pack header structure. * \param *bitstr The bitstream to use. * \param *pack_header A pointer to a pack_header structure. * \param *system_header A pointer to a system_header structure. * \return retcode 1 if succeed, 0 otherwise. * * This parser is based on the 'ISO/IEC 13818-1' international standard, part 1: * 'Transmission multiplexing and synchronization'. */ static int parse_pack_header(Bitstream_t *bitstr, PackHeader_t *pack_header, SystemHeader_t *system_header) { TRACE_INFO(MPS, BLD_GREEN "parse_pack_header()" CLR_RESET " @ %i\n", bitstream_get_absolute_byte_offset(bitstr) - 4); int retcode = SUCCESS; int i = 0; pack_header->pack_start_code = PES_PACK_HEADER; if (read_bits(bitstr, 2) != 1) { TRACE_ERROR(MPS, "wrong 'marker_bit'\n"); return FAILURE; } pack_header->system_clock_reference_base = read_bits(bitstr, 3) << 30; MARKER_BIT pack_header->system_clock_reference_base += read_bits(bitstr, 15) << 15; MARKER_BIT pack_header->system_clock_reference_base += read_bits(bitstr, 15); MARKER_BIT pack_header->system_clock_reference_extension = read_bits(bitstr, 9); MARKER_BIT pack_header->program_mux_rate = read_bits(bitstr, 22); MARKER_BIT MARKER_BIT int reserved = read_bits(bitstr, 5); pack_header->pack_stuffing_length = read_bits(bitstr, 3); // Stuffing for (i = 0; i < pack_header->pack_stuffing_length; i++) { if (read_bits(bitstr, 8) != 0xFF) { TRACE_ERROR(MPS, "Wrong 'stuffing_byte'\n"); return FAILURE; } } // System header if (next_bits(bitstr, 32) == PES_SYSTEM_HEADER) { TRACE_INFO(MPS, BLD_GREEN "parse_system_header()" CLR_RESET " @ %i\n", bitstream_get_absolute_byte_offset(bitstr) - 4); skip_bits(bitstr, 32); system_header->header_length = read_bits(bitstr, 16); MARKER_BIT system_header->rate_bound = read_bits(bitstr, 22); MARKER_BIT system_header->audio_bound = read_bits(bitstr, 6); system_header->fixed_flag = read_bits(bitstr, 1); system_header->CSPS_flag = read_bits(bitstr, 1); system_header->system_audio_lock_flag = read_bits(bitstr, 1); system_header->system_video_lock_flag = read_bits(bitstr, 1); MARKER_BIT system_header->video_bound = read_bits(bitstr, 5); system_header->packet_rate_restriction_flag = read_bits(bitstr, 1); int reserved_bits = read_bits(bitstr, 7); // stack it? while (next_bit(bitstr) == 1) { system_header->stream_id = read_bits(bitstr, 8); MARKER_BIT MARKER_BIT system_header->PSTD_buffer_bound_scale = read_bits(bitstr, 1); system_header->PSTD_buffer_size_bound = read_bits(bitstr, 13); } } else { TRACE_2(MPS, " > No system_header()\n"); } return retcode; }
/*! * \brief Parse a pack header structure. * \param *bitstr The bitstream to use. * \param *pack_header A pointer to a pack_header structure. * \return 1 if succeed, 0 otherwise. * * From 'ISO/IEC 13818-1' specification: * 2.5.3.3 Pack layer of Program Stream. * Table 2-33 – Program Stream pack header */ static int parse_pack_header(Bitstream_t *bitstr, PesHeader_t *header, PackHeader_t *packet) { TRACE_INFO(MPS, BLD_GREEN "parse_pack_header()" CLR_RESET " @ %lli", header->offset_start); int retcode = SUCCESS; // Pack Headers do not have lengh field, rewind 2 bytes rewind_bits(bitstr, 16); if (read_bits(bitstr, 2) != 1) { TRACE_ERROR(MPS, "wrong 'marker_bits'"); return FAILURE; } packet->system_clock_reference_base = read_bits(bitstr, 3) << 30; MARKER_BIT packet->system_clock_reference_base += read_bits(bitstr, 15) << 15; MARKER_BIT packet->system_clock_reference_base += read_bits(bitstr, 15); MARKER_BIT packet->system_clock_reference_extension = read_bits(bitstr, 9); MARKER_BIT packet->program_mux_rate = read_bits(bitstr, 22); MARKER_BIT MARKER_BIT /*unsigned reserved =*/ read_bits(bitstr, 5); packet->pack_stuffing_length = read_bits(bitstr, 3); // Stuffing for (uint8_t i = 0; i < packet->pack_stuffing_length; i++) { if (read_bits(bitstr, 8) != 0xFF) { TRACE_ERROR(MPS, "Wrong 'stuffing_byte'"); return FAILURE; } } // System header // TODO split into its own function? if (next_bits(bitstr, 32) == 0x000001BB) { TRACE_INFO(MPS, BLD_GREEN "parse_system_header()" CLR_RESET " @ %lli", bitstream_get_absolute_byte_offset(bitstr) - 4); skip_bits(bitstr, 48); // start code + size SystemHeader_t system_header; MARKER_BIT system_header.rate_bound = read_bits(bitstr, 22); MARKER_BIT system_header.audio_bound = read_bits(bitstr, 6); system_header.fixed_flag = read_bits(bitstr, 1); system_header.CSPS_flag = read_bits(bitstr, 1); system_header.system_audio_lock_flag = read_bits(bitstr, 1); system_header.system_video_lock_flag = read_bits(bitstr, 1); MARKER_BIT system_header.video_bound = read_bits(bitstr, 5); system_header.packet_rate_restriction_flag = read_bits(bitstr, 1); /*unsigned reserved_bits =*/ read_bits(bitstr, 7); // stack it? while (next_bit(bitstr) == 1) { system_header.stream_id = read_bits(bitstr, 8); MARKER_BIT MARKER_BIT system_header.PSTD_buffer_bound_scale = read_bits(bitstr, 1); system_header.PSTD_buffer_size_bound = read_bits(bitstr, 13); } } else { TRACE_2(MPS, " > No system_header()"); } // Pack header have no length field, so we just have to parse them correctly header->offset_end = bitstream_get_absolute_byte_offset(bitstr); header->payload_length = header->offset_end - header->offset_start - 4; return retcode; }
void init_prime_sieve(uint64_t pmax) { uint_fast32_t *sieve; uint32_t low_prime_limit, max_low_primes, *low_primes, low_prime_count; uint32_t sieve_index, max_prime, max_primes_in_table; uint32_t p, minp, i, composite; assert(primes_in_prime_table == 0); pmax = MAX(MINIMUM_PMAX,pmax); max_prime = sqrt(pmax)+1; low_prime_limit = sqrt(max_prime)+1; max_low_primes = primes_bound(low_prime_limit); low_primes = xmalloc(max_low_primes * sizeof(uint32_t)); low_primes[0] = 3; low_prime_count = 1; for (p = 5; p < low_prime_limit; p += 2) for (minp = 0; minp <= low_prime_count; minp++) { if (low_primes[minp] * low_primes[minp] > p) { low_primes[low_prime_count] = p; low_prime_count++; break; } if (p % low_primes[minp] == 0) break; } assert(low_prime_count <= max_low_primes); /* Divide max_prime by 2 to save memory, also because already know that all even numbers in the sieve are composite. */ sieve = make_bitmap(max_prime/2); fill_bits(sieve,1,max_prime/2-1); for (i = 0; i < low_prime_count; i++) { /* Get the current low prime. Start sieving at 3x that prime since 1x is prime and 2x is divisible by 2. sieve[1]=3, sieve[2]=5, etc. */ composite = 3*low_primes[i]; sieve_index = (composite-1)/2; while (composite < max_prime) { /* composite will always be odd, so add 2*low_primes[i] */ clear_bit(sieve,sieve_index); sieve_index += low_primes[i]; composite += 2*low_primes[i]; } } free(low_primes); max_primes_in_table = primes_bound(max_prime); prime_table = xmalloc(max_primes_in_table * sizeof(uint32_t)); for (i = first_bit(sieve); i < max_prime/2; i = next_bit(sieve,i+1)) { /* Convert the value back to an actual prime. */ prime_table[primes_in_prime_table] = 2*i + 1; primes_in_prime_table++; } assert(primes_in_prime_table <= max_primes_in_table); free(sieve); composite_table = xmalloc(primes_in_prime_table * sizeof(uint64_t)); }
void prime_sieve(uint64_t low_prime, uint64_t high_prime, void(*fun)(uint64_t), uint32_t mod, const uint_fast32_t *map) { uint64_t composite, prime, low_end_of_range, candidate; uint_fast32_t *sieve; uint32_t sieve_index, i, j, k; assert(primes_in_prime_table > 0); if (low_prime <= prime_table[primes_in_prime_table-1]) { /* Skip ahead to low_prime. A binary search would be faster. */ for (i = 0; prime_table[i] < low_prime; i++) ; while (i < primes_in_prime_table) { if (mod == 0) /* Null filter */ for (j = MIN(i+PROGRESS_STEP/3,primes_in_prime_table); i < j; i++) { if (prime_table[i] > high_prime) return; check_events(prime_table[i]); fun(prime_table[i]); } else if (map == NULL) /* Global GFN filter */ for (j = MIN(i+PROGRESS_STEP/3,primes_in_prime_table); i < j; i++) { if (prime_table[i] > high_prime) return; if (((uint_fast32_t)prime_table[i] & mod) == 0) { check_events(prime_table[i]); fun(prime_table[i]); } } else /* Global QR filter */ for (j = MIN(i+PROGRESS_STEP/3,primes_in_prime_table); i < j; i++) { if (prime_table[i] > high_prime) return; if (test_bit(map,prime_table[i]%mod)) { check_events(prime_table[i]); fun(prime_table[i]); } } check_progress(); } low_end_of_range = prime_table[primes_in_prime_table-1]+1; } else /* Set low_end_of_range to the greatest even number <= low_prime */ low_end_of_range = (low_prime | 1) - 1; sieve = make_bitmap(RANGE_SIZE); primes_used_in_range = 0; while (low_end_of_range <= high_prime) { setup_sieve(low_end_of_range); fill_bits(sieve,0,RANGE_SIZE-1); for (i = 0; i < primes_used_in_range; i++) { prime = prime_table[i]; composite = composite_table[i]; sieve_index = (composite - low_end_of_range)/2; while (composite < low_end_of_range + 2*RANGE_SIZE) { clear_bit(sieve,sieve_index); sieve_index += prime; composite += 2*prime; } composite_table[i] = composite; } k = MIN((high_prime-low_end_of_range+1)/2,RANGE_SIZE); i = first_bit(sieve); while (i < k) { if (mod == 0) /* Null filter */ for (j = MIN(i+PROGRESS_STEP,k); i < j; i = next_bit(sieve,i+1)) { candidate = low_end_of_range + 2*i + 1; check_events(candidate); fun(candidate); } else if (map == NULL) /* Global GFN filter */ for (j = MIN(i+PROGRESS_STEP,k); i < j; i = next_bit(sieve,i+1)) { candidate = low_end_of_range + 2*i + 1; if (((uint_fast32_t)candidate & mod) == 0) { check_events(candidate); fun(candidate); } } else /* Global QR filter */ for (j = MIN(i+PROGRESS_STEP,k); i < j; i = next_bit(sieve,i+1)) { candidate = low_end_of_range + 2*i + 1; if (test_bit(map,candidate%mod)) { check_events(candidate); fun(candidate); } } check_progress(); } low_end_of_range += 2*RANGE_SIZE; } free(sieve); }
int main(int argc, char *argv[]) { struct sigaction sigact; struct hardware hw; int ch, min, res; bool raw = false, verbose = true; while ((ch = getopt(argc, argv, "qr")) != -1) { switch (ch) { case 'q' : verbose = false; break; case 'r' : raw = true; break; default: printf("usage: %s [-qr]\n", argv[0]); return EX_USAGE; } } res = read_config_file(ETCDIR"/config.txt"); if (res != 0) { cleanup(); return res; } res = set_mode_live(); if (res != 0) { cleanup(); return res; } hw = get_hardware_parameters(); sigact.sa_handler = do_cleanup; sigemptyset(&sigact.sa_mask); sigact.sa_flags = 0; sigaction(SIGINT, &sigact, (struct sigaction *)NULL); min = -1; for (;;) { struct bitinfo bi; struct GB_result bit; if (raw) { struct timespec slp; slp.tv_sec = 1.0 / hw.freq; slp.tv_nsec = 1e9 / hw.freq; printf("%i", get_pulse()); fflush(stdout); while (nanosleep(&slp, &slp)) ; continue; } bit = get_bit_live(); bi = get_bitinfo(); if (verbose) { if (bi.freq_reset) printf("!"); /* display first bi->t pulses */ for (unsigned long long i = 0; i < bi.t / 8; i++) for (unsigned j = 0; j < 8; j++) printf("%c", (bi.signal[i] & (1 << j)) > 0 ? '+' : '-'); /* * display pulses in the last partially filled item * bi.t is 0-based, hence the <= comparison */ for (unsigned j = 0; j <= (bi.t & 7); j++) printf("%c", (bi.signal[bi.t / 8] & (1 << j)) > 0 ? '+' : '-'); printf("\n"); } if (bit.marker == emark_toolong || bit.marker == emark_late) min++; printf("%i %i %u %llu %llu %llu %i:%i\n", bi.tlow, bi.tlast0, bi.t, bi.bit0, bi.bit20, bi.realfreq, min, get_bitpos()); if (bit.marker == emark_minute) min++; bit = next_bit(); } /* NOTREACHED */ }