package bladerf // #cgo darwin CFLAGS: -I/usr/local/include // #cgo darwin LDFLAGS: -L/usr/local/lib // #cgo LDFLAGS: -lbladeRF // #include // // extern void* cbGo(struct bladerf *dev, struct bladerf_stream *stream, struct bladerf_metadata *md, void* samples, size_t num_samples, void* user_data); import "C" import ( error2 "bladerf/error" "fmt" "unsafe" ) //export cbGo func cbGo(dev *C.struct_bladerf, stream *C.struct_bladerf_stream, metadata *C.struct_bladerf_metadata, samples unsafe.Pointer, numSamples C.size_t, userData unsafe.Pointer) unsafe.Pointer { data := (*[0]uint16)(samples) if len(*data) > 0 { println(data) } else { println(data) } var rv unsafe.Pointer return rv } type GainMode int type Backend int type Direction int type ChannelLayout int type Correction int type Format int type Loopback int type RXMux int type ClockSelect int type PowerSource int type PMICRegister int type IOModule int const ( IOTX IOModule = C.BLADERF_MODULE_TX IORX IOModule = C.BLADERF_MODULE_RX ) const ( Default GainMode = C.BLADERF_GAIN_DEFAULT Manual GainMode = C.BLADERF_GAIN_MGC FastAttack_AGC GainMode = C.BLADERF_GAIN_FASTATTACK_AGC SlowAttack_AGC GainMode = C.BLADERF_GAIN_SLOWATTACK_AGC Hybrid_AGC GainMode = C.BLADERF_GAIN_HYBRID_AGC ) const ( Any Backend = C.BLADERF_BACKEND_ANY Linux Backend = C.BLADERF_BACKEND_LINUX LibUSB Backend = C.BLADERF_BACKEND_LIBUSB Cypress Backend = C.BLADERF_BACKEND_CYPRESS Dummy Backend = C.BLADERF_BACKEND_DUMMY ) const ( TX Direction = C.BLADERF_TX RX Direction = C.BLADERF_RX ) const ( RX_X1 ChannelLayout = C.BLADERF_RX_X1 TX_X1 ChannelLayout = C.BLADERF_TX_X1 RX_X2 ChannelLayout = C.BLADERF_RX_X2 TX_X2 ChannelLayout = C.BLADERF_TX_X2 ) const ( DCOFF_I Correction = C.BLADERF_CORR_DCOFF_I DCOFF_Q Correction = C.BLADERF_CORR_DCOFF_Q PHASE Correction = C.BLADERF_CORR_PHASE GAIN Correction = C.BLADERF_CORR_GAIN ) const ( SC16_Q11 Format = C.BLADERF_FORMAT_SC16_Q11 SC16_Q11_META Format = C.BLADERF_FORMAT_SC16_Q11_META ) const ( Disabled Loopback = C.BLADERF_LB_NONE Firmware Loopback = C.BLADERF_LB_FIRMWARE BB_TXLPF_RXVGA2 Loopback = C.BLADERF_LB_BB_TXLPF_RXVGA2 BB_TXVGA1_RXVGA2 Loopback = C.BLADERF_LB_BB_TXVGA1_RXVGA2 BB_TXLPF_RXLPF Loopback = C.BLADERF_LB_BB_TXLPF_RXLPF BB_TXVGA1_RXLPF Loopback = C.BLADERF_LB_BB_TXVGA1_RXLPF RF_LNA1 Loopback = C.BLADERF_LB_RF_LNA1 RF_LNA2 Loopback = C.BLADERF_LB_RF_LNA2 RF_LNA3 Loopback = C.BLADERF_LB_RF_LNA3 RFIC_BIST Loopback = C.BLADERF_LB_RFIC_BIST ) const ( Invalid RXMux = C.BLADERF_RX_MUX_INVALID Baseband RXMux = C.BLADERF_RX_MUX_BASEBAND Counter_12bit RXMux = C.BLADERF_RX_MUX_12BIT_COUNTER Counter_32bit RXMux = C.BLADERF_RX_MUX_32BIT_COUNTER Digital_Loopback RXMux = C.BLADERF_RX_MUX_DIGITAL_LOOPBACK ) const ( ClockSelectUnknown ClockSelect = -99 ClockSelectVCTCXO ClockSelect = C.CLOCK_SELECT_ONBOARD ClockSelectExternal ClockSelect = C.CLOCK_SELECT_EXTERNAL ) const ( PowerSourceUnknown PowerSource = C.BLADERF_UNKNOWN PowerSourceDC_Barrel PowerSource = C.BLADERF_PS_DC PowerSourceUSB_VBUS PowerSource = C.BLADERF_PS_USB_VBUS ) const ( Configuration PMICRegister = C.BLADERF_PMIC_CONFIGURATION Voltage_shunt PMICRegister = C.BLADERF_PMIC_VOLTAGE_SHUNT Voltage_bus PMICRegister = C.BLADERF_PMIC_VOLTAGE_BUS Power PMICRegister = C.BLADERF_PMIC_POWER Current PMICRegister = C.BLADERF_PMIC_CURRENT Calibration PMICRegister = C.BLADERF_PMIC_CALIBRATION ) const ( RX_V int = 0x0 TX_V int = 0x1 ) const ( BLADERF_VCTCXO_FREQUENCY = 38.4e6 BLADERF_REFIN_DEFAULT = 10.0e6 BLADERF_SERIAL_LENGTH = 33 ) func checkError(e error) { if e != nil { fmt.Printf(e.Error()) } } type Version struct { version *C.struct_bladerf_version major int minor int patch int describe string } type DevInfo struct { devInfo *C.struct_bladerf_devinfo } type Range struct { bfRange *C.struct_bladerf_range } type BladeRF struct { bladeRF *C.struct_bladerf } type Module struct { module *C.struct_bladerf_module } type Stream struct { stream *C.struct_bladerf_stream } func GetVersion() Version { var version C.struct_bladerf_version C.bladerf_version(&version) return Version{version: &version, major: int(version.major), minor: int(version.minor), patch: int(version.patch), describe: C.GoString(version.describe)} } func PrintVersion(version Version) { fmt.Printf("v%d.%d.%d (\"%s\")", version.major, version.minor, version.patch, version.describe) } func GetError(e C.int) error { if e == 0 { return nil } return error2.Error(e) } func LoadFpga(bladeRF BladeRF, imagePath string) { path := C.CString(imagePath) defer C.free(unsafe.Pointer(path)) C.bladerf_load_fpga(bladeRF.bladeRF, path) C.bladerf_close(bladeRF.bladeRF) } func FreeDeviceList(devInfo DevInfo) { C.bladerf_free_device_list(devInfo.devInfo) } func GetDeviceList() []DevInfo { var devInfo *C.struct_bladerf_devinfo var devices []DevInfo count := int(C.bladerf_get_device_list(&devInfo)) if count < 1 { return devices } first := DevInfo{devInfo: devInfo} defer FreeDeviceList(first) devices = append(devices, first) for i := 0; i < count-1; i++ { size := unsafe.Sizeof(*devInfo) devInfo = (*C.struct_bladerf_devinfo)(unsafe.Pointer(uintptr(unsafe.Pointer(devInfo)) + size)) devices = append(devices, DevInfo{devInfo: devInfo}) } return devices } func GetBootloaderList() []DevInfo { var devInfo *C.struct_bladerf_devinfo var devices []DevInfo count := int(C.bladerf_get_bootloader_list(&devInfo)) if count < 1 { return devices } first := DevInfo{devInfo: devInfo} defer FreeDeviceList(first) devices = append(devices, first) for i := 0; i < count-1; i++ { size := unsafe.Sizeof(*devInfo) devInfo = (*C.struct_bladerf_devinfo)(unsafe.Pointer(uintptr(unsafe.Pointer(devInfo)) + size)) devices = append(devices, DevInfo{devInfo: devInfo}) } return devices } func CHANNEL_RX(ch int) int { return (ch << 1) | RX_V } func CHANNEL_TX(ch int) int { return (ch << 1) | TX_V } func GetDevInfo() DevInfo { var devInfo C.struct_bladerf_devinfo C.bladerf_init_devinfo(&devInfo) return DevInfo{devInfo: &devInfo} } func OpenWithDevInfo(devInfo DevInfo) BladeRF { var bladeRF *C.struct_bladerf C.bladerf_open_with_devinfo(&bladeRF, devInfo.devInfo) return BladeRF{bladeRF: bladeRF} } func OpenWithDeviceIdentifier(identify string) BladeRF { var bladeRF *C.struct_bladerf C.bladerf_open(&bladeRF, C.CString(identify)) return BladeRF{bladeRF: bladeRF} } func Open() BladeRF { var bladeRF *C.struct_bladerf C.bladerf_open(&bladeRF, nil) return BladeRF{bladeRF: bladeRF} } func Close(bladeRF BladeRF) { C.bladerf_close(bladeRF.bladeRF) } func SetLoopback(bladeRF *BladeRF, loopback Loopback) { C.bladerf_set_loopback((*bladeRF).bladeRF, C.bladerf_loopback(loopback)) } func SetFrequency(bladeRF *BladeRF, module IOModule, frequency int) error { return GetError(C.bladerf_set_frequency((*bladeRF).bladeRF, C.bladerf_module(module), C.ulonglong(frequency))) } func SetSampleRate(bladeRF *BladeRF, module IOModule, sampleRate int) error { var actual C.uint err := GetError(C.bladerf_set_sample_rate((*bladeRF).bladeRF, C.bladerf_module(module), C.uint(sampleRate), &actual)) if err == nil { println(uint(actual)) } return err } func GetSampleRateRange(bladeRF *BladeRF, module IOModule) (int, int, int, error) { var bfRange *C.struct_bladerf_range err := GetError(C.bladerf_get_sample_rate_range((*bladeRF).bladeRF, C.bladerf_module(module), &bfRange)) if err != nil { return 0, 0, 0, err } return int(bfRange.min), int(bfRange.max), int(bfRange.step), nil } func SetBandwidth(bladeRF *BladeRF, module IOModule, bandwidth int) (int, error) { var actual C.bladerf_bandwidth return int(actual), GetError(C.bladerf_set_bandwidth((*bladeRF).bladeRF, C.bladerf_module(module), C.uint(bandwidth), &actual)) } func SetGain(bladeRF *BladeRF, module IOModule, gain int) error { return GetError(C.bladerf_set_gain((*bladeRF).bladeRF, C.bladerf_module(module), C.int(gain))) } func GetGainMode(bladeRF *BladeRF, module IOModule) (GainMode, error) { var mode C.bladerf_gain_mode err := GetError(C.bladerf_get_gain_mode((*bladeRF).bladeRF, C.bladerf_module(module), &mode)) result := GainMode(int(mode)) if err == nil { return result, nil } return -1, err } func SetGainMode(bladeRF *BladeRF, module IOModule, mode GainMode) error { return GetError(C.bladerf_set_gain_mode((*bladeRF).bladeRF, C.bladerf_module(module), C.bladerf_gain_mode(mode))) } func EnableModule(bladeRF *BladeRF, direction Direction) error { return GetError(C.bladerf_enable_module((*bladeRF).bladeRF, C.bladerf_module(direction), true)) } func DisableModule(bladeRF *BladeRF, direction Direction) error { return GetError(C.bladerf_enable_module((*bladeRF).bladeRF, C.bladerf_module(direction), false)) } var call = 0 func do_work() bool { call = call + 1 return call >= 5000 } func SyncRX(bladeRF *BladeRF, bufferSize uintptr) []int16 { var metadata C.struct_bladerf_metadata var buff *C.int16_t size := unsafe.Sizeof(*buff) start := C.malloc(C.size_t(size * bufferSize * 2 * 1)) var err error var done bool var results []int16 for err == nil && !done { err = GetError(C.bladerf_sync_rx((*bladeRF).bladeRF, start, C.uint(bufferSize), &metadata, 32)) if err == nil { done = do_work() if done { for i := 0; i < (int(metadata.actual_count)); i++ { n := (*C.int16_t)(unsafe.Pointer(uintptr(start) + (size * uintptr(i)))) results = append(results, int16(*n)) } } } else { fmt.Printf("Failed to RX samples: %s", err) } } return results } func InitStream(bladeRF *BladeRF, format Format, numBuffers int, samplesPerBuffer int, numTransfers int) *Stream { var buffers *unsafe.Pointer var data unsafe.Pointer var rxStream *C.struct_bladerf_stream stream := Stream{stream: rxStream} C.bladerf_init_stream( &((stream).stream), (*bladeRF).bladeRF, (*[0]byte)((C.cbGo)), &buffers, C.ulong(numBuffers), C.bladerf_format(format), C.ulong(samplesPerBuffer), C.ulong(numTransfers), data, ) return &stream } func DeInitStream(stream *Stream) { C.bladerf_deinit_stream(stream.stream) } func GetStreamTimeout(bladeRF *BladeRF, direction Direction) int { var timeout C.uint err := GetError(C.bladerf_get_stream_timeout((*bladeRF).bladeRF, C.bladerf_direction(direction), &timeout)) fmt.Println(err) return int(timeout) } func SetStreamTimeout(bladeRF *BladeRF, direction Direction, timeout int) { err := GetError(C.bladerf_set_stream_timeout((*bladeRF).bladeRF, C.bladerf_direction(direction), C.uint(timeout))) fmt.Println(err) } func SyncConfig(bladeRF *BladeRF, layout ChannelLayout, format Format, numBuffers int, bufferSize int, numTransfers int, timeout int) error { err := GetError(C.bladerf_sync_config((*bladeRF).bladeRF, C.bladerf_channel_layout(layout), C.bladerf_format(format), C.uint(numBuffers), C.uint(bufferSize), C.uint(numTransfers), C.uint(timeout))) return err } func StartStream(stream *Stream, layout ChannelLayout) { err := GetError(C.bladerf_stream(stream.stream, C.bladerf_channel_layout(layout))) fmt.Println(err) }