ABS input sensing

Go To Last Post
7 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
I'm using the code below to setup up the event system to capture pulses from a pair of anti-lock brake sensors.  It counts the pulses just fine on PB6, but 
not on PB7; tested with the same signal applied to both pins.  As the code is nearly identical, I'm stumped on what the issue could be.  I tried different 
timers and event channels but the issue seems to be the pin.  I got the same results on two new chips, so I'm pretty sure the pin itself is OK.  
Running an XMEGA-A128A3u. Any thought appreciated.



TCC0.CTRLB = TC_WGMODE_NORMAL_gc;

TCC0.CTRLA = TC_CLKSEL_EVCH2_gc;   // Event channel2

TCC0.PER   = 20000;//sets top

TCC0.CTRLD = TC_EVACT_CAPT_gc | TC_EVSEL_CH2_gc;

PORTB.PIN6CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_FALLING_gc;//input on PORTB pin 6

EVSYS.CH2MUX = EVSYS_CHMUX_PORTB_PIN6_gc;//increment counter on pin change portb/pin6

EVSYS.CH2CTRL = EVSYS_DIGFILT_8SAMPLES_gc;

/////////////////////////////////////  V2
TCF0.CTRLB = TC_WGMODE_NORMAL_gc;

TCF0.CTRLA = TC_CLKSEL_EVCH4_gc;   // Event channel4

TCF0.PER   = 20000;//sets top

TCF0.CTRLD = TC_EVACT_CAPT_gc | TC_EVSEL_CH4_gc;//0X0A;

PORTB.PIN7CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_FALLING_gc;//input on PORTB pin 7

EVSYS.CH4MUX = EVSYS_CHMUX_PORTB_PIN7_gc;//increment counter on pin change portb/pin7

EVSYS.CH4CTRL = EVSYS_DIGFILT_8SAMPLES_gc;

 

This topic has a solution.
Last Edited: Fri. Jan 13, 2017 - 04:54 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Possibly try something simple first. Write a program to use pin 7 as an input, and write state to an output pin or LED. Perhaps pin 7 is already used by some other feature.

It all starts with a mental vision.

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

KitCarlson,

 

    I tried simply reading pin 7 as input pin as suggested.  It returns 0 regardless of input, which makes your supposition about another feature interfering make sense, but I can't find any other feature that should make a difference.  I'm using the ADC on PORTA, SPI on PORTC and PORTD, Quadrature read on PORTE, as well as PWM out.  PORTB pins 0-4 are set as outputs.  I'd think the pin was damaged, but since it's the same on two brand new chips, that seems unlikely, plus the only signal applied is the same applied to PORTB PIN6 which is working just as expected.   My configuration code is below.   

 

void Config32MHzClock(void)
{
CCP = CCP_IOREG_gc; //Security Signature to modify clock
// initialize clock source to be 32MHz internal oscillator (no PLL)
OSC.CTRL = OSC_RC32MEN_bm; // enable internal 32MHz oscillator
while(!(OSC.STATUS & OSC_RC32MRDY_bm)); // wait for oscillator ready
CCP = CCP_IOREG_gc; //Security Signature to modify clock
CLK.CTRL = 0x01; //select sysclock 32MHz osc
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////

void io_init(){
//Balance and Warning lights as output
PORTB.DIRSET = PIN0_bm | PIN1_bm | PIN2_bm | PIN3_bm | PIN4_bm;

//tach input on PORTB6,7
PORTB.DIRCLR = PIN6_bm | PIN7_bm;
//MC  --  DIR1 and PWM1
PORTE.DIRSET = PIN3_bm | PIN4_bm;//

}
void clk_init(){

OSC.CTRL |= OSC_RC32KEN_bm;
while ( !( OSC_STATUS & OSC_RC32KRDY_bm ) ); /* Wait for the int. 32kHz oscillator to stabilize. */


CLK.RTCCTRL = CLK_RTCEN_bm | 0x0C;//0x0C is for 32.768kHz internal oscillator
while (RTC.STATUS & RTC_SYNCBUSY_bm);

RTC.PER = 65534;
RTC.CTRL = RTC_PRESCALER_DIV1_gc; // div by 1
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void quadrature_counter(){//TCE0
PORTE.PIN0CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_LEVEL_gc;//input on PORTE pin 0,1 with pull ups on and LEVEL sensing
PORTE.PIN1CTRL = PORT_OPC_PULLUP_gc | PORT_ISC_LEVEL_gc;

EVSYS.CH0MUX =  EVSYS_CHMUX_PORTE_PIN0_gc;

EVSYS.CH0CTRL = EVSYS_QDEN_bm | EVSYS_DIGFILT_2SAMPLES_gc;

TCE0.CTRLD = TC_EVACT_QDEC_gc | TC_EVSEL_CH0_gc;

TCE0.CNT = encoder_zero_steer;

TCE0.CTRLA = TC_CLKSEL_DIV1_gc;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void pwm_init(){//TCE1
//set up for PWM 
//COMP output set via TCE1
TCE1.CTRLB = TC_WGMODE_SS_gc | TC1_CCAEN_bm;// | TC0_CCBEN_bm | TC0_CCCEN_bm;

// configure timer/counter0
TCE1.CTRLA = TC_CLKSEL_DIV1_gc;

//2000 sets top and 16kHz PWM frequency
TCE1.PER	= 2000;
TCE1.CCA=0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void V_init(){//TCF0 and TCC0
/////////  Sets up TCF0, TCC0 counter to count tach hits from V1 and V2 speed sensors on PORTB 6/7
////////////////////////////////V1
//set up for normal mode
TCC0.CTRLB = TC_WGMODE_NORMAL_gc;

TCC0.CTRLA = TC_CLKSEL_EVCH2_gc;   // Event channel2

TCC0.PER   = 20000;//sets top

TCC0.CTRLD = TC_EVACT_CAPT_gc | TC_EVSEL_CH2_gc;

PORTB.PIN6CTRL = PORT_ISC_FALLING_gc;//input on PORTB pin 6

EVSYS.CH2MUX = EVSYS_CHMUX_PORTB_PIN6_gc;//increment counter on pin change portb/pin6

EVSYS.CH2CTRL = EVSYS_DIGFILT_8SAMPLES_gc;

/////////////////////////////////////  V2
/*TCF0.CTRLB = TC_WGMODE_NORMAL_gc;

TCF0.CTRLA = TC_CLKSEL_EVCH4_gc;   // Event channel4

TCF0.PER   = 20000;//sets top

TCF0.CTRLD = TC_EVACT_CAPT_gc | TC_EVSEL_CH4_gc;//0X0A;

PORTB.PIN7CTRL = PORT_ISC_FALLING_gc;//input on PORTB pin 7

EVSYS.CH4MUX = EVSYS_CHMUX_PORTB_PIN7_gc;//increment counter on pin change portb/pin7

EVSYS.CH4CTRL = EVSYS_DIGFILT_8SAMPLES_gc;*/
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
void ADC_init() {
PORTA.DIRCLR = PIN1_bm | PIN2_bm | PIN5_bm | PIN6_bm | PIN7_bm;//configure PORTA pn 1,2,5,6,7 as input
PORTA.PIN3CTRL = PORT_OPC_PULLDOWN_gc;//pull down on
PORTA.PIN4CTRL = PORT_OPC_PULLDOWN_gc;
ADCA.CH0.CTRL = ADC_CH_INPUTMODE_DIFF_gc;//ADC_CH_INPUTMODE_SINGLEENDED_gc;//
ADCA.CTRLA = ADC_ENABLE_bm;	// enable adc
ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc | ADC_CONMODE_bm;	 // 12 bit conversion, signed
ADCA.REFCTRL = ADC_REFSEL_AREFA_gc;
ADCA.PRESCALER = ADC_PRESCALER_DIV64_gc;	 // peripheral clk/8 (2MHz/16=250kHz)
ADCA.CH0.CTRL = ADC_ENABLE_bm | ADC_CH_START_bm; // start conversion on channel 0
while ((ADCA.INTFLAGS & ADC_CH0IF_bm) == 0);
ADCA.INTFLAGS = ADC_CH0IF_bm;//clear flag
}

uint16_t adc_read(uint8_t adc_pin){
ADCA.CH0.MUXCTRL = adc_pin<<3 | 7;
ADCA.CH0.CTRL = ADC_ENABLE_bm | ADC_CH_START_bm; // start conversion on channel 0
while ((ADCA.INTFLAGS & ADC_CH0IF_bm) == 0);
ADCA.INTFLAGS = ADC_CH0IF_bm;//clear flag
return(ADCA.CH0RES);
}
#include "spic.h"
volatile uint8_t spic_data_in[SPI_BUFFER_SIZE];


// Functions
//setup as SPI master
	void master_PORTC_SPI_init(){
	//set MOSI,SCK,SS as output
	PORTC.DIRSET = PIN5_bm | PIN7_bm;//MOSI, SCK
	PORTC.DIRCLR = PIN6_bm;//MISO input
	
		//set SS as output via Macro
		SLVC_SET(SLVC0);
		//SLV_SET(SLV1);
		//SLV_SET(SLV2);
		//SLV_SET(SLV3);
		
		//Init SPI SLVs to inactive state via Macro setting SS pin high
		SLVC_RELEASE(SLVC0);
		//SLV_RELEASE(SLV1);
		//SLV_RELEASE(SLV2);
		//SLV_RELEASE(SLV3);
	
	//initiate the SPI module in master mode at 2Mhz	
	SPIC.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_PRESCALER_DIV16_gc;
	}

		
	

//************************************************************************************************//
void spic_read(uint8_t slave_select,uint8_t address_read, uint8_t read_bytes){// slave_select, address to read from, number of bytes to read
uint8_t i;	
	switch (slave_select){
		case 0:	 SLVC_SELECT(SLVC0);//pull CS line low for SLV1
		break;
		case 1:  SLVC_SELECT(SLVC1);//pull CS line low for SLV1 
		break;
		case 2:  SLVC_SELECT(SLVC2);//pull CS line low for SLV2
		break;
		case 3:  SLVC_SELECT(SLVC3);//pull CS line low for SLV3
		break;
		default:
		break;}
	
	_delay_us(10);
	address_read=(address_read | 0x80);//sets MSB in byte to tell slave this is a read request
	
	
	//send data to begin transmit/receive
	SPIC.DATA = address_read;
	
	// Wait for transmission complete
	while(!(SPIC.STATUS&SPI_IF_bm));
	
	for(i=1; i<=read_bytes; i++){_delay_us(10);//allow slave to set outgoing data
	//Send consecutive  transmissions for burst read starting at previously selected register value in slave
	SPIC.DATA = address_read+i;
	// Wait for transmission complete
	while(!(SPIC.STATUS&SPI_IF_bm));
	spic_data_in[i-1]= SPIC.DATA;	}
	
	
	switch (slave_select){
		case 0:	 SLVC_RELEASE(SLVC0);//pull CS line low for SLV1
		break;
		case 1:  SLVC_RELEASE(SLVC1);
		break;
		case 2:  SLVC_RELEASE(SLVC2);
		break;
		case 3:  SLVC_RELEASE(SLVC3);
		default:
		break;}
}

/////////////////////////////////////////////////////////////////////////////////////////////////////
void spic_write(uint8_t slave_select,uint8_t address_write, uint8_t write_byte){//address to write to and data to write
	
		switch (slave_select){
			case 0:	 SLVC_SELECT(SLVC0);//pull CS line low for SLV1
			break;
			case 1:  SLVC_SELECT(SLVC1);//pull CS line low for SLV1
			break;
			case 2:  SLVC_SELECT(SLVC2);//pull CS line low for SLV2
			break;
			case 3:  SLVC_SELECT(SLVC3);//pull CS line low for SLV3
			break;
			default:
			break;}

	//send data to begin transmit/receive
	SPIC.DATA = address_write;//send address to write to
	// Wait for transmission complete
	while(!(SPIC.STATUS&SPI_IF_bm));
	address_write=SPIC.DATA;
	
	SPIC.DATA = write_byte;//send byte to write
	// Wait for transmission complete
	while(!(SPIC.STATUS&SPI_IF_bm));
	
		switch (slave_select){
			case 0:	 SLVC_RELEASE(SLVC0);//pull CS line low for SLV1
			break;
			case 1:  SLVC_RELEASE(SLVC1);
			break;
			case 2:  SLVC_RELEASE(SLVC2);
			break;
			case 3:  SLVC_RELEASE(SLVC3);
			default:
			break;}
}
#include "spid.h"
volatile uint8_t spid_data_in[SPI_BUFFER_SIZE];


// Functions
//setup as SPI master
	void master_PORTD_SPI_init(){
	//set MOSI,SCK,SS as output
	PORTD.DIRSET = PIN5_bm | PIN7_bm;//MOSI, SCK, SS1
	PORTD.DIRCLR = PIN6_bm;//MISO input
	
		//set SS as output via Macro
		//SLVD_SET(SLVD0);
		SLVD_SET(SLVD1);
		SLVD_SET(SLVD2);
		SLVD_SET(SLVD3);
		
		//Init SPI SLVs to inactive state via Macro setting SS pin high
		SLVD_RELEASE(SLVD0);
		SLVD_RELEASE(SLVD1);
		SLVD_RELEASE(SLVD2);
		SLVD_RELEASE(SLVD3);
	
	//initiate the SPI module in master mode at .5 Mhz	
	SPID.CTRL = SPI_ENABLE_bm | SPI_MASTER_bm | SPI_PRESCALER_DIV64_gc;
	}

		
	

//************************************************************************************************//
void spid_read(uint8_t slave_select,uint8_t address_read, uint8_t read_bytes){// slave_select, address to read from, number of bytes to read
uint8_t i;	
	switch (slave_select){
		case 0:	 SLVD_SELECT(SLVD0);//pull CS line low for SLV1
		break;
		case 1:  SLVD_SELECT(SLVD1);//pull CS line low for SLV1 
		break;
		case 2:  SLVD_SELECT(SLVD2);//pull CS line low for SLV2
		break;
		case 3:  SLVD_SELECT(SLVD3);//pull CS line low for SLV3
		break;
		default:
		break;}
	
	_delay_us(10);
	address_read=(address_read | 0x80);//sets MSB in byte to tell slave this is a read request
	
	
	//send data to begin transmit/receive
	SPID.DATA = address_read;
	
	// Wait for transmission complete
	while(!(SPID.STATUS&SPI_IF_bm));
	
	for(i=1; i<=read_bytes; i++){_delay_us(10);//allow slave to set outgoing data
	//Send consecutive  transmissions for burst read starting at previously selected register value in slave
	SPID.DATA = address_read+i;
	// Wait for transmission complete
	while(!(SPID.STATUS&SPI_IF_bm));
	spid_data_in[i-1]= SPID.DATA;	}
	
	
	switch (slave_select){
		case 0:	 SLVD_RELEASE(SLVD0);
		break;
		case 1:  SLVD_RELEASE(SLVD1);
		break;
		case 2:  SLVD_RELEASE(SLVD2);
		break;
		case 3:  SLVD_RELEASE(SLVD3);
		default:
		break;}
}


/////////////////////////////////////////////////////////////////////////////////////////////////////
void spid_write(uint8_t slave_select,uint8_t address_write, uint8_t write_byte){//address to write to and data to write
	
		switch (slave_select){
			case 0:	 SLVD_SELECT(SLVD0);//pull CS line low for SLV1
			break;
			case 1:  SLVD_SELECT(SLVD1);//pull CS line low for SLV1
			break;
			case 2:  SLVD_SELECT(SLVD2);//pull CS line low for SLV2
			break;
			case 3:  SLVD_SELECT(SLVD3);//pull CS line low for SLV3
			break;
			default:
			break;}

	//send data to begin transmit/receive
	SPID.DATA = address_write;//send address to write to
	// Wait for transmission complete
	while(!(SPID.STATUS&SPI_IF_bm));
	address_write=SPID.DATA;
	
	SPID.DATA = write_byte;//send byte to write
	// Wait for transmission complete
	while(!(SPID.STATUS&SPI_IF_bm));
	
		switch (slave_select){
			case 0:	 SLVD_RELEASE(SLVD0);//pull CS line low for SLV1
			break;
			case 1:  SLVD_RELEASE(SLVD1);
			break;
			case 2:  SLVD_RELEASE(SLVD2);
			break;
			case 3:  SLVD_RELEASE(SLVD3);
			default:
			break;}
}

 

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

Did you set the JTAG disable fuse? Any other peripherals in use? I'm just throwing out the usual stuff.

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

If the port pin works then perhaps a signed/unsigned char problem (bit 7 is the sign bit of a signed char).

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

It all starts with a mental vision.

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

Thank you for your help; my problem was the JTAG fuse.  Works as expected now.