35 #if defined(PIOS_INCLUDE_DAC_FSK)
41 static void PIOS_FSKDAC_RegisterTxCallback(uintptr_t fskdac_id,
pios_com_callback tx_out_cb, uintptr_t context);
42 static void PIOS_FSKDAC_TxStart(uintptr_t fskdac_id, uint16_t tx_bytes_avail);
44 #define SAMPLES_PER_BIT 20
48 .bind_tx_cb = PIOS_FSKDAC_RegisterTxCallback,
53 #define FSKDAC_DEV_MAGIC 0x674b5346 // 'FSKg'
65 uintptr_t tx_out_context;
70 static bool PIOS_FSKDAC_cb(
void *ctx, uint16_t *buf,
int len);
72 static bool PIOS_FSKDAC_validate(
fskdac_dev_t fskdac_dev)
74 return (fskdac_dev->magic == FSKDAC_DEV_MAGIC);
87 if (!fskdac_dev)
return -1;
89 *fskdac_dev = (
struct fskdac_dev_s) {
90 .magic = FSKDAC_DEV_MAGIC,
94 *fskdac_id = fskdac_dev;
99 static void PIOS_FSKDAC_RegisterTxCallback(uintptr_t fskdac_id,
pios_com_callback tx_out_cb, uintptr_t context)
103 bool valid = PIOS_FSKDAC_validate(fskdac_dev);
111 fskdac_dev->tx_out_context = context;
112 fskdac_dev->tx_out_cb = tx_out_cb;
115 static void PIOS_FSKDAC_TxStart(uintptr_t fskdac_id, uint16_t tx_bytes_avail)
119 bool valid = PIOS_FSKDAC_validate(fskdac_dev);
122 if (fskdac_dev->tx_running) {
126 fskdac_dev->tx_running =
true;
129 PIOS_FSKDAC_cb, fskdac_dev);
133 static inline uint16_t serial_frame_char(uint8_t c,
int bits,
bool parity,
bool even,
134 bool twostop,
bool inverted, uint8_t *framed_size)
141 uint16_t framed = c << 1;
155 for (
int i = 0;
i < bits;
i++) {
180 framed <<= (16 - num);
189 static bool PIOS_FSKDAC_cb(
void *ctx, uint16_t *buf,
int len)
193 bool no_next_c =
false;
195 for (
int i = 0;
i < len;
i += SAMPLES_PER_BIT) {
196 if ((!no_next_c) && (!dev->send_state)) {
198 uint16_t bytes_to_send = 0;
202 if (dev->tx_out_cb) {
203 bytes_to_send = (dev->tx_out_cb)(dev->tx_out_context,
204 &b, 1, NULL, &tx_need_yield);
208 if (bytes_to_send > 0) {
209 dev->send_state = serial_frame_char(b,
210 8,
true,
false,
false,
217 uint16_t freq = ((dev->send_state & 0x8000) || (no_next_c)) ?
220 for (
int j = 0;
j < SAMPLES_PER_BIT;
j++) {
221 dev->phase_accum += freq;
223 uint16_t result = 32768 +
224 ((
sin_approx(dev->phase_accum >> 1) * 6) >> 2);
226 buf[
i +
j] = result & 0xFFF0;
229 dev->send_state <<= 1;
Main PiOS header to include all the compiled in PiOS options.
bool PIOS_DAC_install_callback(dac_dev_t dev, uint8_t priority, fill_dma_cb cb, void *ctx)
#define PIOS_DEBUG_Assert(test)
void * PIOS_malloc(size_t size)
struct fskdac_dev_s * fskdac_dev_t
static struct flyingpicmd_cfg_fa cfg
int32_t PIOS_FSKDAC_Init(fskdac_dev_t *fskdac_id, dac_dev_t dac)
Allocate and initialise FSKDAC device.
static int16_t sin_approx(int32_t x)
Fast approximation of sine; 3rd order taylor expansion. Based on http://www.coranac.com/2009/07/sines/.
const struct pios_com_driver pios_fskdac_com_driver
struct dac_dev_s * dac_dev_t
#define PIOS_Assert(test)
void(* tx_start)(uintptr_t id, uint16_t tx_bytes_avail)
uint16_t(* pios_com_callback)(uintptr_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken)