dRonin  adbada4
dRonin firmware
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pios_annuncdac.c
Go to the documentation of this file.
1 
15 /*
16  * This program is free software; you can redistribute it and/or modify
17  * it under the terms of the GNU General Public License as published by
18  * the Free Software Foundation; either version 3 of the License, or
19  * (at your option) any later version.
20  *
21  * This program is distributed in the hope that it will be useful, but
22  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
23  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24  * for more details.
25  *
26  * You should have received a copy of the GNU General Public License along
27  * with this program; if not, write to the Free Software Foundation, Inc.,
28  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29  */
30 
31 /* Project Includes */
32 #include <pios.h>
33 
34 #if defined(PIOS_INCLUDE_DAC_ANNUNCIATOR)
35 #include <pios_annuncdac.h>
36 
37 #include <misc_math.h>
38 
39 struct annuncdac_dev_s {
40  uint32_t magic;
41 #define ANNUNCDAC_DEV_MAGIC 0x43414441 // 'ADAC'
42 
43  dac_dev_t dac;
44 
45  volatile bool value;
46 
47  uint8_t history;
48  uint16_t phase_accum;
49 
50  pios_com_callback tx_out_cb;
51  uintptr_t tx_out_context;
52 
53  bool tx_running;
54 };
55 
56 static bool PIOS_ANNUNCDAC_cb(void *ctx, uint16_t *buf, int len);
57 
58 static bool PIOS_ANNUNCDAC_validate(annuncdac_dev_t annuncdac_dev)
59 {
60  return (annuncdac_dev->magic == ANNUNCDAC_DEV_MAGIC);
61 }
62 
66 int32_t PIOS_ANNUNCDAC_Init(annuncdac_dev_t *annuncdac_id, dac_dev_t dac)
67 {
68  PIOS_DEBUG_Assert(annuncdac_id);
70 
71  annuncdac_dev_t annuncdac_dev = PIOS_malloc(sizeof(*annuncdac_dev));
72 
73  if (!annuncdac_dev) return -1;
74 
75  *annuncdac_dev = (struct annuncdac_dev_s) {
76  .magic = ANNUNCDAC_DEV_MAGIC,
77  .dac = dac,
78  };
79 
80  *annuncdac_id = annuncdac_dev;
81 
82  PIOS_DAC_install_callback(annuncdac_dev->dac, 100,
83  PIOS_ANNUNCDAC_cb, annuncdac_dev);
84 
85  return 0;
86 }
87 
88 static inline void FillBuf(annuncdac_dev_t dev, uint16_t *buf, int len,
89  uint16_t freq, int start_mag, int stop_mag) {
90  int mag_span = stop_mag - start_mag;
91 
92  for (int i=0; i < len; i++) {
93  dev->phase_accum += freq;
94 
95  int magnitude = (mag_span * i + len / 2) / len;
96  magnitude += start_mag;
97 
98  uint16_t result = 32768 +
99  (magnitude * sin_approx(dev->phase_accum >> 1) >> 2);
100 
101  buf[i] = result & 0xFFF0;
102  }
103 }
104 
105 #define ANNUNC_FREQ 1911 /* 65536 / (24000Hz / 700Hz) =~ 1911 */
106 static bool PIOS_ANNUNCDAC_cb(void *ctx, uint16_t *buf, int len)
107 {
108  annuncdac_dev_t dev = ctx;
109  PIOS_Assert(PIOS_ANNUNCDAC_validate(dev));
110 
111  dev->history <<= 1;
112 
113  if (dev->value) {
114  dev->history |= 1;
115  }
116 
117  switch (dev->history & 3) {
118  case 0:
119  /* Off, has been off */
120  for (int i = 0; i < len; i++) {
121  buf[i] = 32768;
122  }
123  return true;
124  case 1:
125  FillBuf(dev, buf, len, ANNUNC_FREQ, 1, 6);
126  break;
127  case 2:
128  /* Going off */
129  FillBuf(dev, buf, len, ANNUNC_FREQ, 6, 1);
130  break;
131  case 3:
132  /* Steady state */
133  FillBuf(dev, buf, len, ANNUNC_FREQ, 6, 6);
134  break;
135  }
136 
137  return true;
138 }
139 
140 void PIOS_ANNUNCDAC_SetValue(annuncdac_dev_t dev, bool active, bool value)
141 {
142  (void) active;
143 
144  PIOS_Assert(PIOS_ANNUNCDAC_validate(dev));
145 
146  dev->value = value;
147 }
148 
149 #endif /* PIOS_INCLUDE_DAC_ANNUNCIATOR */
150 
Main PiOS header to include all the compiled in PiOS options.
int32_t PIOS_ANNUNCDAC_Init(annuncdac_dev_t *annuncdac_id, dac_dev_t dac)
Allocate and initialise ANNUNCDAC device.
bool PIOS_DAC_install_callback(dac_dev_t dev, uint8_t priority, fill_dma_cb cb, void *ctx)
#define PIOS_DEBUG_Assert(test)
Definition: pios_debug.h:51
void * PIOS_malloc(size_t size)
Definition: pios_heap.c:125
static struct flyingpicmd_cfg_fa cfg
Definition: main.c:49
void PIOS_ANNUNCDAC_SetValue(annuncdac_dev_t dev, bool active, bool value)
Set whether we should be beeping.
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/.
Definition: misc_math.h:90
uint8_t i
Definition: msp_messages.h:97
uint16_t value
Definition: storm32bgc.c:155
uint32_t magic
struct dac_dev_s * dac_dev_t
Definition: pios_dac.h:40
struct annuncdac_dev_s * annuncdac_dev_t
#define PIOS_Assert(test)
Definition: pios_debug.h:52
uint16_t(* pios_com_callback)(uintptr_t context, uint8_t *buf, uint16_t buf_len, uint16_t *headroom, bool *task_woken)
Definition: pios_com.h:41