static sync_worker_state exec_idle_state(struct bladerf_sync *s) { sync_worker_state next_state = SYNC_WORKER_STATE_IDLE; pthread_mutex_lock(&s->worker->request_lock); while (s->worker->requests == 0) { log_verbose("%s worker: Waiting for pending requests\n", MODULE_STR(s)); pthread_cond_wait(&s->worker->requests_pending, &s->worker->request_lock); } if (s->worker->requests & SYNC_WORKER_STOP) { log_verbose("%s worker: Got request to stop\n", module2str(s->stream_config.module)); next_state = SYNC_WORKER_STATE_SHUTTING_DOWN; } else if (s->worker->requests & SYNC_WORKER_START) { log_verbose("%s worker: Got request to start\n", module2str(s->stream_config.module)); next_state = SYNC_WORKER_STATE_RUNNING; } else { log_warning("Invalid request value encountered: 0x%08X\n", s->worker->requests); } s->worker->requests = 0; pthread_mutex_unlock(&s->worker->request_lock); return next_state; }
int print_trigger(struct cli_state *state, bladerf_module module, bladerf_trigger_signal signal) { int status; struct bladerf_trigger t; bool master, armed, fired, fire_req; const char *sig_str, *role_str, *module_str; status = bladerf_trigger_init(state->dev, module, signal, &t); if (status != 0) { goto out; } status = bladerf_trigger_state(state->dev, &t, &armed, &fired, &fire_req, NULL, NULL); if (status != 0) { goto out; } printf("\n"); master = (t.role == BLADERF_TRIGGER_ROLE_MASTER); role_str = triggerrole2str(t.role); sig_str = trigger2str(signal); module_str = module2str(module); printf(" %s %s trigger\n", sig_str, module_str); printf(" State: %s\n", armed ? "Armed" : "Disarmed"); printf(" Role: %s\n", role_str); if (master) { printf(" Fire Requested: %s\n", fire_req ? "Yes" : "No"); } printf(" Fired: %s\n", fired ? "Yes" : "No"); printf("\n"); out: if (status != 0) { state->last_lib_error = status; return CLI_RET_LIBBLADERF; } return status; }
static inline int config_trigger(struct cli_state *state, bladerf_module module, bladerf_trigger_signal signal, const char *cmd, const char *argv0) { int status; struct bladerf_trigger trigger; bool armed, fired, fire_req, master; const char *module_str, *sig_str; /* Dissect current value to print certain warnings */ status = bladerf_trigger_init(state->dev, module, signal, &trigger); if (status != 0) { goto out; } status = bladerf_trigger_state(state->dev, &trigger, &armed, &fired, &fire_req, NULL, NULL); if (status != 0) { goto out; } master = (trigger.role == BLADERF_TRIGGER_ROLE_MASTER); module_str = module2str(module); sig_str = trigger2str(signal); if (!strcasecmp(cmd, "off") || !strcasecmp(cmd, "disable") || !strcasecmp(cmd, "disabled")) { /* Disarm trigger and restore it to a slave role */ trigger.role = BLADERF_TRIGGER_ROLE_DISABLED; status = bladerf_trigger_arm(state->dev, &trigger, false, 0, 0); if (status != 0) { goto out; } printf("\n %s %s trigger disabled\n\n", sig_str, module_str); } else if (!strcasecmp(cmd, "slave")) { if (fired) { printf("\n WARNING: Trigger signal is already asserted; trigger will fire immediately.\n"); } if (master && fire_req) { printf("\n WARNING: Fire request on this master was active. Changing from master to slave will stop other triggered slaves.\n"); } trigger.role = BLADERF_TRIGGER_ROLE_SLAVE; status = bladerf_trigger_arm(state->dev, &trigger, true, 0, 0); if (status != 0) { goto out; } printf("\n %s %s trigger armed as a slave.\n\n", sig_str, module_str); } else if (!strcasecmp(cmd, "master")) { if (armed && !master) { printf("\n WARNING: Changing from slave to master. Ensure there is only one master in the trigger chain!\n"); } trigger.role = BLADERF_TRIGGER_ROLE_MASTER; status = bladerf_trigger_arm(state->dev, &trigger, true, 0, 0); if (status != 0) { goto out; } printf("\n %s %s trigger armed as master.\n\n", sig_str, module_str); } else if (!strcasecmp(cmd, "fire")) { if (!(armed && master)) { cli_err(state, argv0, "%s %s trigger not configured as master, can't fire\n", sig_str, module_str); return CLI_RET_INVPARAM; } if (fired) { printf("\n WARNING: Trigger already fired. Ignoring fire request.\n\n"); return 0; } status = bladerf_trigger_fire(state->dev, &trigger); if (status != 0) { goto out; } printf("\n %s %s trigger fire request submitted successfully.\n\n", sig_str, module_str); } else { cli_err(state, cmd, "Invalid trigger command.\n"); return CLI_RET_INVPARAM; } out: if (status != 0) { state->last_lib_error = status; status = CLI_RET_LIBBLADERF; } return status; }
int tuning_set_freq(struct bladerf *dev, bladerf_module module, unsigned int frequency) { int status; const bladerf_xb attached = dev->xb; int16_t dc_i, dc_q; const struct dc_cal_tbl *dc_cal = (module == BLADERF_MODULE_RX) ? dev->cal.dc_rx : dev->cal.dc_tx; log_debug("Setting %s frequency to %u\n", module2str(module), frequency); if (attached == BLADERF_XB_200) { if (frequency < BLADERF_FREQUENCY_MIN) { status = xb200_set_path(dev, module, BLADERF_XB200_MIX); if (status) { return status; } status = xb200_auto_filter_selection(dev, module, frequency); if (status) { return status; } frequency = 1248000000 - frequency; } else { status = xb200_set_path(dev, module, BLADERF_XB200_BYPASS); if (status) return status; } } switch (dev->tuning_mode) { case BLADERF_TUNING_MODE_HOST: status = lms_set_frequency(dev, module, frequency); if (status != 0) { return status; } status = band_select(dev, module, frequency < BLADERF_BAND_HIGH); break; case BLADERF_TUNING_MODE_FPGA: { struct lms_freq f; status = lms_calculate_tuning_params(frequency, &f); if (status == 0) { /* The band selection will occur in the NIOS II */ status = tuning_schedule(dev, module, BLADERF_RETUNE_NOW, &f); } break; } default: log_debug("Invalid tuning mode: %d\n", dev->tuning_mode); status = BLADERF_ERR_INVAL; break; } if (status != 0) { return status; } if (dc_cal != NULL) { dc_cal_tbl_vals(dc_cal, frequency, &dc_i, &dc_q); status = lms_set_dc_offset_i(dev, module, dc_i); if (status != 0) { return status; } status = lms_set_dc_offset_q(dev, module, dc_q); if (status != 0) { return status; } log_verbose("Set %s DC offset cal (I, Q) to: (%d, %d)\n", (module == BLADERF_MODULE_RX) ? "RX" : "TX", dc_i, dc_q); } return status; }
static sync_worker_state exec_idle_state(struct bladerf_sync *s) { sync_worker_state next_state = SYNC_WORKER_STATE_IDLE; unsigned int requests; unsigned int i; pthread_mutex_lock(&s->worker->request_lock); while (s->worker->requests == 0) { log_verbose("%s worker: Waiting for pending requests\n", MODULE_STR(s)); pthread_cond_wait(&s->worker->requests_pending, &s->worker->request_lock); } requests = s->worker->requests; s->worker->requests = 0; pthread_mutex_unlock(&s->worker->request_lock); if (requests & SYNC_WORKER_STOP) { log_verbose("%s worker: Got request to stop\n", module2str(s->stream_config.module)); next_state = SYNC_WORKER_STATE_SHUTTING_DOWN; } else if (requests & SYNC_WORKER_START) { log_verbose("%s worker: Got request to start\n", module2str(s->stream_config.module)); pthread_mutex_lock(&s->buf_mgmt.lock); if (s->stream_config.module == BLADERF_MODULE_TX) { /* If we've previously timed out on a stream, we'll likely have some * stale buffers marked "in-flight" that have since been cancelled. */ for (i = 0; i < s->buf_mgmt.num_buffers; i++) { if (s->buf_mgmt.status[i] == SYNC_BUFFER_IN_FLIGHT) { s->buf_mgmt.status[i] = SYNC_BUFFER_EMPTY; } } pthread_cond_signal(&s->buf_mgmt.buf_ready); } else { assert(s->stream_config.module == BLADERF_MODULE_RX); s->buf_mgmt.prod_i = s->stream_config.num_xfers; for (i = 0; i < s->buf_mgmt.num_buffers; i++) { if (i < s->stream_config.num_xfers) { s->buf_mgmt.status[i] = SYNC_BUFFER_IN_FLIGHT; } else if (s->buf_mgmt.status[i] == SYNC_BUFFER_IN_FLIGHT) { s->buf_mgmt.status[i] = SYNC_BUFFER_EMPTY; } } } pthread_mutex_unlock(&s->buf_mgmt.lock); next_state = SYNC_WORKER_STATE_RUNNING; } else { log_warning("Invalid request value encountered: 0x%08X\n", s->worker->requests); } return next_state; }