/* *************************************************************************** * * Author: Teunis van Beelen * * Copyright (C) 2016 - 2025 Teunis van Beelen * * Email: teuniz@protonmail.com * *************************************************************************** * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * *************************************************************************** * * RS-232 protocol: * * settings in this example: 8N1 * * character value in this example: 'G', 71, 0x47, 0b01000111 * * * * idle start 1 1 1 0 0 0 1 0 stop idle * bit bit * -------------------------+ +-----+-----+-----+ +-----+ +-----+----------------------------- * +12V | | | | | | * | | | | | | * | | | | | | * | | | | | | * -12V +-----+ +-----+-----+-----+ +-----+ * * 0 1 2 3 4 5 6 7 * * LSB MSB * * * default (positive )line RS-232 LSB first (little endian) * * negative: everything inverted, used by microcontrollers, TTL/CMOS level * *************************************************************************** */ void UI_Mainwindow::serial_decoder(struct device_settings *d_parms) { int i, j, threshold[MAX_CHNS], uart_tx_start, uart_tx_data_bit, uart_rx_start, uart_rx_data_bit, uart_parity_bit, uart_parity, spi_data_mosi_bit, spi_data_miso_bit, spi_mosi_bit0_pos=0, spi_miso_bit0_pos=0, spi_clk_new, spi_clk_old, spi_chars=1, spi_timeout, spi_timeout_cntr, stop_bit_error; unsigned int uart_val=0, spi_mosi_val=0, spi_miso_val=0; short s_max, s_min; double uart_sample_per_bit, uart_tx_x_pos, uart_rx_x_pos, bit_per_volt; d_parms->math_decode_uart_tx_nval = 0; d_parms->math_decode_uart_rx_nval = 0; d_parms->math_decode_spi_mosi_nval = 0; d_parms->math_decode_spi_miso_nval = 0; if(d_parms->wavebufsz < 32) return; if(d_parms->math_decode_threshold_auto) { for(j=0; jchandisplay[j]) continue; s_max = -32768; s_min = 32767; for(i=0; iwavebufsz; i++) { if(d_parms->wavebuf[j][i] > s_max) s_max = d_parms->wavebuf[j][i]; if(d_parms->wavebuf[j][i] < s_min) s_min = d_parms->wavebuf[j][i]; } threshold[j] = (s_max + s_min) / 2; } } else { if(d_parms->math_decode_mode == DECODE_MODE_UART) { if(d_parms->math_decode_uart_tx) { if(d_parms->modelserie == 6) { bit_per_volt = 32.0 / d_parms->chanscale[d_parms->math_decode_uart_tx - 1]; threshold[d_parms->math_decode_uart_tx - 1] = (d_parms->math_decode_threshold_uart_tx + d_parms->chanoffset[d_parms->math_decode_uart_tx - 1]) * bit_per_volt; } else { bit_per_volt = 25.0 / d_parms->chanscale[d_parms->math_decode_uart_tx - 1]; threshold[d_parms->math_decode_uart_tx - 1] = (d_parms->math_decode_threshold[d_parms->math_decode_uart_tx - 1] + d_parms->chanoffset[d_parms->math_decode_uart_tx - 1]) * bit_per_volt; } } if(d_parms->math_decode_uart_rx) { if(d_parms->modelserie == 6) { bit_per_volt = 32.0 / d_parms->chanscale[d_parms->math_decode_uart_rx - 1]; threshold[d_parms->math_decode_uart_rx - 1] = (d_parms->math_decode_threshold_uart_rx + d_parms->chanoffset[d_parms->math_decode_uart_rx - 1]) * bit_per_volt; } else { bit_per_volt = 25.0 / d_parms->chanscale[d_parms->math_decode_uart_rx - 1]; threshold[d_parms->math_decode_uart_rx - 1] = (d_parms->math_decode_threshold[d_parms->math_decode_uart_rx - 1] + d_parms->chanoffset[d_parms->math_decode_uart_rx - 1]) * bit_per_volt; } } } else if(d_parms->math_decode_mode == DECODE_MODE_SPI) { if(d_parms->modelserie == 6) { bit_per_volt = 32.0 / d_parms->chanscale[d_parms->math_decode_spi_clk]; threshold[d_parms->math_decode_spi_clk] = (d_parms->math_decode_threshold[2] + d_parms->chanoffset[d_parms->math_decode_spi_clk]) * bit_per_volt; } else { bit_per_volt = 25.0 / d_parms->chanscale[d_parms->math_decode_spi_clk]; threshold[d_parms->math_decode_spi_clk] = (d_parms->math_decode_threshold[d_parms->math_decode_spi_clk] + d_parms->chanoffset[d_parms->math_decode_spi_clk]) * bit_per_volt; } if(d_parms->math_decode_spi_mosi) { if(d_parms->modelserie == 6) { bit_per_volt = 32.0 / d_parms->chanscale[d_parms->math_decode_spi_mosi - 1]; threshold[d_parms->math_decode_spi_mosi - 1] = (d_parms->math_decode_threshold[1] + d_parms->chanoffset[d_parms->math_decode_spi_mosi - 1]) * bit_per_volt; } else { bit_per_volt = 25.0 / d_parms->chanscale[d_parms->math_decode_spi_mosi - 1]; threshold[d_parms->math_decode_spi_mosi - 1] = (d_parms->math_decode_threshold[d_parms->math_decode_spi_mosi - 1] + d_parms->chanoffset[d_parms->math_decode_spi_mosi - 1]) * bit_per_volt; } } if(d_parms->math_decode_spi_miso) { if(d_parms->modelserie == 6) { bit_per_volt = 32.0 / d_parms->chanscale[d_parms->math_decode_spi_miso - 1]; threshold[d_parms->math_decode_spi_miso - 1] = (d_parms->math_decode_threshold[0] + d_parms->chanoffset[d_parms->math_decode_spi_miso -1]) * bit_per_volt; } else { bit_per_volt = 25.0 / d_parms->chanscale[d_parms->math_decode_spi_miso - 1]; threshold[d_parms->math_decode_spi_miso - 1] = (d_parms->math_decode_threshold[d_parms->math_decode_spi_miso - 1] + d_parms->chanoffset[d_parms->math_decode_spi_miso -1]) * bit_per_volt; } } if(d_parms->math_decode_spi_cs) { if(d_parms->modelserie == 6) { bit_per_volt = 32.0 / d_parms->chanscale[d_parms->math_decode_spi_cs - 1]; threshold[d_parms->math_decode_spi_cs - 1] = (d_parms->math_decode_threshold[3] + d_parms->chanoffset[d_parms->math_decode_spi_cs - 1]) * bit_per_volt; } else { bit_per_volt = 25.0 / d_parms->chanscale[d_parms->math_decode_spi_cs - 1]; threshold[d_parms->math_decode_spi_cs - 1] = (d_parms->math_decode_threshold[d_parms->math_decode_spi_cs - 1] + d_parms->chanoffset[d_parms->math_decode_spi_cs - 1]) * bit_per_volt; } } } } if(d_parms->math_decode_mode == DECODE_MODE_UART) { d_parms->math_decode_uart_tx_nval = 0; d_parms->math_decode_uart_rx_nval = 0; if(d_parms->wave_mem_view_enabled) { uart_sample_per_bit = d_parms->samplerate / (double)d_parms->math_decode_uart_baud; } else { if(d_parms->timebasedelayenable) { uart_sample_per_bit = (100.0 / d_parms->timebasedelayscale) / (double)d_parms->math_decode_uart_baud; } else { uart_sample_per_bit = (100.0 / d_parms->timebasescale) / (double)d_parms->math_decode_uart_baud; } } if(uart_sample_per_bit < 3) return; uart_tx_start = 0; uart_tx_data_bit = 0; uart_tx_x_pos = 1; uart_rx_start = 0; uart_rx_data_bit = 0; uart_rx_x_pos = 1; // if(d_parms->modelserie == 6) // { // printf("chanscale: %f\n" // "chanoffset: %f\n" // "math_decode_threshold_uart_tx: %f\n" // "math_decode_uart_tx: %i\n" // "threshold: %i\n" // "uart_sample_per_bit: %f\n" // "wavebufsz: %i\n", // d_parms->chanscale[d_parms->math_decode_uart_tx - 1], // d_parms->chanoffset[d_parms->math_decode_uart_tx - 1], // d_parms->math_decode_threshold_uart_tx, // d_parms->math_decode_uart_tx, // threshold[d_parms->math_decode_uart_tx - 1], // uart_sample_per_bit, // d_parms->wavebufsz); // } // else // { // // printf("chanscale: %f\n" // "chanoffset: %f\n" // "math_decode_threshold: %f\n" // "math_decode_uart_tx: %i\n" // "threshold: %i\n" // "uart_sample_per_bit: %f\n" // "wavebufsz: %i\n", // d_parms->chanscale[d_parms->math_decode_uart_tx - 1], // d_parms->chanoffset[d_parms->math_decode_uart_tx - 1], // d_parms->math_decode_threshold[d_parms->math_decode_uart_tx - 1], // d_parms->math_decode_uart_tx, // threshold[d_parms->math_decode_uart_tx - 1], // uart_sample_per_bit, // d_parms->wavebufsz); // } if(d_parms->math_decode_uart_tx) { if(d_parms->chandisplay[d_parms->math_decode_uart_tx - 1]) // don't try to decode if channel isn't enabled... { for(i=1; iwavebufsz; i++) { if(d_parms->math_decode_uart_tx_nval >= DECODE_MAX_CHARS) { break; } if(!uart_tx_start) { if(d_parms->math_decode_uart_pol) // positive, line level RS-232 { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i-1] >= d_parms->math_decode_threshold_uart_tx) { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] < d_parms->math_decode_threshold_uart_tx) { uart_tx_start = 1; uart_val = 0; uart_tx_x_pos = (uart_sample_per_bit * 1.5) + i; i = uart_tx_x_pos - 1; } } } else // modelserie = 1, 2 or 4 { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i-1] >= threshold[d_parms->math_decode_uart_tx - 1]) { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] < threshold[d_parms->math_decode_uart_tx - 1]) { uart_tx_start = 1; uart_val = 0; uart_tx_x_pos = (uart_sample_per_bit * 1.5) + i; i = uart_tx_x_pos - 1; } } } } else // negative, cpu level TTL/CMOS { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i-1] < d_parms->math_decode_threshold_uart_tx) { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] >= d_parms->math_decode_threshold_uart_tx) { uart_tx_start = 1; uart_val = 0; uart_tx_x_pos = (uart_sample_per_bit * 1.5) + i; i = uart_tx_x_pos - 1; } } } else // modelserie = 1, 2 or 4 { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i-1] < threshold[d_parms->math_decode_uart_tx - 1]) { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] >= threshold[d_parms->math_decode_uart_tx - 1]) { uart_tx_start = 1; uart_val = 0; uart_tx_x_pos = (uart_sample_per_bit * 1.5) + i; i = uart_tx_x_pos - 1; } } } } } else // uart_rx_start != 0 { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] >= d_parms->math_decode_threshold_uart_tx) { uart_val += (1 << uart_tx_data_bit); } } else // modelserie = 1, 2 or 4 { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] >= threshold[d_parms->math_decode_uart_tx - 1]) { uart_val += (1 << uart_tx_data_bit); } } if(++uart_tx_data_bit == d_parms->math_decode_uart_width) { if((d_parms->math_decode_uart_end) && (d_parms->math_decode_format != 4)) // big endian? { uart_val = reverse_bitorder_8(uart_val); uart_val >>= (8 - uart_tx_data_bit); } if(!d_parms->math_decode_uart_pol) // positive, line level RS-232 or negative, cpu level TTL/CMOS? { uart_val = ~uart_val; uart_val &= (0xff >> (8 - uart_tx_data_bit)); } d_parms->math_decode_uart_tx_val[d_parms->math_decode_uart_tx_nval] = uart_val; d_parms->math_decode_uart_tx_val_pos[d_parms->math_decode_uart_tx_nval] = i - (uart_tx_data_bit * uart_sample_per_bit) + (0.5 * uart_sample_per_bit); uart_tx_data_bit = 0; uart_tx_start = 0; d_parms->math_decode_uart_tx_err[d_parms->math_decode_uart_tx_nval] = 0; if(d_parms->math_decode_uart_par) { uart_tx_x_pos += uart_sample_per_bit; i = uart_tx_x_pos; if(i < d_parms->wavebufsz) { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] >= d_parms->math_decode_threshold_uart_tx) { if(d_parms->math_decode_uart_pol) { uart_parity_bit = 1; } else { uart_parity_bit = 0; } } else { if(d_parms->math_decode_uart_pol) { uart_parity_bit = 0; } else { uart_parity_bit = 1; } } } else { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] >= threshold[d_parms->math_decode_uart_tx - 1]) { if(d_parms->math_decode_uart_pol) { uart_parity_bit = 1; } else { uart_parity_bit = 0; } } else { if(d_parms->math_decode_uart_pol) { uart_parity_bit = 0; } else { uart_parity_bit = 1; } } } for(j=0, uart_parity=0; jmath_decode_uart_width; j++) { uart_parity += ((uart_val >> j) & 1); } if(d_parms->math_decode_uart_par & 1) { uart_parity++; } if((uart_parity & 1) != uart_parity_bit) { d_parms->math_decode_uart_tx_err[d_parms->math_decode_uart_tx_nval] = 1; } } } uart_tx_x_pos += uart_sample_per_bit; i = uart_tx_x_pos; stop_bit_error = 0; // check stop bit if(i < d_parms->wavebufsz) { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] >= d_parms->math_decode_threshold_uart_tx) { stop_bit_error = 1; } } else // modelserie = 1, 2 or 4 { if(d_parms->wavebuf[d_parms->math_decode_uart_tx - 1][i] >= threshold[d_parms->math_decode_uart_tx - 1]) { stop_bit_error = 1; } } if(d_parms->math_decode_uart_pol) { if(stop_bit_error) { stop_bit_error = 0; } else { stop_bit_error = 1; } } if(stop_bit_error) { d_parms->math_decode_uart_tx_err[d_parms->math_decode_uart_tx_nval] = 1; } } if(d_parms->math_decode_uart_stop == 1) { uart_tx_x_pos += uart_sample_per_bit / 2; } else if(d_parms->math_decode_uart_stop == 2) { uart_tx_x_pos += uart_sample_per_bit; } i = uart_tx_x_pos - 1; d_parms->math_decode_uart_tx_nval++; } else { uart_tx_x_pos += uart_sample_per_bit; i = uart_tx_x_pos - 1; } } } } } if(d_parms->math_decode_uart_rx) { if(d_parms->chandisplay[d_parms->math_decode_uart_rx - 1]) // don't try to decode if channel isn't enabled... { for(i=1; iwavebufsz; i++) { if(d_parms->math_decode_uart_rx_nval >= DECODE_MAX_CHARS) { break; } if(!uart_rx_start) { if(d_parms->math_decode_uart_pol) // positive, line level RS-232 { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i-1] >= d_parms->math_decode_threshold_uart_rx) { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] < d_parms->math_decode_threshold_uart_rx) { uart_rx_start = 1; uart_val = 0; uart_rx_x_pos = (uart_sample_per_bit * 1.5) + i; i = uart_rx_x_pos - 1; } } } else // modelserie = 1, 2 or 4 { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i-1] >= threshold[d_parms->math_decode_uart_rx - 1]) { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] < threshold[d_parms->math_decode_uart_rx - 1]) { uart_rx_start = 1; uart_val = 0; uart_rx_x_pos = (uart_sample_per_bit * 1.5) + i; i = uart_rx_x_pos - 1; } } } } else // negative, cpu level TTL/CMOS { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i-1] < d_parms->math_decode_threshold_uart_rx) { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] >= d_parms->math_decode_threshold_uart_rx) { uart_rx_start = 1; uart_val = 0; uart_rx_x_pos = (uart_sample_per_bit * 1.5) + i; i = uart_rx_x_pos - 1; } } } else // modelserie = 1, 2 or 4 { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i-1] < threshold[d_parms->math_decode_uart_rx - 1]) { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] >= threshold[d_parms->math_decode_uart_rx - 1]) { uart_rx_start = 1; uart_val = 0; uart_rx_x_pos = (uart_sample_per_bit * 1.5) + i; i = uart_rx_x_pos - 1; } } } } } else // uart_rx_start != 0 { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] >= d_parms->math_decode_threshold_uart_rx) { uart_val += (1 << uart_rx_data_bit); } } else // modelserie = 1, 2 or 4 { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] >= threshold[d_parms->math_decode_uart_rx - 1]) { uart_val += (1 << uart_rx_data_bit); } } if(++uart_rx_data_bit == d_parms->math_decode_uart_width) { if((d_parms->math_decode_uart_end) && (d_parms->math_decode_format != 4)) // big endian? { uart_val = reverse_bitorder_8(uart_val); uart_val >>= (8 - uart_rx_data_bit); } if(!d_parms->math_decode_uart_pol) // positive, line level RS-232 or negative, cpu level TTL/CMOS? { uart_val = ~uart_val; uart_val &= (0xff >> (8 - uart_rx_data_bit)); } d_parms->math_decode_uart_rx_val[d_parms->math_decode_uart_rx_nval] = uart_val; d_parms->math_decode_uart_rx_val_pos[d_parms->math_decode_uart_rx_nval] = i - (uart_rx_data_bit * uart_sample_per_bit) + (0.5 * uart_sample_per_bit); uart_rx_data_bit = 0; uart_rx_start = 0; d_parms->math_decode_uart_rx_err[d_parms->math_decode_uart_rx_nval] = 0; if(d_parms->math_decode_uart_par) { uart_rx_x_pos += uart_sample_per_bit; i = uart_rx_x_pos; if(i < d_parms->wavebufsz) { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] >= d_parms->math_decode_threshold_uart_rx) { if(d_parms->math_decode_uart_pol) { uart_parity_bit = 1; } else { uart_parity_bit = 0; } } else { if(d_parms->math_decode_uart_pol) { uart_parity_bit = 0; } else { uart_parity_bit = 1; } } } else { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] >= threshold[d_parms->math_decode_uart_rx - 1]) { if(d_parms->math_decode_uart_pol) { uart_parity_bit = 1; } else { uart_parity_bit = 0; } } else { if(d_parms->math_decode_uart_pol) { uart_parity_bit = 0; } else { uart_parity_bit = 1; } } } for(j=0, uart_parity=0; jmath_decode_uart_width; j++) { uart_parity += ((uart_val >> j) & 1); } if(d_parms->math_decode_uart_par & 1) { uart_parity++; } if((uart_parity & 1) != uart_parity_bit) { d_parms->math_decode_uart_rx_err[d_parms->math_decode_uart_rx_nval] = 1; } } } uart_rx_x_pos += uart_sample_per_bit; i = uart_rx_x_pos; stop_bit_error = 0; // check stop bit if(i < d_parms->wavebufsz) { if(d_parms->modelserie == 6) { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] >= d_parms->math_decode_threshold_uart_rx) { stop_bit_error = 1; } } else // modelserie = 1, 2 or 4 { if(d_parms->wavebuf[d_parms->math_decode_uart_rx - 1][i] >= threshold[d_parms->math_decode_uart_rx - 1]) { stop_bit_error = 1; } } if(d_parms->math_decode_uart_pol) { if(stop_bit_error) { stop_bit_error = 0; } else { stop_bit_error = 1; } } if(stop_bit_error) { d_parms->math_decode_uart_rx_err[d_parms->math_decode_uart_rx_nval] = 1; } } if(d_parms->math_decode_uart_stop == 1) { uart_rx_x_pos += uart_sample_per_bit / 2; } else if(d_parms->math_decode_uart_stop == 2) { uart_rx_x_pos += uart_sample_per_bit; } i = uart_rx_x_pos - 1; d_parms->math_decode_uart_rx_nval++; } else { uart_rx_x_pos += uart_sample_per_bit; i = uart_rx_x_pos - 1; } } } } } } if(d_parms->math_decode_mode == DECODE_MODE_SPI) { d_parms->math_decode_spi_mosi_nval = 0; d_parms->math_decode_spi_miso_nval = 0; spi_data_mosi_bit = 0; spi_data_miso_bit = 0; spi_mosi_val = 0; spi_miso_val = 0; spi_timeout_cntr = 0; if(d_parms->math_decode_spi_width > 24) { spi_chars = 4; } else if(d_parms->math_decode_spi_width > 16) { spi_chars = 3; } else if(d_parms->math_decode_spi_width > 8) { spi_chars = 2; } else { spi_chars = 1; } if(d_parms->math_decode_spi_edge) // sample at rising edge of spi clock? { spi_clk_old = 1; } else { spi_clk_old = 0; } if(!d_parms->chandisplay[d_parms->math_decode_spi_clk]) // without a clock we can't do much... { goto SPI_DECODE_OUT; } if(d_parms->math_decode_spi_mode) // use chip select line? { if(d_parms->math_decode_spi_cs) // is chip select channel selected? { if(!d_parms->chandisplay[d_parms->math_decode_spi_cs]) // is selected channel for CS enabled? { goto SPI_DECODE_OUT; } } else { goto SPI_DECODE_OUT; } } else // use timeout to detect start of frame { if(d_parms->timebasedelayenable) { spi_timeout = d_parms->math_decode_spi_timeout / (d_parms->timebasedelayscale / 100.0); } else { spi_timeout = d_parms->math_decode_spi_timeout / (d_parms->timebasescale / 100.0); } } for(i=0; iwavebufsz; i++) { if(d_parms->math_decode_spi_mosi_nval >= DECODE_MAX_CHARS) { break; } if(d_parms->math_decode_spi_mode) // use chip select line? { if(d_parms->math_decode_spi_select) // use positive chip select? { if(d_parms->wavebuf[d_parms->math_decode_spi_cs - 1][i] < threshold[d_parms->math_decode_spi_cs - 1]) { spi_data_mosi_bit = 0; spi_data_miso_bit = 0; spi_mosi_val = 0; spi_miso_val = 0; continue; // chip select is not active } } else // use negative chip select? { if(d_parms->wavebuf[d_parms->math_decode_spi_cs - 1][1] >= threshold[d_parms->math_decode_spi_cs - 1]) { spi_data_mosi_bit = 0; spi_data_miso_bit = 0; spi_mosi_val = 0; spi_miso_val = 0; continue; // chip select is not active } } } else // use timeout to detect start of frame { if(spi_timeout_cntr > spi_timeout) { spi_data_mosi_bit = 0; spi_data_miso_bit = 0; spi_mosi_val = 0; spi_miso_val = 0; } else { spi_timeout_cntr++; } } if(d_parms->wavebuf[d_parms->math_decode_spi_clk][i] >= threshold[d_parms->math_decode_spi_clk]) { spi_clk_new = 1; } else { spi_clk_new = 0; } if(spi_clk_old == spi_clk_new) { continue; // no clock change } if(d_parms->math_decode_spi_edge != spi_clk_new) // wrong clock edge? { spi_clk_old = spi_clk_new; continue; } spi_timeout_cntr = 0; spi_clk_old = spi_clk_new; if(d_parms->math_decode_spi_mosi) { if(d_parms->chandisplay[d_parms->math_decode_spi_mosi - 1]) // don't try to decode if channel isn't enabled... { if(d_parms->wavebuf[d_parms->math_decode_spi_mosi - 1][i] >= threshold[d_parms->math_decode_spi_mosi - 1]) { spi_mosi_val += (1 << spi_data_mosi_bit); } if(!spi_data_mosi_bit) spi_mosi_bit0_pos = i; if(++spi_data_mosi_bit == d_parms->math_decode_spi_width) { if((d_parms->math_decode_spi_end) && (d_parms->math_decode_format != 4)) // big endian? { spi_mosi_val = reverse_bitorder_32(spi_mosi_val); spi_mosi_val >>= (32 - spi_data_mosi_bit); } if(!d_parms->math_decode_spi_pol) { spi_mosi_val = ~spi_mosi_val; switch(spi_chars) { case 1: spi_mosi_val &= 0xff; break; case 2: spi_mosi_val &= 0xffff; break; case 3: spi_mosi_val &= 0xffffff; break; } } d_parms->math_decode_spi_mosi_val[d_parms->math_decode_spi_mosi_nval] = spi_mosi_val; d_parms->math_decode_spi_mosi_val_pos[d_parms->math_decode_spi_mosi_nval] = spi_mosi_bit0_pos; d_parms->math_decode_spi_mosi_val_pos_end[d_parms->math_decode_spi_mosi_nval++] = i; spi_data_mosi_bit = 0; spi_mosi_val = 0; } } } if(d_parms->math_decode_spi_miso) { if(d_parms->chandisplay[d_parms->math_decode_spi_miso - 1]) // don't try to decode if channel isn't enabled... { if(d_parms->wavebuf[d_parms->math_decode_spi_miso - 1][i] >= threshold[d_parms->math_decode_spi_miso - 1]) { spi_miso_val += (1 << spi_data_miso_bit); } if(!spi_data_miso_bit) spi_miso_bit0_pos = i; if(++spi_data_miso_bit == d_parms->math_decode_spi_width) { if((d_parms->math_decode_spi_end) && (d_parms->math_decode_format != 4)) // big endian? { spi_miso_val = reverse_bitorder_32(spi_miso_val); spi_miso_val >>= (32 - spi_data_miso_bit); } if(!d_parms->math_decode_spi_pol) { spi_miso_val = ~spi_miso_val; } d_parms->math_decode_spi_miso_val[d_parms->math_decode_spi_miso_nval] = spi_miso_val; d_parms->math_decode_spi_miso_val_pos[d_parms->math_decode_spi_miso_nval] = spi_miso_bit0_pos; d_parms->math_decode_spi_miso_val_pos_end[d_parms->math_decode_spi_miso_nval++] = i; spi_data_miso_bit = 0; spi_miso_val = 0; } } } } SPI_DECODE_OUT: i = 0; // FIXME } } inline unsigned char UI_Mainwindow::reverse_bitorder_8(unsigned char byte) { byte = (byte & 0xf0) >> 4 | (byte & 0x0f) << 4; byte = (byte & 0xcc) >> 2 | (byte & 0x33) << 2; byte = (byte & 0xaa) >> 1 | (byte & 0x55) << 1; return byte; } inline unsigned int UI_Mainwindow::reverse_bitorder_32(unsigned int val) { val = (val & 0xffff0000) >> 16 | (val & 0x0000ffff) << 16; val = (val & 0xff00ff00) >> 8 | (val & 0x00ff00ff) << 8; val = (val & 0xf0f0f0f0) >> 4 | (val & 0x0f0f0f0f) << 4; val = (val & 0xcccccccc) >> 2 | (val & 0x33333333) << 2; val = (val & 0xaaaaaaaa) >> 1 | (val & 0x55555555) << 1; return val; }