2 * Copyright (c) 2014, Texas Instruments Incorporated
\r
3 * All rights reserved.
\r
5 * Redistribution and use in source and binary forms, with or without
\r
6 * modification, are permitted provided that the following conditions
\r
9 * * Redistributions of source code must retain the above copyright
\r
10 * notice, this list of conditions and the following disclaimer.
\r
12 * * Redistributions in binary form must reproduce the above copyright
\r
13 * notice, this list of conditions and the following disclaimer in the
\r
14 * documentation and/or other materials provided with the distribution.
\r
16 * * Neither the name of Texas Instruments Incorporated nor the names of
\r
17 * its contributors may be used to endorse or promote products derived
\r
18 * from this software without specific prior written permission.
\r
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
\r
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
\r
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
\r
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
\r
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
\r
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
\r
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
\r
27 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
\r
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
\r
29 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\r
30 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\r
32 //*****************************************************************************
\r
34 // esi.h - Driver for the ESI Module.
\r
36 //*****************************************************************************
\r
38 //*****************************************************************************
\r
40 //! \addtogroup esi_api
\r
43 //*****************************************************************************
\r
45 #include "inc/hw_regaccess.h"
\r
46 #include "inc/hw_memmap.h"
\r
48 #ifdef __MSP430_HAS_ESI__
\r
53 // Uncomment for finding lower peak of the lower half cycle.
\r
54 // This required to set ESI comparator output as inverted
\r
57 static uint16_t measureESIOSC(void);
\r
58 static void FindDAC(uint8_t selected_channel,
\r
59 uint8_t software_trigger);
\r
61 const ESI_AFE1_InitParams ESI_AFE1_INITPARAMS_DEFAULT =
\r
62 {ESI_EXCITATION_CIRCUIT_DISABLED,
\r
63 ESI_SAMPLE_HOLD_DISABLED,
\r
64 ESI_MID_VOLTAGE_GENERATOR_DISABLED,
\r
65 ESI_SAMPLE_HOLD_VSS_TO_ESIVSS,
\r
66 ESI_INVERTER_FOR_AFE1_DISABLE};
\r
68 const ESI_AFE2_InitParams ESI_AFE2_INITPARAMS_DEFAULT = {
\r
69 ESI_AFE2_INPUT_SELECT_CHx,
\r
70 ESI_INVERTER_FOR_AFE2_DISABLE,
\r
71 ESI_TSM_COMPARATOR_CONTROL_AFE2_DISABLE,
\r
72 ESI_TSM_DAC_CONTROL_AFE2_DISABLE
\r
75 const ESI_TSM_InitParams ESI_TSM_INITPARAMS_DEFAULT = { ESI_TSM_SMCLK_DIV_1,
\r
77 ESI_TSM_START_TRIGGER_DIV_2,
\r
78 ESI_TSM_REPEAT_NEW_TRIGGER,
\r
79 ESI_TSM_STOP_SEQUENCE,
\r
80 ESI_TSM_HIGH_FREQ_CLK_FUNCTION_ON};
\r
82 const ESI_PSM_InitParams ESI_PSM_INITPARAMS_DEFAULT = { ESI_PSM_Q6_DISABLE,
\r
83 ESI_PSM_Q7_TRIGGER_DISABLE,
\r
84 ESI_PSM_CNT0_DISABLE,
\r
86 ESI_PSM_CNT1_DISABLE,
\r
88 ESI_PSM_CNT2_DISABLE,
\r
91 ESI_PSM_TEST4_IS_Q2,};
\r
93 //*****************************************************************************
\r
95 //! Get ESI PSM Counter 0 Value
\r
97 //! This function reads the ESI Counter 0 register
\r
99 //! \return Counter value
\r
101 //*****************************************************************************
\r
102 uint16_t ESI_getCounter0(void)
\r
107 //*****************************************************************************
\r
109 //! Get ESI PSM Counter 1 Value
\r
111 //! This function reads the ESI Counter1 register
\r
113 //! \return Counter value
\r
115 //*****************************************************************************
\r
116 uint16_t ESI_getCounter1(void)
\r
121 //*****************************************************************************
\r
123 //! Get ESI PSM Counter 2 Value
\r
125 //! This function reads the ESI Counter2 register
\r
127 //! \return Counter value
\r
129 //*****************************************************************************
\r
130 uint16_t ESI_getCounter2(void)
\r
135 //*****************************************************************************
\r
137 //! Get ESI PSM Oscillator Counter Value
\r
139 //! This function reads the ESI Oscillator Counter register
\r
141 //! \return Counter value
\r
143 //*****************************************************************************
\r
144 uint16_t ESI_getOscCounter(void)
\r
149 //*****************************************************************************
\r
151 //! Initializes the ESI analog front end AFE1
\r
153 //! \param params is ESI_AFE1_InitParams struct
\r
155 //! This functions initializes the ESI analog front end AFE1.
\r
159 //*****************************************************************************
\r
161 void ESI_AFE1_init(ESI_AFE1_InitParams *params)
\r
163 // Unset the AFE1 bits
\r
164 ESIAFE &= ~(ESITEN + ESISH + ESIVCC2 + ESIVSS + ESICACI3 + ESICISEL +
\r
165 ESICA1X + ESICA1INV);
\r
167 params->excitationCircuitSelect +
\r
168 params->sampleAndHoldSelect +
\r
169 params->midVoltageGeneratorSelect +
\r
170 params->sampleAndHoldVSSConnect +
\r
171 params->inverterSelectOutputAFE1
\r
174 switch(params->inputSelectAFE1)
\r
176 case ESI_AFE1_INPUT_SELECT_CHx:
\r
178 case ESI_AFE1_INPUT_SELECT_CIx:
\r
181 case ESI_AFE1_INPUT_SELECT_CI3:
\r
183 ESIAFE &= ~ESICISEL;
\r
184 ESIAFE |= ESICACI3;
\r
186 case ESI_AFE1_INPUT_SELECT_CI:
\r
188 ESIAFE |= ESICISEL;
\r
195 //*****************************************************************************
\r
197 //! Initializes the ESI analog front end - AFE2
\r
199 //! \param params is ESI_AFE2_InitParams struct
\r
201 //! This functions initializes the ESI analog front end AFE2
\r
205 //*****************************************************************************
\r
207 void ESI_AFE2_init(ESI_AFE2_InitParams *params)
\r
209 // Unset the AFE2 bits
\r
210 ESIAFE &= ~(ESICA2X + ESICA2INV + ESICA2EN + ESIDAC2EN);
\r
213 params->inputSelectAFE2 +
\r
214 params->inverterSelectOutputAFE2 +
\r
215 params->tsmControlComparatorAFE2 +
\r
216 params->tsmControlDacAFE2
\r
220 //*****************************************************************************
\r
222 //! Reads the latched comparator outputs form the AFEs
\r
224 //! \param channelSelect. Valid values are
\r
225 //! ESI_AFE1_CHANNEL0_SELECT
\r
226 //! ESI_AFE1_CHANNEL1_SELECT
\r
227 //! ESI_AFE1_CHANNEL2_SELECT
\r
228 //! ESI_AFE1_CHANNEL3_SELECT
\r
229 //! ESI_AFE2_CHANNEL0_SELECT
\r
230 //! ESI_AFE2_CHANNEL1_SELECT
\r
231 //! ESI_AFE2_CHANNEL2_SELECT
\r
232 //! ESI_AFE2_CHANNEL3_SELECT
\r
233 //! ESI_AFE1_TEST_CHANNEL0_SELECT
\r
234 //! ESI_AFE1_TEST_CHANNEL1_SELECT
\r
236 //! This function gets the ESIPPU register to get latched output values of the
\r
237 //! comparator outputs for AFE1 and AFE2
\r
239 //! \return Valid values are
\r
240 //! ESI_AFE_OUTPUT_LOW
\r
241 //! ESI_AFE_OUTPUT_HIGH
\r
243 //*****************************************************************************
\r
244 uint16_t ESI_getLatchedComparatorOutput(uint16_t channelSelect)
\r
250 return (result &= channelSelect);
\r
253 //*****************************************************************************
\r
255 //! Initializes the TSM
\r
257 //! \param params is ESI_TSM_InitParams struct
\r
259 //! This function initializes the TSM.
\r
263 //*****************************************************************************
\r
265 void ESI_TSM_init(ESI_TSM_InitParams *params)
\r
268 params->smclkDivider +
\r
269 params->aclkDivider +
\r
270 params->startTriggerAclkDivider +
\r
271 params->repeatMode +
\r
272 params->startTriggerSelection +
\r
273 params->tsmFunctionSelection
\r
277 //*****************************************************************************
\r
279 //! Clear TSM entries
\r
281 //! This function clears all TSM entries
\r
285 //*****************************************************************************
\r
286 void ESI_TSM_clearTable(void)
\r
290 // Clear TSM Table (for testing only. not neccessary in real application)
\r
291 pTsm = (uint16_t *)&ESITSM0;
\r
292 for(i = 0; i < 32; i++)
\r
298 //*****************************************************************************
\r
300 //! Copy TSM entries
\r
302 //! This function copies all TSM entries
\r
306 //*****************************************************************************
\r
307 void ESI_TSM_copyTable(uint16_t* tsmTable,
\r
310 uint16_t *pt_tsmTable;
\r
313 // Copy the TSM_Table into ESI TSM registers
\r
314 // Destination pointer
\r
315 pt_tsmTable = (uint16_t *)&ESITSM0;
\r
316 // Divided by 2 because of unsigned integer (2bytes)
\r
321 *pt_tsmTable++ = *tsmTable++;
\r
326 //*****************************************************************************
\r
328 //! TSM trigger using software
\r
330 //! This function starts a software initiated TSM sequence
\r
334 //*****************************************************************************
\r
335 void ESI_TSM_softwareTrigger(void)
\r
337 ESITSM |= ESISTART;
\r
340 //*****************************************************************************
\r
342 //! TSM trigger using software
\r
344 //! This function starts a software initiated TSM sequence
\r
346 //! \return ESIREATx bits from selected stateRegNum
\r
348 //*****************************************************************************
\r
349 uint8_t ESI_TSM_getTSMStateDuration(uint8_t stateRegNum)
\r
351 volatile uint16_t* stateRegBase = (volatile uint16_t*)&ESITSM0;
\r
353 return((*(stateRegBase + stateRegNum) & 0xf800) >> 11);
\r
356 //*****************************************************************************
\r
358 //! TSM trigger using software
\r
360 //! This function starts a software initiated TSM sequence
\r
362 //! \return ESIREATx bits from selected stateRegNum
\r
364 //*****************************************************************************
\r
365 void ESI_TSM_setTSMStateDuration(uint8_t stateRegNum,
\r
368 assert(stateRegNum <= ESI_TSM_STATE_REG_31);
\r
369 assert(duration <= ESI_TSM_STATE_DURATION_MAX);
\r
371 volatile uint16_t* stateRegBase = (volatile uint16_t*)&ESITSM0;
\r
373 *(stateRegBase + stateRegNum) &= ~0xF800;
\r
375 *(stateRegBase + stateRegNum) |= (duration << 11);
\r
378 //*****************************************************************************
\r
380 //! Initialize Processing State Machine
\r
382 //! \param params is ESI_PSM_InitParams struct
\r
384 //! This function initializes the PSM registers.
\r
388 //*****************************************************************************
\r
389 void ESI_PSM_init(ESI_PSM_InitParams *params)
\r
393 params->Q7TriggerSelect +
\r
394 params->count0Select +
\r
395 params->count0Reset +
\r
396 params->count1Select +
\r
397 params->count1Reset +
\r
398 params->count2Select +
\r
399 params->count2Reset +
\r
401 params->TEST4Select
\r
405 //*****************************************************************************
\r
407 //! Clear PSM entries
\r
409 //! This function clears all PSM entries
\r
413 //*****************************************************************************
\r
414 void ESI_PSM_clearTable(void)
\r
418 // Clear TSM Table (for testing only. not neccessary in real application)
\r
419 pPsm = (uint8_t *)&ESIRAM0;
\r
420 for(i = 0; i < 128; i++)
\r
426 //*****************************************************************************
\r
428 //! Copy PSM entries
\r
430 //! This function copies all PSM entries
\r
434 //*****************************************************************************
\r
435 void ESI_PSM_copyTable(uint8_t* psmTable,
\r
438 uint8_t *pt_psmTable;
\r
441 assert(size <= 128);
\r
443 // Copy the TSM_Table into ESI TSM registers
\r
444 pt_psmTable = (uint8_t *)&ESIRAM0; // Destination pointer
\r
449 *pt_psmTable++ = *psmTable++;
\r
454 //*****************************************************************************
\r
456 //! Reset PSM counters
\r
458 //! \param counterToReset is the counter that needs t be reset
\r
460 //! This function resets the PSM counters
\r
464 //*****************************************************************************
\r
465 void ESI_PSM_resetCounter(uint16_t counterToReset)
\r
467 ESIPSM |= counterToReset;
\r
470 //*****************************************************************************
\r
472 //! Enables the internal Oscillator
\r
475 //! This function enables the high frequency internal oscillator
\r
479 //*****************************************************************************
\r
480 void ESI_enableInternalOscillator(void)
\r
482 ESIOSC |= ESIHFSEL;
\r
485 //*****************************************************************************
\r
487 //! Disables the internal Oscillator
\r
490 //! This function disables the high frequency internal oscillator
\r
494 //*****************************************************************************
\r
495 void ESI_disableInternalOscillator(void)
\r
497 ESIOSC &= ~ESIHFSEL;
\r
500 //*****************************************************************************
\r
502 //! Connects comparator output to timerA input
\r
504 //! \param counterToReset ESI_TIMERA_INPUT_TSM_COMPOUT or
\r
505 //! ESI_TIMERA_INPUT_TSM_PPUSRC
\r
507 //! This function connects the chosen comparator output to TimerA
\r
511 //*****************************************************************************
\r
512 void ESI_timerAInputSelect(uint16_t select)
\r
517 //*****************************************************************************
\r
519 //! Connects psm source to comparator output
\r
521 //! \param sourceNum PSM_S1_SOURCE, PSM_S2_SOURCE or PSM_S3_SOURCE
\r
522 //! \param sourceSelect can have the following values
\r
523 //! ESI_PSM_SOURCE_IS_ESIOUT0
\r
524 //! ESI_PSM_SOURCE_IS_ESIOUT1
\r
525 //! ESI_PSM_SOURCE_IS_ESIOUT2
\r
526 //! ESI_PSM_SOURCE_IS_ESIOUT3
\r
527 //! ESI_PSM_SOURCE_IS_ESIOUT4
\r
528 //! ESI_PSM_SOURCE_IS_ESIOUT5
\r
529 //! ESI_PSM_SOURCE_IS_ESIOUT6
\r
530 //! ESI_PSM_SOURCE_IS_ESIOUT7
\r
532 //! This function connects the chosen comparator output to TimerA
\r
536 //*****************************************************************************
\r
537 void ESI_psmSourceSelect(uint16_t sourceNum,
\r
538 uint16_t sourceSelect)
\r
542 case PSM_S1_SOURCE:
\r
543 ESICTL &= ~(ESIS1SEL0 | ESIS1SEL1 | ESIS1SEL2);
\r
544 ESICTL |= (sourceSelect << 7);
\r
546 case PSM_S2_SOURCE:
\r
547 ESICTL &= ~(ESIS2SEL0 | ESIS2SEL1 | ESIS2SEL2);
\r
548 ESICTL |= (sourceSelect << 10);
\r
550 case PSM_S3_SOURCE:
\r
551 ESICTL &= ~(ESIS3SEL0 | ESIS3SEL1 | ESIS3SEL2);
\r
552 ESICTL |= (sourceSelect << 13);
\r
559 //*****************************************************************************
\r
561 //! Connects testChannel0 to comparator input
\r
563 //! \param sourceSelect can have the following values
\r
564 //! ESI_TEST_CHANNEL0_SOURCE_IS_CH0_CI0
\r
565 //! ESI_TEST_CHANNEL0_SOURCE_IS_CH1_CI1
\r
566 //! ESI_TEST_CHANNEL0_SOURCE_IS_CH2_CI2
\r
567 //! ESI_TEST_CHANNEL0_SOURCE_IS_CH3_CI3
\r
569 //! This function connects the chosen comparator input to the test channel0
\r
573 //*****************************************************************************
\r
574 void ESI_testChannel0SourceSelect(uint16_t sourceSelect)
\r
576 ESICTL &= ~(ESI_TEST_CHANNEL0_SOURCE_IS_CH3_CI3);
\r
577 ESICTL |= sourceSelect;
\r
580 //*****************************************************************************
\r
582 //! Connects testChannel1to comparator input
\r
584 //! \param sourceSelect can have the following values
\r
585 //! ESI_TEST_CHANNEL1_SOURCE_IS_CH0_CI0
\r
586 //! ESI_TEST_CHANNEL1_SOURCE_IS_CH1_CI1
\r
587 //! ESI_TEST_CHANNEL1_SOURCE_IS_CH2_CI2
\r
588 //! ESI_TEST_CHANNEL1_SOURCE_IS_CH3_CI3
\r
590 //! This function connects the chosen comparator input to the test channel1
\r
594 //*****************************************************************************
\r
595 void ESI_testChannel1SourceSelect(uint16_t sourceSelect)
\r
597 ESICTL &= ~(ESI_TEST_CHANNEL1_SOURCE_IS_CH3_CI3);
\r
598 ESICTL |= sourceSelect;
\r
601 //*****************************************************************************
\r
603 //! Enable ESI peripheral
\r
607 //*****************************************************************************
\r
608 void ESI_enable(void)
\r
613 //*****************************************************************************
\r
615 //! Disable ESI peripheral
\r
619 //*****************************************************************************
\r
620 void ESI_disable(void)
\r
625 //*****************************************************************************
\r
627 //! Start calibration on ESI internal Oscillator
\r
629 //! This function starts calibration of internal osciallator. After calling this
\r
630 //! function the user and use ESI_adjustInternalOscFreq() to adjust the freq. of
\r
631 //! the oscillator.
\r
635 //*****************************************************************************
\r
636 void ESI_startInternalOscCal(void)
\r
638 assert(ESIOSC | ESIHFSEL);
\r
639 ESIOSC |= ESICLKGON;
\r
642 //*****************************************************************************
\r
644 //! Adjusts frequency ESI internal Oscillator
\r
646 //! This function adjusts frequency ESI internal Oscillator. It increases or
\r
647 //! decrease the freq by 3% based on incOrDec value.
\r
651 //*****************************************************************************
\r
652 void ESI_adjustInternalOscFreq(uint16_t incOrDec)
\r
654 uint16_t adjustValue;
\r
656 assert(ESIOSC | ESIHFSEL);
\r
658 adjustValue = ESIOSC >> 8;
\r
660 if(incOrDec == ESI_INTERNAL_OSC_FREQ_INCREASE)
\r
662 adjustValue = adjustValue + 1;
\r
663 adjustValue = adjustValue << 8;
\r
667 adjustValue = adjustValue - 1;
\r
668 adjustValue = adjustValue << 8;
\r
671 ESIOSC |= adjustValue;
\r
674 //*****************************************************************************
\r
676 //! Sets frequency of ESI internal Oscillator
\r
681 //*****************************************************************************
\r
682 void ESI_setNominalInternalOscFreq(void)
\r
684 ESIOSC = ESICLKFQ5 + ESICLKGON + ESIHFSEL;
\r
687 //*****************************************************************************
\r
689 //! The following function return the number of ESIOSC cycle during an ACLK
\r
695 //*****************************************************************************
\r
696 static uint16_t measureESIOSC(void){
\r
697 // This and next instruction realizes a clear->set ESICLKGON bit.
\r
698 ESIOSC &= ~(ESICLKGON);
\r
700 // This starts measurement.
\r
701 ESIOSC |= ESICLKGON + ESIHFSEL;
\r
703 // Reading ESICNT3 while counting always result in reading a 0x01.
\r
704 while(ESICNT3 == 1)
\r
709 // Stop ESIOSC oscillator
\r
710 ESIOSC &= ~(ESICLKGON);
\r
715 //******************************************************************************
\r
716 //! The following function returns the ESICLKFQx bits on ESIOSC register
\r
720 //! \return ESICLKFQ bits only
\r
721 //******************************************************************************
\r
723 uint8_t ESI_getESICLKFQ(void){
\r
726 // Store ESIOSC content
\r
728 // Get ESICLKFQx bits
\r
729 temp = (temp >> 8) & 0x3F;
\r
734 //******************************************************************************
\r
735 //! The following function sets ESICLKFQx bits on ESIOSC register
\r
737 //! \param setting is to the loaded to ESIOSC. Valid parameters a value between
\r
738 //! 0x00 and 0x3F. 0x00 corresponds to minimum frequency, 0x20
\r
739 //! corresponds to nominal frequency and 0x3F corresponds to maximum
\r
743 //******************************************************************************
\r
744 void ESI_setESICLKFQ(uint8_t setting)
\r
748 assert(setting < 0x40);
\r
750 temp = ESIOSC; // get actual ESIOSC register content
\r
752 temp = ((uint16_t) setting << 8) + temp; // and update ESICLKFQ bits
\r
756 //*****************************************************************************
\r
758 //! Calibrate ESI internal Oscillator
\r
763 //*****************************************************************************
\r
764 void ESI_calibrateInternalOscFreq(uint16_t targetAclkCounts)
\r
766 ESI_setNominalInternalOscFreq();
\r
768 ESI_measureESIOSC(ESI_ESIOSC_OVERSAMPLE_4);
\r
770 if(ESICNT3 > targetAclkCounts)
\r
775 ESI_adjustInternalOscFreq(ESI_INTERNAL_OSC_FREQ_DECREASE);
\r
777 while(ESI_measureESIOSC(ESI_ESIOSC_OVERSAMPLE_4) > targetAclkCounts);
\r
784 ESI_adjustInternalOscFreq(ESI_INTERNAL_OSC_FREQ_INCREASE);
\r
786 while(ESI_measureESIOSC(ESI_ESIOSC_OVERSAMPLE_4) > targetAclkCounts);
\r
787 ESI_adjustInternalOscFreq(ESI_INTERNAL_OSC_FREQ_DECREASE);
\r
791 //*****************************************************************************
\r
793 //! The following function returns an average of ESIOSC measurement.
\r
797 //! \return averaged ESIOSC measurement.
\r
799 //*****************************************************************************
\r
800 uint16_t ESI_measureESIOSC(uint8_t oversample){
\r
804 assert(oversample < 9);
\r
806 for(i = oversample; i > 0; i--)
\r
808 temp += measureESIOSC();
\r
811 temp /= oversample;
\r
815 //*****************************************************************************
\r
817 //! Set upper threshold for PSM counter 1
\r
819 //! \param threshold is the upper threashold that causes ESIIFG3 to get set.
\r
821 //! This function sets the threshold value for PSM counter 1. ESIIFG3 gets set
\r
822 //! when counter value and this threahold are equal.
\r
826 //*****************************************************************************
\r
827 void ESI_setPSMCounter1UpperThreshold(uint16_t threshold)
\r
829 ESITHR1 = threshold;
\r
832 //*****************************************************************************
\r
834 //! Set lower threshold for PSM counter 1
\r
836 //! \param threshold is the lower threashold that causes ESIIFG3 to get set.
\r
838 //! This function set the threshold value for PSM counter 1. ESIIFG3 gets set
\r
839 //! when counter value and this threahold are equal.
\r
843 //*****************************************************************************
\r
844 void ESI_setPSMCounter1LowerThreshold(uint16_t threshold)
\r
846 ESITHR2 = threshold;
\r
849 //*****************************************************************************
\r
851 //! sets AFE1 DAC threshold Value
\r
853 //! \param dacValue is value to be written to DAC register.
\r
854 //! \param dacRegNum is DAC register number
\r
856 //! Write DAC threshold value into selected DAC register
\r
860 //*****************************************************************************
\r
861 void ESI_setAFE1DACValue(uint16_t dacValue,
\r
864 volatile uint16_t* dacRegBase = (volatile uint16_t*) &ESIDAC1R0;
\r
865 *(dacRegBase + dacRegNum) = dacValue;
\r
868 //*****************************************************************************
\r
870 //! gets AFE1 DAC threshold Value
\r
872 //! \param dacValue is value to be written to DAC register.
\r
873 //! \param dacRegNum is DAC register number
\r
875 //! Read DAC threshold value into selected DAC register
\r
877 //! \return DAC value from selected DAC register.
\r
879 //*****************************************************************************
\r
880 uint16_t ESI_getAFE1DACValue(uint8_t dacRegNum)
\r
882 volatile uint16_t* dacRegBase = (volatile uint16_t*) &ESIDAC1R0;
\r
883 return(*(dacRegBase + dacRegNum));
\r
886 //*****************************************************************************
\r
888 //! sets AFE2 DAC threshold Value
\r
890 //! \param dacValue is value to be written to DAC register.
\r
891 //! \param dacRegNum is DAC register number
\r
893 //! Write DAC threshold value into selected DAC register
\r
897 //*****************************************************************************
\r
898 void ESI_setAFE2DACValue(uint16_t dacValue,
\r
901 volatile uint16_t* dacRegBase = (volatile uint16_t*) &ESIDAC2R0;
\r
902 *(dacRegBase + dacRegNum) = dacValue;
\r
905 //*****************************************************************************
\r
907 //! gets AFE2 DAC threshold Value
\r
909 //! \param dacValue is value to be written to DAC register.
\r
910 //! \param dacRegNum is DAC register number
\r
912 //! Read DAC threshold value into selected DAC register
\r
914 //! \return DAC value from selected DAC register.
\r
916 //*****************************************************************************
\r
917 uint16_t ESI_getAFE2DACValue(uint8_t dacRegNum)
\r
919 volatile uint16_t* dacRegBase = (volatile uint16_t*) &ESIDAC2R0;
\r
920 return(*(dacRegBase + dacRegNum));
\r
923 //*****************************************************************************
\r
925 //! sets TSM state register
\r
927 //! \param params constructs the state value
\r
928 //! \param stateRegNum is state register offset
\r
930 //! Sets selected TSM state register.
\r
934 //*****************************************************************************
\r
935 void ESI_setTSMstateReg(ESI_TSM_StateParams *params,
\r
936 uint8_t stateRegNum)
\r
938 volatile uint16_t* stateRegBase = (volatile uint16_t*) &ESITSM0;
\r
939 *(stateRegBase + stateRegNum) =
\r
940 (params->inputChannelSelect +
\r
941 params->LCDampingSelect +
\r
942 params->excitationSelect +
\r
943 params->comparatorSelect +
\r
944 params->highFreqClkOn_or_compAutoZeroCycle +
\r
945 params->outputLatchSelect +
\r
946 params->testCycleSelect +
\r
947 params->dacSelect +
\r
949 params->tsmClkSrc) |
\r
950 (params->duration << 11);
\r
953 //*****************************************************************************
\r
955 //! Get ESI interrupt Vector Register
\r
959 //*****************************************************************************
\r
960 uint16_t ESI_getInterruptVectorRegister(void)
\r
965 //*****************************************************************************
\r
967 //! Enables ESI interrupts
\r
969 //! \param interruptMask is the bit mask of the interrupt sources to
\r
970 //! be enabled. Mask value is the logical OR of any of the following:
\r
971 //! \b ESI_INTERRUPT_AFE1_ESIOUTX
\r
972 //! \b ESI_INTERRUPT_ESISTOP
\r
973 //! \b ESI_INTERRUPT_ESISTART
\r
974 //! \b ESI_INTERRUPT_ESICNT1
\r
975 //! \b ESI_INTERRUPT_ESICNT2
\r
976 //! \b ESI_INTERRUPT_Q6_BIT_SET
\r
977 //! \b ESI_INTERRUPT_Q7_BIT_SET
\r
978 //! \b ESI_INTERRUPT_ESICNT0_COUNT_INTERVAL
\r
979 //! \b ESI_INTERRUPT_AFE2_ESIOUTX
\r
981 //! Modified bits of \b ESIINT1 register.
\r
985 //*****************************************************************************
\r
986 void ESI_enableInterrupt(uint16_t interruptMask)
\r
988 ESIINT1 |= (interruptMask);
\r
991 //*****************************************************************************
\r
993 //! Disables ESI interrupts
\r
995 //! \param interruptMask is the bit mask of the interrupt sources to
\r
996 //! be disabled. Mask value is the logical OR of any of the following:
\r
997 //! \b ESI_INTERRUPT_AFE1_ESIOUTX
\r
998 //! \b ESI_INTERRUPT_ESISTOP
\r
999 //! \b ESI_INTERRUPT_ESISTART
\r
1000 //! \b ESI_INTERRUPT_ESICNT1
\r
1001 //! \b ESI_INTERRUPT_ESICNT2
\r
1002 //! \b ESI_INTERRUPT_Q6_BIT_SET
\r
1003 //! \b ESI_INTERRUPT_Q7_BIT_SET
\r
1004 //! \b ESI_INTERRUPT_ESICNT0_COUNT_INTERVAL
\r
1005 //! \b ESI_INTERRUPT_AFE2_ESIOUTX
\r
1007 //! Modified bits of \b ESIINT1 register.
\r
1011 //*****************************************************************************
\r
1012 void ESI_disableInterrupt(uint16_t interruptMask)
\r
1014 ESIINT1 &= ~(interruptMask);
\r
1017 //*****************************************************************************
\r
1019 //! Get ESI interrupt status
\r
1021 //! \param interruptMask is the masked interrupt flag status to be returned.
\r
1022 //! Mask value is the logical OR of any of the following:
\r
1023 //! - \b ESI_INTERRUPT_FLAG_AFE1_ESIOUTX
\r
1024 //! - \b ESI_INTERRUPT_FLAG_ESISTOP
\r
1025 //! - \b ESI_INTERRUPT_FLAG_ESISTART
\r
1026 //! - \b ESI_INTERRUPT_FLAG_ESICNT1
\r
1027 //! - \b ESI_INTERRUPT_FLAG_ESICNT2
\r
1028 //! - \b ESI_INTERRUPT_FLAG_Q6_BIT_SET
\r
1029 //! - \b ESI_INTERRUPT_FLAG_Q7_BIT_SET
\r
1030 //! - \b ESI_INTERRUPT_FLAG_ESICNT0_COUNT_INTERVAL
\r
1031 //! - \b ESI_INTERRUPT_FLAG_AFE2_ESIOUTX
\r
1033 //! \return Logical OR of any of the following:
\r
1034 //! - \b ESI_INTERRUPT_FLAG_AFE1_ESIOUTX
\r
1035 //! - \b ESI_INTERRUPT_FLAG_ESISTOP
\r
1036 //! - \b ESI_INTERRUPT_FLAG_ESISTART
\r
1037 //! - \b ESI_INTERRUPT_FLAG_ESICNT1
\r
1038 //! - \b ESI_INTERRUPT_FLAG_ESICNT2
\r
1039 //! - \b ESI_INTERRUPT_FLAG_Q6_BIT_SET
\r
1040 //! - \b ESI_INTERRUPT_FLAG_Q7_BIT_SET
\r
1041 //! - \b ESI_INTERRUPT_FLAG_ESICNT0_COUNT_INTERVAL
\r
1042 //! - \b ESI_INTERRUPT_FLAG_AFE2_ESIOUTX
\r
1043 //! \n indicating the status of the masked flags
\r
1045 //*****************************************************************************
\r
1046 uint16_t ESI_getInterruptStatus(uint16_t interruptMask)
\r
1048 return (ESIINT2 & interruptMask);
\r
1051 //*****************************************************************************
\r
1053 //! Clear ESI interrupt flag
\r
1055 //! \param interruptMask is the masked interrupt flag status to be returned.
\r
1056 //! Mask value is the logical OR of any of the following:
\r
1057 //! - \b ESI_INTERRUPT_FLAG_AFE1_ESIOUTX
\r
1058 //! - \b ESI_INTERRUPT_FLAG_ESISTOP
\r
1059 //! - \b ESI_INTERRUPT_FLAG_ESISTART
\r
1060 //! - \b ESI_INTERRUPT_FLAG_ESICNT1
\r
1061 //! - \b ESI_INTERRUPT_FLAG_ESICNT2
\r
1062 //! - \b ESI_INTERRUPT_FLAG_Q6_BIT_SET
\r
1063 //! - \b ESI_INTERRUPT_FLAG_Q7_BIT_SET
\r
1064 //! - \b ESI_INTERRUPT_FLAG_ESICNT0_COUNT_INTERVAL
\r
1065 //! - \b ESI_INTERRUPT_FLAG_AFE2_ESIOUTX
\r
1069 //*****************************************************************************
\r
1070 void ESI_clearInterrupt(uint16_t interruptMask)
\r
1072 ESIINT2 &= ~(interruptMask);
\r
1075 //*****************************************************************************
\r
1077 //! Set source of IFG0 interrupt flag
\r
1079 //! \param ifg0Src values are as follows
\r
1080 //! ESI_IFG0_SET_WHEN_ESIOUT0_SET
\r
1081 //! ESI_IFG0_SET_WHEN_ESIOUT0_RESET
\r
1082 //! ESI_IFG0_SET_WHEN_ESIOUT1_SET
\r
1083 //! ESI_IFG0_SET_WHEN_ESIOUT1_RESET
\r
1084 //! ESI_IFG0_SET_WHEN_ESIOUT2_SET
\r
1085 //! ESI_IFG0_SET_WHEN_ESIOUT2_RESET
\r
1086 //! ESI_IFG0_SET_WHEN_ESIOUT3_SET
\r
1087 //! ESI_IFG0_SET_WHEN_ESIOUT3_RESET
\r
1091 //*****************************************************************************
\r
1092 void ESI_setIFG0Source(uint16_t ifg0Src)
\r
1094 ESIINT1 &= ~ESI_IFG0_SET_WHEN_ESIOUT3_RESET;
\r
1095 ESIINT1 |= ifg0Src;
\r
1098 //*****************************************************************************
\r
1100 //! Set source of IFG8 interrupt flag
\r
1102 //! \param ifg8Src values are as follows
\r
1103 //! ESI_IFG8_SET_WHEN_ESIOUT4_SET
\r
1104 //! ESI_IFG8_SET_WHEN_ESIOUT4_RESET
\r
1105 //! ESI_IFG8_SET_WHEN_ESIOUT5_SET
\r
1106 //! ESI_IFG8_SET_WHEN_ESIOUT5_RESET
\r
1107 //! ESI_IFG8_SET_WHEN_ESIOUT6_SET
\r
1108 //! ESI_IFG8_SET_WHEN_ESIOUT6_RESET
\r
1109 //! ESI_IFG8_SET_WHEN_ESIOUT7_SET
\r
1110 //! ESI_IFG8_SET_WHEN_ESIOUT7_RESET
\r
1114 //*****************************************************************************
\r
1115 void ESI_setIFG8Source(uint16_t ifg8Src)
\r
1117 ESIINT1 &= ~ESI_IFG8_SET_WHEN_ESIOUT7_RESET;
\r
1118 ESIINT1 |= ifg8Src;
\r
1121 //*****************************************************************************
\r
1123 //! Set source of IFG7 interrupt flag
\r
1125 //! \param ifg7Src values are as follows
\r
1126 //! ESI_IFG7_SOURCE_EVERY_COUNT_OF_CNT0
\r
1127 //! ESI_IFG7_SOURCE_CNT0_MOD4
\r
1128 //! ESI_IFG7_SOURCE_CNT0_MOD256
\r
1129 //! ESI_IFG7_SOURCE_CNT0_ROLLOVER
\r
1133 //*****************************************************************************
\r
1134 void ESI_setIFG7Source(uint16_t ifg7Src)
\r
1136 ESIINT2 &= ~ESI_IFG7_SOURCE_CNT0_ROLLOVER;
\r
1137 ESIINT2 |= ifg7Src;
\r
1140 //*****************************************************************************
\r
1142 //! Set source of IFG4 interrupt flag
\r
1144 //! \param ifg4Src values are as follows
\r
1145 //! ESI_IFG4_SOURCE_EVERY_COUNT_OF_CNT2
\r
1146 //! ESI_IFG4_SOURCE_CNT2_MOD4
\r
1147 //! ESI_IFG4_SOURCE_CNT2_MOD256
\r
1148 //! ESI_IFG4_SOURCE_CNT2_ROLLOVER
\r
1152 //*****************************************************************************
\r
1153 void ESI_setIFG4Source(uint16_t ifg4Src)
\r
1155 ESIINT2 &= ~ESI_IFG4_SOURCE_CNT2_ROLLOVER;
\r
1156 ESIINT2 |= ifg4Src;
\r
1159 //*****************************************************************************
\r
1161 //! Simple DAC calibration code using pre-defined TSM
\r
1162 //! Supports AFE1 only.
\r
1163 //! \param selected_channel acceptable values
\r
1164 //! ESI_AFE1_CHANNEL0_SELECT
\r
1165 //! ESI_AFE1_CHANNEL1_SELECT
\r
1166 //! ESI_AFE1_CHANNEL2_SELECT
\r
1167 //! ESI_AFE1_CHANNEL3_SELECT
\r
1172 //*****************************************************************************
\r
1173 void ESI_LC_DAC_calibration(uint8_t selected_channel)
\r
1175 #define NUM_SENSOR_CAL 4
\r
1176 #define MIN_HYSTERESIS 30
\r
1177 #define STEP_TO_FINISH 4
\r
1180 unsigned char test_bit, done;
\r
1181 unsigned int hysteresis[NUM_SENSOR_CAL],
\r
1182 hysteresis_hi[NUM_SENSOR_CAL],
\r
1183 hysteresis_lo[NUM_SENSOR_CAL],
\r
1184 current[NUM_SENSOR_CAL],
\r
1185 average[NUM_SENSOR_CAL],
\r
1186 max[NUM_SENSOR_CAL],
\r
1187 min[NUM_SENSOR_CAL];
\r
1189 // State: 0 = output low
\r
1190 // 1 = output high
\r
1191 // 2 = undetermined (between 2 hysteresis level)
\r
1192 unsigned char previous_state[NUM_SENSOR_CAL],
\r
1193 current_state[NUM_SENSOR_CAL],
\r
1194 step[NUM_SENSOR_CAL];
\r
1197 for(i = 0; i < NUM_SENSOR_CAL; i++)
\r
1201 previous_state[i] = 2;
\r
1207 // Find the current oscillating level, using software mode
\r
1208 FindDAC(selected_channel, 1);
\r
1213 for(i = 0; i < NUM_SENSOR_CAL; i++)
\r
1215 // skip if the channel is not selected
\r
1216 if(test_bit & selected_channel)
\r
1218 current[i] = ESI_getAFE1DACValue(i * 2);
\r
1220 // Record max and min value
\r
1221 if(current[i] > max[i])
\r
1223 max[i] = current[i];
\r
1225 if(current[i] < min[i])
\r
1227 min[i] = current[i];
\r
1230 // Update average and hysteresis level
\r
1231 average[i] = (max[i] + min[i]) >> 1;
\r
1232 hysteresis[i] = (max[i] - min[i]) >> 3;
\r
1234 if(hysteresis[i] < MIN_HYSTERESIS)
\r
1236 hysteresis[i] = MIN_HYSTERESIS;
\r
1239 hysteresis[i] >>= 1;
\r
1240 hysteresis_hi[i] = average[i] + hysteresis[i];
\r
1241 hysteresis_lo[i] = average[i] - hysteresis[i];
\r
1243 // Determine output state based on hysteresis_hi and hysteresis_lo
\r
1244 if(current[i] < hysteresis_lo[i])
\r
1246 current_state[i] = 0;
\r
1248 else if(current[i] > hysteresis_hi[i])
\r
1250 current_state[i] = 1;
\r
1254 current_state[i] = 2;
\r
1257 // If there is state change, proceed to next step
\r
1258 switch(current_state[i])
\r
1262 if(previous_state[i] != current_state[i])
\r
1265 previous_state[i] = current_state[i];
\r
1273 // Any selected sensor which has not finished calibration will set done to zero
\r
1274 if(step[i] < STEP_TO_FINISH)
\r
1284 // Record DAC Values
\r
1286 done = ESI_DAC1_REG0; // Temp value for recording DAC
\r
1287 for(i = 0; i < NUM_SENSOR_CAL; i++)
\r
1289 if(test_bit & selected_channel)
\r
1291 ESI_setAFE1DACValue(hysteresis_hi[i], done++);
\r
1292 ESI_setAFE1DACValue(hysteresis_lo[i], done++);
\r
1298 //*****************************************************************************
\r
1300 //! Find the current oscillating level, using software mode
\r
1305 //*****************************************************************************
\r
1307 static void FindDAC(unsigned char selected_channel,
\r
1308 unsigned char software_trigger)
\r
1310 // DAC Level tester, using successive approximation approach
\r
1311 unsigned int DAC_BIT = 0x0800, Prev_DAC_BIT = 0x0C00;
\r
1314 unsigned int test_bit, DAC_index;
\r
1316 // Set initial DAC value for each selected channel
\r
1319 if(selected_channel & 0x0f)
\r
1322 DAC_index = ESI_DAC1_REG0;
\r
1323 for(i = 0; i < 4; i++)
\r
1325 if(selected_channel & test_bit)
\r
1327 ESI_setAFE1DACValue(DAC_BIT, DAC_index++);
\r
1328 ESI_setAFE1DACValue(DAC_BIT, DAC_index++);
\r
1339 if(selected_channel & 0xf0)
\r
1342 DAC_index = ESI_DAC2_REG0;
\r
1343 for(i = 0; i < 4; i++)
\r
1345 if(selected_channel & test_bit)
\r
1347 ESI_setAFE2DACValue(DAC_BIT, DAC_index++);
\r
1348 ESI_setAFE2DACValue(DAC_BIT, DAC_index++);
\r
1358 ESI_enableInterrupt(ESI_INTERRUPT_ESISTOP); // enable ESISTOP INT
\r
1360 // Find the DAC value for each selected channel
\r
1363 ESI_clearInterrupt (ESI_INTERRUPT_FLAG_ESISTOP);
\r
1365 if(software_trigger)
\r
1367 ESI_TSM_softwareTrigger();
\r
1370 __bis_SR_register(LPM3_bits + GIE); // wait for the ESISTOP flag
\r
1371 DAC_BIT >>= 1; // right shift one bit
\r
1374 if(selected_channel & 0x0f)
\r
1377 DAC_index = ESI_DAC1_REG0;
\r
1378 for(i = 0; i < 4; i++)
\r
1380 if(selected_channel & test_bit)
\r
1383 if(ESI_getLatchedComparatorOutput(test_bit) ==
\r
1384 ESI_AFE_OUTPUT_HIGH)
\r
1386 if(ESI_getLatchedComparatorOutput(test_bit) ==
\r
1387 ESI_AFE_OUTPUT_LOW)
\r
1390 ESI_setAFE1DACValue(ESI_getAFE1DACValue(
\r
1391 DAC_index) | DAC_BIT,
\r
1394 ESI_setAFE1DACValue(ESI_getAFE1DACValue(
\r
1395 DAC_index) | DAC_BIT,
\r
1401 ESI_setAFE1DACValue(ESI_getAFE1DACValue(
\r
1402 DAC_index) ^ Prev_DAC_BIT,
\r
1405 ESI_setAFE1DACValue(ESI_getAFE1DACValue(
\r
1406 DAC_index) ^ Prev_DAC_BIT,
\r
1420 if(selected_channel & 0xf0)
\r
1423 DAC_index = ESI_DAC2_REG0;
\r
1424 for(i = 0; i < 4; i++)
\r
1426 if(selected_channel & test_bit)
\r
1429 if(ESI_getLatchedComparatorOutput(test_bit) ==
\r
1430 ESI_AFE_OUTPUT_HIGH)
\r
1432 if(ESI_getLatchedComparatorOutput(test_bit) ==
\r
1433 ESI_AFE_OUTPUT_LOW)
\r
1436 ESI_setAFE1DACValue(ESI_getAFE2DACValue(
\r
1437 DAC_index) | DAC_BIT,
\r
1440 ESI_setAFE1DACValue(ESI_getAFE2DACValue(
\r
1441 DAC_index) | DAC_BIT,
\r
1447 ESI_setAFE1DACValue(ESI_getAFE2DACValue(
\r
1448 DAC_index) ^ Prev_DAC_BIT,
\r
1451 ESI_setAFE1DACValue(ESI_getAFE2DACValue(
\r
1452 DAC_index) ^ Prev_DAC_BIT,
\r
1464 Prev_DAC_BIT >>= 1; // right shift one bit
\r
1468 ESI_disableInterrupt(ESI_INTERRUPT_ESISTOP);
\r
1472 //*****************************************************************************
\r
1474 //! Close the doxygen group for esi_api
\r
1477 //*****************************************************************************
\r