Exemplo n.º 1
0
/**************************************************************************//**
 * @brief  Setup the ACMP
 *****************************************************************************/
void setupACMP(void)
{
  /* ACMP configuration constant table. */
  static const ACMP_Init_TypeDef initACMP =
  {
    .fullBias = false,                 /* fullBias */
    .halfBias = true,                  /* halfBias */
    .biasProg =  0x0,                  /* biasProg */
    .interruptOnFallingEdge =  false,  /* interrupt on rising edge */
    .interruptOnRisingEdge =  false,   /* interrupt on falling edge */
    //.interruptOnFallingEdge =  true,  /* interrupt on rising edge */
    //.interruptOnRisingEdge =  true,   /* interrupt on falling edge */
    .warmTime = acmpWarmTime4,       /* 512 cycle warmup to be safe */
    .hysteresisLevel = acmpHysteresisLevel0, /* No Hysteresis */
    .inactiveValue = false,            /* inactive value */
    .lowPowerReferenceEnabled = true, /* low power reference */
    .vddLevel = 32,                  /* VDD level : VDD/2 */
    .enable = false                    /* Don't request enabling. */
  };


  /* Configure ACMP. */
  ACMP_Init(ACMP1, &initACMP);
  /* Disable ACMP0 out to a pin. */
  ACMP_GPIOSetup(ACMP1, 0, false, false);
  /* Set up ACMP negSel to VDD, posSel is controlled by LESENSE. */
  ACMP_ChannelSet(ACMP1, acmpChannelVDD, acmpChannel0);
  /* LESENSE controls ACMP thus ACMP_Enable(ACMP0) should NOT be called in order
   * to ensure lower current consumption. */

#ifdef DEBUG_ACMP
  ACMP_ChannelSet(ACMP1, acmpChannelVDD, acmpChannel2);
  ACMP1->IEN = 1;
  ACMP_Enable(ACMP1);
  NVIC_ClearPendingIRQ(ACMP0_IRQn);
  NVIC_EnableIRQ(ACMP0_IRQn);
#endif
}

#ifdef DEBUG_ACMP
// ACMP IRQ Handler is shared between ACMP0 and ACMP1
void ACMP0_IRQHandler(void)
{
  PRINTF("%s\r\n",__func__);
  ACMP1->IFC = 1;
  NVIC_ClearPendingIRQ(ACMP0_IRQn);
}
/**************************************************************************//**
 * @brief  ACMP_setup
 * Configures and starts the ACMP
 *****************************************************************************/
void ACMP_setup(void)
{
  /* Enable necessary clocks */
  CMU_ClockEnable(cmuClock_ACMP0, true);
  CMU_ClockEnable(cmuClock_GPIO, true);

  /* Configure PC4 as input with pull down for ACMP channel 4 input */
  GPIO_PinModeSet(gpioPortC, 4, gpioModeInputPullFilter, 0);

  /* Analog comparator parameters */
  const ACMP_Init_TypeDef acmpInit =
  {
    .fullBias                 = false,                  /* no full bias current*/
    .halfBias                 = false,                  /* no half bias current */
    .biasProg                 = 7,                      /* Biasprog current 1.4 uA */
    .interruptOnFallingEdge   = false,                  /* disable interrupt for falling edge */
    .interruptOnRisingEdge    = false,                  /* disable interrupt for rising edge */
    .warmTime                 = acmpWarmTime256,        /* Warm-up time in clock cycles, should be >140 cycles for >10us warm-up @ 14MHz */
    .hysteresisLevel          = acmpHysteresisLevel0,   /* Hysteresis level 0  - no hysteresis */
    .inactiveValue            = 0,                      /* Inactive comparator output value */
    .lowPowerReferenceEnabled = false,                  /* Low power reference mode disabled */
    .vddLevel                 = 32,                     /* Vdd reference scaling of 32 */
  };

  /* Init ACMP and set ACMP channel 4 as positive input
     and scaled Vdd as negative input */
  ACMP_Init(ACMP0, &acmpInit);
  ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel4);
  ACMP_Enable(ACMP0);
}

/**************************************************************************//**
 * @brief  PRS_ScanChannel
 * Waits for activity on a selected PRS channel and writes on the LCD 
   when activity occurs
 *  
 * @param[in] timer  
 *   Pointer to TIMER peripheral register block.
 *
 * @param[in] prsCh
 * 	 PRS Channel to be monitored
 *
 * @param[in] edgeType
 *   Signal edge to be monitored/captured 
 *****************************************************************************/
void PRS_ScanChannel(TIMER_TypeDef *timer, TIMER_PRSSEL_TypeDef prsCh, TIMER_Edge_TypeDef edgeType)
{
  
/* enable the clock for the correct timer */  
#define TIMER_Clock(T) (T==TIMER0 ? cmuClock_TIMER0 : \
                          T==TIMER1 ? cmuClock_TIMER1 : 0)
  
  /* Enable necessary clocks */
  CMU_ClockEnable((CMU_Clock_TypeDef)TIMER_Clock(timer), true);
    
  /* Initialize LCD */
  SegmentLCD_Init(false);

  /* Select CC channel parameters */
  const TIMER_InitCC_TypeDef timerCCInit = 
  {
    .eventCtrl  = timerEventFalling,      /* input capture event control */
    .edge       = edgeType,               /* input capture on falling edge */
    .prsSel     = prsCh,                  /* prs channel select channel 5*/
    .cufoa      = timerOutputActionNone,  /* no action on counter underflow */
    .cofoa      = timerOutputActionNone,  /* no action on counter overflow */
    .cmoa       = timerOutputActionNone,  /* no action on counter match */
    .mode       = timerCCModeCapture,     /* CC channel mode capture */
    .filter     = false,                  /* no filter */
    .prsInput   = true,                   /* CC channel PRS input */
    .coist      = false,                  /* comparator output initial state */
    .outInvert  = false,                  /* no output invert */
  };
  
  /* Initialize TIMER0 CC0 */
  TIMER_InitCC(timer, 0, &timerCCInit);
  
  /* Select timer parameters */  
  const TIMER_Init_TypeDef timerInit =
  {
    .enable     = true,                         /* start counting when init complete */         
    .debugRun   = false,                        /* counter not running on debug halt */  
    .prescale   = timerPrescale1024,            /* prescaler of 64 */
    .clkSel     = timerClkSelHFPerClk,          /* TIMER0 clocked by the HFPERCLK */
    .fallAction = timerInputActionNone,         /* stop counter on falling edge */
    .riseAction = timerInputActionNone,         /* reload and start on rising edge */
    .mode       = timerModeUp,                  /* counting up */
    .dmaClrAct  = false,                        /* no DMA */
    .quadModeX4 = false,                        /* no quad decoding */
    .oneShot    = false,                        /* counting up constinuously */
    .sync       = false,                        /* no start/stop/reload by other timers */
  };
  
  /* Initialize TIMER0 */
  TIMER_Init(timer, &timerInit);  
  
  /* Poll the Input Capture Valid flag in the Status register
      The program will hang at this point waiting for activity on this
	  channel */
  while(!((TIMER0->STATUS & _TIMER_STATUS_ICV0_MASK )>>16));  
}

/**************************************************************************//**
 * @brief  Main function
 * Main is called from __iar_program_start, see assembly startup file
 *****************************************************************************/
int main(void)
{
  /* Align different chip revisions*/
  CHIP_Init();
  
  /* Initialise the ACMP */
  ACMP_setup();

  /* PRS setup */
  /* Enable clock for PRS and select ACMP as source and ACMP0OUT (ACMP0 OUTPUT) as signal 
     for channel 5 */
  CMU_ClockEnable(cmuClock_PRS, true);
  PRS_SourceSignalSet(5, PRS_CH_CTRL_SOURCESEL_ACMP0, PRS_CH_CTRL_SIGSEL_ACMP0OUT, prsEdgeOff);
  
  /* Start PRS scan 
     This function will halt the program while there is no PRS activity
     This function assumes that the PRS has been setup previously */
  PRS_ScanChannel(TIMER0, timerPRSSELCh5, timerEdgeFalling);
  
  /* Write PRS and channel number on the LCD to acknowledge PRS activity */  
  SegmentLCD_Write("PRS");
  SegmentLCD_Number((int)timerPRSSELCh5);
  
  while(1)
  {
    /* Enter EM1 while waiting for capture. */
    EMU_EnterEM1();
  }
}
Exemplo n.º 3
0
/**************************************************************************//**
 * @brief  TIMER0_setup
 * Configures the TIMER
 *****************************************************************************/
void TIMER_setup(void)
{
  /* Enable necessary clocks */
  CMU_ClockEnable(cmuClock_TIMER0, true);
  CMU_ClockEnable(cmuClock_PRS, true);

  /* Select CC channel parameters */
  TIMER_InitCC_TypeDef timerCCInit =
  {
    .eventCtrl  = timerEventEveryEdge,      /* Input capture event control */
    .edge       = timerEdgeBoth,       /* Input capture on falling edge */
    .prsSel     = timerPRSSELCh5,         /* Prs channel select channel 5*/
    .cufoa      = timerOutputActionNone,  /* No action on counter underflow */
    .cofoa      = timerOutputActionNone,  /* No action on counter overflow */
    .cmoa       = timerOutputActionNone,  /* No action on counter match */
    .mode       = timerCCModeCapture,     /* CC channel mode capture */
    .filter     = false,                  /* No filter */
    .prsInput   = true,                   /* CC channel PRS input */
    .coist      = false,                  /* Comparator output initial state */
    .outInvert  = false,                  /* No output invert */
  };

  /* Initialize TIMER0 CC0 channel */
  TIMER_InitCC(HIJACK_RX_TIMER, 0, &timerCCInit);

  /* Select timer parameters */
  const TIMER_Init_TypeDef timerInit =
  {
    .enable     = false,                        /* Do not start counting when init complete */
    .debugRun   = false,                        /* Counter not running on debug halt */
    .prescale   = HIJACK_TIMER_RESOLUTION,      /* Prescaler of 1 */
    .clkSel     = timerClkSelHFPerClk,          /* TIMER0 clocked by the HFPERCLK */
    .fallAction = timerInputActionReloadStart,         /* Stop counter on falling edge */
    .riseAction = timerInputActionReloadStart,  /* Reload and start on rising edge */
    .mode       = timerModeUp,                  /* Counting up */
    .dmaClrAct  = false,                        /* No DMA */
    .quadModeX4 = false,                        /* No quad decoding */
    .oneShot    = false,                        /* Counting up constinuously */
    .sync       = false,                        /* No start/stop/reload by other timers */
  };

  /* Initialize TIMER0 */
  TIMER_Init(HIJACK_RX_TIMER, &timerInit);

  /* PRS setup */
  /* Select ACMP as source and ACMP0OUT (ACMP0 OUTPUT) as signal */
  PRS_SourceSignalSet(5, PRS_CH_CTRL_SOURCESEL_ACMP0, PRS_CH_CTRL_SIGSEL_ACMP0OUT, prsEdgeOff);

  /* Enable CC0 interrupt */
  TIMER_IntEnable(HIJACK_RX_TIMER, TIMER_IF_CC0);

  /* Enable TIMER0 interrupt vector in NVIC */
  NVIC_EnableIRQ(TIMER0_IRQn);
}

/**************************************************************************//**
 * @brief  ACMP_setup
 * Configures and starts the ACMP
 *****************************************************************************/
static void ACMP_setup(void)
{
  /* Enable necessary clocks */
  CMU_ClockEnable(HIJACK_RX_ACMPCLK, true);
  CMU_ClockEnable(cmuClock_GPIO, true);

  /* Configure ACMP input pin. */
  GPIO_PinModeSet(HIJACK_RX_GPIO_PORT, HIJACK_RX_GPIO_PIN, gpioModeInput, 0);

  /* Analog comparator parameters */
  const ACMP_Init_TypeDef acmpInit =
  {
    .fullBias                 = false,                  /* No full bias current*/
    .halfBias                 = true,                  /* No half bias current */
    .biasProg                 = 2,                      /* Biasprog current 1.4 uA */
    .interruptOnFallingEdge   = false,                  /* Disable interrupt for falling edge */
    .interruptOnRisingEdge    = false,                  /* Disable interrupt for rising edge */
    .warmTime                 = acmpWarmTime256,        /* Warm-up time in clock cycles, should be >140 cycles for >10us warm-up @ 14MHz */
    .hysteresisLevel          = acmpHysteresisLevel7,   /* Hysteresis level 0  - no hysteresis */
    .inactiveValue            = 1,                      /* Inactive comparator output value */
    .lowPowerReferenceEnabled = false,                  /* Low power reference mode disabled */
    .vddLevel                 = HIJACK_RX_ACMP_LEVEL,                     /* Vdd reference scaling of 32 */
  };

  /* Use ACMP0 output, PD6 . */
  //GPIO_PinModeSet(gpioPortD, 6, gpioModePushPull, 0);
  //ACMP_GPIOSetup(ACMP0, 2, true, false);

  /* Init ACMP and set ACMP channel 4 as positive input
     and scaled Vdd as negative input */
  ACMP_Init(HIJACK_RX_ACMP, &acmpInit);
  ACMP_ChannelSet(HIJACK_RX_ACMP, HIJACK_RX_ACMP_NEG, HIJACK_RX_ACMP_CH);
  ACMP_Enable(HIJACK_RX_ACMP);
}

/**
 * @brief calculate whether cnt is in 500us region
 * ticker = 64Mhz/128 = 2us
 * 475us < cnt < 510us
 *
 */
static chk_result_t IsTime2Detect(uint32_t inv)
{
  	chk_result_t ret;
	
  	if( inv < HIJACK_DEC_NUM_TICKS_MIN){
    	offset = inv;
	    ret = pass;
  	}
	else if ( ( inv <= HIJACK_DEC_NUM_TICKS_MAX ) && ( inv >= HIJACK_DEC_NUM_TICKS_MIN ) ) {
		offset = 0;
		inv = 0;
	  	ret = suit;
	}
	else{
		offset = 0;
		inv = 0;
		ret = error;
	}
	return ret;
}

/*
 * Find phase remain or phase reversal.
*/

static void dec_parser(uint8_t bit_msk, state_t state)
{
  	if ( ( suit == IsTime2Detect(inv) ) ){ //it's time to determine
		if( falling == cur_edge ){
	  		dec.data &= ~(1 << bit_msk);
#if DEC_DEBUG == 1
			uartPutChar( '+' ) ;
			uartPutChar( '_' ) ;
#endif//DEC_DEBUG == 1
		}
		else{
		   	dec.data |= (1 << bit_msk);
#if DEC_DEBUG == 1
			uartPutChar( '_' ) ;
			uartPutChar( '+' ) ;
#endif//DEC_DEBUG == 1
			dec.odd++;
		}
		dec.state = state;   //state switch
	}
	else if ( error == IsTime2Detect(inv) ){   //wait for edge detection time
		dec.state = Waiting;   //state switch
	}
}
/**************************************************************************//**
 * @brief  decode state machine
 * Invoke in TIMER_ISR for decoding.
 *****************************************************************************/
void decode_machine(void)
{
   	inv = offset + cur_stamp;  //update offset
#if 0
	if( dec.state > Waiting ){
	  	USART_printHexBy16u(inv);
		if(cur_edge == rising){
			uartPutChar( '\\' ) ;
		}
		else{
			uartPutChar( '/' ) ;
		}
	}
#endif	
	switch (dec.state){
		case Waiting:
         	/* go to start bit if rising edge exist. */
         	if (rising == cur_edge) {
            	dec.state = Sta0;
            	offset = 0;
				inv = 0;
         	}
			break;
			//
		case Sta0:
         	if( ( suit == IsTime2Detect(inv) ) && ( falling == cur_edge ) ){
				dec.data = 0;  //clear data field for store new potential data
				dec.odd = 0;   //clear odd field parity counter
				dec.state = Bit0;
#if DEC_DEBUG == 1
			  	uartPutChar( 'S' ) ;
				uartPutChar( '+' ) ;
				uartPutChar( '_' ) ;
#endif
         	}
			else{
				dec.state = Waiting;
			}
	   		break;
			//
		case Bit0:
#if DEC_DEBUG == 1
			uartPutChar( '0' ) ;
#endif
		  	dec_parser(BIT0, Bit1);
	   		break;
			//
		case Bit1:
#if DEC_DEBUG == 1
			uartPutChar( '1' ) ;
#endif
		  	dec_parser(BIT1, Bit2);
	   		break;
			//
		case Bit2:
#if DEC_DEBUG == 1
			uartPutChar( '2' ) ;
#endif
		  	dec_parser(BIT2, Bit3);
	   		break;
			//
		case Bit3:
#if DEC_DEBUG == 1
			uartPutChar( '3' ) ;
#endif
		  	dec_parser(BIT3, Bit4);
	   		break;
			//
		case Bit4:
#if DEC_DEBUG == 1
			uartPutChar( '4' ) ;
#endif
		  	dec_parser(BIT4, Bit5);
	   		break;
			//
		case Bit5:
#if DEC_DEBUG == 1
			uartPutChar( '5' ) ;
#endif
		  	dec_parser(BIT5, Bit6);
	   		break;
			//
		case Bit6:
#if DEC_DEBUG == 1
			uartPutChar( '6' ) ;
#endif
		  	dec_parser(BIT6, Bit7);
	   		break;
			//
		case Bit7:
#if DEC_DEBUG == 1
			uartPutChar( '7' ) ;
#endif
		  	dec_parser(BIT7, Parity);
	   		break;
			//
		case Parity:		
			if ( ( suit == IsTime2Detect(inv) ) ){ //it's time to determine
				if( rising == cur_edge ){
				   dec.odd++;
#if DEC_DEBUG == 1
				   uartPutChar( '_' ) ;
				   uartPutChar( '+' ) ;
#endif
				}
				else{
#if DEC_DEBUG == 1
				   uartPutChar( '+' ) ;
				 	uartPutChar( '_' ) ;
#endif					
				}
#if DEC_DEBUG == 1
					uartPutChar( dec.odd + 0x30) ;
#endif
				if( 1 == (dec.odd%2)){  //parity pass
				   dec.state = Sto0;
				}
				else{ //parity failed
				   dec.state = Waiting;
				}
			 }
			 else if ( error == IsTime2Detect(inv) ){   //wait for edge detection time
				dec.state = Waiting;
			 }
			break;
			//
      	case Sto0:	
         	if ( ( suit == IsTime2Detect(inv) ) ){ //it's time to determine
				if( rising == cur_edge ){  //stop bit is rising edge
				    USART_txByte(dec.data);
#if DEC_DEBUG == 1
					uartPutChar( '_' ) ;
				    uartPutChar( '+' ) ;
#endif
				    HIJACKPutData(&dec.data, &decBuf, sizeof(uint8_t));
				}
				else{
#if DEC_DEBUG == 1
				  	uartPutChar( '+' ) ;
				 	uartPutChar( '_' ) ;
#endif			
				}
				dec.state = Waiting;
#if DEC_DEBUG == 1
				uartPutChar( '\r' ) ;
				uartPutChar( '\n' ) ;
#endif
         	}
         	else if ( error == IsTime2Detect(inv) ){   //wait for edge detection time
				dec.state = Waiting;
			}
         	break;
         	//
		default:
	  		break;
			//
	}
}
/**************************************************************************//**
 * @brief  Sets up the ACMP
 *****************************************************************************/
void setupACMP(void)
{
  /* Configuration structure for ACMP */
  static const ACMP_Init_TypeDef acmpInit =
  {
    .fullBias                 = false,                
    .halfBias                 = false,                
    .biasProg                 = 0x6,                  /* Experiment with higher value if sensor doesn't work */
    .interruptOnFallingEdge   = false,
    .interruptOnRisingEdge    = false,
    .warmTime                 = acmpWarmTime256,      /* Warmuptime should be longer than 10 micro s */
    .hysteresisLevel          = acmpHysteresisLevel0, 
    .inactiveValue            = false,
    .lowPowerReferenceEnabled = false,
    .vddLevel                 = 0x00,                 /* Controlled by LESENSE */
    .enable                   = false
  };

  /* Initialize ACMP */
  ACMP_Init(ACMP0, &acmpInit);
  /* Disable ACMP0 out to a pin. */
  ACMP_GPIOSetup(ACMP0, 0, false, false);
  
  /* Set up ACMP negSel to VDD, posSel is controlled by LESENSE. */
  ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel0);

  /* LESENSE controls ACMP thus ACMP_Enable(ACMP0) should NOT be called in order
   * to ensure lower current consumption. */
}



/**************************************************************************//**
 * @brief  Sets up the LESENSE
 *****************************************************************************/
void setupLESENSE(void)
{
  /* LESENSE configuration structure */
  static const LESENSE_Init_TypeDef initLesense =
  {
    .coreCtrl         =  LESENSE_CORECTRL_DESC_DEFAULT,
    .timeCtrl         =  LESENSE_TIMECTRL_DESC_DEFAULT,
    .perCtrl          = 
    {
      .dacCh0Data     = lesenseDACIfData,
      .dacCh0ConvMode = lesenseDACConvModeDisable,
      .dacCh0OutMode  = lesenseDACOutModeDisable,
      .dacCh1Data     = lesenseDACIfData,
      .dacCh1ConvMode = lesenseDACConvModeDisable,
      .dacCh1OutMode  = lesenseDACOutModeDisable,
      .dacPresc       = 0,
      .dacRef         = lesenseDACRefBandGap,
      .acmp0Mode      = lesenseACMPModeMuxThres, /* LESENSE controls the threshold value (VDDLEVEL) of ACMP0 */
      .acmp1Mode      = lesenseACMPModeMuxThres, /* LESENSE controls the threshold value (VDDLEVEL) of ACMP1 */
      .warmupMode     = lesenseWarmupModeNormal  /* The analog comparators are shut down when LESENSE is idle */
    },
    .decCtrl          = LESENSE_DECCTRL_DESC_DEFAULT
  };

  /* Channel configuration */
  static const LESENSE_ChDesc_TypeDef initLesenseCh =
  {
    .enaScanCh     = true,                      /* Enable scan on this channel */
    .enaPin        = false,
    .enaInt        = false, 
    .chPinExMode   = lesenseChPinExHigh,        /*  Pin is high when excitating */
    .chPinIdleMode = lesenseChPinIdleDis,       /* Pin idle when channel idle  */
    .useAltEx      = true,                      /* Use alternative excitation pin  */
    .shiftRes      = true,                      /* Result is shifted into the decoder register */
    .invRes        = false,
    .storeCntRes   = true,
    .exClk         = lesenseClkHF,              /* Use HF clock for excitation timing */
    .sampleClk     = lesenseClkHF,              /* Use HF clock for sample timing */
    .exTime        = 0x1F,                      /* Clk cycles to excite emitter and decoder */
    .sampleDelay   = 0x1F,                      /* Clc cycles to wait before sampling comparator */
    .measDelay     = 0x00, 
    .acmpThres     = 0x0F,                      /* Initial comperator threshold  */
    .sampleMode    = lesenseSampleModeACMP,
    .intMode       = lesenseSetIntNone,
    .cntThres      = 0x0000,
    .compMode      = lesenseCompModeLess 
  };

  /* Alternate excitation channels configuration */
  static const LESENSE_ConfAltEx_TypeDef initAltEx =
  {
    .altExMap = lesenseAltExMapALTEX, 
    .AltEx[0] = 
    {
      .enablePin = true,
      .idleConf  = lesenseAltExPinIdleDis,
      .alwaysEx  = true /* Connected to IR sensor */
    },
    .AltEx[1] = 
    {
      .enablePin = true,
      .idleConf  = lesenseAltExPinIdleDis,
      .alwaysEx  = false /* Connected to IR LED */
    }
  };

  /* Initialize LESENSE interface _with_ RESET. */
  LESENSE_Init(&initLesense, true);
   
  /* Configure channels */
  LESENSE_ChannelConfig(&initLesenseCh, 0);
  LESENSE_ChannelConfig(&initLesenseCh, 1); 
  
  /* Configure alternate excitation channels */
  LESENSE_AltExConfig(&initAltEx);
  
  
  /* State machine proximity sensor setup */
  
  LESENSE_DecStDesc_TypeDef decConf =
  {
    .chainDesc = false,
    .confA     = 
    {
      .compVal   = 0x1, /* Trigger transition when scan result = compVal */
      .compMask  = 0xC, /* Mask out the upper two bits */
      .nextState = STATE_1,
      .prsAct    = lesenseTransActNone,
      .setInt    = true
    },
    .confB       = 
    {
      .compVal   = 0x1, 
      .compMask  = 0xC, 
      .nextState = STATE_1,
      .prsAct    = lesenseTransActNone,
      .setInt    = true
    }
  };
Exemplo n.º 5
0
/**************************************************************************//**
 * @brief  Setup the ACMP
 *****************************************************************************/
void setupACMP(void)
{
  /* ACMP configuration constant table. */
  static const ACMP_Init_TypeDef initACMP =
  {
    .fullBias                 = false,                  /* fullBias */
    .halfBias                 = true,                   /* halfBias */
    .biasProg                 = 0xE,                    /* biasProg */
    .interruptOnFallingEdge   = false,                  /* interrupt on rising edge */
    .interruptOnRisingEdge    = false,                  /* interrupt on falling edge */
    .warmTime                 = acmpWarmTime512,        /* 512 cycle warmup to be safe */
    .hysteresisLevel          = acmpHysteresisLevel0,   /* hysteresis level 0 */
    .inactiveValue            = false,                  /* inactive value */
    .lowPowerReferenceEnabled = false,                  /* low power reference */
    .vddLevel                 = 0x0D                    /* VDD level */
  };


  /* Initialize ACMP */
  ACMP_Init(ACMP0, &initACMP);

  ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel7);

  /* don't disable ACMP so that output can be routed out to a pin */
  ACMP0->CTRL &= ~ACMP_CTRL_EN;
}


/**************************************************************************//**
 * @brief  Setup the LESENSE
 *****************************************************************************/
void setupLESENSE(void)
{
  /* LESENSE channel configuration constant table. */
  static const LESENSE_ChAll_TypeDef initChs = LESENSE_LCSENSE_SCAN_CONF;
  /* LESENSE central configuration constant table. */
  static const LESENSE_Init_TypeDef initLESENSE =
  {
    .coreCtrl =
    {
      .scanStart      = lesenseScanStartPeriodic,
      .prsSel         = lesensePRSCh0,
      .scanConfSel    = lesenseScanConfDirMap,
      .invACMP0       = false,
      .invACMP1       = false,
      .dualSample     = false,
      .storeScanRes   = false,
      .bufOverWr      = true,
      .bufTrigLevel   = lesenseBufTrigHalf,
      .wakeupOnDMA    = lesenseDMAWakeUpDisable,
      .biasMode       = lesenseBiasModeDutyCycle,
      .debugRun       = false
    },

    .timeCtrl =
    {
      .startDelay     = 0U
    },

    .perCtrl =
    {
      .dacCh0Data     = lesenseDACIfData,
      .dacCh0ConvMode = lesenseDACConvModeSampleOff,
      .dacCh0OutMode  = lesenseDACOutModeDisable,
      .dacCh1Data     = lesenseDACIfData,
      .dacCh1ConvMode = lesenseDACConvModeSampleOff,
      .dacCh1OutMode  = lesenseDACOutModePin,
      .dacPresc       = 31U,
      .dacRef         = lesenseDACRefVdd,
      .acmp0Mode      = lesenseACMPModeMux,
      .acmp1Mode      = lesenseACMPModeDisable,
      .warmupMode     = lesenseWarmupModeNormal
    },

    .decCtrl =
/**************************************************************************//**
 * @brief  Sets up the DAC
 *****************************************************************************/
void setupDAC(void)
{
  /* Configuration structure for the DAC */
  static const DAC_Init_TypeDef dacInit =
  {
    .refresh      = dacRefresh8,
    .reference    = dacRefVDD,
    .outMode      = dacOutputPin,
    .convMode     = dacConvModeContinuous,
    .prescale     = 0,
    .lpEnable     = false,
    .ch0ResetPre  = false,
    .outEnablePRS = false,
    .sineEnable   = false,
    .diff         = false
  };

  /* Initialize DAC */
  DAC_Init(DAC0, &dacInit);

  /* Set data for DAC channel 0 */
  writeDataDAC(DAC0, (unsigned int) DAC_DATA, DAC_CHANNEL);
}

/**************************************************************************//**
 * @brief  Write DAC conversion value
 *****************************************************************************/
void writeDataDAC(DAC_TypeDef *dac, unsigned int value, unsigned int ch)
{
  /* Write data output value to the correct register. */
  if (!ch)
  {
    /* Write data to DAC ch 0 */
    dac->CH0DATA = value;
  }
  else
  {
    /* Write data to DAC ch 1 */
    dac->CH1DATA = value;
  }
}

/**************************************************************************//**
 * @brief  Sets up the ACMP
 *****************************************************************************/
void setupACMP(void)
{
  /* There is no default configuration for this */
  static const ACMP_Init_TypeDef acmpInit =
  {
    .fullBias                 = false,
    .halfBias                 = true,
    .biasProg                 = 0xF,
    .interruptOnFallingEdge   = false,
    .interruptOnRisingEdge    = false,
    .warmTime                 = acmpWarmTime4,
    .hysteresisLevel          = acmpHysteresisLevel0,
    .inactiveValue            = false,
    .lowPowerReferenceEnabled = false,
    .vddLevel                 = ACMP_VDD_SCALE,
    .enable                   = false
  };

  /* Initialize ACMPs */
  ACMP_Init(ACMP0, &acmpInit);
  ACMP_Init(ACMP1, &acmpInit);

  /* Select Vdd as negative reference
   * Positive reference is controlled by LESENSE */
  ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel6);
  ACMP_ChannelSet(ACMP1, acmpChannelVDD, acmpChannel4);
}

/**************************************************************************//**
 * @brief  Sets up the LESENSE
 *****************************************************************************/
void setupLESENSE(void)
{
  static const LESENSE_Init_TypeDef initLesense =
  {
    .coreCtrl         =
    {
      .scanStart    = lesenseScanStartPeriodic,
      .prsSel       = lesensePRSCh0,
      .scanConfSel  = lesenseScanConfDirMap,
      .invACMP0     = false,
      .invACMP1     = false,
      .dualSample   = false,
      .storeScanRes = false,
      .bufOverWr    = true,
      .bufTrigLevel = lesenseBufTrigHalf,
      .wakeupOnDMA  = lesenseDMAWakeUpDisable,
      .biasMode     = lesenseBiasModeDutyCycle,
      .debugRun     = false
    },

    .timeCtrl         =
    {
      .startDelay     = 0
    },

    .perCtrl          =
    {
      .dacCh0Data     = lesenseDACIfData,
      .dacCh0ConvMode = lesenseDACConvModeSampleOff,
      .dacCh0OutMode  = lesenseDACOutModeDisable,
      .dacCh1Data     = lesenseDACIfData,
      .dacCh1ConvMode = lesenseDACConvModeSampleOff,
      .dacCh1OutMode  = lesenseDACOutModePin,
      .dacPresc       = 31,
      .dacRef         = lesenseDACRefVdd,
      .acmp0Mode      = lesenseACMPModeMux,
      .acmp1Mode      = lesenseACMPModeMux,
      .warmupMode     = lesenseWarmupModeNormal
    },

    .decCtrl          =
    {
      .decInput  = lesenseDecInputSensorSt,
      .initState = 0,
      .chkState  = true,
      .intMap    = false,
      .hystPRS0  = false,
      .hystPRS1  = false,
      .hystPRS2  = false,
      .hystIRQ   = false,
      .prsCount  = true,
      .prsChSel0 = lesensePRSCh0,
      .prsChSel1 = lesensePRSCh1,
      .prsChSel2 = lesensePRSCh2,
      .prsChSel3 = lesensePRSCh3
    }
  };
Exemplo n.º 7
0
/**************************************************************************//**
 * @brief  Setup the ACMP
 *****************************************************************************/
void setupACMP(void)
{
  /* ACMP configuration constant table. */
  static const ACMP_Init_TypeDef initACMP =
  {
    .fullBias = false,                 /* fullBias */
    .halfBias = true,                  /* halfBias */
    .biasProg =  0x0,                  /* biasProg */
    .interruptOnFallingEdge =  false,  /* interrupt on rising edge */
    .interruptOnRisingEdge =  false,   /* interrupt on falling edge */
    .warmTime = acmpWarmTime512,       /* 512 cycle warmup to be safe */
    .hysteresisLevel = acmpHysteresisLevel5, /* hysteresis level 5 */
    .inactiveValue = false,            /* inactive value */
    .lowPowerReferenceEnabled = false, /* low power reference */
    .vddLevel = 0x00,                  /* VDD level */
    .enable = false                    /* Don't request enabling. */
  };


  /* Configure ACMP. */
  ACMP_Init(ACMP0, &initACMP);
  /* Disable ACMP0 out to a pin. */
  ACMP_GPIOSetup(ACMP0, 0, false, false);
  /* Set up ACMP negSel to VDD, posSel is controlled by LESENSE. */
  ACMP_ChannelSet(ACMP0, acmpChannelVDD, acmpChannel0);
  /* LESENSE controls ACMP thus ACMP_Enable(ACMP0) should NOT be called in order
   * to ensure lower current consumption. */
}


/**************************************************************************//**
 * @brief  Setup the LESENSE
 *****************************************************************************/
void setupLESENSE(void)
{
  /* LESENSE channel configuration constant table. */
  static const LESENSE_ChAll_TypeDef initChs = LESENSE_LIGHTSENSE_SCAN_CONF;
  /* LESENSE alternate excitation channel configuration constant table. */
  static const LESENSE_ConfAltEx_TypeDef initAltEx = LESENSE_LIGHTSENSE_ALTEX_CONF;
  /* LESENSE central configuration constant table. */
  static const LESENSE_Init_TypeDef initLESENSE =
  {
    .coreCtrl =
    {
      .scanStart = lesenseScanStartPeriodic,
      .prsSel = lesensePRSCh0,
      .scanConfSel = lesenseScanConfDirMap,
      .invACMP0 = false,
      .invACMP1 = false,
      .dualSample = false,
      .storeScanRes = false,
      .bufOverWr = true,
      .bufTrigLevel = lesenseBufTrigHalf,
      .wakeupOnDMA = lesenseDMAWakeUpDisable,
      .biasMode = lesenseBiasModeDutyCycle,
      .debugRun = false
    },

    .timeCtrl =
    {
      .startDelay = 0U
    },

    .perCtrl =
    {
      .dacCh0Data = lesenseDACIfData,
      .dacCh0ConvMode = lesenseDACConvModeDisable,
      .dacCh0OutMode = lesenseDACOutModeDisable,
      .dacCh1Data = lesenseDACIfData,
      .dacCh1ConvMode = lesenseDACConvModeDisable,
      .dacCh1OutMode = lesenseDACOutModeDisable,
      .dacPresc = 0U,
      .dacRef = lesenseDACRefBandGap,
      .acmp0Mode = lesenseACMPModeMuxThres,
      .acmp1Mode = lesenseACMPModeMuxThres,
      .warmupMode = lesenseWarmupModeNormal
    },

    .decCtrl =