Go Down

Topic: setting registers for inputs, outputs, interrupts and timers (Read 522 times) previous topic - next topic

drummin89

Im working on porting my code that I originally wrote to run on an avr to run on the arduino due. Its code I wrote for my CNC and I have 6 inputs (from limit switches) that I want to setup as pin change interrupts. I also have registers for setting up timer 3 (TC1 CH0) for pulsing the step input to the stepper drivers.

My problem is it doesn't get past the setup. I put print statements in and it seems to be getting stuck here.

Code: [Select]
 //ENABLE INTERRUPTS FOR THE FOLLOWING PINS
  REG_PIOA_IER |= ((0x01 << Z_OVERTRAVELPROX) | (0x01 << Z_UNDERTRAVELPROX));
  REG_PIOB_IER |= (0x01 << X_OVERTRAVELPROX);
  REG_PIOC_IER |= (0x01 << X_UNDERTRAVELPROX);
  REG_PIOD_IER |= ((0x01 << Y_OVERTRAVELPROX) | (0x01 << Y_UNDERTRAVELPROX));


complete setup routine with defines

Code: [Select]

//OUTPUTS
#define X_STEP 16 //0x10 //PORTF0, X axis "STEP" Control Bit, PORTA P16, PIN A0
#define X_DIR 24 //0x1000000 //PORTF1, X Axis "DIRECTION" Control Bit, PORTA P24, PIN A1
#define X_EN 6 //0x40 //PORTD7, X Axis "ENABLE" Control Bit, PORTC P6, PIN D38
#define Y_STEP 3 //0x8 //PORTF6, Y axis "STEP" Control Bit, PORTA P3, PIN A6
#define Y_DIR 2 //0x4 //PORTF7, Y Axis "DIRECTION" Control Bit, PORTA P2, PIN A7
#define Y_EN 23 //0x800000 //PORTF2, Y Axis "ENABLE" Control Bit, PORTA P23, PIN A2
#define Z_STEP 17 //0x20000 //PORTL3, Z axis "STEP" Control Bit, PORTC P17, PIN D46
#define Z_DIR 15 //0x8000 //PORTL1, Z Axis "DIRECTION" Control Bit, PORTC P15, PIN D48
#define Z_EN 17 //0x20000 //PORTK0, Z Axis "ENABLE" Control Bit, PORTB P17, PIN A8
#define SPINDLE_PWM 1  //PWM signal to spindle speed control, ???

//INPUTS
#define X_OVERTRAVELPROX 25  //X Axis under travel prox input, PORTB P25, PIN D2
#define X_UNDERTRAVELPROX 28  //X Axis over travel prox input, PORTC P28, PIN D3
#define Y_OVERTRAVELPROX 5  //Y Axis under travel prox input, PORTD P5, PIN D15
#define Y_UNDERTRAVELPROX 4  //Y Axis over travel prox input, PORTD P4, PIN D14
#define Z_OVERTRAVELPROX 10  //Z Axis under travel prox input, PORTA P10, PIN D19
#define Z_UNDERTRAVELPROX 11  //Z Axis over travel prox input, PORTA P11, PIN D18

void setup() {
  Serial.begin(19200);
  Serial.println("CNC_v17");
  //SET THE FOLLOWING PINS AS GPIO (ALLOW THEM TO BE USED AS INPUT/OUTPUT)
  REG_PIOA_PER |= ((0x01 << X_STEP) | (0x01 << X_DIR) | (0x01 << Y_STEP) | (0x01 << Y_DIR) | (0x01 << Y_EN) | (0x01 << Z_OVERTRAVELPROX) | (0x01 << Z_UNDERTRAVELPROX));
  REG_PIOB_PER |= ((0x01 << Z_EN) | (0x01 << X_OVERTRAVELPROX));
  REG_PIOC_PER |= ((0x01 << X_EN) | (0x01 << Z_STEP) | (0x01 << Z_DIR) | (0x01 << X_UNDERTRAVELPROX));
  REG_PIOD_PER |= ((0x01 << Y_OVERTRAVELPROX) | (0x01 << Y_UNDERTRAVELPROX));
  //SET THE FOLLOWING PINS AS OUTPUT
  REG_PIOA_OER |= ((0x01 << X_STEP) | (0x01 << X_DIR) | (0x01 << Y_STEP) | (0x01 << Y_DIR) | (0x01 << Y_EN));
  REG_PIOB_OER |= (0x01 << Z_EN);
  REG_PIOC_OER |= ((0x01 << X_EN) | (0x01 << Z_STEP) | (0x01 << Z_DIR));
  //SET THE FOLLOWING PINS AS INPUT
  REG_PIOA_ODR |= ((0x01 << Z_OVERTRAVELPROX) | (0x01 << Z_UNDERTRAVELPROX));
  REG_PIOB_ODR |= (0x01 << X_OVERTRAVELPROX);
  REG_PIOC_ODR |= (0x01 << X_UNDERTRAVELPROX);
  REG_PIOD_ODR |= ((0x01 << Y_OVERTRAVELPROX) | (0x01 << Y_UNDERTRAVELPROX));
  //ENABLE THE INTERNAL PULL-UP FOR THE FOLLOWING PINS
  REG_PIOA_PUER |= ((0x01 << X_STEP) | (0x01 << X_DIR) | (0x01 << Y_STEP) | (0x01 << Y_DIR));
  REG_PIOC_PUER |= ((0x01 << Z_STEP) | (0x01 << Z_DIR));
  //DISABLE THE INTERNAL PULL-UP FOR THE FOLLOWING PINS
  REG_PIOA_PUDR |= ((0x01 << Y_EN) | (0x01 << Z_OVERTRAVELPROX) | (0x01 << Z_UNDERTRAVELPROX));
  REG_PIOB_PUDR |= ((0x01 << Z_EN) | (0x01 << X_OVERTRAVELPROX));
  REG_PIOC_PUDR |= ((0x01 << X_EN) | (0x01 << X_UNDERTRAVELPROX));
  REG_PIOD_PUDR |= ((0x01 << Y_OVERTRAVELPROX) | (0x01 << Y_UNDERTRAVELPROX));
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT A
  pmc_enable_periph_clk(PIOA_IRQn);
  NVIC_DisableIRQ(PIOA_IRQn);
  NVIC_ClearPendingIRQ(PIOA_IRQn);
  NVIC_SetPriority(PIOA_IRQn, 1);
  NVIC_EnableIRQ(PIOA_IRQn);
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT B
  pmc_enable_periph_clk(PIOB_IRQn);
  NVIC_DisableIRQ(PIOB_IRQn);
  NVIC_ClearPendingIRQ(PIOB_IRQn);
  NVIC_SetPriority(PIOB_IRQn, 1);
  NVIC_EnableIRQ(PIOB_IRQn);
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT C
  pmc_enable_periph_clk(PIOC_IRQn);
  NVIC_DisableIRQ(PIOC_IRQn);
  NVIC_ClearPendingIRQ(PIOC_IRQn);
  NVIC_SetPriority(PIOC_IRQn, 1);
  NVIC_EnableIRQ(PIOC_IRQn);
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT D
  pmc_enable_periph_clk(PIOD_IRQn);
  NVIC_DisableIRQ(PIOD_IRQn);
  NVIC_ClearPendingIRQ(PIOD_IRQn);
  NVIC_SetPriority(PIOD_IRQn, 1);
  NVIC_EnableIRQ(PIOD_IRQn);
  //SET THE FOLLOWING PINS FOR PIN CHANGE INTERRUPT
  REG_PIOA_AIMDR |= ((0x01 << Z_OVERTRAVELPROX) | (0x01 << Z_UNDERTRAVELPROX));
  REG_PIOB_AIMDR |= (0x01 << X_OVERTRAVELPROX);
  REG_PIOC_AIMDR |= (0x01 << X_UNDERTRAVELPROX);
  REG_PIOD_AIMDR |= ((0x01 << Y_OVERTRAVELPROX) | (0x01 << Y_UNDERTRAVELPROX));
  //ENABLE INTERRUPTS FOR THE FOLLOWING PINS
  REG_PIOA_IER |= ((0x01 << Z_OVERTRAVELPROX) | (0x01 << Z_UNDERTRAVELPROX));
  REG_PIOB_IER |= (0x01 << X_OVERTRAVELPROX);
  REG_PIOC_IER |= (0x01 << X_UNDERTRAVELPROX);
  REG_PIOD_IER |= ((0x01 << Y_OVERTRAVELPROX) | (0x01 << Y_UNDERTRAVELPROX));
  
  //ENALBE INTERRUPT PRIORITY FOR TIMER 3
  pmc_enable_periph_clk(TC3_IRQn);
  NVIC_DisableIRQ(TC3_IRQn);
  //SET BITS 14 AND 15 OF TIMER COUNTER MODE REGISTER FOR TC1 CH0
  //BIT 14 = WAVESEL: Waveform Selection #2 UP_RC
  //BIT 15 = WAVE: Wareform Mode Enable
  REG_TC1_CMR0 = 0xC000;
  //SET BITS 0 AND 2 OF TIMER COUNTER CONFIGURE REGISTER FOR TC1 CH0
  //BIT 0 = ENABLE CLOCK
  //BIT 2 = SOFTWARE TRIGGER
  REG_TC1_CCR0 = 0x05;  
  //SET BIT 4 OF TIMER COUNTER INTERRUPT ENABLE REGISTER FOR TC1 CH0
  //BIT 4 = CPCS: RC Compare Interrupt Enable
  REG_TC1_IER0 = 0x10;  
  //THE FOLLOWING DISABLES ANY OTHER INTERRUPTS FOR TC1 CH0 THAT MIGHT BE ENABLED
  REG_TC1_IDR0 = 0xEF;  
  //1ms = 1000Hz, 5ms = 200Hz
  REG_TC1_RC0 = 200;
  //ENABLE AND SET INTERRUPT PRIORITY FOR TIMER 3
  NVIC_ClearPendingIRQ(TC3_IRQn);
  NVIC_SetPriority(TC3_IRQn, 0);
  NVIC_EnableIRQ(TC3_IRQn);
  
  clearStack();

  Serial.println("SETUP COMPLETE");
}


Any help would be appreciated

Also are there individual functions for each pin that is setup as an interrupt or just one for each port.

drummin89

do you have to use attachInterrupt if you want a function (or interrupt service routine) called when a pin state change occurs??? Can I not use PIOx_Handler in my sketch?

I'm fine with having 1 ISR per port and sorting out which pin has changed.

drummin89

figured it out. still need to test but I got it to complete the setup.

Code: [Select]

#define X_STEP_PORT_OUTPUT_HIGH REG_PIOA_SODR
#define X_STEP_PORT_OUTPUT_LOW REG_PIOA_CODR
#define X_DIR_PORT_OUTPUT_HIGH REG_PIOA_SODR
#define X_DIR_PORT_OUTPUT_LOW REG_PIOA_CODR
#define X_EN_PORT_OUTPUT_HIGH REG_PIOC_SODR
#define X_EN_PORT_OUTPUT_LOW REG_PIOC_CODR
#define Y_STEP_PORT_OUTPUT_HIGH REG_PIOA_SODR
#define Y_STEP_PORT_OUTPUT_LOW REG_PIOA_CODR
#define Y_DIR_PORT_OUTPUT_HIGH REG_PIOA_SODR
#define Y_DIR_PORT_OUTPUT_LOW REG_PIOA_CODR
#define Y_EN_PORT_OUTPUT_HIGH REG_PIOA_SODR
#define Y_EN_PORT_OUTPUT_LOW REG_PIOA_CODR
#define Z_STEP_PORT_OUTPUT_HIGH REG_PIOC_SODR
#define Z_STEP_PORT_OUTPUT_LOW REG_PIOC_CODR
#define Z_DIR_PORT_OUTPUT_HIGH REG_PIOC_SODR
#define Z_DIR_PORT_OUTPUT_LOW REG_PIOC_CODR
#define Z_EN_PORT_OUTPUT_HIGH REG_PIOB_SODR
#define Z_EN_PORT_OUTPUT_LOW REG_PIOB_CODR

#define X_OVERTRAVELPROX_PORT_STATUS REG_PIOB_PDSR  
#define X_UNDERTRAVELPROX_PORT_STATUS REG_PIOC_PDSR  
#define Y_OVERTRAVELPROX_PORT_STATUS REG_PIOD_PDSR  
#define Y_UNDERTRAVELPROX_PORT_STATUS REG_PIOD_PDSR  
#define Z_OVERTRAVELPROX_PORT_STATUS REG_PIOA_PDSR  
#define Z_UNDERTRAVELPROX_PORT_STATUS REG_PIOA_PDSR  

//OUTPUTS
#define X_STEP 16 //0x10 //PORTF0, X axis "STEP" Control Bit, PORTA P16, PIN A0
#define X_DIR 24 //0x1000000 //PORTF1, X Axis "DIRECTION" Control Bit, PORTA P24, PIN A1
#define X_EN 6 //0x40 //PORTD7, X Axis "ENABLE" Control Bit, PORTC P6, PIN D38
#define Y_STEP 3 //0x8 //PORTF6, Y axis "STEP" Control Bit, PORTA P3, PIN A6
#define Y_DIR 2 //0x4 //PORTF7, Y Axis "DIRECTION" Control Bit, PORTA P2, PIN A7
#define Y_EN 23 //0x800000 //PORTF2, Y Axis "ENABLE" Control Bit, PORTA P23, PIN A2
#define Z_STEP 17 //0x20000 //PORTL3, Z axis "STEP" Control Bit, PORTC P17, PIN D46
#define Z_DIR 15 //0x8000 //PORTL1, Z Axis "DIRECTION" Control Bit, PORTC P15, PIN D48
#define Z_EN 17 //0x20000 //PORTK0, Z Axis "ENABLE" Control Bit, PORTB P17, PIN A8
#define SPINDLE_PWM 1  //PWM signal to spindle speed control, ???

//INPUTS
#define X_OVERTRAVELPROX 25  //X Axis under travel prox input, PORTB P25, PIN D2
#define X_UNDERTRAVELPROX 28  //X Axis over travel prox input, PORTC P28, PIN D3
#define Y_OVERTRAVELPROX 5  //Y Axis under travel prox input, PORTD P5, PIN D15
#define Y_UNDERTRAVELPROX 4  //Y Axis over travel prox input, PORTD P4, PIN D14
#define Z_OVERTRAVELPROX 10  //Z Axis under travel prox input, PORTA P10, PIN D19
#define Z_UNDERTRAVELPROX 11  //Z Axis over travel prox input, PORTA P11, PIN D18

void setup() {
  Serial.begin(19200);
  Serial.println("CNC DUE v1");
  //INPUT PIN CONFIGURATION
  //ENABLE PERIPHERAL FOR CLOCKING INPUT ON FOLLOWING PORTS
  pmc_enable_periph_clk(ID_PIOA);
  pmc_enable_periph_clk(ID_PIOB);
  pmc_enable_periph_clk(ID_PIOC);
  pmc_enable_periph_clk(ID_PIOD);
  //DISABLE INTERRUPTS FOR THE FOLLOWING PINS
  PIOA -> PIO_IDR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_IDR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_IDR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_IDR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_IDR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_IDR = (0x01 << Y_UNDERTRAVELPROX);  
  //DISABLE THE INTERNAL PULL-UP FOR THE FOLLOWING PINS
  PIOA -> PIO_PUDR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_PUDR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_PUDR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_PUDR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_PUDR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_PUDR = (0x01 << Y_UNDERTRAVELPROX);
  //DISABLE INPUT FILTERING FOR THE FOLLOWING PINS
  PIOA -> PIO_IFDR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_IFDR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_IFDR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_IFDR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_IFDR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_IFDR = (0x01 << Y_UNDERTRAVELPROX);
  //SET THE FOLLOWING PINS AS INPUT
  PIOA -> PIO_ODR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_ODR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_ODR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_ODR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_ODR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_ODR = (0x01 << Y_UNDERTRAVELPROX);
  //SET THE FOLLOWING PINS AS GPIO (ALLOW THEM TO BE USED AS INPUT/OUTPUT)
  PIOA -> PIO_PER = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_PER = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_PER = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_PER = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_PER = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_PER = (0x01 << Y_UNDERTRAVELPROX);
  Serial.println("INPUT PIN SETUP COMPLETE");

  //OUTPUT PIN CONFIGURATION
  //DISABLE INTERRUPTS FOR THE FOLLOWING PINS
  PIOA -> PIO_IDR = (0x01 << X_STEP);
  PIOA -> PIO_IDR = (0x01 << X_DIR);
  PIOA -> PIO_IDR = (0x01 << Y_STEP);
  PIOA -> PIO_IDR = (0x01 << Y_DIR);
  PIOA -> PIO_IDR = (0x01 << Y_EN);
  PIOB -> PIO_IDR = (0x01 << Z_EN);  
  PIOC -> PIO_IDR = (0x01 << X_EN);  
  PIOC -> PIO_IDR = (0x01 << Z_STEP);  
  PIOC -> PIO_IDR = (0x01 << Z_DIR);
  //ENABLE THE INTERNAL PULL-UP FOR THE FOLLOWING PINS
  PIOA -> PIO_PUER = (0x01 << X_STEP);
  PIOA -> PIO_PUER = (0x01 << X_DIR);
  PIOA -> PIO_PUER = (0x01 << Y_STEP);
  PIOA -> PIO_PUER = (0x01 << Y_DIR);
  PIOC -> PIO_PUER = (0x01 << Z_STEP);
  PIOC -> PIO_PUER = (0x01 << Z_DIR);
  //DISABLE THE INTERNAL PULL-UP FOR THE FOLLOWING PINS
  PIOA -> PIO_PUER = (0x01 << Y_EN);
  PIOB -> PIO_PUER = (0x01 << Z_EN);
  PIOC -> PIO_PUER = (0x01 << X_EN);
  //DISABLE MULTI-DRIVE FOR THE FOLLOWING PINS
  PIOA -> PIO_MDDR = (0x01 << X_STEP);
  PIOA -> PIO_MDDR = (0x01 << X_DIR);
  PIOA -> PIO_MDDR = (0x01 << Y_STEP);
  PIOA -> PIO_MDDR = (0x01 << Y_DIR);
  PIOA -> PIO_MDDR = (0x01 << Y_EN);
  PIOB -> PIO_MDDR = (0x01 << Z_EN);  
  PIOC -> PIO_MDDR = (0x01 << X_EN);  
  PIOC -> PIO_MDDR = (0x01 << Z_STEP);  
  PIOC -> PIO_MDDR = (0x01 << Z_DIR);
  //SET THE FOLLOWING PINS AS OUTPUT
  PIOA -> PIO_OER = (0x01 << X_STEP);
  PIOA -> PIO_OER = (0x01 << X_DIR);
  PIOA -> PIO_OER = (0x01 << Y_STEP);
  PIOA -> PIO_OER = (0x01 << Y_DIR);
  PIOA -> PIO_OER = (0x01 << Y_EN);
  PIOB -> PIO_OER = (0x01 << Z_EN);
  PIOC -> PIO_OER = (0x01 << X_EN);
  PIOC -> PIO_OER = (0x01 << Z_STEP);
  PIOC -> PIO_OER = (0x01 << Z_DIR);
  //SET THE FOLLOWING PINS AS GPIO (ALLOW THEM TO BE USED AS INPUT/OUTPUT)
  PIOA -> PIO_PER = (0x01 << X_STEP);
  PIOA -> PIO_PER = (0x01 << X_DIR);
  PIOA -> PIO_PER = (0x01 << Y_STEP);
  PIOA -> PIO_PER = (0x01 << Y_DIR);
  PIOA -> PIO_PER = (0x01 << Y_EN);
  PIOB -> PIO_PER = (0x01 << Z_EN);
  PIOC -> PIO_PER = (0x01 << X_EN);
  PIOC -> PIO_PER = (0x01 << Z_STEP);
  PIOC -> PIO_PER = (0x01 << Z_DIR);
  Serial.println("OUTPUT PIN SETUP COMPLETE");

  //INPUT PIN CHANGE INTERRUPT CONFIGURATION
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT A
  pmc_enable_periph_clk(ID_PIOA);
  NVIC_DisableIRQ(PIOA_IRQn);
  NVIC_ClearPendingIRQ(PIOA_IRQn);
  NVIC_SetPriority(PIOA_IRQn, 0);
  NVIC_EnableIRQ(PIOA_IRQn);
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT B
  pmc_enable_periph_clk(ID_PIOB);
  NVIC_DisableIRQ(PIOB_IRQn);
  NVIC_ClearPendingIRQ(PIOB_IRQn);
  NVIC_SetPriority(PIOB_IRQn, 0);
  NVIC_EnableIRQ(PIOB_IRQn);
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT C
  pmc_enable_periph_clk(ID_PIOC);
  NVIC_DisableIRQ(PIOC_IRQn);
  NVIC_ClearPendingIRQ(PIOC_IRQn);
  NVIC_SetPriority(PIOC_IRQn, 0);
  NVIC_EnableIRQ(PIOC_IRQn);
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT D
  pmc_enable_periph_clk(ID_PIOD);
  NVIC_DisableIRQ(PIOD_IRQn);
  NVIC_ClearPendingIRQ(PIOD_IRQn);
  NVIC_SetPriority(PIOD_IRQn, 0);
  NVIC_EnableIRQ(PIOD_IRQn);  
  //SET THE FOLLOWING PINS FOR PIN CHANGE INTERRUPT
  PIOA -> PIO_AIMDR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_AIMDR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_AIMDR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_AIMDR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_AIMDR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_AIMDR = (0x01 << Y_UNDERTRAVELPROX);
  //ENABLE INTERRUPTS FOR THE FOLLOWING PINS
  PIOA -> PIO_IER = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_IER = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_IER = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_IER = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_IER = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_IER = (0x01 << Y_UNDERTRAVELPROX);
  Serial.println("INPUT INTERRUPT SETUP COMPLETE");

  Serial.println("SETUP COMPLETE");
}

drummin89

Code: [Select]

void PIOB_Handler() {
  uint32_t isr = PIOB -> PIO_ISR;
  if ((Y_OVERTRAVELPROX_PORT_STATUS & (0x01 << Y_OVERTRAVELPROX)) == (0x01 << Y_OVERTRAVELPROX)) {
    if (!homingActive)
      motionEnable = 0;
    YaxisHardPosOverTravelProx = 1;
  }
  else
    YaxisHardPosOverTravelProx = 0;
}


Had to add
Code: [Select]
uint32_t isr = PIOB -> PIO_ISR;
to each PIO_HANDLER to get it to work.

MorganS

Thanks for posting the solution. I am definitely going to refer to this in the future when I need to use these interrupts.

drummin89

I still need to figure what is going on. The pio_handler is getting called immediately after I set the pins up as interrupts then they don't run again.

drummin89

Nevermind everything is working fine. While just testing I didn't have the pins externally pulled down to ground so they were floating high. When I connected each pin to ground it called the associated handler.

drummin89

Just for reference.

Code: [Select]

//OUTPUTS
#define X_STEP 16 //0x10 //PORTF0, X axis "STEP" Control Bit, PORTA P16, PIN A0
#define X_DIR 24 //0x1000000 //PORTF1, X Axis "DIRECTION" Control Bit, PORTA P24, PIN A1
#define X_EN 6 //0x40 //PORTD7, X Axis "ENABLE" Control Bit, PORTC P6, PIN D38
#define Y_STEP 3 //0x8 //PORTF6, Y axis "STEP" Control Bit, PORTA P3, PIN A6
#define Y_DIR 2 //0x4 //PORTF7, Y Axis "DIRECTION" Control Bit, PORTA P2, PIN A7
#define Y_EN 23 //0x800000 //PORTF2, Y Axis "ENABLE" Control Bit, PORTA P23, PIN A2
#define Z_STEP 17 //0x20000 //PORTL3, Z axis "STEP" Control Bit, PORTC P17, PIN D46
#define Z_DIR 15 //0x8000 //PORTL1, Z Axis "DIRECTION" Control Bit, PORTC P15, PIN D48
#define Z_EN 17 //0x20000 //PORTK0, Z Axis "ENABLE" Control Bit, PORTB P17, PIN A8
#define SPINDLE_PWM 1  //PWM signal to spindle speed control, ???

//INPUTS
#define X_OVERTRAVELPROX 25  //X Axis under travel prox input, PORTB P25, PIN D2
#define X_UNDERTRAVELPROX 28  //X Axis over travel prox input, PORTC P28, PIN D3
#define Y_OVERTRAVELPROX 5  //Y Axis under travel prox input, PORTD P5, PIN D15
#define Y_UNDERTRAVELPROX 4  //Y Axis over travel prox input, PORTD P4, PIN D14
#define Z_OVERTRAVELPROX 10  //Z Axis under travel prox input, PORTA P10, PIN D19
#define Z_UNDERTRAVELPROX 11  //Z Axis over travel prox input, PORTA P11, PIN D18


The following code ran in setup configures 6 pins as GPIO, Input with filtering (debounce), pull-up disabled and interrupt disabled (enabled later)
Code: [Select]

  //ENABLE PERIPHERAL FOR CLOCKING INPUT ON FOLLOWING PORTS
  pmc_enable_periph_clk(PIOA_IRQn);
  pmc_enable_periph_clk(PIOB_IRQn);
  pmc_enable_periph_clk(PIOC_IRQn);
  pmc_enable_periph_clk(PIOD_IRQn);
  //DISABLE INTERRUPTS FOR THE FOLLOWING PINS
  PIOA -> PIO_IDR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_IDR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_IDR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_IDR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_IDR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_IDR = (0x01 << Y_UNDERTRAVELPROX);  
  //DISABLE THE INTERNAL PULL-UP FOR THE FOLLOWING PINS
  PIOA -> PIO_PUDR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_PUDR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_PUDR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_PUDR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_PUDR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_PUDR = (0x01 << Y_UNDERTRAVELPROX);
  //ENABLE INPUT FILTERING FOR THE FOLLOWING PINS
  PIOA -> PIO_IFER = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_IFER = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_IFER = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_IFER = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_IFER = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_IFER = (0x01 << Y_UNDERTRAVELPROX);
  //SET SLOW CLOCK DIVIDER (2) FOR DEBOUNCING ON ALL 4 PIO PORTS
  PIOA -> PIO_SCDR = 0x04;
  PIOB -> PIO_SCDR = 0x04;
  PIOC -> PIO_SCDR = 0x04;
  PIOD -> PIO_SCDR = 0x04;
  //ENABLE INPUT DEBOUNCING FOR THE FOLLOWING PINS
  PIOA -> PIO_DIFSR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_DIFSR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_DIFSR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_DIFSR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_DIFSR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_DIFSR = (0x01 << Y_UNDERTRAVELPROX);
  //SET THE FOLLOWING PINS AS INPUT
  PIOA -> PIO_ODR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_ODR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_ODR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_ODR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_ODR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_ODR = (0x01 << Y_UNDERTRAVELPROX);
  //SET THE FOLLOWING PINS AS GPIO (ALLOW THEM TO BE USED AS INPUT/OUTPUT)
  PIOA -> PIO_PER = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_PER = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_PER = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_PER = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_PER = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_PER = (0x01 << Y_UNDERTRAVELPROX);
  


The following code enables pin change interrupt on the 6 pins we just setup as input.
Code: [Select]
 
  //INPUT PIN CHANGE INTERRUPT CONFIGURATION
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT A
  pmc_enable_periph_clk(ID_PIOA);
  NVIC_DisableIRQ(PIOA_IRQn);
  NVIC_ClearPendingIRQ(PIOA_IRQn);
  NVIC_SetPriority(PIOA_IRQn, 0);
  NVIC_EnableIRQ(PIOA_IRQn);
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT B
  pmc_enable_periph_clk(ID_PIOB);
  NVIC_DisableIRQ(PIOB_IRQn);
  NVIC_ClearPendingIRQ(PIOB_IRQn);
  NVIC_SetPriority(PIOB_IRQn, 0);
  NVIC_EnableIRQ(PIOB_IRQn);
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT C
  pmc_enable_periph_clk(ID_PIOC);
  NVIC_DisableIRQ(PIOC_IRQn);
  NVIC_ClearPendingIRQ(PIOC_IRQn);
  NVIC_SetPriority(PIOC_IRQn, 0);
  NVIC_EnableIRQ(PIOC_IRQn);
  //ENALBE AND SET INTERRUPT PRIORITY ON PORT D
  pmc_enable_periph_clk(ID_PIOD);
  NVIC_DisableIRQ(PIOD_IRQn);
  NVIC_ClearPendingIRQ(PIOD_IRQn);
  NVIC_SetPriority(PIOD_IRQn, 0);
  NVIC_EnableIRQ(PIOD_IRQn);  
  //SET THE FOLLOWING PINS FOR PIN CHANGE INTERRUPT
  PIOA -> PIO_AIMDR = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_AIMDR = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_AIMDR = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_AIMDR = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_AIMDR = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_AIMDR = (0x01 << Y_UNDERTRAVELPROX);
  //ENABLE INTERRUPTS FOR THE FOLLOWING PINS
  PIOA -> PIO_IER = (0x01 << Z_OVERTRAVELPROX);
  PIOA -> PIO_IER = (0x01 << Z_UNDERTRAVELPROX);
  PIOB -> PIO_IER = (0x01 << X_OVERTRAVELPROX);
  PIOC -> PIO_IER = (0x01 << X_UNDERTRAVELPROX);
  PIOD -> PIO_IER = (0x01 << Y_OVERTRAVELPROX);
  PIOD -> PIO_IER = (0x01 << Y_UNDERTRAVELPROX);


And the handlers for each of the 4 ports.
Code: [Select]
void PIOA_Handler(void) {
  uint32_t isr = PIOA -> PIO_ISR;
}

void PIOB_Handler(void) {
  uint32_t isr = PIOB -> PIO_ISR;
}

void PIOC_Handler(void) {
  uint32_t isr = PIOC -> PIO_ISR;
}

void PIOD_Handler(void) {
  uint32_t isr = PIOD -> PIO_ISR;
}
code]

drummin89

Following code sets 9 pins as GPIO, Output, 6 with internal pullup enabled.
Code: [Select]
 //OUTPUT PIN CONFIGURATION
  //DISABLE INTERRUPTS FOR THE FOLLOWING PINS
  PIOA -> PIO_IDR = (0x01 << X_STEP);
  PIOA -> PIO_IDR = (0x01 << X_DIR);
  PIOA -> PIO_IDR = (0x01 << Y_STEP);
  PIOA -> PIO_IDR = (0x01 << Y_DIR);
  PIOA -> PIO_IDR = (0x01 << Y_EN);
  PIOB -> PIO_IDR = (0x01 << Z_EN);  
  PIOC -> PIO_IDR = (0x01 << X_EN);  
  PIOC -> PIO_IDR = (0x01 << Z_STEP);  
  PIOC -> PIO_IDR = (0x01 << Z_DIR);
  //ENABLE THE INTERNAL PULL-UP FOR THE FOLLOWING PINS
  PIOA -> PIO_PUER = (0x01 << X_STEP);
  PIOA -> PIO_PUER = (0x01 << X_DIR);
  PIOA -> PIO_PUER = (0x01 << Y_STEP);
  PIOA -> PIO_PUER = (0x01 << Y_DIR);
  PIOC -> PIO_PUER = (0x01 << Z_STEP);
  PIOC -> PIO_PUER = (0x01 << Z_DIR);
  //DISABLE THE INTERNAL PULL-UP FOR THE FOLLOWING PINS
  PIOA -> PIO_PUER = (0x01 << Y_EN);
  PIOB -> PIO_PUER = (0x01 << Z_EN);
  PIOC -> PIO_PUER = (0x01 << X_EN);
  //DISABLE MULTI-DRIVE FOR THE FOLLOWING PINS
  PIOA -> PIO_MDDR = (0x01 << X_STEP);
  PIOA -> PIO_MDDR = (0x01 << X_DIR);
  PIOA -> PIO_MDDR = (0x01 << Y_STEP);
  PIOA -> PIO_MDDR = (0x01 << Y_DIR);
  PIOA -> PIO_MDDR = (0x01 << Y_EN);
  PIOB -> PIO_MDDR = (0x01 << Z_EN);  
  PIOC -> PIO_MDDR = (0x01 << X_EN);  
  PIOC -> PIO_MDDR = (0x01 << Z_STEP);  
  PIOC -> PIO_MDDR = (0x01 << Z_DIR);
  //SET THE FOLLOWING PINS AS OUTPUT
  PIOA -> PIO_OER = (0x01 << X_STEP);
  PIOA -> PIO_OER = (0x01 << X_DIR);
  PIOA -> PIO_OER = (0x01 << Y_STEP);
  PIOA -> PIO_OER = (0x01 << Y_DIR);
  PIOA -> PIO_OER = (0x01 << Y_EN);
  PIOB -> PIO_OER = (0x01 << Z_EN);
  PIOC -> PIO_OER = (0x01 << X_EN);
  PIOC -> PIO_OER = (0x01 << Z_STEP);
  PIOC -> PIO_OER = (0x01 << Z_DIR);
  //SET THE FOLLOWING PINS AS GPIO (ALLOW THEM TO BE USED AS INPUT/OUTPUT)
  PIOA -> PIO_PER = (0x01 << X_STEP);
  PIOA -> PIO_PER = (0x01 << X_DIR);
  PIOA -> PIO_PER = (0x01 << Y_STEP);
  PIOA -> PIO_PER = (0x01 << Y_DIR);
  PIOA -> PIO_PER = (0x01 << Y_EN);
  PIOB -> PIO_PER = (0x01 << Z_EN);
  PIOC -> PIO_PER = (0x01 << X_EN);
  PIOC -> PIO_PER = (0x01 << Z_STEP);
  PIOC -> PIO_PER = (0x01 << Z_DIR);
  


And I will throw in some timer code as well.
The following code sets up timer 3 (TC1 CH0) to trigger a software interrupt when the timer reaches compare value RC, counter resets to zero and starts all over again.
Code: [Select]
 //TIMER 3 (FOR PULSING STEP INPUT TO STEPPER DRIVERS) SETUP
  //ENALBE INTERRUPT PRIORITY FOR TIMER 3
  pmc_enable_periph_clk(TC3_IRQn);
  NVIC_DisableIRQ(TC3_IRQn);
  //SET BITS 14 AND 15 OF TIMER COUNTER MODE REGISTER FOR TC1 CH0
  //BIT 14 = WAVESEL: Waveform Selection #2 UP_RC
  //BIT 15 = WAVE: Wareform Mode Enable
  REG_TC1_CMR0 = 0xC000;
  //SET BITS 0 AND 2 OF TIMER COUNTER CONFIGURE REGISTER FOR TC1 CH0
  //BIT 0 = ENABLE CLOCK
  //BIT 2 = SOFTWARE TRIGGER
  REG_TC1_CCR0 = 0x05;  
  //SET BIT 4 OF TIMER COUNTER INTERRUPT ENABLE REGISTER FOR TC1 CH0
  //BIT 4 = CPCS: RC Compare Interrupt Enable
  REG_TC1_IER0 = 0x10;  
  //THE FOLLOWING DISABLES ANY OTHER INTERRUPTS FOR TC1 CH0 THAT MIGHT BE ENABLED
  REG_TC1_IDR0 = 0xEF;  
  //1ms = 1000Hz, 5ms = 200Hz
  REG_TC1_RC0 = feedrate;
  //ENABLE AND SET INTERRUPT PRIORITY FOR TIMER 3
  NVIC_ClearPendingIRQ(TC3_IRQn);
  NVIC_SetPriority(TC3_IRQn, 1);
  NVIC_EnableIRQ(TC3_IRQn);


Handler for timer 3.
Code: [Select]
void TC3_Handler() {
  TC_GetStatus(TC1, 0);
}



Go Up