Marker search and SD initialization

Removed_REF_marker
erikkaashoek 5 years ago
parent 6b730a9bea
commit de3d0f66a1

@ -582,7 +582,7 @@ void ili9341_bulk(int x, int y, int w, int h)
#ifdef __REMOTE_DESKTOP__ #ifdef __REMOTE_DESKTOP__
if (auto_capture) { if (auto_capture) {
send_region("bulk", x, y, w, h); send_region("bulk", x, y, w, h);
send_buffer((uint8_t *)buffer, w * h * sizeof(pixel_t)); send_buffer((uint8_t *)spi_buffer, w *h * sizeof(pixel_t));
} }
#endif #endif
} }
@ -1459,7 +1459,7 @@ static uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg) {
} }
// Power on SD // Power on SD
static void SD_PowerOn(void) { void SD_PowerOn(void) {
uint16_t n; uint16_t n;
SD_Select_SPI(SD_INIT_SPI_SPEED); SD_Select_SPI(SD_INIT_SPI_SPEED);

@ -188,7 +188,7 @@ static THD_FUNCTION(Thread1, arg)
redraw_request |= REDRAW_CELLS | REDRAW_BATTERY; redraw_request |= REDRAW_CELLS | REDRAW_BATTERY;
// STOP_PROFILE; // STOP_PROFILE;
if (uistat.marker_tracking) { if (uistat.marker_tracking) {
int i = marker_search_max(); int i = marker_search_max(active_marker);
if (i != -1 && active_marker != MARKER_INVALID) { if (i != -1 && active_marker != MARKER_INVALID) {
markers[active_marker].index = i; markers[active_marker].index = i;
markers[active_marker].frequency = frequencies[i]; markers[active_marker].frequency = frequencies[i];
@ -1397,7 +1397,7 @@ VNA_SHELL_FUNCTION(cmd_marker)
case 0: markers[t].enabled = TRUE; active_marker = t; return; case 0: markers[t].enabled = TRUE; active_marker = t; return;
case 1: markers[t].enabled =FALSE; if (active_marker == t) active_marker = MARKER_INVALID; return; case 1: markers[t].enabled =FALSE; if (active_marker == t) active_marker = MARKER_INVALID; return;
case 2: markers[t].enabled = TRUE; active_marker = t; case 2: markers[t].enabled = TRUE; active_marker = t;
int i = marker_search_max(); int i = marker_search_max(active_marker);
if (i == -1) i = 0; if (i == -1) i = 0;
markers[active_marker].index = i; markers[active_marker].index = i;
markers[active_marker].frequency = frequencies[i]; markers[active_marker].frequency = frequencies[i];
@ -2277,6 +2277,10 @@ int main(void)
dacPutChannelX(&DACD2, 0, config.dac_value); dacPutChannelX(&DACD2, 0, config.dac_value);
#endif #endif
dacStart(&DACD1, &dac1cfg1); dacStart(&DACD1, &dac1cfg1);
#ifdef TINYSA4
disk_initialize(0);
// SD_PowerOn();
#endif
chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO-1, Thread1, NULL); chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO-1, Thread1, NULL);

@ -801,11 +801,11 @@ void draw_cal_status(void);
int distance_to_index(int8_t t, uint16_t idx, int16_t x, int16_t y); int distance_to_index(int8_t t, uint16_t idx, int16_t x, int16_t y);
int search_nearest_index(int x, int y, int t); int search_nearest_index(int x, int y, int t);
int marker_search_max(void); int marker_search_max(int m);
int marker_search_left_max(int from); int marker_search_left_max(int m);
int marker_search_right_max(int from); int marker_search_right_max(int m);
int marker_search_left_min(int from); int marker_search_left_min(int m);
int marker_search_right_min(int from); int marker_search_right_min(int m);
// _request flag for update screen // _request flag for update screen
#define REDRAW_CELLS (1<<0) #define REDRAW_CELLS (1<<0)

@ -286,12 +286,13 @@ draw_on_strut(int v0, int d, int color)
/* /*
* calculate log10f(abs(gamma)) * calculate log10f(abs(gamma))
*/ */
#if 0
float float
index_to_value(const int i) index_to_value(const int i)
{ {
return(value(actual_t[i])); return(value(actual_t[i]));
} }
#endif
float float
marker_to_value(const int i) marker_to_value(const int i)
{ {
@ -1422,9 +1423,15 @@ static void trace_print_value_string( // Only used at one place
float coeff[POINTS_COUNT]) float coeff[POINTS_COUNT])
{ {
(void) bold; (void) bold;
int ref_marker=-1;
for (int i = 0; i < MARKER_COUNT; i++) {
if (markers[i].enabled && markers[i].mtype & M_REFERENCE && ((markers[i].mtype & M_STORED) == (markers[mi].mtype & M_STORED))) {
ref_marker = i;
}
}
int mtype = markers[mi].mtype; int mtype = markers[mi].mtype;
int idx = markers[mi].index; int idx = markers[mi].index;
float v = value(coeff[idx]); float v = marker_to_value(mi);
char buf2[24]; char buf2[24];
char *ptr2 = buf2; char *ptr2 = buf2;
// Prepare marker type string // Prepare marker type string
@ -1452,14 +1459,14 @@ static void trace_print_value_string( // Only used at one place
freq_t freq = markers[mi].frequency; freq_t freq = markers[mi].frequency;
int unit_index = setting.unit; int unit_index = setting.unit;
// Setup delta values // Setup delta values
if (mtype & M_DELTA) { if (mtype & M_DELTA && ref_marker>=0) {
*ptr2++ = S_DELTA[0]; *ptr2++ = S_DELTA[0];
unit_index+= 5; unit_index+= 5;
freq_t ref_freq = markers[ri].frequency; freq_t ref_freq = markers[ref_marker].frequency;
int ridx = markers[ri].index; int ridx = markers[ref_marker].index;
if (ridx > idx) {freq = ref_freq - freq; idx = ridx - idx; *ptr2++ = '-';} if (ridx > idx) {freq = ref_freq - freq; idx = ridx - idx; *ptr2++ = '-';}
else {freq = freq - ref_freq; idx = idx - ridx; *ptr2++ = '+';} else {freq = freq - ref_freq; idx = idx - ridx; *ptr2++ = '+';}
v-= marker_to_value(ri); v-= marker_to_value(ref_marker);
} else } else
freq += (setting.frequency_offset - FREQUENCY_SHIFT); freq += (setting.frequency_offset - FREQUENCY_SHIFT);
@ -1784,13 +1791,46 @@ redraw_frame(void)
draw_cal_status(); draw_cal_status();
} }
int display_test(void) int display_test_pattern(pixel_t p)
{ {
// write and read display, return false on fail. // write and read display, return false on fail.
for (int h = 0; h < LCD_HEIGHT; h++) { for (int h = 0; h < LCD_HEIGHT; h++) {
// write test pattern to LCD // write test pattern to LCD
for (int w = 0; w < LCD_WIDTH; w++) for (int w = 0; w < LCD_WIDTH; w++)
spi_buffer[w] = w*h; spi_buffer[w] = p;
ili9341_bulk(0, h, LCD_WIDTH, 1);
// Cleanup buffer
memset(spi_buffer, 0, LCD_WIDTH * sizeof(pixel_t));
// try read data
ili9341_read_memory(0, h, LCD_WIDTH, 1, spi_buffer);
// Check pattern from data for (volatile int w = 0; w < LCD_WIDTH; w++)
for (int w = 0; w < LCD_WIDTH; w++)
if (spi_buffer[w] != p)
return false;
}
return true;
}
int display_test(void)
{
#if 0
if (!display_test_pattern(RGB565(0,0,0)))
return false;
if (!display_test_pattern(RGB565(255,255,255)))
return false;
if (!display_test_pattern(RGB565(255,0,0)))
return false;
if (!display_test_pattern(RGB565(0,255,0)))
return false;
if (!display_test_pattern(RGB565(0,0,255)))
return false;
if (!display_test_pattern(0xd200))
return false;
#endif
for (int h = 0; h < LCD_HEIGHT; h++) {
// write test pattern to LCD
for (int w = 0; w < LCD_WIDTH; w++)
spi_buffer[w] = h*w; //(h<<8)+w;
ili9341_bulk(0, h, LCD_WIDTH, 1); ili9341_bulk(0, h, LCD_WIDTH, 1);
// Cleanup buffer // Cleanup buffer
memset(spi_buffer, 0, LCD_WIDTH * sizeof(pixel_t)); memset(spi_buffer, 0, LCD_WIDTH * sizeof(pixel_t));
@ -1798,7 +1838,7 @@ int display_test(void)
ili9341_read_memory(0, h, LCD_WIDTH, 1, spi_buffer); ili9341_read_memory(0, h, LCD_WIDTH, 1, spi_buffer);
// Check pattern from data // Check pattern from data
for (volatile int w = 0; w < LCD_WIDTH; w++) for (volatile int w = 0; w < LCD_WIDTH; w++)
if (spi_buffer[w] != (pixel_t)(w*h)) // WARNING: Comparison fails without typecast of (w*h) to pixel_t if (spi_buffer[w] != (pixel_t) (h*w) )// ((h<<8)+w)) // WARNING: Comparison fails without typecast of (w*h) to pixel_t
return false; return false;
} }
return true; return true;

@ -431,7 +431,6 @@ VNA_SHELL_FUNCTION(cmd_ultra_start)
} }
} }
VNA_SHELL_FUNCTION(cmd_if1) VNA_SHELL_FUNCTION(cmd_if1)
{ {
if (argc != 1) { if (argc != 1) {

@ -2181,6 +2181,11 @@ int index_of_frequency(freq_t f) // Search which index in the frequency tab
void interpolate_maximum(int m) void interpolate_maximum(int m)
{ {
float *ref_marker_levels;
if (markers[m].mtype & M_STORED )
ref_marker_levels = stored_t;
else
ref_marker_levels = actual_t;
const int idx = markers[m].index; const int idx = markers[m].index;
markers[m].frequency = frequencies[idx]; markers[m].frequency = frequencies[idx];
if (idx > 0 && idx < sweep_points-1) if (idx > 0 && idx < sweep_points-1)
@ -2191,9 +2196,9 @@ void interpolate_maximum(int m)
#else #else
#define INTER_TYPE float #define INTER_TYPE float
#endif #endif
const INTER_TYPE y1 = actual_t[idx - 1]; const INTER_TYPE y1 = ref_marker_levels[idx - 1];
const INTER_TYPE y2 = actual_t[idx + 0]; const INTER_TYPE y2 = ref_marker_levels[idx + 0];
const INTER_TYPE y3 = actual_t[idx + 1]; const INTER_TYPE y3 = ref_marker_levels[idx + 1];
const INTER_TYPE d = abs(delta_Hz) * 0.5 * (y1 - y3) / ((y1 - (2 * y2) + y3) + 1e-12); const INTER_TYPE d = abs(delta_Hz) * 0.5 * (y1 - y3) / ((y1 - (2 * y2) + y3) + 1e-12);
//const float bin = (float)idx + d; //const float bin = (float)idx + d;
markers[m].frequency += d; markers[m].frequency += d;
@ -2204,6 +2209,12 @@ void interpolate_maximum(int m)
int int
search_maximum(int m, freq_t center, int span) search_maximum(int m, freq_t center, int span)
{ {
float *ref_marker_levels;
if (markers[m].mtype & M_STORED )
ref_marker_levels = stored_t;
else
ref_marker_levels = actual_t;
#ifdef TINYSA4 #ifdef TINYSA4
int center_index = index_of_frequency(center); int center_index = index_of_frequency(center);
#else #else
@ -2221,29 +2232,29 @@ search_maximum(int m, freq_t center, int span)
if (to > setting._sweep_points-1) if (to > setting._sweep_points-1)
to = setting._sweep_points-1; to = setting._sweep_points-1;
temppeakIndex = 0; temppeakIndex = 0;
temppeakLevel = actual_t[from]; temppeakLevel = ref_marker_levels[from];
max_index[cur_max] = from; max_index[cur_max] = from;
int downslope = true; int downslope = true;
for (int i = from; i <= to; i++) { for (int i = from; i <= to; i++) {
if (downslope) { if (downslope) {
if (temppeakLevel > actual_t[i]) { // Follow down if (temppeakLevel > ref_marker_levels[i]) { // Follow down
temppeakIndex = i; // Latest minimum temppeakIndex = i; // Latest minimum
temppeakLevel = actual_t[i]; temppeakLevel = ref_marker_levels[i];
} else if (temppeakLevel + setting.noise < actual_t[i]) { // Local minimum found } else if (temppeakLevel + setting.noise < ref_marker_levels[i]) { // Local minimum found
temppeakIndex = i; // This is now the latest maximum temppeakIndex = i; // This is now the latest maximum
temppeakLevel = actual_t[i]; temppeakLevel = ref_marker_levels[i];
downslope = false; downslope = false;
} }
} else { } else {
if (temppeakLevel < actual_t[i]) { // Follow up if (temppeakLevel < ref_marker_levels[i]) { // Follow up
temppeakIndex = i; temppeakIndex = i;
temppeakLevel = actual_t[i]; temppeakLevel = ref_marker_levels[i];
} else if (temppeakLevel - setting.noise > actual_t[i]) { // Local max found } else if (temppeakLevel - setting.noise > ref_marker_levels[i]) { // Local max found
found = true; found = true;
int j = 0; // Insertion index int j = 0; // Insertion index
while (j<cur_max && actual_t[max_index[j]] >= temppeakLevel) // Find where to insert while (j<cur_max && ref_marker_levels[max_index[j]] >= temppeakLevel) // Find where to insert
j++; j++;
if (j < MAX_MAX) { // Larger then one of the previous found if (j < MAX_MAX) { // Larger then one of the previous found
int k = MAX_MAX-1; int k = MAX_MAX-1;
@ -2253,14 +2264,14 @@ search_maximum(int m, freq_t center, int span)
k--; k--;
} }
max_index[j] = temppeakIndex; max_index[j] = temppeakIndex;
// maxlevel_index[j] = actual_t[temppeakIndex]; // Only for debugging // maxlevel_index[j] = ref_marker_levels[temppeakIndex]; // Only for debugging
if (cur_max < MAX_MAX) { if (cur_max < MAX_MAX) {
cur_max++; cur_max++;
} }
//STOP_PROFILE //STOP_PROFILE
} }
temppeakIndex = i; // Latest minimum temppeakIndex = i; // Latest minimum
temppeakLevel = actual_t[i]; temppeakLevel = ref_marker_levels[i];
downslope = true; downslope = true;
} }
@ -2268,9 +2279,9 @@ search_maximum(int m, freq_t center, int span)
} }
if (false && !found) { if (false && !found) {
temppeakIndex = from; temppeakIndex = from;
temppeakLevel = actual_t[from]; temppeakLevel = ref_marker_levels[from];
for (int i = from+1; i <= to; i++) { for (int i = from+1; i <= to; i++) {
if (temppeakLevel<actual_t[i]) if (temppeakLevel<ref_marker_levels[i])
temppeakIndex = i; temppeakIndex = i;
} }
found = true; found = true;
@ -4433,10 +4444,10 @@ static volatile int dummy;
markers[1].index = markers[0].index + (setting.mode == M_LOW ? WIDTH/4 : -WIDTH/4); // Position phase noise marker at requested offset markers[1].index = markers[0].index + (setting.mode == M_LOW ? WIDTH/4 : -WIDTH/4); // Position phase noise marker at requested offset
markers[1].frequency = frequencies[markers[1].index]; markers[1].frequency = frequencies[markers[1].index];
} else if (setting.measurement == M_STOP_BAND && markers[0].index > 10) { // -------------Stop band measurement } else if (setting.measurement == M_STOP_BAND && markers[0].index > 10) { // -------------Stop band measurement
markers[1].index = marker_search_left_min(markers[0].index); markers[1].index = marker_search_left_min(0);
if (markers[1].index < 0) markers[1].index = 0; if (markers[1].index < 0) markers[1].index = 0;
markers[1].frequency = frequencies[markers[1].index]; markers[1].frequency = frequencies[markers[1].index];
markers[2].index = marker_search_right_min(markers[0].index); markers[2].index = marker_search_right_min(0);
if (markers[2].index < 0) markers[1].index = setting._sweep_points - 1; if (markers[2].index < 0) markers[1].index = setting._sweep_points - 1;
markers[2].frequency = frequencies[markers[2].index]; markers[2].frequency = frequencies[markers[2].index];
} else if ((setting.measurement == M_PASS_BAND || setting.measurement == M_FM) && markers[0].index > 10) { // ----------------Pass band measurement } else if ((setting.measurement == M_PASS_BAND || setting.measurement == M_FM) && markers[0].index > 10) { // ----------------Pass band measurement
@ -4480,7 +4491,7 @@ static volatile int dummy;
channel_power_watt[c] = 0.0; channel_power_watt[c] = 0.0;
int sp_div3 = sweep_points/3; int sp_div3 = sweep_points/3;
for (int i =0; i < sp_div3; i++) { for (int i =0; i < sp_div3; i++) {
channel_power_watt[c] += index_to_value(i + c*sp_div3); channel_power_watt[c] += value(actual_t[i + c*sp_div3]);
} }
float rbw_cor = (float)(get_sweep_frequency(ST_SPAN)/3) / ((float)actual_rbw_x10 * 100.0); float rbw_cor = (float)(get_sweep_frequency(ST_SPAN)/3) / ((float)actual_rbw_x10 * 100.0);
channel_power_watt[c] = channel_power_watt[c] * rbw_cor /(float)sp_div3; channel_power_watt[c] = channel_power_watt[c] * rbw_cor /(float)sp_div3;
@ -4562,16 +4573,23 @@ static volatile int dummy;
//------------------------------- SEARCH --------------------------------------------- //------------------------------- SEARCH ---------------------------------------------
int int
marker_search_left_max(int from) marker_search_left_max(int m)
{ {
int i; int i;
float *ref_marker_levels;
if (markers[m].mtype & M_STORED )
ref_marker_levels = stored_t;
else
ref_marker_levels = actual_t;
int from = markers[m].index;
int found = -1; int found = -1;
if (uistat.current_trace == TRACE_INVALID) if (uistat.current_trace == TRACE_INVALID)
return -1; return -1;
float value = actual_t[from]; float value = ref_marker_levels[from];
for (i = from - 1; i >= 0; i--) { for (i = from - 1; i >= 0; i--) {
float new_value = actual_t[i]; float new_value = ref_marker_levels[i];
if (new_value < value) { if (new_value < value) {
value = new_value; value = new_value;
found = i; found = i;
@ -4580,7 +4598,7 @@ marker_search_left_max(int from)
} }
for (; i >= 0; i--) { for (; i >= 0; i--) {
float new_value = actual_t[i]; float new_value = ref_marker_levels[i];
if (new_value > value) { if (new_value > value) {
value = new_value; value = new_value;
found = i; found = i;
@ -4591,16 +4609,23 @@ marker_search_left_max(int from)
} }
int int
marker_search_right_max(int from) marker_search_right_max(int m)
{ {
int i; int i;
float *ref_marker_levels;
if (markers[m].mtype & M_STORED )
ref_marker_levels = stored_t;
else
ref_marker_levels = actual_t;
int from = markers[m].index;
int found = -1; int found = -1;
if (uistat.current_trace == TRACE_INVALID) if (uistat.current_trace == TRACE_INVALID)
return -1; return -1;
float value = actual_t[from]; float value = ref_marker_levels[from];
for (i = from + 1; i < sweep_points; i++) { for (i = from + 1; i < sweep_points; i++) {
float new_value = actual_t[i]; float new_value = ref_marker_levels[i];
if (new_value < value) { // follow down if (new_value < value) { // follow down
value = new_value; value = new_value;
found = i; found = i;
@ -4608,7 +4633,7 @@ marker_search_right_max(int from)
break; // past the minimum break; // past the minimum
} }
for (; i < sweep_points; i++) { for (; i < sweep_points; i++) {
float new_value = actual_t[i]; float new_value = ref_marker_levels[i];
if (new_value > value) { // follow up if (new_value > value) { // follow up
value = new_value; value = new_value;
found = i; found = i;
@ -4618,14 +4643,19 @@ marker_search_right_max(int from)
return found; return found;
} }
int marker_search_max(void) int marker_search_max(int m)
{ {
int i = 0; int i = 0;
float *ref_marker_levels;
if (markers[m].mtype & M_STORED )
ref_marker_levels = stored_t;
else
ref_marker_levels = actual_t;
int found = 0; int found = 0;
float value = actual_t[i]; float value = ref_marker_levels[i];
for (; i < sweep_points; i++) { for (; i < sweep_points; i++) {
int new_value = actual_t[i]; int new_value = ref_marker_levels[i];
if (new_value > value) { // follow up if (new_value > value) { // follow up
value = new_value; value = new_value;
found = i; found = i;
@ -4638,16 +4668,22 @@ int marker_search_max(void)
int int
marker_search_left_min(int from) marker_search_left_min(int m)
{ {
int i; int i;
float *ref_marker_levels;
if (markers[m].mtype & M_STORED )
ref_marker_levels = stored_t;
else
ref_marker_levels = actual_t;
int from = markers[m].index;
int found = from; int found = from;
if (uistat.current_trace == TRACE_INVALID) if (uistat.current_trace == TRACE_INVALID)
return -1; return -1;
int value_x10 = actual_t[from]*10; int value_x10 = ref_marker_levels[from]*10;
for (i = from - 1; i >= 0; i--) { for (i = from - 1; i >= 0; i--) {
int new_value_x10 = actual_t[i]*10; int new_value_x10 = ref_marker_levels[i]*10;
if (new_value_x10 > value_x10) { if (new_value_x10 > value_x10) {
value_x10 = new_value_x10; // follow up value_x10 = new_value_x10; // follow up
// found = i; // found = i;
@ -4656,7 +4692,7 @@ marker_search_left_min(int from)
} }
for (; i >= 0; i--) { for (; i >= 0; i--) {
int new_value_x10 = actual_t[i]*10; int new_value_x10 = ref_marker_levels[i]*10;
if (new_value_x10 < value_x10) { if (new_value_x10 < value_x10) {
value_x10 = new_value_x10; // follow down value_x10 = new_value_x10; // follow down
found = i; found = i;
@ -4667,16 +4703,22 @@ marker_search_left_min(int from)
} }
int int
marker_search_right_min(int from) marker_search_right_min(int m)
{ {
int i; int i;
float *ref_marker_levels;
if (markers[m].mtype & M_STORED )
ref_marker_levels = stored_t;
else
ref_marker_levels = actual_t;
int from = markers[m].index;
int found = from; int found = from;
if (uistat.current_trace == TRACE_INVALID) if (uistat.current_trace == TRACE_INVALID)
return -1; return -1;
int value_x10 = actual_t[from]*10; int value_x10 = ref_marker_levels[from]*10;
for (i = from + 1; i < sweep_points; i++) { for (i = from + 1; i < sweep_points; i++) {
int new_value_x10 = actual_t[i]*10; int new_value_x10 = ref_marker_levels[i]*10;
if (new_value_x10 > value_x10) { // follow up if (new_value_x10 > value_x10) { // follow up
value_x10 = new_value_x10; value_x10 = new_value_x10;
// found = i; // found = i;
@ -4684,7 +4726,7 @@ marker_search_right_min(int from)
break; // past the maximum break; // past the maximum
} }
for (; i < sweep_points; i++) { for (; i < sweep_points; i++) {
int new_value_x10 = actual_t[i]*10; int new_value_x10 = ref_marker_levels[i]*10;
if (new_value_x10 < value_x10) { // follow down if (new_value_x10 < value_x10) { // follow down
value_x10 = new_value_x10; value_x10 = new_value_x10;
found = i; found = i;

10
ui.c

@ -735,19 +735,19 @@ static UI_FUNCTION_CALLBACK(menu_marker_search_cb)
markers[active_marker].mtype &= ~M_TRACKING; markers[active_marker].mtype &= ~M_TRACKING;
switch (data) { switch (data) {
case 0: /* search Left */ case 0: /* search Left */
i = marker_search_left_min(markers[active_marker].index); i = marker_search_left_min(active_marker);
break; break;
case 1: /* search right */ case 1: /* search right */
i = marker_search_right_min(markers[active_marker].index); i = marker_search_right_min(active_marker);
break; break;
case 2: /* search Left */ case 2: /* search Left */
i = marker_search_left_max(markers[active_marker].index); i = marker_search_left_max(active_marker);
break; break;
case 3: /* search right */ case 3: /* search right */
i = marker_search_right_max(markers[active_marker].index); i = marker_search_right_max(active_marker);
break; break;
case 4: /* peak search */ case 4: /* peak search */
i = marker_search_max(); i = marker_search_max(active_marker);
break; break;
} }
if (i != -1) { if (i != -1) {

Loading…
Cancel
Save

Powered by TurnKey Linux.