Can I dynamically change the input to the event Channel

Go To Last Post
6 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

dear

i have xmega256A3u . i have to operate 16 ultrasonic Hcsr04 directly to the MCU, where i am using the TC0 timers (TCC0,TCD0,TCE0,TCF0).in each of them i use the four capture channel CCA,CCB,CCC,CCD in normal mode with Pulse-Width capture,

the 16 Hcsr04 sensors are divided into 4 groups, each group have 4 sensor and each sensor use one capture channel of the related timer, so the for first two sensor group(8 sensor) i use TCC0 and TCD0, with selection of the event channel 0 to event channel 7 connected to PORTA which receive the echo signals, but for the second-tow  sensor group(8 sensor) i am trying to change the source of the event channel to operate another 8 echo which the are connected to PORTD, below some parts of my code, i use TCC1 for timer out for 30 ms , for the first two group i use "init_event_system(&ECHO_PORT1)", and for the secon i use init_event_system(&ECHO_PORT2);

 

#define TIME_OUT_TIMER      TCC1
#define FIRST_LAYER_TIMER   TCC0
#define SECOND_LAYER_TIMER  TCD0
#define THIRD_LAYER_TIMER   TCE0
#define FORTH_LAYER_TIMER   TCF0
#define FIRST_SONAR_LAYER          1
#define SECOND_SONAR_LAYER         2
#define THIRD_SONAR_LAYER          3
#define FOURTH_SONAR_LAYER         4
#define ECHO_PORT1    PORTA
#define ECHO_PORT2    PORTD
#define TRIGG_PORT1   PORTB
#define TRIGG_PORT2   PORTC

void init_TC1_normal_mode(TC1_t *t)
{
    t->CTRLA = TC_CLKSEL_OFF_gc;
    t->CTRLB=(0<<TC0_CCDEN_bp) | (0<<TC0_CCCEN_bp) | (0<<TC0_CCBEN_bp) | (0<<TC0_CCAEN_bp) | TC_WGMODE_NORMAL_gc;
    t->CTRLD=TC_EVACT_OFF_gc | TC_EVSEL_OFF_gc;
    t->CTRLE=TC_BYTEM_NORMAL_gc;
    t->INTCTRLA=TC_ERRINTLVL_OFF_gc | TC_OVFINTLVL_LO_gc;

    t->INTCTRLB = TC_CCDINTLVL_OFF_gc | TC_CCCINTLVL_OFF_gc | TC_CCBINTLVL_OFF_gc | TC_CCAINTLVL_OFF_gc;
    HIRESF.CTRLA &= ~HIRES_HREN0_bm;
    t->INTFLAGS=TCF0.INTFLAGS;
    t->CNT=0x0000;
    t->PER=0xEA5F;//oxEE47;30 ms
    t->CCA=0x0000;
    t->CCB=0x0000;

    SREG=s;
}
void init_TC0_capture_input(TC0_t *timer)
{
    timer_0_disable(timer);
    timer->CTRLB    = TC0_CCAEN_bm | TC0_CCBEN_bm | TC0_CCCEN_bm | TC0_CCDEN_bm| TC_WGMODE_NORMAL_gc;
    timer->CTRLA    = TC_CLKSEL_DIV8_gc;
    timer->INTCTRLB = TC_CCAINTLVL_OFF_gc | TC_CCBINTLVL_OFF_gc | TC_CCCINTLVL_OFF_gc | TC_CCDINTLVL_OFF_gc;
    timer->INTFLAGS = timer->INTFLAGS;
    if((timer == &FIRST_LAYER_TIMER) | (timer  == &THIRD_LAYER_TIMER))
        timer->CTRLD    = TC_EVACT_PW_gc | TC_EVSEL_CH0_gc;
    else
        timer->CTRLD    = TC_EVACT_PW_gc | TC_EVSEL_CH4_gc;				
}
void init_event_system(PORT_t* _port)
{
    if(_port == &ECHO_PORT1)
    {
        EVSYS.CH0MUX  = EVSYS_CHMUX_PORTA_PIN0_gc;
        EVSYS.CH1MUX  = EVSYS_CHMUX_PORTA_PIN1_gc;
        EVSYS.CH2MUX  = EVSYS_CHMUX_PORTA_PIN2_gc; 
        EVSYS.CH3MUX  = EVSYS_CHMUX_PORTA_PIN3_gc; 
        EVSYS.CH4MUX  = EVSYS_CHMUX_PORTA_PIN4_gc; 
        EVSYS.CH5MUX  = EVSYS_CHMUX_PORTA_PIN5_gc;
        EVSYS.CH6MUX  = EVSYS_CHMUX_PORTA_PIN6_gc; 
        EVSYS.CH7MUX  = EVSYS_CHMUX_PORTA_PIN7_gc; 
    }
    if(_port == &ECHO_PORT2)
    {
        EVSYS.CH0MUX  = EVSYS_CHMUX_PORTD_PIN0_gc; 
        EVSYS.CH1MUX  = EVSYS_CHMUX_PORTD_PIN1_gc;
        EVSYS.CH2MUX  = EVSYS_CHMUX_PORTD_PIN2_gc; 
        EVSYS.CH3MUX  = EVSYS_CHMUX_PORTD_PIN3_gc; 
        EVSYS.CH4MUX  = EVSYS_CHMUX_PORTD_PIN4_gc; 
        EVSYS.CH5MUX  = EVSYS_CHMUX_PORTD_PIN5_gc; 
        EVSYS.CH6MUX  = EVSYS_CHMUX_PORTD_PIN6_gc; 
        EVSYS.CH7MUX  = EVSYS_CHMUX_PORTD_PIN7_gc; 
    }
}
void init_ports()
{
    //***************** Ultrasonic PORTs ****************************************

    /* TRIG PORT ...PORTB, PORTC */
    PORTB.DIRCLR = 0xFF;
    PORTC.DIRCLR = 0xFF;
    

    PORTA.PIN0CTRL = PORT_ISC_BOTHEDGES_gc | PORT_OPC_TOTEM_gc;
    PORTA.PIN1CTRL = PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLUP_gc ;
    PORTA.PIN2CTRL = PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLUP_gc;
    PORTA.PIN3CTRL = PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLUP_gc;
    PORTA.PIN4CTRL = PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLUP_gc;
    PORTA.PIN5CTRL = PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLUP_gc;
    PORTA.PIN6CTRL = PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLUP_gc;
    PORTA.PIN7CTRL = PORT_ISC_BOTHEDGES_gc | PORT_OPC_PULLUP_gc;
    
    PORTB.PIN0CTRL =  PORT_OPC_PULLDOWN_gc;
    PORTB.PIN1CTRL =  PORT_OPC_PULLDOWN_gc ;
    PORTB.PIN2CTRL =  PORT_OPC_PULLDOWN_gc;
    PORTB.PIN3CTRL =  PORT_OPC_PULLDOWN_gc;
    PORTB.PIN4CTRL =  PORT_OPC_PULLDOWN_gc;
    PORTB.PIN5CTRL =  PORT_OPC_PULLDOWN_gc;
    PORTB.PIN6CTRL =  PORT_OPC_PULLDOWN_gc;
    PORTB.PIN7CTRL =  PORT_OPC_PULLDOWN_gc;
}
int main(void)
{
    init_TC0_capture_input(&FIRST_LAYER_TIMER);
    init_TC0_capture_input(&SECOND_LAYER_TIMER);
    init_TC0_capture_input(&THIRD_LAYER_TIMER);
    init_TC0_capture_input(&FORTH_LAYER_TIMER);
    init_TC1_normal_mode(&TIME_OUT_TIMER);
    init_ports()
}
void startup_scan_process(bool _scanDirection)
{
    myStepper.currentDirection = _scanDirection;
    for(uint8_t i = 0; i< myStepper.numberOfActivLayer; i++)
    {
        if(i >(uint8_t)FIRST_SONAR_LAYER)
        {
            
            init_event_system(&ECHO_PORT2);
            measure_distance(&sonarVector[i],_scanDirection);
        }
        else
        {
            
            init_event_system(&ECHO_PORT1);
            measure_distance(&sonarVector[i],_scanDirection);
        }
    }
    _delay_ms(100);
    transmitt_acqusition_block_data(sonarVector,myStepper.currentDirection);
    stepper_action(sonarVector,myStepper.currentDirection,false);
    _delay_ms(500);
}
void measure_distance(HCSR04* _sensorGroup ,uint8_t _scanDirection)
{
    TIME_OUT_TIMER.CTRLA |= TC_CLKSEL_OFF_gc;
    for(uint8_t u = 0; u < _sensorGroup->sensorCount; u++)
    {
        TIME_OUT_TIMER.CNT = 0;
        _sensorGroup->trig(_sensorGroup->layerSensorGroup[u],_sensorGroup->sideNumber);
        TIME_OUT_TIMER.CTRLA |= TC_CLKSEL_DIV8_gc;
        while(!sonarEchoFlag & !sonarTimeoutFlag);
        TIME_OUT_TIMER.CTRLA=(TIME_OUT_TIMER.CTRLA & (~TC1_CLKSEL_gm)) | TC_CLKSEL_OFF_gc;
        if(sonarTimeoutFlag)
        {
            if(_sensorGroup->sideNumber == 2)
            {
                if(u == 3 )
                {
                    PORTF.OUTTGL = PIN0_bm;
                    sonarTimeoutFlag = false;
                    _sensorGroup->SonarRangUnion.measurmentPulse[u]=0;
                    _sensorGroup->SonarAngleUnion.measurmentAngel[u] = _sensorGroup->sonarOrintation[u];
                }
            }
            
        }
        else
        {
            if(sonarEchoFlag)
            {
                _sensorGroup->calculateDistance(_sensorGroup->layerSensorGroup[u],_sensorGroup);
                sonarEchoFlag = false;
            }
        }
        sonarTimeoutFlag = false;
    }
}
oid HCSR04::calculateDistance(uint8_t trigPin, HCSR04* _sensorGroup)
{
	uint16_t pulseWidth = 0;
	uint8_t counter = 0;
	uint8_t _whichSide = _sensorGroup->sideNumber;
	switch(_whichSide)
	{
		case FIRST_SONAR_LAYER:
		switch(trigPin)
		{
			case SONAR1:
			pulseWidth =  TC_GetCaptureA(&FIRST_LAYER_TIMER);
			counter = 0;
			break;
			case SONAR2:
			pulseWidth =  TC_GetCaptureB(&FIRST_LAYER_TIMER);
			counter = 1;
			break;
			case SONAR3:
			pulseWidth =  TC_GetCaptureC(&FIRST_LAYER_TIMER);
			counter = 2;
			break;
			case SONAR4:
			pulseWidth =  TC_GetCaptureD(&FIRST_LAYER_TIMER);
			counter = 3;
			break;
		}
		break;
		case SECOND_SONAR_LAYER:
		switch(trigPin)
		{
			case SONAR5:
			pulseWidth =  TC_GetCaptureA(&SECOND_LAYER_TIMER);
			counter = 0;
			break;
			case SONAR6:
			pulseWidth =  TC_GetCaptureB(&SECOND_LAYER_TIMER);
			counter = 1;
			break;
			case SONAR7:
			pulseWidth =  TC_GetCaptureC(&SECOND_LAYER_TIMER);
			counter = 2;
			break;
			case SONAR8:
			pulseWidth =  TC_GetCaptureD(&SECOND_LAYER_TIMER);
			counter = 3;
			break;
		}
		break;
		case THIRD_SONAR_LAYER:
		switch(trigPin)
		{
			case SONAR1:
			pulseWidth =  TC_GetCaptureA(&THIRD_LAYER_TIMER);
			counter = 0;
			break;
			case SONAR2:
			pulseWidth =  TC_GetCaptureB(&THIRD_LAYER_TIMER);
			counter = 1;
			break;
			case SONAR3:
			pulseWidth =  TC_GetCaptureC(&THIRD_LAYER_TIMER);
			counter = 2;
			break;
			case SONAR4:
			pulseWidth =  TC_GetCaptureD(&THIRD_LAYER_TIMER);
			counter = 3;
			break;
		}
		break;
		case FOURTH_SONAR_LAYER:
		switch(trigPin)
		{
			case SONAR5:
			pulseWidth =  TC_GetCaptureA(&FORTH_LAYER_TIMER);
			counter = 0;
			break;
			case SONAR6:
			pulseWidth =  TC_GetCaptureB(&FORTH_LAYER_TIMER);
			counter = 1;
			break;
			case SONAR7:
			pulseWidth =  TC_GetCaptureC(&FORTH_LAYER_TIMER);
			counter = 2;
			break;
			case SONAR8:
			pulseWidth =  TC_GetCaptureD(&FORTH_LAYER_TIMER);
			counter = 3;
			break;
		}
		break;
	}
	_sensorGroup->SonarRangUnion.measurmentPulse[counter] =  
	((pulseWidth > this->sensorMaxRang )||((pulseWidth < this->sensorMinRang))?0:pulseWidth);
	_sensorGroup->SonarAngleUnion.measurmentAngel[counter] = _sensorGroup->sonarOrintation[counter];

the "measure_distance" function just round for each sensor and trig it for 12us and th MCU wait for TCC1 overFlow or for TCC0 input captuer, at the ISR i just rise a flage and disable the timer

//----------------------------------------------------- Timer TCCO Interrupt ISR-------------------------------------
ISR(TCC0_CCA_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; FIRST_LAYER_TIMER.INTCTRLB  =  TC_CCAINTLVL_OFF_gc ; }
ISR(TCC0_CCB_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; FIRST_LAYER_TIMER.INTCTRLB  =  TC_CCBINTLVL_OFF_gc ; }
ISR(TCC0_CCC_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; FIRST_LAYER_TIMER.INTCTRLB  =  TC_CCCINTLVL_OFF_gc ; }
ISR(TCC0_CCD_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; FIRST_LAYER_TIMER.INTCTRLB  =  TC_CCDINTLVL_OFF_gc ; }
//----------------------------------------------------- Timer TCDO Interrupt ISR-------------------------------------
ISR(TCD0_CCA_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; SECOND_LAYER_TIMER.INTCTRLB =  TC_CCAINTLVL_OFF_gc ; }
ISR(TCD0_CCB_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; SECOND_LAYER_TIMER.INTCTRLB =  TC_CCBINTLVL_OFF_gc ; }
ISR(TCD0_CCC_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; SECOND_LAYER_TIMER.INTCTRLB =  TC_CCCINTLVL_OFF_gc ; }
ISR(TCD0_CCD_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; SECOND_LAYER_TIMER.INTCTRLB =  TC_CCDINTLVL_OFF_gc ; }
//-------------------------------------------------------------------------------------------------------------------
//----------------------------------------------------- Timer TCEO Interrupt ISR-------------------------------------
ISR(TCE0_CCA_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; THIRD_LAYER_TIMER.INTCTRLB =  TC_CCAINTLVL_OFF_gc ; }
ISR(TCE0_CCB_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; THIRD_LAYER_TIMER.INTCTRLB =  TC_CCBINTLVL_OFF_gc ; }
ISR(TCE0_CCC_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; THIRD_LAYER_TIMER.INTCTRLB =  TC_CCCINTLVL_OFF_gc ; }
ISR(TCE0_CCD_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; THIRD_LAYER_TIMER.INTCTRLB =  TC_CCDINTLVL_OFF_gc ; }
//----------------------------------------------------- Timer TCFO Interrupt ISR-------------------------------------
ISR(TCF0_CCA_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; FORTH_LAYER_TIMER.INTCTRLB =  TC_CCAINTLVL_OFF_gc ; }
ISR(TCF0_CCB_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; FORTH_LAYER_TIMER.INTCTRLB =  TC_CCBINTLVL_OFF_gc ; }
ISR(TCF0_CCC_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; FORTH_LAYER_TIMER.INTCTRLB =  TC_CCCINTLVL_OFF_gc ; }
ISR(TCF0_CCD_vect) { if(!sonarEchoFlag) sonarEchoFlag = true ; FORTH_LAYER_TIMER.INTCTRLB =  TC_CCDINTLVL_OFF_gc ; }

ISR(TCC1_OVF_vect) { sonarTimeoutFlag = true; TIME_OUT_TIMER.CTRLA=(TIME_OUT_TIMER.CTRLA & (~TC1_CLKSEL_gm)) | TC_CLKSEL_OFF_gc;}

i dont know if i can dynamically change the input (source) of event channel, i get some wrong data i some times get value from disconnected sensor, so i need your experince to ensure the validation of this approach

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am considering doing much the same thing. 

 

What DOES concern me is a false event when the switching occurs. Don't know if this is a real "issue" but I want to try to see if it happens or not. Part of the challenge might be that all switching combinations might to behave exacty the same.

 

So, my answer, at this point, is "who knows"? Not I.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

AdamMe wrote:
i dont know if i can dynamically change the input (source) of event channel,

 

I don't see why you cannot change the source.  I mean, in my init routine for an XMEGA32E5, I set the input to teh event channel(s), so why couldn't you change the inputs while the application is running?

 

But can you expand on what you men by 'dynamically'?  That word gets thrown around a lot here and with different intents..

 

East Side Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My guess is that the reference is to changing it while looping code executes.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ka7ehk wrote:

My guess is that the reference is to changing it while looping code executes.

 

Jim

 

And in order to do that, one would have to have some sort of 'decision' statement ie an "IF" I would guess.

 

if "this data comes in and its not correct"
{
    change the input to the event to this;
}
else
{
    do this instead;
}

crude, but makes the point.

 

East side Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Event System connections are defined by register setup, and not hard coded by the compiler.
I don't have a board with me currently, but I don't see any reason one can't change the Event System on the fly.
JC