hackrf.js
Version:
Control HackRF devices from Node.js
420 lines (419 loc) • 13 kB
TypeScript
/**
* Main module, contains the USB interfacing code
* and user-facing API
* @module
*/
/// <reference types="node" />
import { usb } from 'usb';
declare type Device = usb.Device;
import { BoardId, RfPathFilter, OperacakePorts, SweepStyle, TransceiverMode } from './constants';
export interface StreamOptions {
/** number of concurrent transfers */
transferCount?: number;
/**
* size of each transfer.
* should be multiple of packet size to avoid overflow
*/
transferBufferSize?: number;
}
export declare const defaultStreamOptions: StreamOptions;
declare type PollCallback = (x: Int8Array) => undefined | void | false;
export interface DeviceInfo {
device: Device;
usbBoardId: number;
serialNumber?: string;
}
/**
* Return info about each HackRF device present.
*/
export declare function listDevices(): AsyncGenerator<DeviceInfo, void, unknown>;
/**
* Open the first device whose serial number ends with the passed suffix.
* If no suffix is passed, open the first device.
*
* @param serialNumber Serial number suffix to match
*/
export declare function open(serialNumber?: string): Promise<HackrfDevice>;
/**
* Reference to an open HackRF device
*
* This is mostly a direct API to the USB interface. Call
* [[close]] when no longer needed.
*
* Keep in mind some methods require a certain API version
* to be implemented by your device's firmware; this is noted
* in their documentation, and an `USB_API_VERSION` error will
* be thrown if you attempt to use them. [[usbApiVersion]]
* returns the version implemented by the firmware. It's
* strongly recommended to upgrade your device's firmware to
* the latest version to avoid problems and glitches.
*
* This API does strict validation of passed integers (they
* should be integers and be in-range). Gains, in particular,
* will be *rejected* instead of rounded down to the nearest
* step.
*/
export declare class HackrfDevice {
private readonly handle;
private readonly iface;
private readonly inEndpoint;
private readonly outEndpoint;
private _open;
/**
* Open the passed USB device
*
* This function does **not** validate the device,
* it's recommended to use the `open` module function
* instead of this function directly.
*
* @param device USB device (must not be open)
* @category Main
*/
static open(device: Device): Promise<HackrfDevice>;
private constructor();
get open(): boolean;
/**
* Release resources and close the USB device
*
* Unless the device is used until process exit, this **must** be
* called once when it's no longer needed.
*
* There must be no pending promises or an active stream when
* calling this. After return, no more methods should be called
* on this object.
*
* @category Main
*/
close(): Promise<void>;
/**
* Version of the USB API implemented by the device's firmware
*
* In `0xAABB` form (`AA` = major, `BB` = minor).
*/
get usbApiVersion(): number;
private usbApiRequired;
private controlTransferIn;
private controlTransferOut;
protected setTransceiverMode(value: TransceiverMode): Promise<void>;
/**
* Query the firmware version
*
* @category Device info
*/
getVersionString(): Promise<string>;
/**
* @category Device info
*/
getBoardId(): Promise<BoardId>;
/**
* @category Device info
*/
getBoardPartIdSerialNo(): Promise<{
partId: [number, number];
serialNo: [number, number, number, number];
}>;
/**
* @category IC
*/
max2837_read(register: number): Promise<number>;
/**
* @category IC
*/
max2837_write(register: number, value: number): Promise<void>;
/**
* @category IC
*/
si5351c_read(register: number): Promise<number>;
/**
* @category IC
*/
si5351c_write(register: number, value: number): Promise<void>;
/**
* @category IC
*/
rffc5071_read(register: number): Promise<number>;
/**
* @category IC
*/
rffc5071_write(register: number, value: number): Promise<void>;
/**
* @category Flash & CPLD
*/
spiflash_erase(): Promise<void>;
/**
* @category Flash & CPLD
*/
spiflash_write(address: number, data: Buffer): Promise<void>;
/**
* @category Flash & CPLD
*/
spiflash_read(address: number, length: number): Promise<Buffer>;
/**
* TODO
*
* Requires USB API 1.3.
*
* @category Flash & CPLD
*/
spiflash_getStatus(): Promise<Buffer>;
/**
* TODO
*
* Requires USB API 1.3.
*
* @category Flash & CPLD
*/
spiflash_clearStatus(): Promise<void>;
/**
* Set baseband filter bandwidth in Hz
*
* Possible values: 1.75/2.5/3.5/5/5.5/6/7/8/9/10/12/14/15/20/24/28MHz
*
* @category Radio control
*/
setBasebandFilterBandwidth(freqHz: number): Promise<void>;
/**
* Set the tuning frequency
*
* @category Radio control
*/
setFrequency(freqHz: number): Promise<void>;
/**
* Set the tuning frequency (raw version)
*
* @param iFreqHz intermediate frequency
* @param loFreqHz front-end local oscillator frequency
* @param path image rejection filter path
* @category Radio control
*/
setFrequencyExplicit(iFreqHz: number, loFreqHz: number, path: RfPathFilter): Promise<void>;
/**
* Set the sample rate (raw version)
*
* You should probably use [[setSampleRate]] instead of this
* function.
*
* For anti-aliasing, the baseband filter bandwidth is automatically set to the
* widest available setting that is no more than 75% of the sample rate. This
* happens every time the sample rate is set. If you want to override the
* baseband filter selection, you must do so after setting the sample rate.
*
* 2-20Mhz - as a fraction, i.e. freq 20000000 divider 2 -> 10Mhz
*
* @category Radio control
*/
setSampleRateManual(freqHz: number, divider: number): Promise<void>;
/**
* Set the sample rate
*
* For anti-aliasing, the baseband filter bandwidth is automatically set to the
* widest available setting that is no more than 75% of the sample rate. This
* happens every time the sample rate is set. If you want to override the
* baseband filter selection, you must do so after setting the sample rate.
*
* @param freqHz frequency in Hz, 2-20MHz (double)
*
* @category Radio control
*/
setSampleRate(freqHz: number): Promise<void>;
/**
* Enable / disable RX/TX RF external amplifier
*
* @category Radio control
*/
setAmpEnable(value: boolean): Promise<void>;
/**
* Set RX LNA (IF) gain, 0-40dB in 8dB steps
*
* @category Radio control
*/
setLnaGain(gainDb: number): Promise<void>;
/**
* Set RX VGA (baseband) gain, 0-62dB in 2dB steps
*
* @category Radio control
*/
setVgaGain(gainDb: number): Promise<void>;
/**
* Set TX VGA (IF) gain, 0-47dB in 1dB steps
*
* @category Radio control
*/
setTxVgaGain(gainDb: number): Promise<void>;
/**
* Antenna port power control
*
* @category Radio control
*/
setAntennaEnable(value: boolean): Promise<void>;
/**
* Enable / disable hardware sync
*
* Multiple boards can be made to syncronize
* their USB transfers through a GPIO connection
* between them.
*
* Requires USB API 1.2.
*
* @category Radio control
*/
setHwSyncMode(value: boolean): Promise<void>;
/**
* Reset the device
*
* Requires USB API 1.2.
*
* @category Main
*/
reset(): Promise<void>;
/**
* Initialize sweep mode
*
* Requires USB API 1.2.
*
* @param ranges is a list of `[start, stop]` pairs of frequencies in MHz,
* no more than [[MAX_SWEEP_RANGES]] entries.
* @param numBytes the number of sample bytes to capture after each tuning.
* @param stepWidth the width in Hz of the tuning step.
* @param offset number of Hz added to every tuning frequency.
* Use to select center frequency based on the expected usable bandwidth.
* @category Radio control
*/
initSweep(ranges: [number, number][], numBytes: number, stepWidth: number, offset: number, style: SweepStyle): Promise<void>;
/**
* Retrieve list of Opera Cake board addresses (uint8, terminated by 0)
*
* Requires USB API 1.2.
*
* @category Opera Cake
*/
getOperacakeBoards(): Promise<number[]>;
/**
* Set Opera Cake ports
*
* Requires USB API 1.2.
*
* @category Opera Cake
*/
setOperacakePorts(address: number, portA: OperacakePorts, portB: OperacakePorts): Promise<void>;
/**
* Set Opera Cake [frequency-antenna ranges](https://github.com/mossmann/hackrf/wiki/Opera-Cake#opera-glasses)
*
* Requires USB API 1.3.
*
* @category Opera Cake
*/
setOperacakeRanges(ranges: Buffer): Promise<void>;
/**
* Test GPIO functionality of an Opera Cake
*
* Returns test result (uint16)
*
* Requires USB API 1.3.
*
* @category Opera Cake
*/
operacakeGpioTest(address: number): Promise<Buffer>;
/**
* Enable / disable clock output through CLKOUT
*
* Requires USB API 1.3.
*
* @category Radio control
*/
setClkoutEnable(value: boolean): Promise<void>;
/**
* Enable / disable PortaPack display
*
* Requires USB API 1.4.
*
* @category Radio control
*/
setUiEnable(value: boolean): Promise<void>;
private _streaming;
/**
* Returns `true` if there's an active stream.
*/
get streaming(): boolean;
private _lockStream;
private _stopRequested;
/**
* Requests stopping the active stream (if there is one)
*
* Calling this has the same effect as returning `false`
* the next time the callback gets called. Note that the
* stream doesn't finish instantly, you still need to
* wait for the promise to end. This is merely a convenience
* function.
*
* @category Main
*/
requestStop(): void;
private _stream;
/**
* Put the radio in TX mode and stream I/Q samples
*
* The supplied callback will be regularly called with an
* `Int8Array` buffer to fill before return. Every two
* values of the buffer form an I/Q sample. Different
* buffers may be passed or reused, so avoid storing
* references to them after return.
*
* To request ending the stream, return `false` from the
* callback or use [[requestStop]] (the callback will no
* longer be called and the current buffer will not be
* transmitted). Any transfer / callback error rejects
* the promise and cancels all transfers. The promise won't
* settle until all transfers are finished, regardless of
* whether the stream is ended or errored.
*
* This throws if there's another stream in progress.
*
* @category Main
*/
transmit(callback: PollCallback, options?: StreamOptions): Promise<void>;
/**
* Put the radio in RX mode and stream I/Q samples
*
* The supplied callback will be regularly called with an
* `Int8Array` buffer. Every two values of the buffer
* form an I/Q sample. The buffer may be overwritten
* later, so avoid storing any reference to it; instead
* make a copy of the data if needed.
*
* To request ending the stream, return `false` from the
* callback or use [[requestStop]] (the callback will no
* longer be called). Any transfer / callback error rejects
* the promise and cancels all transfers. The promise won't
* settle until all transfers are finished, regardless of
* whether the stream is ended or errored.
*
* This throws if there's another stream in progress.
*
* @category Main
*/
receive(callback: PollCallback, options?: StreamOptions): Promise<void>;
/**
* Put the radio in sweep RX mode and stream I/Q samples
*
* Like [[receive]], but with frequency sweep active.
* You should call [[initSweep]] first.
*
* Requires USB API 1.4.
*
* @category Main
*/
sweepReceive(callback: PollCallback, options?: StreamOptions): Promise<void>;
/**
* Put the radio in CPLD firmware upgrade mode and
* write the payload
*
* This throws if there's another stream in progress.
*
* The device will need to be reset after this.
*
* @category Flash & CPLD
*/
cpld_write(data: Buffer, chunkSize?: number): Promise<void>;
}
export {};