Paparazzi UAS  v7.0_unstable
Paparazzi is a free software Unmanned Aircraft System.
dshot_erps.c
Go to the documentation of this file.
2 //#include "stdutil.h"
3 
4 
8 static const uint8_t gcrNibble[16] = {
9  0x19, 0x1B, 0x12, 0x13, 0x1D, 0x15, 0x16, 0x17,
10  0x1A, 0x09, 0x0A, 0x0B, 0x1E, 0x0D, 0x0E, 0x0F};
11 
15 static const uint8_t gcrNibbleInv[32] = {
16  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
17  0xff, 0x9, 0xa, 0xb, 0xff, 0xd, 0xe, 0xf,
18  0xff, 0xff, 0x2, 0x3, 0xff, 0x5, 0x6, 0x7,
19  0xff, 0x0, 0x8, 0x1, 0xff, 0x4, 0xc, 0xff};
20 
21 static uint8_t crc4(uint16_t val);
22 static DshotEPeriodPacket eperiodToPacked(const uint32_t eperiod);
23 static uint32_t greyEncode(uint32_t num);
24 static uint32_t greyDecode(const uint32_t num);
25 static uint32_t gcrEncode(uint32_t from);
26 static uint32_t gcrDecode(uint32_t from);
27 static uint32_t eperiodEncode(const uint16_t eperiod);
28 static uint32_t eperiodDecode(const uint32_t frame);
29 
30 
31 
32 static void setFromEperiod(DshotErps *derpsp, uint32_t eperiod);
33 static void frameToPacket(DshotErps *derpsp);
34 static void packetToFrame(DshotErps *derpsp);
35 
36 
37 
45 {
46  derpsp->ef = frame;
47  frameToPacket(derpsp);
48  return derpsp;
49 }
50 
58 {
59  uint32_t eperiod = ((uint32_t) 60e6f) / rpm;
60  setFromEperiod(derpsp, eperiod);
61  return derpsp;
62 }
63 
73 {
74  return derpsp->ep.mantisse << derpsp->ep.exponent;
75 }
76 
77 
88 {
89  return ((uint32_t) 60e6f) / DshotErpsGetEperiod(derpsp);
90 }
91 
99 bool DshotErpsCheckCrc4(const DshotErps *derpsp)
100 {
101  return (crc4(derpsp->ep.rawFrame) == derpsp->ep.crc);
102 }
103 
112 {
113  val >>= 4;
114  return (~(val ^ (val >> 4) ^ (val >> 8))) & 0x0F;
115 }
116 
125 {
127  const uint32_t exponent = eperiod >> 9;
128 
129  if (exponent > 128) {
130  p = (DshotEPeriodPacket) {.crc = 0, .mantisse = 511, .exponent = 7};
131  } else {
132  p.exponent = 32U - __builtin_clz(exponent);
133  p.mantisse = eperiod >> p.exponent;
134  }
135  p.crc = crc4(p.rawFrame);
136  return p;
137 }
138 
147 {
148  num ^= (num >> 16);
149  num ^= (num >> 8);
150  num ^= (num >> 4);
151  num ^= (num >> 2);
152  num ^= (num >> 1);
153  return num;
154 }
155 
163 static uint32_t greyDecode(const uint32_t num)
164 {
165  return num ^ (num >> 1);
166 }
167 
176 {
177  uint32_t ret = 0;
178  for (size_t i = 0U; i < 4U; i++) {
179  // printf("nibble %u from = 0x%x to = 0x%x\n",
180  // i, from & 0xf, gcrNibble[from & 0xf]);
181  ret |= (gcrNibble[from & 0xf] << (i*5));
182  from >>= 4U;
183  }
184  return ret;
185 }
186 
195 {
196  uint32_t ret = 0;
197  for (size_t i = 0; i < 4U; i++) {
198  const uint32_t nibble = gcrNibbleInv[from & 0x1f];
199  if (nibble == 0xff) {
200  ret = 0x0;
201  break;
202  }
203  // printf("nibble %u from = 0x%x to = 0x%x\n",
204  // i, from & 0xf, gcrNibble[from & 0xf]);
205  ret |= (nibble << (i << 2U));
206  from >>= 5U;
207  }
208  return ret;
209 }
210 
218 static uint32_t eperiodEncode(const uint16_t eperiod)
219 {
220  return greyEncode(gcrEncode(eperiod));
221 }
222 
231 {
232  return gcrDecode(greyDecode(frame));
233 }
234 
242 static void setFromEperiod(DshotErps *derpsp, uint32_t eperiod)
243 {
244  derpsp->ep = eperiodToPacked(eperiod);
245  packetToFrame(derpsp);
246 }
247 
254 static void frameToPacket(DshotErps *derpsp)
255 {
256  derpsp->ep.rawFrame = eperiodDecode(derpsp->ef);
257  // DebugTrace("DBG> 0x%lx => 0x%x", derpsp->ef, derpsp->ep.rawFrame);
258 }
259 
266 static void packetToFrame(DshotErps *derpsp)
267 {
268  derpsp->ef = eperiodEncode(derpsp->ep.rawFrame);
269 }
270 
static uint8_t frame[20]
static const uint8_t gcrNibble[16]
IBM GCR encoding lookup table.
Definition: dshot_erps.c:8
static uint32_t greyDecode(const uint32_t num)
get natural binary value from grey binary
Definition: dshot_erps.c:163
const DshotErps * DshotErpsSetFromFrame(DshotErps *derpsp, uint32_t frame)
initialise from GCR encoded frame
Definition: dshot_erps.c:44
static void frameToPacket(DshotErps *derpsp)
decode eperiod
Definition: dshot_erps.c:254
static uint32_t eperiodEncode(const uint16_t eperiod)
encode eperiod to 20 bits GCR of grey value
Definition: dshot_erps.c:218
static uint32_t gcrEncode(uint32_t from)
encode 16 bit value to 20 bits GCR
Definition: dshot_erps.c:175
static uint8_t crc4(uint16_t val)
calculate crc4
Definition: dshot_erps.c:111
uint32_t DshotErpsGetRpm(const DshotErps *derpsp)
calculate and return rpm
Definition: dshot_erps.c:87
static void packetToFrame(DshotErps *derpsp)
encode eperiod
Definition: dshot_erps.c:266
uint32_t DshotErpsGetEperiod(const DshotErps *derpsp)
return eperiod from mantisse and exponent
Definition: dshot_erps.c:72
static uint32_t greyEncode(uint32_t num)
get grey binary value from natural binary
Definition: dshot_erps.c:146
static uint32_t gcrDecode(uint32_t from)
decode 20 bits GCR value to 16 bits natural
Definition: dshot_erps.c:194
static uint32_t eperiodDecode(const uint32_t frame)
decode 20 bits GCR of grey value to eperiod
Definition: dshot_erps.c:230
static const uint8_t gcrNibbleInv[32]
IBM GCR decoding lookup table.
Definition: dshot_erps.c:15
static void setFromEperiod(DshotErps *derpsp, uint32_t eperiod)
initialize from eperiod in microseconds
Definition: dshot_erps.c:242
static DshotEPeriodPacket eperiodToPacked(const uint32_t eperiod)
encode packet from eperiod
Definition: dshot_erps.c:124
bool DshotErpsCheckCrc4(const DshotErps *derpsp)
check packed validity
Definition: dshot_erps.c:99
const DshotErps * DshotErpsSetFromRpm(DshotErps *derpsp, uint32_t rpm)
initialise from rpm value
Definition: dshot_erps.c:57
uint16_t rawFrame
Definition: dshot_erps.h:36
DshotEPeriodPacket ep
Definition: dshot_erps.h:59
uint32_t ef
Definition: dshot_erps.h:60
ERPS complete frame, raw and decoded.
Definition: dshot_erps.h:58
ERPS classic rpm frame.
Definition: dshot_erps.h:30
static float p[2][2]
uint16_t rpm
Definition: rpm_sensor.c:33
uint16_t val[TCOUPLE_NB]
unsigned short uint16_t
Typedef defining 16 bit unsigned short type.
Definition: vl53l1_types.h:88
unsigned int uint32_t
Typedef defining 32 bit unsigned int type.
Definition: vl53l1_types.h:78
unsigned char uint8_t
Typedef defining 8 bit unsigned char type.
Definition: vl53l1_types.h:98