diff --git a/README.md b/README.md index 72f24e4..6fca555 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,3 @@ ## Tested On `libbladeRF 2.2.1-MacPorts-20191220-45521019` - -## Notes - -```shell -brew install pkg-config -brew install portaudio -export PKG_CONFIG_PATH="$PKG_CONFIG_PATH:/usr/local/Cellar/portaudio/19.6.0/lib/pkgconfig" -``` \ No newline at end of file diff --git a/bladerf.go b/bladerf.go index 83287d5..837ed85 100644 --- a/bladerf.go +++ b/bladerf.go @@ -37,8 +37,20 @@ func StreamCallback( ) } - userData.callback(userData.results) - return samples + defer C.free(samples) + status := userData.callback(userData.results) + + if status == GoStreamNoData { + return StreamNoData + } else if status == GoStreamShutdown { + return StreamShutdown + } else { + return unsafe.Pointer( + (*C.uint16_t)( + C.malloc((C.size_t)(C.sizeof_uint16_t * uintptr(numSamples) * 2 * 1)), + ), + ) + } } func GetVersion() Version { @@ -182,8 +194,6 @@ func GetDeviceList() ([]DeviceInfo, error) { (*C.struct_bladerf_devinfo)(unsafe.Pointer(uintptr(unsafe.Pointer(deviceInfo))+(uintptr(i)*size))), )) } - - devices[0].FreeDeviceList() } return devices, nil @@ -213,8 +223,6 @@ func GetBootloaderList() ([]DeviceInfo, error) { (*C.struct_bladerf_devinfo)(unsafe.Pointer(uintptr(unsafe.Pointer(deviceInfo))+(uintptr(i)*size))), )) } - - devices[0].FreeDeviceList() } return devices, nil @@ -578,7 +586,7 @@ func (bladeRF *BladeRF) SetCorrection(channel Channel, correction Correction, co ) } -func (bladeRF *BladeRF) GetCorrection(channel Channel, correction Correction) (uint16, error) { +func (bladeRF *BladeRF) GetCorrection(channel Channel, correction Correction) (int16, error) { var correctionValue C.int16_t err := GetError(C.bladerf_get_correction( bladeRF.ref, @@ -591,7 +599,7 @@ func (bladeRF *BladeRF) GetCorrection(channel Channel, correction Correction) (u return 0, err } - return uint16(correctionValue), nil + return int16(correctionValue), nil } func (backend *Backend) String() string { @@ -803,23 +811,52 @@ func (trigger *Trigger) SetRole(role TriggerRole) { (*trigger.ref).role = C.bladerf_trigger_role(role) } -func (bladeRF *BladeRF) SyncRX(bufferSize uintptr) ([]int16, error) { - var metadata C.struct_bladerf_metadata - start := C.malloc(C.size_t(C.sizeof_int16_t * bufferSize * 2 * 1)) - err := GetError(C.bladerf_sync_rx(bladeRF.ref, start, C.uint(bufferSize), &metadata, 32)) +func (bladeRF *BladeRF) SyncTX(input []int16, metadata Metadata) (Metadata, error) { + if metadata.ref == nil { + var ref C.struct_bladerf_metadata + metadata.ref = &ref + } + + numberOfSample := len(input) + buf := (*C.uint16_t)(C.malloc((C.size_t)(C.sizeof_uint16_t * uintptr(numberOfSample)))) + defer C.free(unsafe.Pointer(buf)) + + for i := 0; i < numberOfSample; i++ { + addr := (*C.uint16_t)(unsafe.Pointer(uintptr(unsafe.Pointer(buf)) + (C.sizeof_uint16_t * uintptr(i)))) + *addr = (C.uint16_t)(input[i]) + } + + err := GetError(C.bladerf_sync_tx(bladeRF.ref, unsafe.Pointer(buf), C.uint(numberOfSample/2), metadata.ref, 5000)) if err != nil { - return nil, err + return metadata, err + } + + return LoadMetadata(metadata.ref), nil +} + +func (bladeRF *BladeRF) SyncRX(bufferSize uintptr, metadata Metadata) ([]int16, Metadata, error) { + if metadata.ref == nil { + var ref C.struct_bladerf_metadata + metadata.ref = &ref + } + + start := C.malloc(C.size_t(C.sizeof_int16_t * bufferSize * 2 * 1)) + defer C.free(unsafe.Pointer(start)) + err := GetError(C.bladerf_sync_rx(bladeRF.ref, start, C.uint(bufferSize), metadata.ref, 5000)) + + if err != nil { + return nil, metadata, err } var results []int16 - for i := 0; i < (int(metadata.actual_count)); i++ { + for i := 0; i < (int(metadata.ref.actual_count)); i++ { n := (*C.int16_t)(unsafe.Pointer(uintptr(start) + (C.sizeof_int16_t * uintptr(i)))) results = append(results, int16(*n)) } - return results, nil + return results, LoadMetadata(metadata.ref), nil } func (bladeRF *BladeRF) InitStream( @@ -827,7 +864,7 @@ func (bladeRF *BladeRF) InitStream( numBuffers int, samplesPerBuffer int, numTransfers int, - callback func(data []int16), + callback func(data []int16) GoStream, ) (Stream, error) { var buffers *unsafe.Pointer var rxStream *C.struct_bladerf_stream @@ -910,7 +947,7 @@ func (bladeRF *BladeRF) GetAttachedExpansionBoard() (ExpansionBoard, error) { return ExpansionBoard(expansionBoard), nil } -func (bladeRF *BladeRF) SetGetVctcxoTamerMode(mode VctcxoTamerMode) error { +func (bladeRF *BladeRF) SetVctcxoTamerMode(mode VctcxoTamerMode) error { return GetError(C.bladerf_set_vctcxo_tamer_mode(bladeRF.ref, C.bladerf_vctcxo_tamer_mode(mode))) } @@ -966,6 +1003,17 @@ func (bladeRF *BladeRF) GetTuningMode() (TuningMode, error) { return TuningMode(mode), nil } +func (bladeRF *BladeRF) GetTimestamp(direction Direction) (Timestamp, error) { + var timestamp C.bladerf_timestamp + err := GetError(C.bladerf_get_timestamp(bladeRF.ref, C.bladerf_direction(direction), ×tamp)) + + if err != nil { + return 0, err + } + + return Timestamp(timestamp), err +} + func (bladeRF *BladeRF) ReadTrigger(channel Channel, signal TriggerSignal) (uint8, error) { var val C.uint8_t err := GetError(C.bladerf_read_trigger( diff --git a/bladerf_test.go b/bladerf_test.go index 08b57c1..56ddc92 100644 --- a/bladerf_test.go +++ b/bladerf_test.go @@ -2,40 +2,1656 @@ package bladerf import ( "fmt" - "github.com/erayarslan/go-bladerf/log" - "github.com/gordonklaus/portaudio" - fifo "github.com/racerxdl/go.fifo" - "github.com/racerxdl/segdsp/demodcore" - "os" - "os/signal" - "syscall" "testing" ) -const audioBufferSize = 8192 / 4 +var Rx1Channel = ChannelRx(0) -var audioStream *portaudio.Stream -var audioFifo = fifo.NewQueue() +func TestGetVersion(t *testing.T) { + version := GetVersion() -var demodulator demodcore.DemodCore - -/* -RX Gain Stage names: lna, rxvga1, rxvga2 -TX Gain Stage names: txvga1, txvga2 -*/ - -func ProcessAudio(out []float32) { - if audioFifo.Len() > 0 { - var z = audioFifo.Next().([]float32) - copy(out, z) + if version.Major != 2 { + t.Error("version.Major FAILED") } else { - for i := range out { - out[i] = 0 - } + t.Log("version.Major PASSED") + } + + if version.Minor != 2 { + t.Error("version.Minor FAILED") + } else { + t.Log("version.Minor PASSED") + } + + if version.Patch != 1 { + t.Error("version.Patch FAILED") + } else { + t.Log("version.Patch PASSED") + } + + if version.Describe != "2.2.1-git-45521019" { + t.Error("version.Describe FAILED") + } else { + t.Log("version.Describe PASSED") } } -func GetFinalData(input []int16) []complex64 { +func TestPrintVersion(t *testing.T) { + version := GetVersion() + version.Print() + t.Log("PASSED") +} + +func TestLoadFpga(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.LoadFpga("invalidAddr") + + if err.Error() != "File not found" { + t.Errorf("FAILED cause got %v", err.Error()) + } else { + t.Log("PASSED") + } +} + +func TestGetFpgaSize(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + size, err := rf.GetFpgaSize() + + if size != FpgaSizeA4 { + t.Errorf("FAILED cause got %v", size) + } else { + t.Log("PASSED") + } +} + +func TestGetQuickTune(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + _, err = rf.GetQuickTune(Rx1Channel) + + if err != nil { + t.Errorf("FAILED cause got %v", err.Error()) + } else { + t.Log("PASSED") + } +} + +func TestCancelScheduledReTunes(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.CancelScheduledReTunes(Rx1Channel) + + if err != nil { + t.Errorf("FAILED cause got %v", err.Error()) + } else { + t.Log("PASSED") + } +} + +func TestGetFpgaSource(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + source, err := rf.GetFpgaSource() + + if source == FpgaSourceHost { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", source) + } +} + +func TestGetFpgaBytes(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + bytes, err := rf.GetFpgaBytes() + + if bytes == 2632660 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", bytes) + } +} + +func TestGetFpgaFlashSize(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + size, isGuess, err := rf.GetFpgaFlashSize() + + if size == 4194304 && !isGuess { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v,%v", size, isGuess) + } +} + +func TestGetFirmwareVersion(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + version, err := rf.GetFirmwareVersion() + + if version.Major != 2 { + t.Error("version.Major FAILED") + } else { + t.Log("version.Major PASSED") + } + + if version.Minor != 3 { + t.Error("version.Minor FAILED") + } else { + t.Log("version.Minor PASSED") + } + + if version.Patch != 2 { + t.Error("version.Patch FAILED") + } else { + t.Log("version.Patch PASSED") + } + + if version.Describe != "2.3.2" { + t.Error("version.Describe FAILED") + } else { + t.Log("version.Describe PASSED") + } +} + +func TestIsFpgaConfigured(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + configured, err := rf.IsFpgaConfigured() + + if configured { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", configured) + } +} + +func TestGetDeviceSpeed(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + speed := rf.GetDeviceSpeed() + + if speed == SpeedHigh { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", speed) + } +} + +func TestGetFpgaVersion(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + version, err := rf.GetFpgaVersion() + + if version.Major != 0 { + t.Error("version.Major FAILED") + } else { + t.Log("version.Major PASSED") + } + + if version.Minor != 11 { + t.Error("version.Minor FAILED") + } else { + t.Log("version.Minor PASSED") + } + + if version.Patch != 0 { + t.Error("version.Patch FAILED") + } else { + t.Log("version.Patch PASSED") + } + + if version.Describe != "0.11.0" { + t.Error("version.Describe FAILED") + } else { + t.Log("version.Describe PASSED") + } +} + +func TestFreeDeviceList(t *testing.T) { + devices, _ := GetDeviceList() + defer devices[0].FreeDeviceList() +} + +func TestGetDeviceList(t *testing.T) { + devices, _ := GetDeviceList() + defer devices[0].FreeDeviceList() + + if len(devices) == 1 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", len(devices)) + } +} + +func TestGetBootloaderList(t *testing.T) { + bootloaders, _ := GetBootloaderList() + + if len(bootloaders) == 0 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", len(bootloaders)) + } +} + +func TestInitDeviceInfo(t *testing.T) { + deviceInfo := InitDeviceInfo() + + if deviceInfo.Serial == "ANY" { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", deviceInfo.Serial) + } +} + +func TestGetDeviceInfo(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + deviceInfo, err := rf.GetDeviceInfo() + + if deviceInfo.Product == "bladeRF 2.0" { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", deviceInfo.Product) + } +} + +func TestDeviceInfoMatches(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + deviceInfo, err := rf.GetDeviceInfo() + + if err == nil && deviceInfo.DeviceInfoMatches(deviceInfo) { + t.Log("PASSED") + } else { + t.Error("FAILED") + } +} + +func TestDeviceStringMatches(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + deviceInfo, err := rf.GetDeviceInfo() + + if err == nil && deviceInfo.DeviceStringMatches("*:serial="+deviceInfo.Serial) { + t.Log("PASSED") + } else { + t.Error("FAILED") + } +} + +func TestGetDeviceInfoFromString(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + deviceInfo, err := rf.GetDeviceInfo() + + if err != nil { + t.Errorf("FAILED cause got %v", err.Error()) + } + + deviceInfoFromString, err := GetDeviceInfoFromString("*:serial=" + deviceInfo.Serial) + + if err == nil && deviceInfoFromString.Serial == deviceInfo.Serial { + t.Log("PASSED") + } else { + t.Error("FAILED") + } +} + +func TestOpenWithDeviceInfo(t *testing.T) { + devices, err := GetDeviceList() + defer devices[0].FreeDeviceList() + + if err != nil { + t.Error(err) + t.FailNow() + } + + if len(devices) == 0 { + t.Error("Device cannot be found") + t.FailNow() + } + + rf, err := devices[0].Open() + defer rf.Close() + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestOpenWithDeviceIdentifier(t *testing.T) { + devices, err := GetDeviceList() + defer devices[0].FreeDeviceList() + + if err != nil { + t.Error(err) + t.FailNow() + } + + if len(devices) == 0 { + t.Error("Device cannot be found") + t.FailNow() + } + + rf, err := OpenWithDeviceIdentifier("*:serial=" + devices[0].Serial) + defer rf.Close() + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestOpen(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + t.Log("PASSED") +} + +func TestClose(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + rf.Close() + + t.Log("PASSED") +} + +func TestSetLoopback(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetLoopback(LoopbackDisabled) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestIsLoopbackModeSupported(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + supported := rf.IsLoopbackModeSupported(LoopbackDisabled) + + if supported { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", supported) + } +} + +func TestGetLoopback(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + loopback, err := rf.GetLoopback() + + if loopback == LoopbackDisabled { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", loopback) + } +} + +func TestScheduleReTune(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + tune, err := rf.GetQuickTune(Rx1Channel) + err = rf.ScheduleReTune(Rx1Channel, ReTuneNow, 1525420000, tune) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSelectBand(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SelectBand(Rx1Channel, 1525420000) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetFrequency(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetFrequency(Rx1Channel, 1525420000) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetFrequency(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetFrequency(Rx1Channel, 1525420000) + freq, err := rf.GetFrequency(Rx1Channel) + + if err == nil && freq == 1525420000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetSampleRate(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + actual, err := rf.SetSampleRate(Rx1Channel, 2000000) + + if err == nil && actual == 2000000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetRxMux(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetRxMux(RxMuxBaseband) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetRxMux(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + rxMux, err := rf.GetRxMux() + + if err == nil && rxMux == RxMuxBaseband { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetRationalSampleRate(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + rate, err := rf.GetRationalSampleRate(Rx1Channel) + _, err = rf.SetRationalSampleRate(Rx1Channel, rate) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetSampleRate(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + actual, err := rf.SetSampleRate(Rx1Channel, 2000000) + sampleRate, err := rf.GetSampleRate(Rx1Channel) + + if err == nil && actual == 2000000 && sampleRate == 2000000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetRationalSampleRate(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + rate, err := rf.GetRationalSampleRate(Rx1Channel) + + if err == nil && rate.Integer == 30720000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetSampleRateRange(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + _range, err := rf.GetSampleRateRange(Rx1Channel) + + if err == nil && _range.Max == 61440000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetFrequencyRange(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + _range, err := rf.GetFrequencyRange(Rx1Channel) + + if err == nil && _range.Max == 6000000000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetBandwidth(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + actual, err := rf.SetBandwidth(Rx1Channel, 1500000) + + if err == nil && actual == 1500000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetBandwidth(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + actual, err := rf.SetBandwidth(Rx1Channel, 1500000) + bandwidth, err := rf.GetBandwidth(Rx1Channel) + + if err == nil && actual == 1500000 && bandwidth == 1500000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetBandwidthRange(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + _range, err := rf.GetBandwidthRange(Rx1Channel) + + if err == nil && _range.Max == 56000000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetGain(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.EnableModule(Rx1Channel) + err = rf.SetGainMode(Rx1Channel, GainModeManual) + err = rf.SetGain(Rx1Channel, 60) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetGain(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.EnableModule(Rx1Channel) + err = rf.SetGainMode(Rx1Channel, GainModeManual) + err = rf.SetGain(Rx1Channel, 60) + gain, err := rf.GetGain(Rx1Channel) + + if err == nil && gain == 60 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", gain) + } +} + +func TestGetGainStage(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + stage, err := rf.GetGainStage(Rx1Channel, "full") + + if err == nil && stage == 71 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", stage) + } +} + +func TestGetGainMode(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetGainMode(Rx1Channel, GainModeManual) + mode, err := rf.GetGainMode(Rx1Channel) + + if err == nil && mode == GainModeManual { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", mode) + } +} + +func TestSetGainStage(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.EnableModule(Rx1Channel) + err = rf.SetGainMode(Rx1Channel, GainModeManual) + err = rf.SetGainStage(Rx1Channel, "full", 70) + stage, err := rf.GetGainStage(Rx1Channel, "full") + + if err == nil && stage == 70 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", stage) + } +} + +func TestGetGainStageRange(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + _range, err := rf.GetGainStageRange(Rx1Channel, "full") + + if err == nil && _range.Min == -4 && _range.Max == 71 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetGainRange(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + _range, err := rf.GetGainRange(Rx1Channel) + + if err == nil && _range.Min == -15 && _range.Max == 60 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetNumberOfGainStages(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + count, err := rf.GetNumberOfGainStages(Rx1Channel) + + if err == nil && count == 1 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetCorrection(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetCorrection(Rx1Channel, CorrectionDcoffI, 2048) + err = rf.SetCorrection(Rx1Channel, CorrectionDcoffQ, 2048) + correctionI, err := rf.GetCorrection(Rx1Channel, CorrectionDcoffI) + correctionQ, err := rf.GetCorrection(Rx1Channel, CorrectionDcoffQ) + + if err == nil && correctionI == -2048 && correctionQ == -2048 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetCorrection(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + correctionI, err := rf.GetCorrection(Rx1Channel, CorrectionDcoffI) + correctionQ, err := rf.GetCorrection(Rx1Channel, CorrectionDcoffQ) + + if err == nil && correctionI < 0 && correctionQ < 0 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestBackendString(t *testing.T) { + libUSB := BackendLibUSB + dummy := BackendDummy + any := BackendAny + cypress := BackendCypress + linux := BackendLinux + + if libUSB.String() == "libusb" && + dummy.String() == "*" && + any.String() == "*" && + cypress.String() == "cypress" && + linux.String() == "linux" { + t.Log("PASSED") + } else { + t.Error("FAILED") + } +} + +func TestGetBoardName(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + name := rf.GetBoardName() + + if name == "bladerf2" { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", name) + } +} + +func TestSetUSBResetOnOpen(t *testing.T) { + SetUSBResetOnOpen(true) + t.Log("PASSED") +} + +func TestGetSerial(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + serial, err := rf.GetSerial() + + if err == nil && len(serial) > 0 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetSerialStruct(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + serial, err := rf.GetSerialStruct() + + if err == nil && len(serial.Serial) > 0 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetGainStages(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + stages, err := rf.GetGainStages(Rx1Channel) + + if err == nil && stages[0] == "full" { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetGainModes(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + modes, err := rf.GetGainModes(Rx1Channel) + + if err == nil && + modes[0].Name == "automatic" && + modes[0].Mode == GainModeDefault && + len(modes) == 5 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetLoopbackModes(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + modes, err := rf.GetLoopbackModes() + + if err == nil && + modes[0].Name == "none" && + modes[0].Mode == LoopbackDisabled && + len(modes) == 3 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetGainMode(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetGainMode(Rx1Channel, GainModeHybridAgc) + mode, err := rf.GetGainMode(Rx1Channel) + + if err == nil && mode == GainModeHybridAgc { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", mode) + } +} + +func TestEnableModule(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.EnableModule(Rx1Channel) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestDisableModule(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.DisableModule(Rx1Channel) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestTrigger(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + triggerMaster, err := rf.TriggerInit(Rx1Channel, TriggerSignalJ714) + triggerMaster.SetRole(TriggerRoleMaster) + triggerSlave, err := rf.TriggerInit(Rx1Channel, TriggerSignalJ714) + triggerSlave.SetRole(TriggerRoleSlave) + + err = rf.TriggerArm(triggerMaster, true, 0, 0) + err = rf.TriggerFire(triggerMaster) + + isArmed, hasFire, fireRequested, resV1, resV2, err := rf.TriggerState(triggerMaster) + + if err == nil && isArmed && hasFire && fireRequested && resV1 == 0 && resV2 == 0 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSyncTX(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SyncConfig(TxX1, FormatSc16Q11, 2, 1024, 1, 3500) + err = rf.EnableModule(ChannelTx(0)) + + data := make([]complex64, 4) + + for i := range data { + data[i] = complex(0.5, 0.5) + } + + _, err = rf.SyncTX(Complex64ToInt16(data), Metadata{}) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSyncRX(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SyncConfig(RxX1, FormatSc16Q11, 2, 1024, 1, 3500) + err = rf.EnableModule(ChannelRx(0)) + + data, _, err := rf.SyncRX(1024, Metadata{}) + + complexData := Int16ToComplex64(data) + + if err == nil && len(data) == 1024 && len(complexData) == 512 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestAsyncRX(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.EnableModule(ChannelRx(0)) + + rxStream, err := rf.InitStream( + FormatSc16Q11, + 2, + 1024, + 1, + func(data []int16) GoStream { + complexData := Int16ToComplex64(data) + + if len(complexData) == 512 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", len(complexData)) + } + + return GoStreamShutdown + }) + + err = rxStream.Start(RxX1) + if err != nil { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestDeInitAsyncRX(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.EnableModule(ChannelRx(0)) + + rxStream, err := rf.InitStream( + FormatSc16Q11, + 2, + 1024, + 1, + func(data []int16) GoStream { + return GoStreamShutdown + }) + + rxStream.DeInit() + t.Log("PASSED") +} + +func TestGetStreamTimeout(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + timeout, err := rf.GetStreamTimeout(Rx) + + if err == nil && timeout == 0 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetStreamTimeout(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetStreamTimeout(Rx, 3000) + timeout, err := rf.GetStreamTimeout(Rx) + + if err == nil && timeout == 3000 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestAttachExpansionBoard(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.AttachExpansionBoard(ExpansionBoard300) + + if err.Error() == "Operation not supported" { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetAttachedExpansionBoard(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + board, err := rf.GetAttachedExpansionBoard() + + if err == nil && board == ExpansionBoardNone { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetVctcxoTamerMode(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetVctcxoTamerMode(VctcxoTamerModeDisabled) + + if err.Error() == "Operation not supported" { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetVctcxoTamerMode(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + _, err = rf.GetVctcxoTamerMode() + + if err.Error() == "Operation not supported" { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetVctcxoTrim(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + trim, err := rf.GetVctcxoTrim() + + if err == nil && trim == 8091 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestTrimDacRead(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + val, err := rf.TrimDacRead() + + if err == nil && val == 8091 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestTrimDacWrite(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.TrimDacWrite(8090) + val, err := rf.TrimDacRead() + + if err == nil && val == 8090 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestSetTuningMode(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetTuningMode(TuningModeHost) + mode, err := rf.GetTuningMode() + + if err == nil && mode == TuningModeHost { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetTuningMode(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.SetTuningMode(TuningModeFpga) + mode, err := rf.GetTuningMode() + + if err == nil && mode == TuningModeFpga { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestGetTimestamp(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + timestamp, err := rf.GetTimestamp(Rx) + + if err == nil && timestamp == 0 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestReadTrigger(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.WriteTrigger(Rx1Channel, TriggerSignalJ511, 10) + val, err := rf.ReadTrigger(Rx1Channel, TriggerSignalJ511) + + if err == nil && val == 10 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestWriteTrigger(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.WriteTrigger(Rx1Channel, TriggerSignalJ511, 12) + val, err := rf.ReadTrigger(Rx1Channel, TriggerSignalJ511) + + if err == nil && val == 12 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestConfigGpioRead(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + val, err := rf.ConfigGpioRead() + + if err == nil && val == 129 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestConfigGpioWrite(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.ConfigGpioWrite(512) + val, err := rf.ConfigGpioRead() + + if err == nil && val == 129+512 { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestEraseFlash(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.EraseFlash(4, 41) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func TestEraseFlashBytes(t *testing.T) { + rf, err := Open() + + if err != nil { + t.Error(err) + } + + defer rf.Close() + + err = rf.EraseFlashBytes(0x00040000, 0x290000) + + if err == nil { + t.Log("PASSED") + } else { + t.Errorf("FAILED cause got %v", err.Error()) + } +} + +func Complex64ToInt16(input []complex64) []int16 { + var ex = make([]int16, len(input)*2) + + for i := 0; i < len(input)*2; i += 2 { + ex[i] = int16(imag(input[i/2]) * 2048) + ex[i+1] = int16(real(input[i/2]) * 2048) + } + + return ex +} + +func Int16ToComplex64(input []int16) []complex64 { var complexFloat = make([]complex64, len(input)/2) for i := 0; i < len(complexFloat); i++ { @@ -45,311 +1661,7 @@ func GetFinalData(input []int16) []complex64 { return complexFloat } -func GetFinalDataString(input []int16) string { - var runes []rune - - for i := 0; i < len(input)/2; i++ { - runes = append(runes, rune(input[2*i+1])) - } - - return string(runes) -} - -func TestBackendSTR(t *testing.T) { - x := BackendLibUSB - y := BackendDummy - z := BackendAny - a := BackendCypress - b := BackendLinux - fmt.Println(x.String(), y.String(), z.String(), a.String(), b.String()) -} - -func TestSetUSBResetOnOpen(t *testing.T) { - SetUSBResetOnOpen(true) - SetUSBResetOnOpen(false) -} - -func TestGetSerial(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - serial, _ := rf.GetSerial() - fmt.Println(serial) -} - -func TestGetSerialStruct(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - serial, _ := rf.GetSerialStruct() - fmt.Print(serial) -} - -func TestGetFpgaSize(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - size, _ := rf.GetFpgaSize() - fmt.Print(size) -} - -func TestGetFpgaSource(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - source, _ := rf.GetFpgaSource() - fmt.Print(source) -} - -func TestGetDeviceSpeed(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - speed := rf.GetDeviceSpeed() - fmt.Print(speed) -} - -func TestGetBoardName(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - name := rf.GetBoardName() - fmt.Print(name) -} - -func TestGetRationalSampleRate(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - rate, _ := rf.GetRationalSampleRate(ChannelRx(1)) - fmt.Print(rate) -} - -func TestGetFpgaBytes(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - bytes, _ := rf.GetFpgaBytes() - fmt.Print(bytes) -} - -func TestGetFpgaFlashSize(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - size, guess, err := rf.GetFpgaFlashSize() - - if err != nil { - panic(err) - } else { - fmt.Print(size) - fmt.Print(guess) - } -} - -func TestGetFirmwareVersion(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - version, err := rf.GetFirmwareVersion() - - if err != nil { - panic(err) - } - - fmt.Print(version.Describe) -} - -func TestGetFpgaVersion(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - version, _ := rf.GetFpgaVersion() - fmt.Print(version.Describe) -} - -func TestGetLoopbackModes(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - modes, _ := rf.GetLoopbackModes() - for _, v := range modes { - fmt.Printf("%s\n\n", v.Name) - } -} - -func TestGetQuickTune(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - channel := ChannelRx(1) - - quickTune, err := rf.GetQuickTune(channel) - - if err != nil { - panic(err) - } - - err = rf.ScheduleReTune(channel, ReTuneNow, 96600000, quickTune) - - if err != nil { - panic(err) - } -} - -func TestExpansionBoard(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - board, err := rf.GetAttachedExpansionBoard() - - if err != nil { - panic(err) - } - - fmt.Println(board) -} - -func TestReTuneNow(t *testing.T) { - fmt.Println(ReTuneNow) -} - -func TestTriggerReg(t *testing.T) { - fmt.Println(TriggerRegArm) - fmt.Println(TriggerRegFire) - fmt.Println(TriggerRegMaster) - fmt.Println(TriggerRegLine) -} - func TestReadFlashBytes(t *testing.T) { - log.SetVerbosity(log.Debug) - devices, _ := GetDeviceList() if len(devices) == 0 { @@ -371,8 +1683,6 @@ func TestReadFlashBytes(t *testing.T) { } func TestReadFlash(t *testing.T) { - log.SetVerbosity(log.Debug) - devices, _ := GetDeviceList() if len(devices) == 0 { @@ -394,8 +1704,6 @@ func TestReadFlash(t *testing.T) { } func TestRfPort(t *testing.T) { - log.SetVerbosity(log.Debug) - devices, _ := GetDeviceList() if len(devices) == 0 { @@ -418,8 +1726,6 @@ func TestRfPort(t *testing.T) { } func TestReadOtp(t *testing.T) { - log.SetVerbosity(log.Debug) - devices, _ := GetDeviceList() if len(devices) == 0 { @@ -438,153 +1744,6 @@ func TestReadOtp(t *testing.T) { rf.ReadOtp() } -func TestTrigger(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - channel := ChannelRx(0) - signal := TriggerSignalJ714 - - triggerMaster, err := rf.TriggerInit(channel, signal) - - if err != nil { - panic(err) - } - - triggerMaster.SetRole(TriggerRoleMaster) - - triggerSlave, err := rf.TriggerInit(channel, signal) - - if err != nil { - panic(err) - } - - triggerSlave.SetRole(TriggerRoleSlave) - - err = rf.TriggerArm(triggerMaster, true, 0, 0) - - if err != nil { - panic(err) - } - - err = rf.TriggerFire(triggerMaster) - - if err != nil { - panic(err) - } - - a, b, c, x, y, err := rf.TriggerState(triggerMaster) - - if err != nil { - panic(err) - } - - fmt.Println(a, b, c, x, y) -} - -func TestIsFpgaConfigured(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - isConfigured, err := rf.IsFpgaConfigured() - - if err != nil { - panic(err) - } - - fmt.Print(isConfigured) -} - -func TestBladeRF(t *testing.T) { - log.SetVerbosity(log.Error) - - version := GetVersion() - version.Print() - - bootloaders, _ := GetBootloaderList() - fmt.Printf("Bootloaders Len: %d\n", len(bootloaders)) - - devices, _ := GetDeviceList() - fmt.Printf("Devices Len: %d\n", len(devices)) - rf, _ := devices[0].Open() - _ = rf.LoadFpga("/Users/erayarslan/Downloads/hostedxA4-latest.rbf") - rf.Close() - - rf, _ = Open() - info, _ := rf.GetDeviceInfo() - rf.Close() - h, _ := rf.GetDeviceInfo() - out, _ := h.Open() - out.Close() - c1, _ := Open() - c1.Close() - c2, _ := OpenWithDeviceIdentifier("*:serial=" + info.Serial) - c2.Close() - o1, _ := GetDeviceInfoFromString("*:serial=" + info.Serial) - out2, _ := o1.Open() - out2.Close() - - g, _ := rf.GetDeviceInfo() - result := g.DeviceInfoMatches(g) - fmt.Println("---------") - fmt.Println(result) - fmt.Println("---------") - - g0, _ := rf.GetDeviceInfo() - result = g0.DeviceStringMatches("*:serial=" + info.Serial) - fmt.Println("---------") - fmt.Println(result) - fmt.Println("---------") - - rf, _ = Open() - - err := rf.EnableModule(ChannelRx(1)) - if err != nil { - fmt.Println(err) - } - _, _ = rf.InitStream(FormatSc16Q11, 16, audioBufferSize, 8, cb) - // _ = StartStream(stream, RX_X1) -} - -func TestSetGainStage(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - stages, _ := rf.GetGainStages(ChannelRx(1)) - fmt.Println(len(stages)) - bfRange, _ := rf.GetGainStageRange(ChannelRx(1), stages[0]) - _ = rf.SetGainStage(ChannelRx(1), stages[0], int(bfRange.Max)) - gain, _ := rf.GetGainStage(ChannelRx(1), stages[0]) - fmt.Println(gain) -} - func TestChannel(t *testing.T) { a := ChannelRx(0) b := ChannelTx(0) @@ -596,208 +1755,3 @@ func TestChannel(t *testing.T) { fmt.Println(ChannelIsTx(2)) fmt.Println(ChannelIsTx(3)) } - -func TestStream(t *testing.T) { - sig := make(chan os.Signal, 1) - signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) - - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - channel := ChannelRx(1) - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - _ = rf.SetFrequency(channel, 96600000) - _range, _ := rf.GetSampleRateRange(channel) - fmt.Printf("Min: %d, Max: %d, Step: %d\n", _range.Min, _range.Max, _range.Step) - _, _ = rf.SetSampleRate(channel, 4e6) - _ = rf.SyncConfig(RxX2, FormatSc16Q11, 16, audioBufferSize, 8, 32) - actual, _ := rf.SetBandwidth(channel, 240000) - fmt.Println(actual) - _ = rf.EnableModule(channel) - _ = rf.SetGainMode(channel, GainModeHybridAgc) - - demodulator = demodcore.MakeWBFMDemodulator(uint32(2e6), 80e3, 48000) - - _ = portaudio.Initialize() - h, _ := portaudio.DefaultHostApi() - - p := portaudio.LowLatencyParameters(nil, h.DefaultOutputDevice) - p.Input.Channels = 0 - p.Output.Channels = 1 - p.SampleRate = 48000 - p.FramesPerBuffer = audioBufferSize - - audioStream, _ = portaudio.OpenStream(p, ProcessAudio) - _ = audioStream.Start() - - go func() { - for { - data, _ := rf.SyncRX(audioBufferSize) - out := demodulator.Work(GetFinalData(data)) - - if out != nil { - var o = out.(demodcore.DemodData) - var nBf = make([]float32, len(o.Data)) - copy(nBf, o.Data) - var buffs = len(nBf) / audioBufferSize - for i := 0; i < buffs; i++ { - audioFifo.Add(nBf[audioBufferSize*i : audioBufferSize*(i+1)]) - } - } - } - }() - - <-sig - fmt.Println("shit") -} - -func cb(data []int16) { - out := demodulator.Work(GetFinalData(data)) - - if out != nil { - var o = out.(demodcore.DemodData) - var nBf = make([]float32, len(o.Data)) - copy(nBf, o.Data) - var buffs = len(nBf) / audioBufferSize - for i := 0; i < buffs; i++ { - audioFifo.Add(nBf[audioBufferSize*i : audioBufferSize*(i+1)]) - } - } -} - -func TestGetGainModes(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - _, _ = rf.GetGainModes(ChannelRx(1)) -} - -func TestGetGainRange(t *testing.T) { - log.SetVerbosity(log.Debug) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - bfRange, _ := rf.GetGainRange(ChannelRx(1)) - fmt.Println(bfRange.Max) -} - -func TestGPSData(t *testing.T) { - log.SetVerbosity(log.Debug) - channel := ChannelRx(1) - - devices, _ := GetDeviceList() - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, _ := devices[0].Open() - defer rf.Close() - - _ = rf.SetFrequency(channel, 1525420000) - _ = rf.SyncConfig(RxX2, FormatSc16Q11, 16, audioBufferSize, 8, 32) - _, _ = rf.SetSampleRate(channel, 2600000) - _, _ = rf.SetBandwidth(channel, 2500000) - _ = rf.SetGainMode(channel, GainModeHybridAgc) - _ = rf.EnableModule(channel) - - for { - data, _ := rf.SyncRX(audioBufferSize) - out := GetFinalDataString(data) - fmt.Println(out) - } -} - -func TestAsyncStream(t *testing.T) { - log.SetVerbosity(log.Debug) - - sig := make(chan os.Signal, 1) - signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill) - - channel := ChannelRx(0) - - devices, err := GetDeviceList() - - if err != nil { - panic(err) - } - - if len(devices) == 0 { - fmt.Println("NO DEVICE") - return - } - - rf, err := devices[0].Open() - - if err != nil { - panic(err) - } - - defer rf.Close() - - _ = rf.SetFrequency(channel, 96600000) - _, _ = rf.SetSampleRate(channel, 4e6) - _, _ = rf.SetBandwidth(channel, 240000) - _ = rf.SetGainMode(channel, GainModeHybridAgc) - _ = rf.EnableModule(channel) - - rxStream, err := rf.InitStream(FormatSc16Q11, 16, audioBufferSize, 8, cb) - if err != nil { - panic(err) - } - defer rxStream.DeInit() - - _ = rf.SetStreamTimeout(Rx, 32) - timeout, _ := rf.GetStreamTimeout(Rx) - println(timeout) - - demodulator = demodcore.MakeWBFMDemodulator(uint32(2e6), 80e3, 48000) - - _ = portaudio.Initialize() - h, _ := portaudio.DefaultHostApi() - - p := portaudio.LowLatencyParameters(nil, h.DefaultOutputDevice) - p.Input.Channels = 0 - p.Output.Channels = 1 - p.SampleRate = 48000 - p.FramesPerBuffer = audioBufferSize - - audioStream, _ = portaudio.OpenStream(p, ProcessAudio) - _ = audioStream.Start() - - go func() { - err = rxStream.Start(RxX2) - if err != nil { - panic(err) - } - }() - - <-sig - fmt.Println("done") -} diff --git a/enums.go b/enums.go index 0cdd850..e1f20e1 100644 --- a/enums.go +++ b/enums.go @@ -24,9 +24,16 @@ type TriggerSignal int type ExpansionBoard int type VctcxoTamerMode int type TuningMode int +type GoStream int const FlashPageSize = 256 // BLADERF_FLASH_PAGE_SIZE - Size of the SPI flash, in pages +const ( + GoStreamNext GoStream = 0 + GoStreamNoData GoStream = 1 + GoStreamShutdown GoStream = 2 +) + const ( BackendAny Backend = C.BLADERF_BACKEND_ANY BackendLinux Backend = C.BLADERF_BACKEND_LINUX diff --git a/go.mod b/go.mod index 1f2c0b8..344abf6 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,5 @@ module github.com/erayarslan/go-bladerf go 1.13 require ( - github.com/gordonklaus/portaudio v0.0.0-20180817120803-00e7307ccd93 github.com/mattn/go-pointer v0.0.1 - github.com/racerxdl/go.fifo v0.0.0-20180604061744-c6aa83afe374 - github.com/racerxdl/segdsp v0.0.0-20190413213320-dfaea7c39d3a ) diff --git a/go.sum b/go.sum index c75317b..1fdefea 100644 --- a/go.sum +++ b/go.sum @@ -1,58 +1,2 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/go-gl/gl v0.0.0-20180407155706-68e253793080/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk= -github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/gordonklaus/portaudio v0.0.0-20180817120803-00e7307ccd93 h1:TSG+DyZBnazM22ZHyHLeUkzM34ClkJRjIWHTq4btvek= -github.com/gordonklaus/portaudio v0.0.0-20180817120803-00e7307ccd93/go.mod h1:HfYnZi/ARQKG0dwH5HNDmPCHdLiFiBf+SI7DbhW7et4= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/llgcode/draw2d v0.0.0-20180825133448-f52c8a71aff0/go.mod h1:mVa0dA29Db2S4LVqDYLlsePDzRJLDfdhVZiI15uY0FA= -github.com/llgcode/ps v0.0.0-20150911083025-f1443b32eedb/go.mod h1:1l8ky+Ew27CMX29uG+a2hNOKpeNYEQjjtiALiBlFQbY= -github.com/logrusorgru/aurora v0.0.0-20181002194514-a7b3b318ed4e/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= -github.com/mattetti/audio v0.0.0-20190404201502-c6aebeb78429 h1:5YWANgpchDSYJ0R6i3ODpZ4KN/1Jm9MZcFDtAtegjNM= -github.com/mattetti/audio v0.0.0-20190404201502-c6aebeb78429/go.mod h1:LlQmBGkOuV/SKzEDXBPKauvN2UqCgzXO2XjecTGj40s= -github.com/mattn/go-pointer v0.0.0-20180825124634-49522c3f3791/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= github.com/mattn/go-pointer v0.0.1 h1:n+XhsuGeVO6MEAp7xyEukFINEa+Quek5psIR/ylA6o0= github.com/mattn/go-pointer v0.0.1/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc= -github.com/myriadrf/limedrv v0.0.0-20190225221912-8583a26e3fce/go.mod h1:/SXVBJBHAVLlvLU1B1n0a0QPcZBtqF1VpH5POPZzuBw= -github.com/oov/audio v0.0.0-20171004131523-88a2be6dbe38 h1:4Upfs5rLQdx7KwBct3bmPYAhWsDDJdx660gYb7Lv9TQ= -github.com/oov/audio v0.0.0-20171004131523-88a2be6dbe38/go.mod h1:Xj06yMta9R1RSKiHmxL0Bo2TB8wiKVnMgA0KVopHHkk= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/quan-to/slog v0.0.0-20190317205605-56a2b4159924/go.mod h1:xc9X6JvWjqAAIox9u4uuolisjwl/GbfkktH6f+nOgqU= -github.com/racerxdl/fastconvert v0.0.0-20190129064530-871b6f6cd82a/go.mod h1:V4kP6uu5nqjDVGhlYMtT/7JG7WJjXnipMGcQ8PFeUqU= -github.com/racerxdl/go.fifo v0.0.0-20180604061744-c6aa83afe374 h1:P2TDDsGEWzzfhAnthdQc+Vwmv/+xEKHwoNFF3Swl6X0= -github.com/racerxdl/go.fifo v0.0.0-20180604061744-c6aa83afe374/go.mod h1:CvYWG6Py4TRzGCUVX2n8+CjE6mrME/+kHkkGmbDA5zw= -github.com/racerxdl/radioserver v0.0.0-20190316070955-f8953f368ce1/go.mod h1:cSQupBUlkn/QhajTmf6QMErp3PbTVT5Xdd5DSiE0hAI= -github.com/racerxdl/radioserver v0.0.0-20190324175745-bd3bd7179419/go.mod h1:N4ejKokz1jnGfAd3KNgO8E6YMCMP4ZgaHXBEdHBQrP8= -github.com/racerxdl/segdsp v0.0.0-20190321214158-1cd3e325e91a/go.mod h1:nQDTqJjqr+YsSQw+CVY58Xag4KVqfoi6TgkSXMHlUO4= -github.com/racerxdl/segdsp v0.0.0-20190413213320-dfaea7c39d3a h1:2QJXxaBOGMsjoZ++ecsek0SE/V4bbraCITBNVji4+4M= -github.com/racerxdl/segdsp v0.0.0-20190413213320-dfaea7c39d3a/go.mod h1:NXNN9LqX1oeK6+o+xm+Dz8ANz+i1uILw4HsL0sq5tzE= -github.com/racerxdl/spy2go v0.0.0-20190103011754-14102c047be5/go.mod h1:ioS4oIwJsgrSeKKPATMpsbJQdi4p2Xsbg3V5j2nCOzM= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190322120337-addf6b3196f6/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/macro_wrapper.c b/macro_wrapper.c index 34fdb25..4ed6e66 100644 --- a/macro_wrapper.c +++ b/macro_wrapper.c @@ -1,10 +1,20 @@ #include "macro_wrapper.h" uint64_t ReTuneNow = BLADERF_RETUNE_NOW; +uint32_t MetaFlagTxBurstStart = BLADERF_META_FLAG_TX_BURST_START; +uint32_t MetaFlagTxBurstEnd = BLADERF_META_FLAG_TX_BURST_END; +uint32_t MetaFlagTxNow = BLADERF_META_FLAG_TX_NOW; +uint32_t MetaFlagTxUpdateTimestamp = BLADERF_META_FLAG_TX_UPDATE_TIMESTAMP; +uint32_t MetaFlagRxNow = BLADERF_META_FLAG_RX_NOW; +uint32_t MetaFlagRxHwUnderflow = BLADERF_META_FLAG_RX_HW_UNDERFLOW; +uint32_t MetaFlagRxHwMiniexp1 = BLADERF_META_FLAG_RX_HW_MINIEXP1; +uint32_t MetaFlagRxHwMiniexp2 = BLADERF_META_FLAG_RX_HW_MINIEXP2; uint8_t TriggerRegArm = BLADERF_TRIGGER_REG_ARM; uint8_t TriggerRegFire = BLADERF_TRIGGER_REG_FIRE; uint8_t TriggerRegMaster = BLADERF_TRIGGER_REG_MASTER; uint8_t TriggerRegLine = BLADERF_TRIGGER_REG_LINE; +void* StreamNoData = BLADERF_STREAM_NO_DATA; +void* StreamShutdown = BLADERF_STREAM_SHUTDOWN; int ChannelRx(const int ch) { return BLADERF_CHANNEL_RX(ch); diff --git a/macro_wrapper.h b/macro_wrapper.h index 73f3d66..e6807f0 100644 --- a/macro_wrapper.h +++ b/macro_wrapper.h @@ -1,10 +1,20 @@ #include extern uint64_t ReTuneNow; +extern uint32_t MetaFlagTxBurstStart; +extern uint32_t MetaFlagTxBurstEnd; +extern uint32_t MetaFlagTxNow; +extern uint32_t MetaFlagTxUpdateTimestamp; +extern uint32_t MetaFlagRxNow; +extern uint32_t MetaFlagRxHwUnderflow; +extern uint32_t MetaFlagRxHwMiniexp1; +extern uint32_t MetaFlagRxHwMiniexp2; extern uint8_t TriggerRegArm; extern uint8_t TriggerRegFire; extern uint8_t TriggerRegMaster; extern uint8_t TriggerRegLine; +extern void* StreamNoData; +extern void* StreamShutdown; int ChannelRx(const int ch); int ChannelTx(const int ch); diff --git a/macros.go b/macros.go index e2dce5b..9fdb2e5 100644 --- a/macros.go +++ b/macros.go @@ -2,13 +2,23 @@ package bladerf // #include "macro_wrapper.h" import "C" +import "unsafe" var ReTuneNow = Timestamp(C.ReTuneNow) - +var MetaFlagTxBurstStart = uint32(C.MetaFlagTxBurstStart) +var MetaFlagTxBurstEnd = uint32(C.MetaFlagTxBurstEnd) +var MetaFlagTxNow = uint32(C.MetaFlagTxNow) +var MetaFlagTxUpdateTimestamp = uint32(C.MetaFlagTxUpdateTimestamp) +var MetaFlagRxNow = uint32(C.MetaFlagRxNow) +var MetaFlagRxHwUnderflow = uint32(C.MetaFlagRxHwUnderflow) +var MetaFlagRxHwMiniexp1 = uint32(C.MetaFlagRxHwMiniexp1) +var MetaFlagRxHwMiniexp2 = uint32(C.MetaFlagRxHwMiniexp2) var TriggerRegArm = C.TriggerRegArm var TriggerRegFire = C.TriggerRegFire var TriggerRegMaster = C.TriggerRegMaster var TriggerRegLine = C.TriggerRegLine +var StreamNoData = unsafe.Pointer(C.StreamNoData) +var StreamShutdown = unsafe.Pointer(C.StreamShutdown) func ChannelRx(ch int) Channel { return Channel(C.ChannelRx(C.int(ch))) diff --git a/structs.go b/structs.go index d06d94a..87f18b0 100644 --- a/structs.go +++ b/structs.go @@ -156,12 +156,40 @@ func NewGainModes(ref *C.struct_bladerf_gain_modes) GainModes { return gainModes } +type Metadata struct { + ref *C.struct_bladerf_metadata + Timestamp Timestamp + Flags uint32 + Status uint32 + ActualCount uint +} + +func LoadMetadata(ref *C.struct_bladerf_metadata) Metadata { + metadata := Metadata{ref: ref} + + metadata.Timestamp = Timestamp(metadata.ref.timestamp) + metadata.Flags = uint32(metadata.ref.flags) + metadata.Status = uint32(metadata.ref.status) + metadata.ActualCount = uint(metadata.ref.actual_count) + + return metadata +} + +func NewMetadata(timestamp Timestamp, flags uint32) Metadata { + ref := C.struct_bladerf_metadata{ + timestamp: C.uint64_t(timestamp), + flags: C.uint32_t(flags), + } + + return LoadMetadata(&ref) +} + type UserData struct { - callback func(data []int16) + callback func(data []int16) GoStream results []int16 bufferSize int } -func NewUserData(callback func(data []int16), bufferSize int) UserData { +func NewUserData(callback func(data []int16) GoStream, bufferSize int) UserData { return UserData{callback: callback, results: make([]int16, bufferSize), bufferSize: bufferSize} }