icE1usb fw: Add USB control for the GPSDO function
Signed-off-by: Sylvain Munaut <tnt@246tNt.com> Change-Id: If92aa68d8a49349fa0d6d556eec81bbb80be989c
This commit is contained in:
parent
e76b643298
commit
c308334de7
|
@ -13,6 +13,8 @@
|
||||||
#include "gpsdo.h"
|
#include "gpsdo.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
|
#include "ice1usb_proto.h"
|
||||||
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
/* Current tuning */
|
/* Current tuning */
|
||||||
|
@ -74,6 +76,72 @@ vctxo_sensitivity[] = {
|
||||||
#define MAX_INVALID 5
|
#define MAX_INVALID 5
|
||||||
|
|
||||||
|
|
||||||
|
static void _gpsdo_coarse_start(void);
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
gpsdo_get_status(struct e1usb_gpsdo_status *status)
|
||||||
|
{
|
||||||
|
const uint8_t state_map[] = {
|
||||||
|
[STATE_DISABLED] = ICE1USB_GPSDO_STATE_DISABLED,
|
||||||
|
[STATE_HOLD_OVER] = ICE1USB_GPSDO_STATE_HOLD_OVER,
|
||||||
|
[STATE_TUNE_COARSE] = ICE1USB_GPSDO_STATE_TUNE_COARSE,
|
||||||
|
[STATE_TUNE_FINE] = ICE1USB_GPSDO_STATE_TUNE_FINE,
|
||||||
|
};
|
||||||
|
const uint8_t ant_map[] = {
|
||||||
|
[ANT_UNKNOWN] = ICE1USB_GPSDO_ANT_UNKNOWN,
|
||||||
|
[ANT_OK] = ICE1USB_GPSDO_ANT_OK,
|
||||||
|
[ANT_OPEN] = ICE1USB_GPSDO_ANT_OPEN,
|
||||||
|
[ANT_SHORT] = ICE1USB_GPSDO_ANT_SHORT,
|
||||||
|
};
|
||||||
|
|
||||||
|
status->state = state_map[g_gpsdo.state];
|
||||||
|
status->antenna_status = ant_map[gps_antenna_status()];
|
||||||
|
status->valid_fix = gps_has_valid_fix();
|
||||||
|
status->mode = (g_gpsdo.state == STATE_DISABLED) ? ICE1USB_GPSDO_MODE_DISABLED : ICE1USB_GPSDO_MODE_AUTO;
|
||||||
|
status->tune.coarse = g_gpsdo.tune.coarse;
|
||||||
|
status->tune.fine = g_gpsdo.tune.fine;
|
||||||
|
status->freq_est = g_gpsdo.meas.last;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gpsdo_enable(bool enable)
|
||||||
|
{
|
||||||
|
if (!enable)
|
||||||
|
g_gpsdo.state = STATE_DISABLED;
|
||||||
|
else if (g_gpsdo.state == STATE_DISABLED)
|
||||||
|
g_gpsdo.state = STATE_HOLD_OVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
gpsdo_enabled(void)
|
||||||
|
{
|
||||||
|
return g_gpsdo.state != STATE_DISABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gpsdo_set_tune(uint16_t coarse, uint16_t fine)
|
||||||
|
{
|
||||||
|
/* Set value */
|
||||||
|
g_gpsdo.tune.coarse = coarse;
|
||||||
|
g_gpsdo.tune.fine = fine;
|
||||||
|
|
||||||
|
pdm_set(PDM_CLK_HI, true, g_gpsdo.tune.coarse, false);
|
||||||
|
pdm_set(PDM_CLK_LO, true, g_gpsdo.tune.fine, false);
|
||||||
|
|
||||||
|
/* If we were in 'fine' mode, reset to coarse */
|
||||||
|
if (g_gpsdo.state == STATE_TUNE_FINE)
|
||||||
|
_gpsdo_coarse_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gpsdo_get_tune(uint16_t *coarse, uint16_t *fine)
|
||||||
|
{
|
||||||
|
*coarse = g_gpsdo.tune.coarse;
|
||||||
|
*fine = g_gpsdo.tune.fine;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_gpsdo_coarse_start(void)
|
_gpsdo_coarse_start(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,5 +12,16 @@ enum gpsdo_vctxo_model {
|
||||||
VCTXO_SITIME_SIT3808_E = 1, /* SIT3808AI-D2-33EE-30.720000T */
|
VCTXO_SITIME_SIT3808_E = 1, /* SIT3808AI-D2-33EE-30.720000T */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct e1usb_gpsdo_status;
|
||||||
|
|
||||||
|
|
||||||
|
void gpsdo_get_status(struct e1usb_gpsdo_status *status);
|
||||||
|
|
||||||
|
void gpsdo_enable(bool enable);
|
||||||
|
bool gpsdo_enabled(void);
|
||||||
|
|
||||||
|
void gpsdo_set_tune(uint16_t coarse, uint16_t fine);
|
||||||
|
void gpsdo_get_tune(uint16_t *coarse, uint16_t *fine);
|
||||||
|
|
||||||
void gpsdo_poll(void);
|
void gpsdo_poll(void);
|
||||||
void gpsdo_init(enum gpsdo_vctxo_model vctxo);
|
void gpsdo_init(enum gpsdo_vctxo_model vctxo);
|
||||||
|
|
|
@ -17,12 +17,51 @@
|
||||||
/*! returns a bit-mask of optional device capabilities (see enum e1usb_dev_capability) */
|
/*! returns a bit-mask of optional device capabilities (see enum e1usb_dev_capability) */
|
||||||
#define ICE1USB_DEV_GET_CAPABILITIES 0x01
|
#define ICE1USB_DEV_GET_CAPABILITIES 0x01
|
||||||
#define ICE1USB_DEV_GET_FW_BUILD 0x02
|
#define ICE1USB_DEV_GET_FW_BUILD 0x02
|
||||||
|
#define ICE1USB_DEV_GET_GPSDO_STATUS 0x10
|
||||||
|
#define ICE1USB_DEV_GET_GPSDO_MODE 0x12 /*!< uint8_t */
|
||||||
|
#define ICE1USB_DEV_SET_GPSDO_MODE 0x13 /*!< wValue = mode */
|
||||||
|
#define ICE1USB_DEV_GET_GPSDO_TUNE 0x14 /*!< data = struct e1usb_gpsdo_tune */
|
||||||
|
#define ICE1USB_DEV_SET_GPSDO_TUNE 0x15 /*!< data = struct e1usb_gpsdo_tune */
|
||||||
|
|
||||||
enum e1usb_dev_capability {
|
enum e1usb_dev_capability {
|
||||||
/*! Does this board have a GPS-DO */
|
/*! Does this board have a GPS-DO */
|
||||||
ICE1USB_DEV_CAP_GPSDO,
|
ICE1USB_DEV_CAP_GPSDO,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ice1usb_gpsdo_mode {
|
||||||
|
ICE1USB_GPSDO_MODE_DISABLED = 0,
|
||||||
|
ICE1USB_GPSDO_MODE_AUTO = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ice1usb_gpsdo_antenna_state {
|
||||||
|
ICE1USB_GPSDO_ANT_UNKNOWN = 0,
|
||||||
|
ICE1USB_GPSDO_ANT_OK = 1,
|
||||||
|
ICE1USB_GPSDO_ANT_OPEN = 2,
|
||||||
|
ICE1USB_GPSDO_ANT_SHORT = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ice1usb_gpsdo_state {
|
||||||
|
ICE1USB_GPSDO_STATE_DISABLED = 0,
|
||||||
|
ICE1USB_GPSDO_STATE_CALIBRATE = 1,
|
||||||
|
ICE1USB_GPSDO_STATE_HOLD_OVER = 2,
|
||||||
|
ICE1USB_GPSDO_STATE_TUNE_COARSE = 3,
|
||||||
|
ICE1USB_GPSDO_STATE_TUNE_FINE = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct e1usb_gpsdo_tune {
|
||||||
|
uint16_t coarse;
|
||||||
|
uint16_t fine;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct e1usb_gpsdo_status {
|
||||||
|
uint8_t state;
|
||||||
|
uint8_t antenna_status; /*!< Antenna status */
|
||||||
|
uint8_t valid_fix; /*!< Valid GPS Fix (0/1) */
|
||||||
|
uint8_t mode; /*!< Current configured operating mode */
|
||||||
|
struct e1usb_gpsdo_tune tune; /*!< Current VCXO tuning values */
|
||||||
|
uint32_t freq_est; /*!< Latest frequency estimate measurement */
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
|
||||||
/* Interface Requests */
|
/* Interface Requests */
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <no2usb/usb_proto.h>
|
#include <no2usb/usb_proto.h>
|
||||||
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
#include "gpsdo.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
|
||||||
#include "ice1usb_proto.h"
|
#include "ice1usb_proto.h"
|
||||||
|
@ -20,6 +21,61 @@
|
||||||
const char *fw_build_str = BUILD_INFO;
|
const char *fw_build_str = BUILD_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
_get_gpsdo_status(struct usb_ctrl_req *req, struct usb_xfer *xfer)
|
||||||
|
{
|
||||||
|
struct e1usb_gpsdo_status status;
|
||||||
|
|
||||||
|
gpsdo_get_status(&status);
|
||||||
|
|
||||||
|
memcpy(xfer->data, &status, sizeof(struct e1usb_gpsdo_status));
|
||||||
|
xfer->len = sizeof(struct e1usb_gpsdo_status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_get_gpsdo_mode(struct usb_ctrl_req *req, struct usb_xfer *xfer)
|
||||||
|
{
|
||||||
|
xfer->data[0] = gpsdo_enabled() ? ICE1USB_GPSDO_MODE_DISABLED : ICE1USB_GPSDO_MODE_AUTO;
|
||||||
|
xfer->len = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_set_gpsdo_mode(struct usb_ctrl_req *req, struct usb_xfer *xfer)
|
||||||
|
{
|
||||||
|
gpsdo_enable(req->wValue != ICE1USB_GPSDO_MODE_DISABLED);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_get_gpsdo_tune(struct usb_ctrl_req *req, struct usb_xfer *xfer)
|
||||||
|
{
|
||||||
|
uint16_t coarse, fine;
|
||||||
|
struct e1usb_gpsdo_tune tune;
|
||||||
|
|
||||||
|
gpsdo_get_tune(&coarse, &fine);
|
||||||
|
tune.coarse = coarse;
|
||||||
|
tune.fine = fine;
|
||||||
|
|
||||||
|
memcpy(xfer->data, &tune, sizeof(struct e1usb_gpsdo_tune));
|
||||||
|
xfer->len = sizeof(struct e1usb_gpsdo_tune);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
_set_gpsdo_tune_done(struct usb_xfer *xfer)
|
||||||
|
{
|
||||||
|
const struct e1usb_gpsdo_tune *tune = (const void *) xfer->data;
|
||||||
|
gpsdo_set_tune(tune->coarse, tune->fine);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_set_gpsdo_tune(struct usb_ctrl_req *req, struct usb_xfer *xfer)
|
||||||
|
{
|
||||||
|
xfer->cb_done = _set_gpsdo_tune_done;
|
||||||
|
xfer->cb_ctx = req;
|
||||||
|
xfer->len = sizeof(struct e1usb_gpsdo_tune);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static enum usb_fnd_resp
|
static enum usb_fnd_resp
|
||||||
_usb_dev_ctrl_req(struct usb_ctrl_req *req, struct usb_xfer *xfer)
|
_usb_dev_ctrl_req(struct usb_ctrl_req *req, struct usb_xfer *xfer)
|
||||||
{
|
{
|
||||||
|
@ -37,6 +93,21 @@ _usb_dev_ctrl_req(struct usb_ctrl_req *req, struct usb_xfer *xfer)
|
||||||
xfer->data = (void*) fw_build_str;
|
xfer->data = (void*) fw_build_str;
|
||||||
xfer->len = strlen(fw_build_str);
|
xfer->len = strlen(fw_build_str);
|
||||||
break;
|
break;
|
||||||
|
case ICE1USB_DEV_GET_GPSDO_STATUS:
|
||||||
|
_get_gpsdo_status(req, xfer);
|
||||||
|
break;
|
||||||
|
case ICE1USB_DEV_GET_GPSDO_MODE:
|
||||||
|
_get_gpsdo_mode(req, xfer);
|
||||||
|
break;
|
||||||
|
case ICE1USB_DEV_SET_GPSDO_MODE:
|
||||||
|
_set_gpsdo_mode(req, xfer);
|
||||||
|
break;
|
||||||
|
case ICE1USB_DEV_GET_GPSDO_TUNE:
|
||||||
|
_get_gpsdo_tune(req, xfer);
|
||||||
|
break;
|
||||||
|
case ICE1USB_DEV_SET_GPSDO_TUNE:
|
||||||
|
_set_gpsdo_tune(req, xfer);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return USB_FND_ERROR;
|
return USB_FND_ERROR;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue