MAXREFDES73# Code Documentation  V02.00
WEARABLE, GALVANIC SKIN RESPONSE SYSTEM
 All Data Structures Files Functions Variables Enumerator Macros Pages
MAXREFDES73.c
Go to the documentation of this file.
1 
61 #include "string.h"
62 #include <inttypes.h>
63 #include <math.h>
64 
65 #include "wsf_types.h"
66 #include "wsf_os.h"
67 #include "wsf_buf.h"
68 #include "wsf_sec.h"
69 #include "hci_handler.h"
70 #include "dm_handler.h"
71 #include "l2c_handler.h"
72 #include "att_handler.h"
73 #include "smp_handler.h"
74 #include "app_api.h"
75 #include "l2c_api.h"
76 #include "smp_api.h"
77 
78 
79 #include "mxc_config.h"
80 
81 #include "icc.h"
82 #include "ioman.h"
83 #include "clkman.h"
84 #include "gpio.h"
85 #include "power.h"
86 #include "systick.h"
87 #include "fit_api.h"
88 #include "hci_drv.h"
89 #include "rtc.h"
90 #include "spi.h"
91 #include "tmr.h"
92 #include "tmon.h"
93 
94 #include "dac.h"
95 #include "adc.h"
96 #include "afe.h"
97 
98 #include "trim_regs.h"
99 
100 #define EM9301_ASSERT_RESET 1
101 #define EM9301_RELEASE_RESET 0
102 #define EM9301_SLEEP 0
103 #define EM9301_WAKEUP 1
104 #define BLE_MS_PER_TIMER_TICK 10 /* milliseconds per WSF timer tick */
105 #define SYSTICK_10_MS 327
106 
107 /* LED pin mapping on the MAXREFDES73 */
108 #define LED_ON 0
109 #define LED_OFF 1
110 
111 #define LED_PORT 0
112 #define RED_LED_PIN 7
113 #define GREEN_LED_PIN 6
114 //#define YELLOW_LED_PIN 5 // not installed.
115 
116 #define SPI_PORT 0
117 #define BLE_SLAVE_SELECT 0
118 #define FC_POLARITY 1
119 #define FC_ENABLE 1
120 #define SS_POLARITY 0
121 #define ACT_DELAY 1
122 #define INACT_DELAY 0
123 /*
124  * BLE pin mapping on the MAXREFDES73: *
125  * WASP EM9301
126  * ---- ------
127  * P0.0 -> SCK SPI master clock
128  * P0.1 -> SDO SPI MOSI
129  * P0.2 <- SDI SPI MISO
130  * P0.3 -> CSN SPI CSN (active low)
131  * P0.4 <- IRQ EM9301 ready to receive
132  * P0.5 -> RST RST (active high)
133  */
134 #define SPI0_PORT 0
135 #define SPI0_SCK 0
136 #define SPI0_SDO 1
137 #define SPI0_SDI 2
138 #define SPI0_CSN 3
139 
140 #define BLE_IRQ_PORT 0
141 #define BLE_IRQ_PIN 4
142 #define BLE_RST_PORT 0
143 #define BLE_RST_PIN 5
144 
145 #define CHARGING_PORT 2
146 #define CHARGING_PIN 7
147 
148 // NTC parameters in Steinhart¨CHart equation.
149 #define NTC_A 824.9707194577557
150 #define NTC_B 222.45487555218145
151 #define NTC_C 0.09559990904037504
152 
153 uint8_t packet_0_buf[20], packet_1_buf[20], packet_2_buf[20];
155 uint8_t BATLEVEL = 100;
156 uint8_t preBATLEVEL = 100;
157 uint16_t packetNumber = 0;
158 uint8_t firstMeasurement = 1;
159 uint8_t BLEconnected = 0;
160 uint8_t BLEadvertising = 1;
161 
162 /**************************************************************************************************
163  Local Variables
164 **************************************************************************************************/
165 #define WSF_BUF_POOLS 4 /* Number of WSF buffer pools */
166 
168 static uint8_t mainBufMem[768];
169 
171 static wsfBufPoolDesc_t mainPoolDesc[WSF_BUF_POOLS] =
172 {
173  { 16, 8 },
174  { 32, 4 },
175  { 64, 2 },
176  { 128, 2 }
177 };
178 
179 /* Initialize WSF(Wicentric Software Foundation) and BLE stack */
180 static void bleStackInit(uint8_t msPerTick)
181 {
182  wsfHandlerId_t handlerId;
183 
184  /* init OS subsystems */
185  WsfTimerInit(msPerTick);
186 
187  WsfBufInit(sizeof(mainBufMem), mainBufMem, WSF_BUF_POOLS, &mainPoolDesc[0]);
188  WsfSecInit(); // security service
189 
190  /* initialize HCI */
191  handlerId = WsfOsSetNextHandler(HciHandler);
192  HciHandlerInit(handlerId);
193 
194  /* initialize DM */
195  handlerId = WsfOsSetNextHandler(DmHandler);
196  DmAdvInit();
197  DmConnInit();
198  DmConnSlaveInit();
199  DmSecInit();
200  DmHandlerInit(handlerId);
201 
202  /* initialize L2C */
203  handlerId = WsfOsSetNextHandler(L2cSlaveHandler);
204  L2cSlaveHandlerInit(handlerId);
205  L2cInit();
206  L2cSlaveInit();
207 
208  /* Initialize ATT */
209  handlerId = WsfOsSetNextHandler(AttHandler);
210  AttHandlerInit(handlerId);
211  AttsInit();
212  AttsIndInit();
213  AttcInit();
214 
215  handlerId = WsfOsSetNextHandler(SmpHandler);
216  SmpHandlerInit(handlerId);
217  SmprInit();
218 
219  handlerId = WsfOsSetNextHandler(AppHandler);
220  AppHandlerInit(handlerId);
221 
222  handlerId = WsfOsSetNextHandler(FitHandler);
223  FitHandlerInit(handlerId);
224 }
225 
226 /* Bring the EM9301 out of sleep (via WU pin) */
227 static void em9301_hw_wakeup(unsigned int wu)
228 {
229  if (wu == EM9301_WAKEUP)
230  GPIO_SetOutVal(SPI0_PORT, SPI0_CSN, EM9301_WAKEUP); /* Assert reset */
231  else
232  GPIO_SetOutVal(SPI0_PORT, SPI0_CSN, EM9301_SLEEP); /* Release reset */
233 }
234 
235 /* Reset the EM9301 via external (active high) pin */
236 static void em9301_hw_reset(unsigned int reset)
237 {
238  if (reset == EM9301_ASSERT_RESET)
239  GPIO_SetOutVal(BLE_RST_PORT, BLE_RST_PIN, EM9301_ASSERT_RESET); /* Assert reset */
240  else
241  GPIO_SetOutVal(BLE_RST_PORT, BLE_RST_PIN, EM9301_RELEASE_RESET);/* Release reset */
242 }
243 
244 spi_slave_t ss;
245 uint8_t mainHciBuf[64];
246 
247 static void spi_read_irq(void)
248 {
249  if(GPIO_GetInVal(BLE_IRQ_PORT, BLE_IRQ_PIN))
250  {
251  SPI_ConfigSpecial(&ss, MXC_E_SPI_FLOW_CTRL_SR, FC_POLARITY, 1, 0, 1);
252  //SPI_ConfigSpecial(&ss, MXC_E_SPI_FLOW_CTRL_NONE, FC_POLARITY, 1, 0, 1);
253  while(SPI_Setup(&ss));
254 
255  if(SPI_WaitFlowControl(&ss)) {
256  memset(mainHciBuf, 0, sizeof(mainHciBuf));
257  hciDrvRead(sizeof(mainHciBuf), &mainHciBuf[0]);
258  }
259  }
260 }
261 
262 #define TMR0 0
263 static tmr32_config_t tmr32_cfg;
264 
265 #define LOOPS 0 /* Run until Stopped */
266 
267 /* globals for the capture data */
268 #define CAPT_SAMPLES0 184
269 #define CAPT_CYCLES0 46
270 #define CYCLE_START0 6
271 
272 #define R1 10000
273 #define RCAL 10000
274 
275 double ZMAG = 0;
276 double ZPHASE = 0;
277 
278 static adc_transport_t adc_capture_handle0;
279 static adc_transport_t adc_capture_handle1;
280 static uint16_t capt_buf0[CAPT_SAMPLES0];
281 static uint16_t capt_buf1[CAPT_SAMPLES0];
282 static uint16_t calc_calA1[CAPT_CYCLES0];
283 static uint16_t calc_calB1[CAPT_CYCLES0];
284 static uint16_t calc_calA2[CAPT_CYCLES0];
285 static uint16_t calc_calB2[CAPT_CYCLES0];
286 
287 static uint16_t calc_tstA1[CAPT_CYCLES0];
288 static uint16_t calc_tstB1[CAPT_CYCLES0];
289 static uint16_t calc_tstA2[CAPT_CYCLES0];
290 static uint16_t calc_tstB2[CAPT_CYCLES0];
291 
292 /* DAC0N 1vpp 1vcm const leaves it in flash, without in sram */
293 static uint16_t sine_wave16bit[] = {
294  0x82ff,
295  0x7cdf,
296  0x76ce,
297  0x70db,
298  0x6b15,
299  0x6589,
300  0x6046,
301  0x5b59,
302  0x56ce,
303  0x52af,
304  0x4f08,
305  0x4be1,
306  0x4941,
307  0x4730,
308  0x45b3,
309  0x44cd,
310  0x447f,
311  0x44cd,
312  0x45b3,
313  0x4730,
314  0x4941,
315  0x4be1,
316  0x4f08,
317  0x52af,
318  0x56ce,
319  0x5b59,
320  0x6046,
321  0x6589,
322  0x6b15,
323  0x70db,
324  0x76ce,
325  0x7cdf,
326  0x82ff,
327  0x8920,
328  0x8f31,
329  0x9524,
330  0x9aea,
331  0xa076,
332  0xa5b9,
333  0xaaa6,
334  0xaf31,
335  0xb350,
336  0xb6f7,
337  0xba1e,
338  0xbcbe,
339  0xbecf,
340  0xc04c,
341  0xc132,
342  0xc17f,
343  0xc132,
344  0xc04c,
345  0xbecf,
346  0xbcbe,
347  0xba1e,
348  0xb6f7,
349  0xb350,
350  0xaf31,
351  0xaaa6,
352  0xa5b9,
353  0xa076,
354  0x9aea,
355  0x9524,
356  0x8f31,
357  0x8920,
358 };
359 
360 static uint32_t data_samples16bit = sizeof(sine_wave16bit)/2;
361 
362 static dac_transport_t dac_wave_handle;
363 
364 static void data_avg (void)
365 {
366  //Averaging
367  int i;
368  double Ic = 0;
369  double It = 0;
370  double Qc = 0;
371  double Qt = 0;
372  double PhaseC = 0;
373  double PhaseT = 0;
374  double MagC = 0;
375  double MagT = 0;
376 
377  double cal_a1 = 0;
378  double cal_b1 = 0;
379  double cal_a2 = 0;
380  double cal_b2 = 0;
381 
382  double tst_a1 = 0;
383  double tst_b1 = 0;
384  double tst_a2 = 0;
385  double tst_b2 = 0;
386 
387  for (i = CYCLE_START0 ; i < CAPT_CYCLES0; ++i)
388  {
389  cal_a1 = cal_a1 + calc_calA1[i];
390  cal_a2 = cal_a2 + calc_calA2[i];
391  cal_b1 = cal_b1 + calc_calB1[i];
392  cal_b2 = cal_b2 + calc_calB2[i];
393  tst_a1 = tst_a1 + calc_tstA1[i];
394  tst_a2 = tst_a2 + calc_tstA2[i];
395  tst_b1 = tst_b1 + calc_tstB1[i];
396  tst_b2 = tst_b2 + calc_tstB2[i];
397  }
398 
399  Ic = (cal_a1 - cal_a2)/(CAPT_CYCLES0 - CYCLE_START0 );
400  It = (tst_a1 - tst_a2)/(CAPT_CYCLES0- CYCLE_START0 );
401  Qc = (cal_b1 - cal_b2)/(CAPT_CYCLES0 - CYCLE_START0 );
402  Qt = (tst_b1 - tst_b2)/(CAPT_CYCLES0 - CYCLE_START0 );
403  PhaseC = atan2(Qc,Ic) ;
404  PhaseT = atan2(Qt,It);
405  MagC = sqrt((Ic*Ic) + (Qc * Qc));
406  MagT = sqrt((It*It) + (Qt * Qt));
407 
408  ZMAG = ((MagC)/(MagT))*RCAL - R1;
409  ZPHASE = (PhaseC - PhaseT)*180/3.14159;
410 }
411 
412 static void print_results(void)
413 {
414  int i;
415  int k;
416 
417  k = CYCLE_START0 * 4;
418  for (i = CYCLE_START0;i < CAPT_CYCLES0; ++i)
419  {
420  calc_calA1[i] = capt_buf0[k];
421  calc_calB1[i] = capt_buf0[k+1];
422  calc_calA2[i] = capt_buf0[k+2];
423  calc_calB2[i] = capt_buf0[k+3];
424  calc_tstA1[i] = capt_buf1[k];
425  calc_tstB1[i] = capt_buf1[k+1];
426  calc_tstA2[i] = capt_buf1[k+2];
427  calc_tstB2[i] = capt_buf1[k+3];
428 
429  k = k + 4;
430  }
431 
432  data_avg();
433 
434  /*if calibration is needed, based on lab data*/
435 #ifdef GSR1
436  if (ZMAG > 1500)
437  {
438  ZMAG = ZMAG*1.0113 - 38.38;
439  }
440  else
441  {
442  ZMAG = ZMAG*1.0092 - 10.609;
443  }
444 #endif
445 
446 }
447 
448 static void capt_results(int32_t exit_status, void *arg)
449 {
450  if(exit_status > 0)
451  {
452  DAC_PatternStop(&dac_wave_handle);
453  }
454 }
455 
456 static void PwrSeq_Setup(void)
457 {
458  PWR_EnableDevRun(MXC_E_PWR_DEVICE_LDO);
459  PWR_EnableDevRun(MXC_E_PWR_DEVICE_RO);
460  PWR_EnableDevRun(MXC_E_PWR_DEVICE_RTC);
461  PWR_DisableDevRun(MXC_E_PWR_DEVICE_SVM3);
462  PWR_DisableDevRun(MXC_E_PWR_DEVICE_SVM1);
463 
464  mxc_pwrseq_reg0_t pwr_reg0 = MXC_PWRSEQ->reg0_f;
465  pwr_reg0.pwr_first_boot = 1;
466  MXC_PWRSEQ->reg0_f = pwr_reg0;
467 
468 
469  PWR_Disable(MXC_E_PWR_ENABLE_AFE);
470  PWR_Disable(MXC_E_PWR_ENABLE_STATIC_PULLUPS);
471  PWR_Disable(MXC_E_PWR_ENABLE_USB);
472 
473  /* enabled dynamic clock gating for PWRMAN functions */
474  mxc_pwrman_pwr_rst_ctrl_t pwr_rst_ctrl = MXC_PWRMAN->pwr_rst_ctrl_f;
475  pwr_rst_ctrl.low_power_mode = 1;
476  MXC_PWRMAN->pwr_rst_ctrl_f = pwr_rst_ctrl;
477 }
478 
479 static void ClkMan_Setup(void)
480 {
481  /* use the internal Ring Osc in 24MHz mode */
482  CLKMAN_SetSystemClock(MXC_E_CLKMAN_SYSTEM_SOURCE_SELECT_24MHZ_RO);
483  //CLKMAN_SetSystemClock(MXC_E_CLKMAN_SYSTEM_SOURCE_SELECT_HFX);
484 
485  CLKMAN_WaitForSystemClockStable();
486 
487  /* set systick to the RTC input 32.768kHz clock, not system clock; this is needed to keep JTAG alive */
488  CLKMAN_SetRTOSMode(TRUE);
489 
490  /* trim the internal clock */
491  CLKMAN_TrimRO_Start();
492  SysTick_Wait(0x663);
493  CLKMAN_TrimRO_Stop();
494 
495  MXC_CLKMAN->clk_config = 0x00;
496 
497  mxc_clkman_clk_gate_ctrl0_t clk_gator0 = MXC_CLKMAN->clk_gate_ctrl0_f;
498  mxc_clkman_clk_gate_ctrl1_t clk_gator1 = MXC_CLKMAN->clk_gate_ctrl1_f;
499  mxc_clkman_clk_gate_ctrl2_t clk_gator2 = MXC_CLKMAN->clk_gate_ctrl2_f;
500 
501  clk_gator0.cm3_clk_gater = 1;
502  clk_gator0.sysbus_clk_gater = 1;
503  clk_gator0.icache_clk_gater = 1;
504  clk_gator0.flash_clk_gater = 1;
505  clk_gator0.sram_clk_gater = 1;
506  clk_gator0.apb_bridge_clk_gater = 1;
507  clk_gator0.sysman_clk_gater = 1;
508  clk_gator0.uart0_clk_gater = 1;
509  clk_gator0.uart1_clk_gater = 0;
510 
511  clk_gator0.watchdog0_clk_gater = 0;
512  clk_gator0.watchdog1_clk_gater = 0;
513  clk_gator0.usb_clk_gater = 0;
514  MXC_CLKMAN->clk_gate_ctrl0_f = clk_gator0;
515 
516  clk_gator1.testacc_clk_gater = 0;
517  clk_gator1.adc_clk_gater = 1;
518  clk_gator1.dac12_0_clk_gater = 1;
519  clk_gator1.dac12_1_clk_gater = 0;
520  clk_gator1.dac8_0_clk_gater = 1;
521  clk_gator1.dac8_1_clk_gater = 0;
522  clk_gator1.pmu_clk_gater = 1;
523  clk_gator1.lcd_clk_gater = 0;
524  clk_gator1.gpio_clk_gater = 1;
525  clk_gator1.pulsetrain_clk_gater = 0;
526  clk_gator1.spi0_clk_gater = 1;
527  clk_gator1.spi1_clk_gater = 0;
528  clk_gator1.spi2_clk_gater = 0;
529  clk_gator1.i2cm0_clk_gater = 0;
530  clk_gator1.i2cm1_clk_gater = 0;
531  clk_gator1.i2cs_clk_gater = 0;
532  MXC_CLKMAN->clk_gate_ctrl1_f = clk_gator1;
533 
534  clk_gator2.crc_clk_gater = 0;
535  clk_gator2.tpu_clk_gater = 0;
536  clk_gator2.ssbmux_clk_gater = 1;
537  clk_gator2.pad_clk_gater = 1;
538  MXC_CLKMAN->clk_gate_ctrl2_f = clk_gator2;
539 
540  CLKMAN_SetClkScale(MXC_E_CLKMAN_CLK_SYS,MXC_E_CLKMAN_CLK_SCALE_ENABLED);
541  CLKMAN_SetClkScale(MXC_E_CLKMAN_CLK_RTC_INT_SYNC, MXC_E_CLKMAN_CLK_SCALE_ENABLED);
542  CLKMAN_SetClkScale(MXC_E_CLKMAN_CLK_DAC0, MXC_E_CLKMAN_CLK_SCALE_ENABLED);
543  CLKMAN_SetClkScale(MXC_E_CLKMAN_CLK_DAC2, MXC_E_CLKMAN_CLK_SCALE_DIV_256);
544 
545 }
546 
547 static void Voltage_Ref(void)
548 {
549  /* Enable the AFE Power */
550  PWR_Enable(MXC_E_PWR_ENABLE_AFE);
551 
552  /* Enable and Set the Voltage Reference for the DACs and ADC */
553  AFE_ADCVRefEnable(MXC_E_AFE_REF_VOLT_SEL_2048);
554  AFE_DACVRefEnable(MXC_E_AFE_REF_VOLT_SEL_2048, MXC_E_AFE_DAC_REF_REFADC);
555 
556 }
557 
558 static void AFE_VRefDisable(void)
559 {
560  mxc_afe_ctrl1_t afe_ctrl1 = MXC_AFE->ctrl1_f;
561  afe_ctrl1.refadc_fast_pwrdn_en = 1;
562  afe_ctrl1.refdac_fast_pwrdn_en = 1;
563  afe_ctrl1.refadc_outen = 0;
564  afe_ctrl1.refdac_outen = 0;
565  afe_ctrl1.ref_pu = 0;
566  MXC_AFE->ctrl1_f = afe_ctrl1;
567 }
568 
569 static void AFE_Disable(void)
570 {
571  PWR_Disable(MXC_E_PWR_ENABLE_AFE);
572  AFE_VRefDisable();
573  AFE_OpAmpDisable(0);
574  AFE_OpAmpDisable(1);
575  AFE_OpAmpDisable(3);
576  DAC_Disable(0);
577  DAC_Disable(2);
578  ADC_Disable();
579 
580  /* Sets the ADC Clock back to default values */
581  mxc_adc_ctrl0_t adc_ctrl0 = MXC_ADC->ctrl0_f;
582  adc_ctrl0.adc_clk_mode = 0x0;
583  MXC_ADC->ctrl0_f = adc_ctrl0;
584  mxc_clkman_clk_ctrl_t clk_ctrl = MXC_CLKMAN->clk_ctrl_f;
585  clk_ctrl.adc_gate_n = 0;
586  clk_ctrl.adc_source_select = 0;
587  MXC_CLKMAN->clk_ctrl_f = clk_ctrl;
588 
589  /* Clears the ADC interrupt */
590  mxc_adc_intr_t adc_int = MXC_ADC->intr_f; //clear the interrupt
591  MXC_ADC->intr_f = adc_int;
592 }
593 
594 static void Switch_Setup (int i)
595 {
596  if (i == 0)
597  {
598  AFE_SetSwitchState(0,1);
599  AFE_SetSwitchState(2,1);
600  AFE_SetSwitchState(1,0);
601  AFE_SetSwitchState(3,0);
602  }
603 
604  if (i == 1)
605  {
606  AFE_SetSwitchState(0,0);
607  AFE_SetSwitchState(2,0);
608  AFE_SetSwitchState(1,1);
609  AFE_SetSwitchState(3,1);
610  }
611 }
612 
613 static void AFE_Init(int i)
614 {
615 #ifdef GSR3
616  MXC_DAC0->trm = 0xffff4200;
617  MXC_DAC2->reg = 0x002400ff;
618 
619 #endif
620 
621  /* Setup DAC0 for DC LEvel Set */
622  DAC_Enable(0, MXC_E_DAC_PWR_MODE_LVL2);
623  DAC_SetStartMode(0, MXC_E_DAC_START_MODE_FIFO_NOT_EMPTY);
624  DAC_SetOutputRaw(0,sine_wave16bit[0]);
625 
626  /* Setup DAC2 for DC LEvel Set */
627  DAC_Enable(2,MXC_E_DAC_PWR_MODE_LVL0);
628  DAC_SetStartMode(2,MXC_E_DAC_START_MODE_FIFO_NOT_EMPTY);
629  DAC_SetOutput(2,140);
630 
631  /* i == 0 used for Calibration Capture, i == 1 used for Test Load Capture */
632  if (i == 0)
633  {
634  //AFE_OpAmpSetup(0,0,MXC_E_AFE_OPAMP_POS_IN_PAD_INxP,MXC_E_AFE_OPAMP_NEG_IN_OUTx,MXC_E_AFE_IN_MODE_COMP_NCH_PCH);
635  AFE_OpAmpSetup(0,0,MXC_E_AFE_OPAMP_POS_IN_PAD_INxP,MXC_E_AFE_OPAMP_NEG_IN_OUTx,MXC_E_AFE_IN_MODE_OPAMP_NCH_PCH);
636  //AFE_NpadSetup(0,MXC_E_AFE_OPAMP_NEG_PAD_DAC0N);
637  AFE_OpAmpEnable(0);
638  //AFE_OpAmpSetup(1,0,MXC_E_AFE_OPAMP_POS_IN_DAC2P,MXC_E_AFE_OPAMP_NEG_IN_PAD_INxN,MXC_E_AFE_IN_MODE_COMP_NCH_PCH);
639  AFE_OpAmpSetup(1,0,MXC_E_AFE_OPAMP_POS_IN_DAC2P,MXC_E_AFE_OPAMP_NEG_IN_PAD_INxN,MXC_E_AFE_IN_MODE_OPAMP_NCH_PCH);
640  AFE_OpAmpEnable(1);
641  //AFE_OpAmpSetup(3,0,MXC_E_AFE_OPAMP_POS_IN_DAC0N,MXC_E_AFE_OPAMP_NEG_IN_OUTx,MXC_E_AFE_IN_MODE_COMP_NCH_PCH);
642  AFE_OpAmpSetup(3,0,MXC_E_AFE_OPAMP_POS_IN_DAC0N,MXC_E_AFE_OPAMP_NEG_IN_OUTx,MXC_E_AFE_IN_MODE_OPAMP_NCH_PCH);
643  AFE_OpAmpEnable(3);
644  Switch_Setup(0);
645  //RTC_delay(10); /* Stabilization after power up of Voltage Reference, OpAmps and DACs */
646  SysTick_Wait(333); /*~10 ms*/
647  }
648 
649  if (i == 1)
650  {
651  Switch_Setup(1);
652  }
653 
654 }
655 
656 static void ADC_Init(int i, float excitation_frequency)
657 {
658  uint32_t adc_slp_cnt = 2000000.0/excitation_frequency - 100;
659  /* i == 0 used for Calibration Capture, i == 1 used for Test Load Capture */
660  if (i == 0)
661  {
662  /* Set MCLK to Divide/3 mode 0'b10 */
663  mxc_adc_ctrl0_t adc_ctrl0 = MXC_ADC->ctrl0_f;
664  adc_ctrl0.adc_clk_mode = 0x2;
665  MXC_ADC->ctrl0_f = adc_ctrl0;
666 
667  /* Set ADC Clock Source to 24MHz Ring Oscillator */
668  CLKMAN_SetADCClock(MXC_E_CLKMAN_ADC_SOURCE_SELECT_24MHZ_RO);
669 
670  /* ADC Setup for 32 kHz sample rate */
671  ADC_SetRate(1,1,7,adc_slp_cnt);
672 
673  ADC_SetMode(MXC_E_ADC_MODE_SMPLCNT_LOW_POWER,MXC_E_ADC_AVG_MODE_FILTER_OUTPUT,2,MXC_E_ADC_BI_POL_BIPOLAR,MXC_E_ADC_RANGE_FULL);
674  ADC_SetMuxSel(MXC_E_ADC_PGA_MUX_CH_SEL_AIN0,MXC_E_ADC_PGA_MUX_DIFF_ENABLE);
675  ADC_SetPGAMode(0,MXC_E_ADC_PGA_GAIN_2);
676  ADC_SetStartMode(MXC_E_ADC_STRT_MODE_SOFTWARE);
677  }
678 
679  /* Enable ADC, Clear Interrupts */
680  ADC_Enable();
681 }
682 
683 static void ADC_Capt(int i, float excitation_frequency)
684 {
685  /* Setup of DAC0 for Sinewave generation at 8 kHz, to Start on ADC Strobe */
686  /* frequency, dac_rate_cnt, adc_sleep_cnt
687  * 100, 3748, 19900
688  * 200, 1873, 9900
689  * 500, 748, 3900
690  * 1000, 373, 1900
691  * 1953.125, 190, 924
692  * 5000, 73, 300
693  * 7812.5, 46, 156
694  * 12500, 28, 60
695  * 15625, 22, 28
696  */
697  uint16_t rate = 24000000.0/(64.0*excitation_frequency)-2;
698  DAC_SetRate(0,rate,MXC_E_DAC_INTERP_MODE_DISABLED);
699  DAC_SetStartMode(0,MXC_E_DAC_START_MODE_ADC_STROBE);
700 
701 
702  /* Setup PMU parameters for DAC0 using dac_wave_handle - DAC Configuration */
703  DAC_PatternStart(&dac_wave_handle);
704 
705  /* disable ssb mux clock gator, no longer needed */
706  mxc_clkman_clk_gate_ctrl2_t clk_gator2 = MXC_CLKMAN->clk_gate_ctrl2_f;
707  clk_gator2.ssbmux_clk_gater = 0;
708  MXC_CLKMAN->clk_gate_ctrl2_f = clk_gator2;
709 
710  /* Lower system clock scale to conserve power */
711  CLKMAN_SetClkScale( MXC_E_CLKMAN_CLK_SYS,MXC_E_CLKMAN_CLK_SCALE_DIV_4);
712 
713  if (i == 0)
714  {
715  /* Start ADC Capture for Calibration path */
716  ADC_CaptureStart(&adc_capture_handle0);
717  PWR_SetMode(MXC_E_PWR_MODE_LP2, NULL);
718  PWR_Sleep();
719  }
720 
721  if (i == 1)
722  {
723  /* Start ADC Capture for Test Load path */
724  ADC_CaptureStart(&adc_capture_handle1);
725  PWR_SetMode(MXC_E_PWR_MODE_LP2, NULL);
726  PWR_Sleep();
727  }
728  CLKMAN_SetClkScale( MXC_E_CLKMAN_CLK_SYS,MXC_E_CLKMAN_CLK_SCALE_ENABLED);
729 
730 }
731 
732 static void ADC_Measure(float excitation_frequency)
733 {
734  /* Setup Voltage Reference */
735  Voltage_Ref();
736 
737  /* Measurement of Calibration path */
738  AFE_Init(0);
739  ADC_Init(0, excitation_frequency);
740  ADC_Capt(0, excitation_frequency);
741 
742  /* Measurement of Test Load Path */
743  AFE_Init(1);
744  ADC_Init(1, excitation_frequency);
745  ADC_Capt(1, excitation_frequency);
746 
747  /*Allow DAC to finish, prior to disabling the AFE */
748  SysTick_Wait(10); /*~0.305 ms*/
749 
750  /* Disable all Analog Components */
751  AFE_Disable();
752 
753  /* Turn on the ssb mux clock gator */
754  mxc_clkman_clk_gate_ctrl2_t clk_gator2 = MXC_CLKMAN->clk_gate_ctrl2_f;
755  clk_gator2.ssbmux_clk_gater = 1;
756  MXC_CLKMAN->clk_gate_ctrl2_f = clk_gator2;
757 }
758 
759 /* Called by tmr0_isr */
760 static uint32_t tmr0_counter;
761 static void tmr32_led(uint32_t ticks)
762 {
763  if((BLEadvertising == 0) && (BLEconnected == 0))
764  return;
765 
766  static uint8_t yellow_led_off = 1;
767 
768  /* Update our BLE stack timers */
769  WsfTimerUpdate(1);
770  wsfOsDispatcher();
771 
772  if(BLEconnected && (tmr0_counter++ == 50))
773  {
774  if (yellow_led_off)
775  {
776  // start GSR measurements
777  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, LED_ON);
778 
779  if(sweeping)
780  {
781  uint8_t loop;
782  for(loop = 0; loop < 8; loop++)
783  {
784  // clear power sequencer wake-up flags
785  PWR_ClearFlags();
786 
787  // Function for Setting up Part to collect measurement
788  switch(loop)
789  {
790  case 0:
791  ADC_Measure(100.0);
792  break;
793  case 1:
794  ADC_Measure(200.0);
795  break;
796  case 2:
797  ADC_Measure(500.0);
798  break;
799  case 3:
800  ADC_Measure(1000.0);
801  break;
802  case 4:
803  ADC_Measure(1953.125);
804  break;
805  case 5:
806  ADC_Measure(5000.0);
807  break;
808  case 6:
809  ADC_Measure(12500.0);
810  break;
811  case 7:
812  ADC_Measure(15625.0);
813  break;
814  }
815 
816  // Perform calculations and print results
817  print_results();
818  // place ZMAG to the GSR1_buf.
819 
820  if(loop < 4)
821  {
822  *(packet_1_buf+(loop+1)*4+0) = ((uint32_t)ZMAG & 0xFF000000) >> 24;
823  *(packet_1_buf+(loop+1)*4+1) = ((uint32_t)ZMAG & 0x00FF0000) >> 16;
824  *(packet_1_buf+(loop+1)*4+2) = ((uint32_t)ZMAG & 0x0000FF00) >> 8;
825  *(packet_1_buf+(loop+1)*4+3) = (uint32_t)ZMAG & 0x000000FF;
826  }
827  else
828  {
829  *(packet_2_buf+((loop-4)+1)*4+0) = ((uint32_t)ZMAG & 0xFF000000) >> 24;
830  *(packet_2_buf+((loop-4)+1)*4+1) = ((uint32_t)ZMAG & 0x00FF0000) >> 16;
831  *(packet_2_buf+((loop-4)+1)*4+2) = ((uint32_t)ZMAG & 0x0000FF00) >> 8;
832  *(packet_2_buf+((loop-4)+1)*4+3) = (uint32_t)ZMAG & 0x000000FF;
833  }
834  }
835  *packet_1_buf = (packetNumber & 0xFF00) >> 8;
836  *(packet_1_buf+1) = packetNumber & 0x00FF;
837  packetNumber++;
838  *(packet_1_buf+2) = 0;
839  *(packet_1_buf+3) = 1;
840  *packet_2_buf = (packetNumber & 0xFF00) >> 8;
841  *(packet_2_buf+1) = packetNumber & 0x00FF;
842  packetNumber++;
843  *(packet_2_buf+2) = 0;
844  *(packet_2_buf+3) = 2;
845 
846  sweepingDone = 1;
847  //sweeping = 0;
848  }
849  else // not sweeping
850  {
851  // clear power sequencer wake-up flags
852  PWR_ClearFlags();
853 
854  // Function for Setting up Part to collect measurement
855  ADC_Measure(7812.5);
856 
857  // Perform calculations and print results
858  print_results();
859 
860  // measure temperature
861  /* Enable the AFE Power */
862  PWR_Enable(MXC_E_PWR_ENABLE_AFE);
863  /* Enable and Set the Voltage Reference for the ADC */
864  AFE_ADCVRefEnable(MXC_E_AFE_REF_VOLT_SEL_2048);
865  /* Setup ADC decimation filter to average 1 sample */
866  ADC_SetMode(MXC_E_ADC_MODE_SMPLCNT_FULL_RATE, MXC_E_ADC_AVG_MODE_FILTER_OUTPUT, 7, 0, MXC_E_ADC_RANGE_FULL);
867  /* Set MCLK to Divide/3 mode 0'b10 */
868  mxc_adc_ctrl0_t adc_ctrl0 = MXC_ADC->ctrl0_f;
869  adc_ctrl0.adc_clk_mode = 0x2;
870  MXC_ADC->ctrl0_f = adc_ctrl0;
871  /* Set ADC Clock Source to 24MHz Ring Oscillator */
872  CLKMAN_SetADCClock(MXC_E_CLKMAN_ADC_SOURCE_SELECT_24MHZ_RO);
873  ADC_SetRate(1,1,0x3F,0);
874  /* Setup current source for external temperature sensor*/
875  TMON_Enable(1);
876  TMON_SetCurrent(0); // 4uA
877  /* PGA = 2*/
878  ADC_SetPGAMode(0, MXC_E_ADC_PGA_GAIN_2);
879  /* Setup ADC input multiplexor and disable a differential measurement */
880  ADC_SetMuxSel(MXC_E_ADC_PGA_MUX_CH_SEL_AIN1, 0);
881  /* enable ADC */
882  ADC_Enable();
883 
884  /* wait 1 ms to get stable ADC capture */
885  SysTick_Wait(32);
886 
887  /* Read NTC sample */
888  uint16_t NTCCODE = ADC_ManualRead();
889 
890  // measure battery voltage
891  /* PGA = 1 */
892  ADC_SetPGAMode(0, MXC_E_ADC_PGA_GAIN_1);
893  /* Setup ADC input multiplexor and disable a differential measurement */
894  ADC_SetMuxSel(MXC_E_ADC_PGA_MUX_CH_SEL_AIN2, 0);
895  /* enable ADC */
896  ADC_Enable();
897 
898  /* wait 1 ms to get stable ADC capture */
899  SysTick_Wait(32);
900 
901  /* Read VBAT sample */
902  uint16_t BATCODE = ADC_ManualRead();
903 
904  // measure charging current
905  // If charging current is less than 1mA (ADC code = 30), battery is fully charged.
906  /* Setup ADC input multiplexor and disable a differential measurement */
907  uint8_t CHARGING = !GPIO_GetInVal(CHARGING_PORT, CHARGING_PIN);
908 
909  if(CHARGING)
910  {
911  ADC_SetMuxSel(MXC_E_ADC_PGA_MUX_CH_SEL_AIN5, 0);
912  /* enable ADC */
913  ADC_Enable();
914  /* wait 1 ms to get stable ADC capture */
915  SysTick_Wait(32);
916  /* Read ICHARGING sample */
917  uint16_t CHARGINGCODE = ADC_ManualRead();
918  // TO DO...
919  }
920 
921  /* Disable ADC reference voltage */
922  AFE_ADCVRefDisable();
923  /* Disable TMON */
924  TMON_Disable();
925  /* Disable ADC */
926  ADC_Disable();
927  PWR_Disable(MXC_E_PWR_ENABLE_AFE);
928 
929  // calculate temperature
930  double RNTC = NTCCODE*2.048/(0.065535*2.0*4.0);
931  double TNTC = 1000000.0/((double)(NTC_A) + (double)(NTC_B) * log(RNTC) + (double)NTC_C * pow(log(RNTC), 3)) - 273.15;
932 
933  // build the packet
934  *packet_0_buf = (packetNumber & 0xFF00) >> 8;
935  *(packet_0_buf+1) = packetNumber & 0x00FF;
936  packetNumber++;
937  *(packet_0_buf+2) = 0;
938  *(packet_0_buf+3) = 0;
939  *(packet_0_buf+4) = (int)TNTC & 0xFF;
940  *(packet_0_buf+5) = TNTC>0?(TNTC- (int)TNTC)*100:((int)TNTC-TNTC)*100;
941  // place ZMAG to the packet
942  *(packet_0_buf+6) = ((uint32_t)ZMAG & 0xFF000000) >> 24;
943  *(packet_0_buf+7) = ((uint32_t)ZMAG & 0x00FF0000) >> 16;
944  *(packet_0_buf+8) = ((uint32_t)ZMAG & 0x0000FF00) >> 8;
945  *(packet_0_buf+9) = (uint32_t)ZMAG & 0x000000FF;
946 
947 
948  // roughly calculate battery level %.
949  double VBAT = BATCODE * 2.048 * 2.0/65535.0;
950  if(VBAT >= 4.05)
951  BATLEVEL = 100;
952  else if (VBAT < 2.5)
953  BATLEVEL = 0;
954  else
955  BATLEVEL = (VBAT-2.5)/1.55*100.0;
956 
957  if(CHARGING)
958  {
959  if(firstMeasurement)
961  else
962  BATLEVEL > preBATLEVEL? (preBATLEVEL = BATLEVEL) : (BATLEVEL = preBATLEVEL);
963 
964  BATLEVEL |= 0x80; // include the charging bit.
965  }
966  else
967  {
968  if(firstMeasurement)
970  else
971  BATLEVEL < preBATLEVEL? (preBATLEVEL = BATLEVEL) : (BATLEVEL = preBATLEVEL);
972 
973  BATLEVEL &= 0x7F; // include the charging bit.
974  }
975 
976  firstMeasurement = 0;
977  }
978 
979  yellow_led_off = 0;
980  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, LED_OFF);
981  }
982  else
983  yellow_led_off = 1;
984 
985  tmr0_counter = 0;
986  }
987 }
988 
989 int main(void)
990 {
991  /* enable instruction cache */
992  ICC_Enable();
993  PwrSeq_Setup();
994  ClkMan_Setup();
995  PWR_Init();
996 
997  firstMeasurement = 1;
998  sweeping = 0;
999  sweepingDone = 0;
1000  packetNumber = 0;
1001  firstMeasurement = 1;
1002  BLEconnected = 0;
1003  BLEadvertising = 1;
1004 
1005  DAC_PatternConfig(0,&dac_wave_handle, sine_wave16bit, data_samples16bit, LOOPS, NULL, NULL);
1006  ADC_CaptureConfig(&adc_capture_handle0,capt_buf0, CAPT_SAMPLES0, NULL, 0,capt_results, capt_buf0, 1);
1007  ADC_CaptureConfig(&adc_capture_handle1,capt_buf1, CAPT_SAMPLES0, NULL, 0,capt_results, capt_buf1, 1);
1008 
1009  /* setup SPI pins */
1010  IOMAN_SPI0(MXC_E_IOMAN_MAPPING_A, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0);
1011 
1012  /* set GPIO clock to 24MHz */
1013  CLKMAN_SetClkScale(MXC_E_CLKMAN_CLK_GPIO, MXC_E_CLKMAN_CLK_SCALE_ENABLED);
1014 
1015  /* set SPI0 clock to 24MHz */
1016  CLKMAN_SetClkScale(MXC_E_CLKMAN_CLK_SPI0, MXC_E_CLKMAN_CLK_SCALE_ENABLED);
1017 
1018  /* enable real-time clock during run mode, this is needed to drive the systick with the RTC crystal */
1019  PWR_EnableDevRun(MXC_E_PWR_DEVICE_RTC);
1020 
1021  /* setup GPIO for the LED */
1022  GPIO_SetOutVal(LED_PORT, GREEN_LED_PIN, 1);
1023  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 1);
1024  GPIO_SetOutMode(LED_PORT, GREEN_LED_PIN, MXC_E_GPIO_OUT_MODE_OPEN_DRAIN_W_PULLUP);
1025  GPIO_SetOutMode(LED_PORT, RED_LED_PIN, MXC_E_GPIO_OUT_MODE_OPEN_DRAIN_W_PULLUP);
1026 
1027  // flash RED led to indicate system boot up
1028  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 0);
1029  SysTick_Wait(6104); // 200ms
1030  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 1);
1031  SysTick_Wait(6104); // 200ms
1032  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 0);
1033  SysTick_Wait(6104); // 200ms
1034  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 1);
1035  SysTick_Wait(6104); // 200ms
1036  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 0);
1037  SysTick_Wait(6104); // 200ms
1038  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 1);
1039  SysTick_Wait(6104); // 200ms
1040  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 0);
1041  SysTick_Wait(6104); // 200ms
1042  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 1);
1043  SysTick_Wait(6104); // 200ms
1044  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 0);
1045  SysTick_Wait(6104); // 200ms
1046  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, 1);
1047 
1048  /* setup GPIO for the charging indicator */
1049  GPIO_SetInMode(CHARGING_PORT, CHARGING_PIN, MXC_E_GPIO_IN_MODE_NORMAL);
1050 
1051  /* Setup BLE chip IRQ/CSN/RST pins */
1052  GPIO_SetInMode(BLE_IRQ_PORT, BLE_IRQ_PIN, MXC_E_GPIO_IN_MODE_NORMAL);
1053  GPIO_SetOutMode(BLE_RST_PORT, BLE_RST_PIN, MXC_E_GPIO_OUT_MODE_NORMAL);
1054  GPIO_SetOutMode(SPI0_PORT, SPI0_CSN, MXC_E_GPIO_OUT_MODE_NORMAL);
1055 
1056  /* Assert CSN and deassert RST_H */
1057  GPIO_SetOutVal(BLE_RST_PORT, BLE_RST_PIN, EM9301_RELEASE_RESET);
1058  GPIO_SetOutVal(SPI0_PORT, SPI0_CSN, EM9301_SLEEP);
1059 
1060  /* Delay for 100us */
1061  SysTick_Wait(3);
1062 
1063  /* Hold EM3901 in reset for at least 1ms */
1064  em9301_hw_reset(EM9301_ASSERT_RESET);
1065 
1066  /* Wait for 2ms */
1067  SysTick_Wait(64);
1068 
1069  /* Relese EM9301 from reset */
1070  em9301_hw_reset(EM9301_RELEASE_RESET);
1071 
1072  /* Initialize SPI */
1073  SPI_Config(&ss, SPI_PORT);
1074  SPI_ConfigClock(&ss, 3, 3, 0, 0, 0, 0);
1075 
1076  /* wait at least 100ns after asserting CS */
1077  SPI_ConfigSlaveSelect(&ss, BLE_SLAVE_SELECT, SS_POLARITY, ACT_DELAY, INACT_DELAY);
1078 
1079  NVIC_SetPriority(SPI0_IRQn, 2);
1080  NVIC_SetPriority(GPIO_P0_IRQn, 6);
1081  NVIC_SetPriority(TMR0_IRQn, 6);
1082 
1083  /* Setup IRQ handler */
1084  GPIO_SetIntMode(BLE_IRQ_PORT, BLE_IRQ_PIN, MXC_E_GPIO_INT_MODE_HIGH_LVL, &spi_read_irq);
1085 
1086  /* Enable tmr0 callback */
1087  uint32_t ticks;
1088  uint8_t prescale;
1089  memset(&tmr32_cfg, 0, sizeof(tmr32_cfg));
1090  TMR32_PeriodToTicks(10, MXC_E_TMR_PERIOD_UNIT_MILLISEC, &ticks, &prescale);
1091  TMR32_Config(&tmr32_cfg, TMR0, MXC_E_TMR_MODE_CONTINUOUS, ticks, prescale, 0, 0);
1092  TMR32_Start(&tmr32_cfg, tmr32_led);
1093 
1094  /* initialize BLE stack */
1095  bleStackInit(BLE_MS_PER_TIMER_TICK);
1096 
1097  /* Configure advertising and services */
1098  FitStart();
1099 
1100  for(;;) {
1101  if(BLEconnected == 0 && BLEadvertising == 0)
1102  PWR_SetMode(MXC_E_PWR_MODE_LP1, NULL);
1103  else
1104  PWR_SetMode(MXC_E_PWR_MODE_LP2, NULL);
1105 
1106  PWR_Sleep();
1107  }
1108 
1109  return 0;
1110 }