diff --git a/firmware/common/max2831.c b/firmware/common/max2831.c index 08e59a59f..d1d4b4673 100644 --- a/firmware/common/max2831.c +++ b/firmware/common/max2831.c @@ -425,3 +425,10 @@ void max2831_set_rx_hpf_frequency(max2831_driver_t* const drv, const max2831_rx_ break; } } + +void max2831_select_temperature(max2831_driver_t* const drv) +{ + /* Switch to temperature sensor. */ + set_MAX2831_RSSI_MUX(drv, MAX2831_RSSI_MUX_TEMP); + max2831_regs_commit(drv); +} diff --git a/firmware/common/max2831.h b/firmware/common/max2831.h index f1a28c54f..5ac4dd20e 100644 --- a/firmware/common/max2831.h +++ b/firmware/common/max2831.h @@ -110,3 +110,4 @@ extern void max2831_tx(max2831_driver_t* const drv); extern void max2831_rx(max2831_driver_t* const drv); extern void max2831_tx_calibration(max2831_driver_t* const drv); extern void max2831_rx_calibration(max2831_driver_t* const drv); +extern void max2831_select_temperature(max2831_driver_t* const drv); diff --git a/firmware/common/max2837.c b/firmware/common/max2837.c index f512c6af8..e98a09d92 100644 --- a/firmware/common/max2837.c +++ b/firmware/common/max2837.c @@ -52,7 +52,7 @@ static const uint16_t max2837_regs_default[MAX2837_NUM_REGS] = { 0x006, /* 6 */ 0x000, /* 7 */ 0x080, /* 8 */ - 0x018, /* 9 */ + 0x01a, /* 9 */ 0x058, /* 10 */ 0x016, /* 11 */ 0x24f, /* 12 */ @@ -393,3 +393,10 @@ bool max2837_set_txvga_gain(max2837_driver_t* const drv, const uint32_t gain_db) max2837_reg_commit(drv, 29); return true; } + +void max2837_select_temperature(max2837_driver_t* const drv) +{ + /* Switch to temperature sensor. */ + set_MAX2837_RSSI_MUX(drv, MAX2837_RSSI_MUX_TEMP); + max2837_regs_commit(drv); +} diff --git a/firmware/common/max2837.h b/firmware/common/max2837.h index a33179acf..4df4383db 100644 --- a/firmware/common/max2837.h +++ b/firmware/common/max2837.h @@ -93,3 +93,4 @@ bool max2837_set_txvga_gain(max2837_driver_t* const drv, const uint32_t gain_db) extern void max2837_tx(max2837_driver_t* const drv); extern void max2837_rx(max2837_driver_t* const drv); +extern void max2837_select_temperature(max2837_driver_t* const drv); diff --git a/firmware/common/max2837_regs.def b/firmware/common/max2837_regs.def index 67eb6dd7c..7e060833c 100644 --- a/firmware/common/max2837_regs.def +++ b/firmware/common/max2837_regs.def @@ -150,7 +150,7 @@ __MREG__(MAX2837_RSSI_MODE,6,8,1) // set to override RXHP pin __MREG__(MAX2837_LPF_MODE_SEL,6,9,1) // set to enable mode in reg 2 ModeCtrl /* REG 7 is R/O */ -// D4:0 ts_adc (temp sensor) +__MREG__(MAX2837_TEMP_VALUE,0,4,5) // temp sensor value // D9:5 zeros or test outputs /* REG 8 */ @@ -162,8 +162,8 @@ __MREG__(MAX2837_BIAS_TRIM_CNTRL,8,8,1) // enable BIAS_TRIM_SPI value __MREG__(MAX2837_RX_IQERR_SPI_EN,8,9,1) // ??? /* REG 9 */ -__MREG__(MAX2837_ts_adc_trigger,9,0,1) // temp sensor trigger (one shot) -__MREG__(MAX2837_ts_en,9,1,1) // temp sensor enable (before trigger) +__MREG__(MAX2837_TEMP_TRIGGER,9,0,1) // temp sensor trigger (one shot) +__MREG__(MAX2837_TEMP_ENABLE,9,1,1) // temp sensor enable (before trigger) __MREG__(MAX2837_LPFtrim_SPI_EN,9,2,1) __MREG__(MAX2837_DOUT_DRVH,9,3,1) #define MAX2837_DOUT_DRVH_1X 0 diff --git a/firmware/common/max2839.c b/firmware/common/max2839.c index a938b733b..7ffb692fc 100644 --- a/firmware/common/max2839.c +++ b/firmware/common/max2839.c @@ -55,7 +55,7 @@ static const uint16_t max2839_regs_default[MAX2839_NUM_REGS] = { 0x000, /* 6 */ 0x208, /* 7 */ 0x220, /* 8: data sheet says 0x220 but read 0x000 */ - 0x018, /* 9 */ + 0x01a, /* 9 */ 0x00c, /* 10 */ 0x004, /* 11: data sheet says 0x004 but read 0x000 */ 0x24f, /* 12 */ @@ -456,3 +456,10 @@ bool max2839_set_txvga_gain(max2839_driver_t* const drv, const uint32_t gain_db) max2839_reg_commit(drv, 29); return true; } + +void max2839_select_temperature(max2839_driver_t* const drv) +{ + /* Switch to temperature sensor. */ + set_MAX2839_RSSI_MUX(drv, MAX2839_RSSI_MUX_TEMP); + max2839_regs_commit(drv); +} diff --git a/firmware/common/max2839.h b/firmware/common/max2839.h index 6430ce371..d1413a510 100644 --- a/firmware/common/max2839.h +++ b/firmware/common/max2839.h @@ -95,3 +95,4 @@ bool max2839_set_txvga_gain(max2839_driver_t* const drv, const uint32_t gain_db) extern void max2839_tx(max2839_driver_t* const drv); extern void max2839_rx(max2839_driver_t* const drv); +extern void max2839_select_temperature(max2839_driver_t* const drv); diff --git a/firmware/common/max2839_regs.def b/firmware/common/max2839_regs.def index 11b1d80d9..04d0f3585 100644 --- a/firmware/common/max2839_regs.def +++ b/firmware/common/max2839_regs.def @@ -119,8 +119,10 @@ __MREG__(MAX2839_RX_VCM,6,9,2) /* REG 7 */ __MREG__(MAX2839_RESERVED_7_0,7,0,1) -__MREG__(MAX2839_RSSIselect,7,1,1) -__MREG__(MAX2839_RSSImode,7,2,1) +__MREG__(MAX2839_RSSI_MUX,7,1,1) +#define MAX2839_RSSI_MUX_RSSI 0 +#define MAX2839_RSSI_MUX_TEMP 1 +__MREG__(MAX2839_RSSI_MODE,7,2,1) __MREG__(MAX2839_RESERVED_7_6,7,6,4) __MREG__(MAX2839_RXBBI_RXBBQ,7,7,1) __MREG__(MAX2839_RESERVED_7_8,7,8,1) @@ -133,8 +135,8 @@ __MREG__(MAX2839_LPFmode_SPI,8,2,1) __MREG__(MAX2839_RESERVED_8_9,8,9,7) /* REG 9 */ -__MREG__(MAX2839_Temperature_ADC,9,0,1) -__MREG__(MAX2839_Temperature_Clk_En,9,1,1) +__MREG__(MAX2839_TEMP_TRIGGER,9,0,1) +__MREG__(MAX2839_TEMP_ENABLE,9,1,1) __MREG__(MAX2839_RESERVED_9_2,9,2,1) __MREG__(MAX2839_DOUT_Drive_Sel,9,3,1) __MREG__(MAX2839_DOUT_3state_Ctrl,9,4,1) diff --git a/firmware/common/max283x.c b/firmware/common/max283x.c index f9486921d..9509c56dc 100644 --- a/firmware/common/max283x.c +++ b/firmware/common/max283x.c @@ -28,6 +28,8 @@ #include +#include "adc.h" +#include "delay.h" #include "fixed_point.h" #include "platform_detect.h" #include "platform_gpio.h" @@ -329,3 +331,24 @@ void max283x_rx_calibration(max283x_driver_t* const drv) { PRALINE_ONLY(drv, max2831_rx_calibration(&drv->drv.max2831)); } + +/* Get chip temperature. */ +int8_t max283x_temperature(max283x_driver_t* const drv) +{ + /* Switch to temperature sensor. */ + CALL(drv, select_temperature); + + /* Wait for output to settle. */ + delay_ms(1); + + /* Read temperature. */ + uint16_t value = adc_read(1); + + /* Convert to degrees C, using: + * ADC 0 = 0V, ADC 1023 = 3.3V + * Analog 0.35V = -40C, 1.6V = +85C + * Offset adjusted empirically. */ + const int32_t prescale = 3332, offset = 928500, divisor = 10000; + + return ((value * prescale) - offset) / divisor; +} diff --git a/firmware/common/max283x.h b/firmware/common/max283x.h index 7c9c03dd3..68a569b73 100644 --- a/firmware/common/max283x.h +++ b/firmware/common/max283x.h @@ -140,6 +140,9 @@ void max283x_set_rx_hpf_frequency( void max283x_tx_calibration(max283x_driver_t* const drv); void max283x_rx_calibration(max283x_driver_t* const drv); +/* Get chip temperature. */ +int8_t max283x_temperature(max283x_driver_t* const drv); + /* Driver instance. */ extern ssp_config_t ssp_config_max283x; extern max283x_driver_t max283x; diff --git a/firmware/hackrf_usb/hackrf_usb.c b/firmware/hackrf_usb/hackrf_usb.c index 813a94539..d0c09c612 100644 --- a/firmware/hackrf_usb/hackrf_usb.c +++ b/firmware/hackrf_usb/hackrf_usb.c @@ -182,6 +182,7 @@ static usb_request_handler_fn vendor_request_handler[] = { usb_vendor_request_write_radio_reg, usb_vendor_request_read_radio_reg, usb_vendor_request_get_buffer_size, + usb_vendor_request_read_temperature, }; static const uint32_t vendor_request_handler_count = diff --git a/firmware/hackrf_usb/usb_api_selftest.c b/firmware/hackrf_usb/usb_api_selftest.c index 7fde6f687..126ee2962 100644 --- a/firmware/hackrf_usb/usb_api_selftest.c +++ b/firmware/hackrf_usb/usb_api_selftest.c @@ -30,6 +30,7 @@ #include #include +#include #include #include #include @@ -266,3 +267,20 @@ usb_request_status_t usb_vendor_request_test_rtc_osc( return USB_REQUEST_STATUS_OK; } } + +usb_request_status_t usb_vendor_request_read_temperature( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage) +{ + if (stage == USB_TRANSFER_STAGE_SETUP) { + endpoint->buffer[0] = max283x_temperature(&max283x); + usb_transfer_schedule_block( + endpoint->in, + &endpoint->buffer, + 1, + NULL, + NULL); + usb_transfer_schedule_ack(endpoint->out); + } + return USB_REQUEST_STATUS_OK; +} diff --git a/firmware/hackrf_usb/usb_api_selftest.h b/firmware/hackrf_usb/usb_api_selftest.h index 7f5af7dab..22ebb3eec 100644 --- a/firmware/hackrf_usb/usb_api_selftest.h +++ b/firmware/hackrf_usb/usb_api_selftest.h @@ -31,3 +31,7 @@ usb_request_status_t usb_vendor_request_read_selftest( usb_request_status_t usb_vendor_request_test_rtc_osc( usb_endpoint_t* const endpoint, const usb_transfer_stage_t stage); + +usb_request_status_t usb_vendor_request_read_temperature( + usb_endpoint_t* const endpoint, + const usb_transfer_stage_t stage); diff --git a/host/hackrf-tools/src/hackrf_info.c b/host/hackrf-tools/src/hackrf_info.c index e214ec927..59961a544 100644 --- a/host/hackrf-tools/src/hackrf_info.c +++ b/host/hackrf-tools/src/hackrf_info.c @@ -260,6 +260,18 @@ int main(void) } #endif /* HACKRF_ISSUE_609_IS_FIXED */ + if (usb_version >= 0x0113) { + int8_t temperature; + result = hackrf_read_temperature(device, &temperature); + if (result != HACKRF_SUCCESS) { + printf("hackrf_read_temperature() failed: %s (%d)\n", + hackrf_error_name(result), + result); + return EXIT_FAILURE; + } + printf("Transceiver temperature: %-d°C\n", temperature); + } + if (usb_version >= 0x0109) { hackrf_selftest selftest; result = hackrf_read_selftest(device, &selftest); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 7bafd5f39..0f67f3430 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -120,6 +120,7 @@ typedef enum { HACKRF_VENDOR_REQUEST_RADIO_WRITE_REG = 59, HACKRF_VENDOR_REQUEST_RADIO_READ_REG = 60, HACKRF_VENDOR_REQUEST_GET_BUFFER_SIZE = 61, + HACKRF_VENDOR_REQUEST_READ_TEMPERATURE = 62, } hackrf_vendor_request; #define USB_CONFIG_STANDARD 0x1 @@ -1415,6 +1416,28 @@ int ADDCALL hackrf_test_rtc_osc(hackrf_device* device, bool* pass) return HACKRF_SUCCESS; } +int ADDCALL hackrf_read_temperature(hackrf_device* device, int8_t* temp) +{ + USB_API_REQUIRED(device, 0x0113); + + int result = libusb_control_transfer( + device->usb_device, + LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE, + HACKRF_VENDOR_REQUEST_READ_TEMPERATURE, + 0, + 0, + (unsigned char*) temp, + 1, + DEFAULT_REQUEST_TIMEOUT); + + if (result < 1) { + last_libusb_error = result; + return HACKRF_ERROR_LIBUSB; + } else { + return HACKRF_SUCCESS; + } +} + int ADDCALL hackrf_read_adc(hackrf_device* device, uint8_t adc_channel, uint16_t* value) { USB_API_REQUIRED(device, 0x0109); diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index eeca65e03..d9322d3c2 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -1375,6 +1375,16 @@ extern ADDAPI int ADDCALL hackrf_read_selftest( */ extern ADDAPI int ADDCALL hackrf_test_rtc_osc(hackrf_device* device, bool* pass); +/** + * Read the temperature of the device + * + * @param[in] device device to query + * @param[out] temp Temperature in degrees C + * @return @ref HACKRF_SUCCESS on success or @ref hackrf_error variant + * @ingroup debug + */ +extern ADDAPI int ADDCALL hackrf_read_temperature(hackrf_device* device, int8_t* temp); + /** * Read a value from an ADC channel *