mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-07-25 21:52:33 -04:00
1479 lines
45 KiB
C
1479 lines
45 KiB
C
/* --COPYRIGHT--,BSD
|
|
* Copyright (c) 2014, Texas Instruments Incorporated
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions
|
|
* are met:
|
|
*
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
*
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* * Neither the name of Texas Instruments Incorporated nor the names of
|
|
* its contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
* --/COPYRIGHT--*/
|
|
//*****************************************************************************
|
|
//
|
|
// esi.h - Driver for the ESI Module.
|
|
//
|
|
//*****************************************************************************
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! \addtogroup esi_api
|
|
//! @{
|
|
//
|
|
//*****************************************************************************
|
|
|
|
#include "inc/hw_regaccess.h"
|
|
#include "inc/hw_memmap.h"
|
|
|
|
#ifdef __MSP430_HAS_ESI__
|
|
#include "esi.h"
|
|
|
|
#include <assert.h>
|
|
|
|
// Uncomment for finding lower peak of the lower half cycle.
|
|
// This required to set ESI comparator output as inverted
|
|
#define INVERTED
|
|
|
|
static uint16_t measureESIOSC(void);
|
|
static void FindDAC(uint8_t selected_channel,
|
|
uint8_t software_trigger);
|
|
|
|
const ESI_AFE1_InitParams ESI_AFE1_INITPARAMS_DEFAULT =
|
|
{ESI_EXCITATION_CIRCUIT_DISABLED,
|
|
ESI_SAMPLE_HOLD_DISABLED,
|
|
ESI_MID_VOLTAGE_GENERATOR_DISABLED,
|
|
ESI_SAMPLE_HOLD_VSS_TO_ESIVSS,
|
|
ESI_INVERTER_FOR_AFE1_DISABLE};
|
|
|
|
const ESI_AFE2_InitParams ESI_AFE2_INITPARAMS_DEFAULT = {
|
|
ESI_AFE2_INPUT_SELECT_CHx,
|
|
ESI_INVERTER_FOR_AFE2_DISABLE,
|
|
ESI_TSM_COMPARATOR_CONTROL_AFE2_DISABLE,
|
|
ESI_TSM_DAC_CONTROL_AFE2_DISABLE
|
|
};
|
|
|
|
const ESI_TSM_InitParams ESI_TSM_INITPARAMS_DEFAULT = { ESI_TSM_SMCLK_DIV_1,
|
|
ESI_TSM_ACLK_DIV_1,
|
|
ESI_TSM_START_TRIGGER_DIV_2,
|
|
ESI_TSM_REPEAT_NEW_TRIGGER,
|
|
ESI_TSM_STOP_SEQUENCE,
|
|
ESI_TSM_HIGH_FREQ_CLK_FUNCTION_ON};
|
|
|
|
const ESI_PSM_InitParams ESI_PSM_INITPARAMS_DEFAULT = { ESI_PSM_Q6_DISABLE,
|
|
ESI_PSM_Q7_TRIGGER_DISABLE,
|
|
ESI_PSM_CNT0_DISABLE,
|
|
ESI_PSM_CNT0_RESET,
|
|
ESI_PSM_CNT1_DISABLE,
|
|
ESI_PSM_CNT1_RESET,
|
|
ESI_PSM_CNT2_DISABLE,
|
|
ESI_PSM_CNT2_RESET,
|
|
ESI_PSM_S3_SELECT,
|
|
ESI_PSM_TEST4_IS_Q2,};
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Get ESI PSM Counter 0 Value
|
|
//!
|
|
//! This function reads the ESI Counter 0 register
|
|
//!
|
|
//! \return Counter value
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_getCounter0(void)
|
|
{
|
|
return (ESICNT0);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Get ESI PSM Counter 1 Value
|
|
//!
|
|
//! This function reads the ESI Counter1 register
|
|
//!
|
|
//! \return Counter value
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_getCounter1(void)
|
|
{
|
|
return (ESICNT1);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Get ESI PSM Counter 2 Value
|
|
//!
|
|
//! This function reads the ESI Counter2 register
|
|
//!
|
|
//! \return Counter value
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_getCounter2(void)
|
|
{
|
|
return (ESICNT2);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Get ESI PSM Oscillator Counter Value
|
|
//!
|
|
//! This function reads the ESI Oscillator Counter register
|
|
//!
|
|
//! \return Counter value
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_getOscCounter(void)
|
|
{
|
|
return (ESICNT3);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Initializes the ESI analog front end AFE1
|
|
//!
|
|
//! \param params is ESI_AFE1_InitParams struct
|
|
//!
|
|
//! This functions initializes the ESI analog front end AFE1.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
|
|
void ESI_AFE1_init(ESI_AFE1_InitParams *params)
|
|
{
|
|
// Unset the AFE1 bits
|
|
ESIAFE &= ~(ESITEN + ESISH + ESIVCC2 + ESIVSS + ESICACI3 + ESICISEL +
|
|
ESICA1X + ESICA1INV);
|
|
ESIAFE |=
|
|
params->excitationCircuitSelect +
|
|
params->sampleAndHoldSelect +
|
|
params->midVoltageGeneratorSelect +
|
|
params->sampleAndHoldVSSConnect +
|
|
params->inverterSelectOutputAFE1
|
|
;
|
|
|
|
switch(params->inputSelectAFE1)
|
|
{
|
|
case ESI_AFE1_INPUT_SELECT_CHx:
|
|
break;
|
|
case ESI_AFE1_INPUT_SELECT_CIx:
|
|
ESIAFE |= ESICA1X;
|
|
break;
|
|
case ESI_AFE1_INPUT_SELECT_CI3:
|
|
ESIAFE |= ESICA1X;
|
|
ESIAFE &= ~ESICISEL;
|
|
ESIAFE |= ESICACI3;
|
|
break;
|
|
case ESI_AFE1_INPUT_SELECT_CI:
|
|
ESIAFE |= ESICA1X;
|
|
ESIAFE |= ESICISEL;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Initializes the ESI analog front end - AFE2
|
|
//!
|
|
//! \param params is ESI_AFE2_InitParams struct
|
|
//!
|
|
//! This functions initializes the ESI analog front end AFE2
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
|
|
void ESI_AFE2_init(ESI_AFE2_InitParams *params)
|
|
{
|
|
// Unset the AFE2 bits
|
|
ESIAFE &= ~(ESICA2X + ESICA2INV + ESICA2EN + ESIDAC2EN);
|
|
|
|
ESIAFE |=
|
|
params->inputSelectAFE2 +
|
|
params->inverterSelectOutputAFE2 +
|
|
params->tsmControlComparatorAFE2 +
|
|
params->tsmControlDacAFE2
|
|
;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Reads the latched comparator outputs form the AFEs
|
|
//!
|
|
//! \param channelSelect. Valid values are
|
|
//! ESI_AFE1_CHANNEL0_SELECT
|
|
//! ESI_AFE1_CHANNEL1_SELECT
|
|
//! ESI_AFE1_CHANNEL2_SELECT
|
|
//! ESI_AFE1_CHANNEL3_SELECT
|
|
//! ESI_AFE2_CHANNEL0_SELECT
|
|
//! ESI_AFE2_CHANNEL1_SELECT
|
|
//! ESI_AFE2_CHANNEL2_SELECT
|
|
//! ESI_AFE2_CHANNEL3_SELECT
|
|
//! ESI_AFE1_TEST_CHANNEL0_SELECT
|
|
//! ESI_AFE1_TEST_CHANNEL1_SELECT
|
|
//!
|
|
//! This function gets the ESIPPU register to get latched output values of the
|
|
//! comparator outputs for AFE1 and AFE2
|
|
//!
|
|
//! \return Valid values are
|
|
//! ESI_AFE_OUTPUT_LOW
|
|
//! ESI_AFE_OUTPUT_HIGH
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_getLatchedComparatorOutput(uint16_t channelSelect)
|
|
{
|
|
uint16_t result;
|
|
|
|
result = ESIPPU;
|
|
|
|
return (result &= channelSelect);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Initializes the TSM
|
|
//!
|
|
//! \param params is ESI_TSM_InitParams struct
|
|
//!
|
|
//! This function initializes the TSM.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
|
|
void ESI_TSM_init(ESI_TSM_InitParams *params)
|
|
{
|
|
ESITSM =
|
|
params->smclkDivider +
|
|
params->aclkDivider +
|
|
params->startTriggerAclkDivider +
|
|
params->repeatMode +
|
|
params->startTriggerSelection +
|
|
params->tsmFunctionSelection
|
|
;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Clear TSM entries
|
|
//!
|
|
//! This function clears all TSM entries
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_TSM_clearTable(void)
|
|
{
|
|
uint16_t *pTsm, i;
|
|
|
|
// Clear TSM Table (for testing only. not neccessary in real application)
|
|
pTsm = (uint16_t *)&ESITSM0;
|
|
for(i = 0; i < 32; i++)
|
|
{
|
|
*pTsm++ = 0x0200;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Copy TSM entries
|
|
//!
|
|
//! This function copies all TSM entries
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_TSM_copyTable(uint16_t* tsmTable,
|
|
uint16_t size)
|
|
{
|
|
uint16_t *pt_tsmTable;
|
|
uint16_t i;
|
|
|
|
// Copy the TSM_Table into ESI TSM registers
|
|
// Destination pointer
|
|
pt_tsmTable = (uint16_t *)&ESITSM0;
|
|
// Divided by 2 because of unsigned integer (2bytes)
|
|
i = size / 2;
|
|
|
|
do
|
|
{
|
|
*pt_tsmTable++ = *tsmTable++;
|
|
}
|
|
while(--i);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! TSM trigger using software
|
|
//!
|
|
//! This function starts a software initiated TSM sequence
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_TSM_softwareTrigger(void)
|
|
{
|
|
ESITSM |= ESISTART;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! TSM trigger using software
|
|
//!
|
|
//! This function starts a software initiated TSM sequence
|
|
//!
|
|
//! \return ESIREATx bits from selected stateRegNum
|
|
//
|
|
//*****************************************************************************
|
|
uint8_t ESI_TSM_getTSMStateDuration(uint8_t stateRegNum)
|
|
{
|
|
volatile uint16_t* stateRegBase = (volatile uint16_t*)&ESITSM0;
|
|
|
|
return((*(stateRegBase + stateRegNum) & 0xf800) >> 11);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! TSM trigger using software
|
|
//!
|
|
//! This function starts a software initiated TSM sequence
|
|
//!
|
|
//! \return ESIREATx bits from selected stateRegNum
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_TSM_setTSMStateDuration(uint8_t stateRegNum,
|
|
uint8_t duration)
|
|
{
|
|
assert(stateRegNum <= ESI_TSM_STATE_REG_31);
|
|
assert(duration <= ESI_TSM_STATE_DURATION_MAX);
|
|
|
|
volatile uint16_t* stateRegBase = (volatile uint16_t*)&ESITSM0;
|
|
|
|
*(stateRegBase + stateRegNum) &= ~0xF800;
|
|
|
|
*(stateRegBase + stateRegNum) |= (duration << 11);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Initialize Processing State Machine
|
|
//
|
|
//! \param params is ESI_PSM_InitParams struct
|
|
//!
|
|
//! This function initializes the PSM registers.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_PSM_init(ESI_PSM_InitParams *params)
|
|
{
|
|
ESIPSM =
|
|
params->Q6Select +
|
|
params->Q7TriggerSelect +
|
|
params->count0Select +
|
|
params->count0Reset +
|
|
params->count1Select +
|
|
params->count1Reset +
|
|
params->count2Select +
|
|
params->count2Reset +
|
|
params->V2Select +
|
|
params->TEST4Select
|
|
;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Clear PSM entries
|
|
//!
|
|
//! This function clears all PSM entries
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_PSM_clearTable(void)
|
|
{
|
|
uint8_t *pPsm, i;
|
|
|
|
// Clear TSM Table (for testing only. not neccessary in real application)
|
|
pPsm = (uint8_t *)&ESIRAM0;
|
|
for(i = 0; i < 128; i++)
|
|
{
|
|
*pPsm++ = 0x0;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Copy PSM entries
|
|
//!
|
|
//! This function copies all PSM entries
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_PSM_copyTable(uint8_t* psmTable,
|
|
uint8_t size)
|
|
{
|
|
uint8_t *pt_psmTable;
|
|
uint8_t i;
|
|
|
|
assert(size <= 128);
|
|
|
|
// Copy the TSM_Table into ESI TSM registers
|
|
pt_psmTable = (uint8_t *)&ESIRAM0; // Destination pointer
|
|
i = size;
|
|
|
|
do
|
|
{
|
|
*pt_psmTable++ = *psmTable++;
|
|
}
|
|
while(--i);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Reset PSM counters
|
|
//!
|
|
//! \param counterToReset is the counter that needs t be reset
|
|
//!
|
|
//! This function resets the PSM counters
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_PSM_resetCounter(uint16_t counterToReset)
|
|
{
|
|
ESIPSM |= counterToReset;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Enables the internal Oscillator
|
|
//!
|
|
//!
|
|
//! This function enables the high frequency internal oscillator
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_enableInternalOscillator(void)
|
|
{
|
|
ESIOSC |= ESIHFSEL;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables the internal Oscillator
|
|
//!
|
|
//!
|
|
//! This function disables the high frequency internal oscillator
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_disableInternalOscillator(void)
|
|
{
|
|
ESIOSC &= ~ESIHFSEL;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Connects comparator output to timerA input
|
|
//!
|
|
//! \param counterToReset ESI_TIMERA_INPUT_TSM_COMPOUT or
|
|
//! ESI_TIMERA_INPUT_TSM_PPUSRC
|
|
//!
|
|
//! This function connects the chosen comparator output to TimerA
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_timerAInputSelect(uint16_t select)
|
|
{
|
|
ESICTL |= select;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Connects psm source to comparator output
|
|
//!
|
|
//! \param sourceNum PSM_S1_SOURCE, PSM_S2_SOURCE or PSM_S3_SOURCE
|
|
//! \param sourceSelect can have the following values
|
|
//! ESI_PSM_SOURCE_IS_ESIOUT0
|
|
//! ESI_PSM_SOURCE_IS_ESIOUT1
|
|
//! ESI_PSM_SOURCE_IS_ESIOUT2
|
|
//! ESI_PSM_SOURCE_IS_ESIOUT3
|
|
//! ESI_PSM_SOURCE_IS_ESIOUT4
|
|
//! ESI_PSM_SOURCE_IS_ESIOUT5
|
|
//! ESI_PSM_SOURCE_IS_ESIOUT6
|
|
//! ESI_PSM_SOURCE_IS_ESIOUT7
|
|
//!
|
|
//! This function connects the chosen comparator output to TimerA
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_psmSourceSelect(uint16_t sourceNum,
|
|
uint16_t sourceSelect)
|
|
{
|
|
switch(sourceNum)
|
|
{
|
|
case PSM_S1_SOURCE:
|
|
ESICTL &= ~(ESIS1SEL0 | ESIS1SEL1 | ESIS1SEL2);
|
|
ESICTL |= (sourceSelect << 7);
|
|
break;
|
|
case PSM_S2_SOURCE:
|
|
ESICTL &= ~(ESIS2SEL0 | ESIS2SEL1 | ESIS2SEL2);
|
|
ESICTL |= (sourceSelect << 10);
|
|
break;
|
|
case PSM_S3_SOURCE:
|
|
ESICTL &= ~(ESIS3SEL0 | ESIS3SEL1 | ESIS3SEL2);
|
|
ESICTL |= (sourceSelect << 13);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Connects testChannel0 to comparator input
|
|
//!
|
|
//! \param sourceSelect can have the following values
|
|
//! ESI_TEST_CHANNEL0_SOURCE_IS_CH0_CI0
|
|
//! ESI_TEST_CHANNEL0_SOURCE_IS_CH1_CI1
|
|
//! ESI_TEST_CHANNEL0_SOURCE_IS_CH2_CI2
|
|
//! ESI_TEST_CHANNEL0_SOURCE_IS_CH3_CI3
|
|
//!
|
|
//! This function connects the chosen comparator input to the test channel0
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_testChannel0SourceSelect(uint16_t sourceSelect)
|
|
{
|
|
ESICTL &= ~(ESI_TEST_CHANNEL0_SOURCE_IS_CH3_CI3);
|
|
ESICTL |= sourceSelect;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Connects testChannel1to comparator input
|
|
//!
|
|
//! \param sourceSelect can have the following values
|
|
//! ESI_TEST_CHANNEL1_SOURCE_IS_CH0_CI0
|
|
//! ESI_TEST_CHANNEL1_SOURCE_IS_CH1_CI1
|
|
//! ESI_TEST_CHANNEL1_SOURCE_IS_CH2_CI2
|
|
//! ESI_TEST_CHANNEL1_SOURCE_IS_CH3_CI3
|
|
//!
|
|
//! This function connects the chosen comparator input to the test channel1
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_testChannel1SourceSelect(uint16_t sourceSelect)
|
|
{
|
|
ESICTL &= ~(ESI_TEST_CHANNEL1_SOURCE_IS_CH3_CI3);
|
|
ESICTL |= sourceSelect;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Enable ESI peripheral
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_enable(void)
|
|
{
|
|
ESICTL |= ESIEN;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Disable ESI peripheral
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_disable(void)
|
|
{
|
|
ESICTL &= ~ESIEN;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Start calibration on ESI internal Oscillator
|
|
//!
|
|
//! This function starts calibration of internal osciallator. After calling this
|
|
//! function the user and use ESI_adjustInternalOscFreq() to adjust the freq. of
|
|
//! the oscillator.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_startInternalOscCal(void)
|
|
{
|
|
assert(ESIOSC | ESIHFSEL);
|
|
ESIOSC |= ESICLKGON;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Adjusts frequency ESI internal Oscillator
|
|
//!
|
|
//! This function adjusts frequency ESI internal Oscillator. It increases or
|
|
//! decrease the freq by 3% based on incOrDec value.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_adjustInternalOscFreq(uint16_t incOrDec)
|
|
{
|
|
uint16_t adjustValue;
|
|
|
|
assert(ESIOSC | ESIHFSEL);
|
|
|
|
adjustValue = ESIOSC >> 8;
|
|
|
|
if(incOrDec == ESI_INTERNAL_OSC_FREQ_INCREASE)
|
|
{
|
|
adjustValue = adjustValue + 1;
|
|
adjustValue = adjustValue << 8;
|
|
}
|
|
else
|
|
{
|
|
adjustValue = adjustValue - 1;
|
|
adjustValue = adjustValue << 8;
|
|
}
|
|
|
|
ESIOSC |= adjustValue;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Sets frequency of ESI internal Oscillator
|
|
//!
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setNominalInternalOscFreq(void)
|
|
{
|
|
ESIOSC = ESICLKFQ5 + ESICLKGON + ESIHFSEL;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! The following function return the number of ESIOSC cycle during an ACLK
|
|
//! cycle.
|
|
//!
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
static uint16_t measureESIOSC(void){
|
|
// This and next instruction realizes a clear->set ESICLKGON bit.
|
|
ESIOSC &= ~(ESICLKGON);
|
|
|
|
// This starts measurement.
|
|
ESIOSC |= ESICLKGON + ESIHFSEL;
|
|
|
|
// Reading ESICNT3 while counting always result in reading a 0x01.
|
|
while(ESICNT3 == 1)
|
|
{
|
|
;
|
|
}
|
|
|
|
// Stop ESIOSC oscillator
|
|
ESIOSC &= ~(ESICLKGON);
|
|
|
|
return (ESICNT3);
|
|
}
|
|
|
|
//******************************************************************************
|
|
//! The following function returns the ESICLKFQx bits on ESIOSC register
|
|
//
|
|
//! \param none
|
|
//
|
|
//! \return ESICLKFQ bits only
|
|
//******************************************************************************
|
|
|
|
uint8_t ESI_getESICLKFQ(void){
|
|
uint16_t temp;
|
|
|
|
// Store ESIOSC content
|
|
temp = ESIOSC;
|
|
// Get ESICLKFQx bits
|
|
temp = (temp >> 8) & 0x3F;
|
|
|
|
return(temp);
|
|
}
|
|
|
|
//******************************************************************************
|
|
//! The following function sets ESICLKFQx bits on ESIOSC register
|
|
//
|
|
//! \param setting is to the loaded to ESIOSC. Valid parameters a value between
|
|
//! 0x00 and 0x3F. 0x00 corresponds to minimum frequency, 0x20
|
|
//! corresponds to nominal frequency and 0x3F corresponds to maximum
|
|
//! frequency.
|
|
//
|
|
//! \return none
|
|
//******************************************************************************
|
|
void ESI_setESICLKFQ(uint8_t setting)
|
|
{
|
|
uint16_t temp;
|
|
|
|
assert(setting < 0x40);
|
|
|
|
temp = ESIOSC; // get actual ESIOSC register content
|
|
temp &= ~(0x3F00);
|
|
temp = ((uint16_t) setting << 8) + temp; // and update ESICLKFQ bits
|
|
ESIOSC = temp;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Calibrate ESI internal Oscillator
|
|
//!
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_calibrateInternalOscFreq(uint16_t targetAclkCounts)
|
|
{
|
|
ESI_setNominalInternalOscFreq();
|
|
|
|
ESI_measureESIOSC(ESI_ESIOSC_OVERSAMPLE_4);
|
|
|
|
if(ESICNT3 > targetAclkCounts)
|
|
{
|
|
//freq is too high
|
|
do
|
|
{
|
|
ESI_adjustInternalOscFreq(ESI_INTERNAL_OSC_FREQ_DECREASE);
|
|
}
|
|
while(ESI_measureESIOSC(ESI_ESIOSC_OVERSAMPLE_4) > targetAclkCounts);
|
|
}
|
|
else
|
|
{
|
|
//freq is too low
|
|
do
|
|
{
|
|
ESI_adjustInternalOscFreq(ESI_INTERNAL_OSC_FREQ_INCREASE);
|
|
}
|
|
while(ESI_measureESIOSC(ESI_ESIOSC_OVERSAMPLE_4) > targetAclkCounts);
|
|
ESI_adjustInternalOscFreq(ESI_INTERNAL_OSC_FREQ_DECREASE);
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! The following function returns an average of ESIOSC measurement.
|
|
//!
|
|
//! \param
|
|
//!
|
|
//! \return averaged ESIOSC measurement.
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_measureESIOSC(uint8_t oversample){
|
|
uint8_t i;
|
|
uint16_t temp = 0;
|
|
|
|
assert(oversample < 9);
|
|
|
|
for(i = oversample; i > 0; i--)
|
|
{
|
|
temp += measureESIOSC();
|
|
}
|
|
|
|
temp /= oversample;
|
|
return(temp);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Set upper threshold for PSM counter 1
|
|
//!
|
|
//! \param threshold is the upper threashold that causes ESIIFG3 to get set.
|
|
//!
|
|
//! This function sets the threshold value for PSM counter 1. ESIIFG3 gets set
|
|
//! when counter value and this threahold are equal.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setPSMCounter1UpperThreshold(uint16_t threshold)
|
|
{
|
|
ESITHR1 = threshold;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Set lower threshold for PSM counter 1
|
|
//!
|
|
//! \param threshold is the lower threashold that causes ESIIFG3 to get set.
|
|
//!
|
|
//! This function set the threshold value for PSM counter 1. ESIIFG3 gets set
|
|
//! when counter value and this threahold are equal.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setPSMCounter1LowerThreshold(uint16_t threshold)
|
|
{
|
|
ESITHR2 = threshold;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! sets AFE1 DAC threshold Value
|
|
//!
|
|
//! \param dacValue is value to be written to DAC register.
|
|
//! \param dacRegNum is DAC register number
|
|
//!
|
|
//! Write DAC threshold value into selected DAC register
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setAFE1DACValue(uint16_t dacValue,
|
|
uint8_t dacRegNum)
|
|
{
|
|
volatile uint16_t* dacRegBase = (volatile uint16_t*) &ESIDAC1R0;
|
|
*(dacRegBase + dacRegNum) = dacValue;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! gets AFE1 DAC threshold Value
|
|
//!
|
|
//! \param dacValue is value to be written to DAC register.
|
|
//! \param dacRegNum is DAC register number
|
|
//!
|
|
//! Read DAC threshold value into selected DAC register
|
|
//!
|
|
//! \return DAC value from selected DAC register.
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_getAFE1DACValue(uint8_t dacRegNum)
|
|
{
|
|
volatile uint16_t* dacRegBase = (volatile uint16_t*) &ESIDAC1R0;
|
|
return(*(dacRegBase + dacRegNum));
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! sets AFE2 DAC threshold Value
|
|
//!
|
|
//! \param dacValue is value to be written to DAC register.
|
|
//! \param dacRegNum is DAC register number
|
|
//!
|
|
//! Write DAC threshold value into selected DAC register
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setAFE2DACValue(uint16_t dacValue,
|
|
uint8_t dacRegNum)
|
|
{
|
|
volatile uint16_t* dacRegBase = (volatile uint16_t*) &ESIDAC2R0;
|
|
*(dacRegBase + dacRegNum) = dacValue;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! gets AFE2 DAC threshold Value
|
|
//!
|
|
//! \param dacValue is value to be written to DAC register.
|
|
//! \param dacRegNum is DAC register number
|
|
//!
|
|
//! Read DAC threshold value into selected DAC register
|
|
//!
|
|
//! \return DAC value from selected DAC register.
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_getAFE2DACValue(uint8_t dacRegNum)
|
|
{
|
|
volatile uint16_t* dacRegBase = (volatile uint16_t*) &ESIDAC2R0;
|
|
return(*(dacRegBase + dacRegNum));
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! sets TSM state register
|
|
//!
|
|
//! \param params constructs the state value
|
|
//! \param stateRegNum is state register offset
|
|
//!
|
|
//! Sets selected TSM state register.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setTSMstateReg(ESI_TSM_StateParams *params,
|
|
uint8_t stateRegNum)
|
|
{
|
|
volatile uint16_t* stateRegBase = (volatile uint16_t*) &ESITSM0;
|
|
*(stateRegBase + stateRegNum) =
|
|
(params->inputChannelSelect +
|
|
params->LCDampingSelect +
|
|
params->excitationSelect +
|
|
params->comparatorSelect +
|
|
params->highFreqClkOn_or_compAutoZeroCycle +
|
|
params->outputLatchSelect +
|
|
params->testCycleSelect +
|
|
params->dacSelect +
|
|
params->tsmStop +
|
|
params->tsmClkSrc) |
|
|
(params->duration << 11);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Get ESI interrupt Vector Register
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_getInterruptVectorRegister(void)
|
|
{
|
|
return (ESIIV);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Enables ESI interrupts
|
|
//!
|
|
//! \param interruptMask is the bit mask of the interrupt sources to
|
|
//! be enabled. Mask value is the logical OR of any of the following:
|
|
//! \b ESI_INTERRUPT_AFE1_ESIOUTX
|
|
//! \b ESI_INTERRUPT_ESISTOP
|
|
//! \b ESI_INTERRUPT_ESISTART
|
|
//! \b ESI_INTERRUPT_ESICNT1
|
|
//! \b ESI_INTERRUPT_ESICNT2
|
|
//! \b ESI_INTERRUPT_Q6_BIT_SET
|
|
//! \b ESI_INTERRUPT_Q7_BIT_SET
|
|
//! \b ESI_INTERRUPT_ESICNT0_COUNT_INTERVAL
|
|
//! \b ESI_INTERRUPT_AFE2_ESIOUTX
|
|
//!
|
|
//! Modified bits of \b ESIINT1 register.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_enableInterrupt(uint16_t interruptMask)
|
|
{
|
|
ESIINT1 |= (interruptMask);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Disables ESI interrupts
|
|
//!
|
|
//! \param interruptMask is the bit mask of the interrupt sources to
|
|
//! be disabled. Mask value is the logical OR of any of the following:
|
|
//! \b ESI_INTERRUPT_AFE1_ESIOUTX
|
|
//! \b ESI_INTERRUPT_ESISTOP
|
|
//! \b ESI_INTERRUPT_ESISTART
|
|
//! \b ESI_INTERRUPT_ESICNT1
|
|
//! \b ESI_INTERRUPT_ESICNT2
|
|
//! \b ESI_INTERRUPT_Q6_BIT_SET
|
|
//! \b ESI_INTERRUPT_Q7_BIT_SET
|
|
//! \b ESI_INTERRUPT_ESICNT0_COUNT_INTERVAL
|
|
//! \b ESI_INTERRUPT_AFE2_ESIOUTX
|
|
//!
|
|
//! Modified bits of \b ESIINT1 register.
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_disableInterrupt(uint16_t interruptMask)
|
|
{
|
|
ESIINT1 &= ~(interruptMask);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Get ESI interrupt status
|
|
//!
|
|
//! \param interruptMask is the masked interrupt flag status to be returned.
|
|
//! Mask value is the logical OR of any of the following:
|
|
//! - \b ESI_INTERRUPT_FLAG_AFE1_ESIOUTX
|
|
//! - \b ESI_INTERRUPT_FLAG_ESISTOP
|
|
//! - \b ESI_INTERRUPT_FLAG_ESISTART
|
|
//! - \b ESI_INTERRUPT_FLAG_ESICNT1
|
|
//! - \b ESI_INTERRUPT_FLAG_ESICNT2
|
|
//! - \b ESI_INTERRUPT_FLAG_Q6_BIT_SET
|
|
//! - \b ESI_INTERRUPT_FLAG_Q7_BIT_SET
|
|
//! - \b ESI_INTERRUPT_FLAG_ESICNT0_COUNT_INTERVAL
|
|
//! - \b ESI_INTERRUPT_FLAG_AFE2_ESIOUTX
|
|
//!
|
|
//! \return Logical OR of any of the following:
|
|
//! - \b ESI_INTERRUPT_FLAG_AFE1_ESIOUTX
|
|
//! - \b ESI_INTERRUPT_FLAG_ESISTOP
|
|
//! - \b ESI_INTERRUPT_FLAG_ESISTART
|
|
//! - \b ESI_INTERRUPT_FLAG_ESICNT1
|
|
//! - \b ESI_INTERRUPT_FLAG_ESICNT2
|
|
//! - \b ESI_INTERRUPT_FLAG_Q6_BIT_SET
|
|
//! - \b ESI_INTERRUPT_FLAG_Q7_BIT_SET
|
|
//! - \b ESI_INTERRUPT_FLAG_ESICNT0_COUNT_INTERVAL
|
|
//! - \b ESI_INTERRUPT_FLAG_AFE2_ESIOUTX
|
|
//! \n indicating the status of the masked flags
|
|
//
|
|
//*****************************************************************************
|
|
uint16_t ESI_getInterruptStatus(uint16_t interruptMask)
|
|
{
|
|
return (ESIINT2 & interruptMask);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Clear ESI interrupt flag
|
|
//!
|
|
//! \param interruptMask is the masked interrupt flag status to be returned.
|
|
//! Mask value is the logical OR of any of the following:
|
|
//! - \b ESI_INTERRUPT_FLAG_AFE1_ESIOUTX
|
|
//! - \b ESI_INTERRUPT_FLAG_ESISTOP
|
|
//! - \b ESI_INTERRUPT_FLAG_ESISTART
|
|
//! - \b ESI_INTERRUPT_FLAG_ESICNT1
|
|
//! - \b ESI_INTERRUPT_FLAG_ESICNT2
|
|
//! - \b ESI_INTERRUPT_FLAG_Q6_BIT_SET
|
|
//! - \b ESI_INTERRUPT_FLAG_Q7_BIT_SET
|
|
//! - \b ESI_INTERRUPT_FLAG_ESICNT0_COUNT_INTERVAL
|
|
//! - \b ESI_INTERRUPT_FLAG_AFE2_ESIOUTX
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_clearInterrupt(uint16_t interruptMask)
|
|
{
|
|
ESIINT2 &= ~(interruptMask);
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Set source of IFG0 interrupt flag
|
|
//!
|
|
//! \param ifg0Src values are as follows
|
|
//! ESI_IFG0_SET_WHEN_ESIOUT0_SET
|
|
//! ESI_IFG0_SET_WHEN_ESIOUT0_RESET
|
|
//! ESI_IFG0_SET_WHEN_ESIOUT1_SET
|
|
//! ESI_IFG0_SET_WHEN_ESIOUT1_RESET
|
|
//! ESI_IFG0_SET_WHEN_ESIOUT2_SET
|
|
//! ESI_IFG0_SET_WHEN_ESIOUT2_RESET
|
|
//! ESI_IFG0_SET_WHEN_ESIOUT3_SET
|
|
//! ESI_IFG0_SET_WHEN_ESIOUT3_RESET
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setIFG0Source(uint16_t ifg0Src)
|
|
{
|
|
ESIINT1 &= ~ESI_IFG0_SET_WHEN_ESIOUT3_RESET;
|
|
ESIINT1 |= ifg0Src;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Set source of IFG8 interrupt flag
|
|
//!
|
|
//! \param ifg8Src values are as follows
|
|
//! ESI_IFG8_SET_WHEN_ESIOUT4_SET
|
|
//! ESI_IFG8_SET_WHEN_ESIOUT4_RESET
|
|
//! ESI_IFG8_SET_WHEN_ESIOUT5_SET
|
|
//! ESI_IFG8_SET_WHEN_ESIOUT5_RESET
|
|
//! ESI_IFG8_SET_WHEN_ESIOUT6_SET
|
|
//! ESI_IFG8_SET_WHEN_ESIOUT6_RESET
|
|
//! ESI_IFG8_SET_WHEN_ESIOUT7_SET
|
|
//! ESI_IFG8_SET_WHEN_ESIOUT7_RESET
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setIFG8Source(uint16_t ifg8Src)
|
|
{
|
|
ESIINT1 &= ~ESI_IFG8_SET_WHEN_ESIOUT7_RESET;
|
|
ESIINT1 |= ifg8Src;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Set source of IFG7 interrupt flag
|
|
//!
|
|
//! \param ifg7Src values are as follows
|
|
//! ESI_IFG7_SOURCE_EVERY_COUNT_OF_CNT0
|
|
//! ESI_IFG7_SOURCE_CNT0_MOD4
|
|
//! ESI_IFG7_SOURCE_CNT0_MOD256
|
|
//! ESI_IFG7_SOURCE_CNT0_ROLLOVER
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setIFG7Source(uint16_t ifg7Src)
|
|
{
|
|
ESIINT2 &= ~ESI_IFG7_SOURCE_CNT0_ROLLOVER;
|
|
ESIINT2 |= ifg7Src;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Set source of IFG4 interrupt flag
|
|
//!
|
|
//! \param ifg4Src values are as follows
|
|
//! ESI_IFG4_SOURCE_EVERY_COUNT_OF_CNT2
|
|
//! ESI_IFG4_SOURCE_CNT2_MOD4
|
|
//! ESI_IFG4_SOURCE_CNT2_MOD256
|
|
//! ESI_IFG4_SOURCE_CNT2_ROLLOVER
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_setIFG4Source(uint16_t ifg4Src)
|
|
{
|
|
ESIINT2 &= ~ESI_IFG4_SOURCE_CNT2_ROLLOVER;
|
|
ESIINT2 |= ifg4Src;
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Simple DAC calibration code using pre-defined TSM
|
|
//! Supports AFE1 only.
|
|
//! \param selected_channel acceptable values
|
|
//! ESI_AFE1_CHANNEL0_SELECT
|
|
//! ESI_AFE1_CHANNEL1_SELECT
|
|
//! ESI_AFE1_CHANNEL2_SELECT
|
|
//! ESI_AFE1_CHANNEL3_SELECT
|
|
//!
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
void ESI_LC_DAC_calibration(uint8_t selected_channel)
|
|
{
|
|
#define NUM_SENSOR_CAL 4
|
|
#define MIN_HYSTERESIS 30
|
|
#define STEP_TO_FINISH 4
|
|
|
|
unsigned int i;
|
|
unsigned char test_bit, done;
|
|
unsigned int hysteresis[NUM_SENSOR_CAL],
|
|
hysteresis_hi[NUM_SENSOR_CAL],
|
|
hysteresis_lo[NUM_SENSOR_CAL],
|
|
current[NUM_SENSOR_CAL],
|
|
average[NUM_SENSOR_CAL],
|
|
max[NUM_SENSOR_CAL],
|
|
min[NUM_SENSOR_CAL];
|
|
|
|
// State: 0 = output low
|
|
// 1 = output high
|
|
// 2 = undetermined (between 2 hysteresis level)
|
|
unsigned char previous_state[NUM_SENSOR_CAL],
|
|
current_state[NUM_SENSOR_CAL],
|
|
step[NUM_SENSOR_CAL];
|
|
|
|
// Reset values
|
|
for(i = 0; i < NUM_SENSOR_CAL; i++)
|
|
{
|
|
max[i] = 0;
|
|
min[i] = 0xffff;
|
|
previous_state[i] = 2;
|
|
step[i] = 0;
|
|
}
|
|
|
|
do
|
|
{
|
|
// Find the current oscillating level, using software mode
|
|
FindDAC(selected_channel, 1);
|
|
|
|
test_bit = 1;
|
|
done = 1;
|
|
|
|
for(i = 0; i < NUM_SENSOR_CAL; i++)
|
|
{
|
|
// skip if the channel is not selected
|
|
if(test_bit & selected_channel)
|
|
{
|
|
current[i] = ESI_getAFE1DACValue(i * 2);
|
|
|
|
// Record max and min value
|
|
if(current[i] > max[i])
|
|
{
|
|
max[i] = current[i];
|
|
}
|
|
if(current[i] < min[i])
|
|
{
|
|
min[i] = current[i];
|
|
}
|
|
|
|
// Update average and hysteresis level
|
|
average[i] = (max[i] + min[i]) >> 1;
|
|
hysteresis[i] = (max[i] - min[i]) >> 3;
|
|
|
|
if(hysteresis[i] < MIN_HYSTERESIS)
|
|
{
|
|
hysteresis[i] = MIN_HYSTERESIS;
|
|
}
|
|
|
|
hysteresis[i] >>= 1;
|
|
hysteresis_hi[i] = average[i] + hysteresis[i];
|
|
hysteresis_lo[i] = average[i] - hysteresis[i];
|
|
|
|
// Determine output state based on hysteresis_hi and hysteresis_lo
|
|
if(current[i] < hysteresis_lo[i])
|
|
{
|
|
current_state[i] = 0;
|
|
}
|
|
else if(current[i] > hysteresis_hi[i])
|
|
{
|
|
current_state[i] = 1;
|
|
}
|
|
else
|
|
{
|
|
current_state[i] = 2;
|
|
}
|
|
|
|
// If there is state change, proceed to next step
|
|
switch(current_state[i])
|
|
{
|
|
case 0:
|
|
case 1:
|
|
if(previous_state[i] != current_state[i])
|
|
{
|
|
step[i]++;
|
|
previous_state[i] = current_state[i];
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
// Any selected sensor which has not finished calibration will set done to zero
|
|
if(step[i] < STEP_TO_FINISH)
|
|
{
|
|
done = 0;
|
|
}
|
|
}
|
|
test_bit <<= 1;
|
|
}
|
|
}
|
|
while(!done);
|
|
|
|
// Record DAC Values
|
|
test_bit = 1;
|
|
done = ESI_DAC1_REG0; // Temp value for recording DAC
|
|
for(i = 0; i < NUM_SENSOR_CAL; i++)
|
|
{
|
|
if(test_bit & selected_channel)
|
|
{
|
|
ESI_setAFE1DACValue(hysteresis_hi[i], done++);
|
|
ESI_setAFE1DACValue(hysteresis_lo[i], done++);
|
|
}
|
|
test_bit <<= 1;
|
|
}
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Find the current oscillating level, using software mode
|
|
//!
|
|
//!
|
|
//! \return None
|
|
//
|
|
//*****************************************************************************
|
|
|
|
static void FindDAC(unsigned char selected_channel,
|
|
unsigned char software_trigger)
|
|
{
|
|
// DAC Level tester, using successive approximation approach
|
|
unsigned int DAC_BIT = 0x0800, Prev_DAC_BIT = 0x0C00;
|
|
|
|
unsigned int i;
|
|
unsigned int test_bit, DAC_index;
|
|
|
|
// Set initial DAC value for each selected channel
|
|
|
|
// AFE 1
|
|
if(selected_channel & 0x0f)
|
|
{
|
|
test_bit = 0x01;
|
|
DAC_index = ESI_DAC1_REG0;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
if(selected_channel & test_bit)
|
|
{
|
|
ESI_setAFE1DACValue(DAC_BIT, DAC_index++);
|
|
ESI_setAFE1DACValue(DAC_BIT, DAC_index++);
|
|
}
|
|
else
|
|
{
|
|
DAC_index += 2;
|
|
}
|
|
test_bit <<= 1;
|
|
}
|
|
}
|
|
|
|
// AFE 2
|
|
if(selected_channel & 0xf0)
|
|
{
|
|
test_bit = 0x10;
|
|
DAC_index = ESI_DAC2_REG0;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
if(selected_channel & test_bit)
|
|
{
|
|
ESI_setAFE2DACValue(DAC_BIT, DAC_index++);
|
|
ESI_setAFE2DACValue(DAC_BIT, DAC_index++);
|
|
}
|
|
else
|
|
{
|
|
DAC_index += 2;
|
|
}
|
|
test_bit <<= 1;
|
|
}
|
|
}
|
|
|
|
ESI_enableInterrupt(ESI_INTERRUPT_ESISTOP); // enable ESISTOP INT
|
|
|
|
// Find the DAC value for each selected channel
|
|
do
|
|
{
|
|
ESI_clearInterrupt (ESI_INTERRUPT_FLAG_ESISTOP);
|
|
|
|
if(software_trigger)
|
|
{
|
|
ESI_TSM_softwareTrigger();
|
|
}
|
|
|
|
__bis_SR_register(LPM3_bits + GIE); // wait for the ESISTOP flag
|
|
DAC_BIT >>= 1; // right shift one bit
|
|
|
|
// AFE 1
|
|
if(selected_channel & 0x0f)
|
|
{
|
|
test_bit = 0x01;
|
|
DAC_index = ESI_DAC1_REG0;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
if(selected_channel & test_bit)
|
|
{
|
|
#ifndef INVERTED
|
|
if(ESI_getLatchedComparatorOutput(test_bit) ==
|
|
ESI_AFE_OUTPUT_HIGH)
|
|
#else
|
|
if(ESI_getLatchedComparatorOutput(test_bit) ==
|
|
ESI_AFE_OUTPUT_LOW)
|
|
#endif
|
|
{
|
|
ESI_setAFE1DACValue(ESI_getAFE1DACValue(
|
|
DAC_index) | DAC_BIT,
|
|
DAC_index);
|
|
DAC_index++;
|
|
ESI_setAFE1DACValue(ESI_getAFE1DACValue(
|
|
DAC_index) | DAC_BIT,
|
|
DAC_index);
|
|
DAC_index++;
|
|
}
|
|
else
|
|
{
|
|
ESI_setAFE1DACValue(ESI_getAFE1DACValue(
|
|
DAC_index) ^ Prev_DAC_BIT,
|
|
DAC_index);
|
|
DAC_index++;
|
|
ESI_setAFE1DACValue(ESI_getAFE1DACValue(
|
|
DAC_index) ^ Prev_DAC_BIT,
|
|
DAC_index);
|
|
DAC_index++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DAC_index += 2;
|
|
}
|
|
test_bit <<= 1;
|
|
}
|
|
}
|
|
|
|
// AFE 2
|
|
if(selected_channel & 0xf0)
|
|
{
|
|
test_bit = 0x10;
|
|
DAC_index = ESI_DAC2_REG0;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
if(selected_channel & test_bit)
|
|
{
|
|
#ifndef INVERTED
|
|
if(ESI_getLatchedComparatorOutput(test_bit) ==
|
|
ESI_AFE_OUTPUT_HIGH)
|
|
#else
|
|
if(ESI_getLatchedComparatorOutput(test_bit) ==
|
|
ESI_AFE_OUTPUT_LOW)
|
|
#endif
|
|
{
|
|
ESI_setAFE1DACValue(ESI_getAFE2DACValue(
|
|
DAC_index) | DAC_BIT,
|
|
DAC_index);
|
|
DAC_index++;
|
|
ESI_setAFE1DACValue(ESI_getAFE2DACValue(
|
|
DAC_index) | DAC_BIT,
|
|
DAC_index);
|
|
DAC_index++;
|
|
}
|
|
else
|
|
{
|
|
ESI_setAFE1DACValue(ESI_getAFE2DACValue(
|
|
DAC_index) ^ Prev_DAC_BIT,
|
|
DAC_index);
|
|
DAC_index++;
|
|
ESI_setAFE1DACValue(ESI_getAFE2DACValue(
|
|
DAC_index) ^ Prev_DAC_BIT,
|
|
DAC_index);
|
|
DAC_index++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DAC_index += 2;
|
|
}
|
|
test_bit <<= 1;
|
|
}
|
|
}
|
|
Prev_DAC_BIT >>= 1; // right shift one bit
|
|
}
|
|
while(DAC_BIT);
|
|
|
|
ESI_disableInterrupt(ESI_INTERRUPT_ESISTOP);
|
|
__no_operation();
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
//! Close the doxygen group for esi_api
|
|
//! @}
|
|
//
|
|
//*****************************************************************************
|
|
#endif
|