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 "misc.h"
|
||||
|
||||
#include "ice1usb_proto.h"
|
||||
|
||||
|
||||
struct {
|
||||
/* Current tuning */
|
||||
|
@ -74,6 +76,72 @@ vctxo_sensitivity[] = {
|
|||
#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
|
||||
_gpsdo_coarse_start(void)
|
||||
{
|
||||
|
|
|
@ -12,5 +12,16 @@ enum gpsdo_vctxo_model {
|
|||
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_init(enum gpsdo_vctxo_model vctxo);
|
||||
|
|
|
@ -17,12 +17,51 @@
|
|||
/*! returns a bit-mask of optional device capabilities (see enum e1usb_dev_capability) */
|
||||
#define ICE1USB_DEV_GET_CAPABILITIES 0x01
|
||||
#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 {
|
||||
/*! Does this board have a GPS-DO */
|
||||
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 */
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include <no2usb/usb_proto.h>
|
||||
|
||||
#include "console.h"
|
||||
#include "gpsdo.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include "ice1usb_proto.h"
|
||||
|
@ -20,6 +21,61 @@
|
|||
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
|
||||
_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->len = strlen(fw_build_str);
|
||||
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:
|
||||
return USB_FND_ERROR;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue