• 0

Wi-Fire external ADC with Timer2 interrup problem


c64

Question

Hi,

I'm using the ChipKit Wi-Fire board where I use an external ADC to capture data and transmit it over the SPI channel based on the Timer2 interrupt. Getting the Timer2 interrupt and ADC capture to work independently is no problem, it's only when I combine them together that something halts in an odd way. Below is my code, and basically, for testing purposes, I sample 50 samples, after which the Timer2 is disabled and I print out the numbers on the serial monitor. In the interrupt routine I set an interrupt flag, which will be caught in the main loop. 

/*
 CS: pin 10
 MOSI: pin 11
 MISO: pin 12
 SCK: pin 13
 */

#include <DSPI.h>
#include <xc.h>             /* contains Vector Name/Number Macros */
#include <sys/attribs.h>    /* contains __ISR() Macros */

DSPI0 spi;
const uint8_t chipSelect = 10;
uint8_t i;
uint16_t buffer[50];

uint16_t num1;
uint8_t num2;
const uint32_t SPI_frequency = 8000000;

volatile uint8_t interrupt_flag;
volatile uint8_t sample_counter;

/* Define the Interrupt Service Routine (ISR) */
void __attribute__((interrupt)) myISR() {
  interrupt_flag = 1;
  clearIntFlag(_TIMER_2_IRQ);
}

void setup() {
  pinMode(4, OUTPUT);
  pinMode(chipSelect, OUTPUT);
  digitalWrite(chipSelect, HIGH);
  spi.begin();
  spi.setTransferSize(DSPI_16BIT);
  spi.setSpeed(SPI_frequency);
  Serial.begin(9600);

  interrupt_flag = 0;
  sample_counter = 0;

  setIntVector(_TIMER_2_VECTOR, myISR);
  setIntPriority(_TIMER_2_VECTOR, 4, 0);
  clearIntFlag(_TIMER_2_IRQ);
  setIntEnable(_TIMER_2_IRQ);
  start_timer_2();
}

void start_timer_2(void) {
  T2CONbits.TON = 0;         /* Turn the timer off */
  T2CONbits.TCKPS = 7;        /* Set the prescaler  */
  TMR2 = 0;                 /* Clear the counter  */
  PR2 = 39062; // 10 kHz             /* Set the frequency     */
  T2CONbits.TON = 1;         /* Turn the timer on  */

} 

void loop() {
  
  if(interrupt_flag == 1)
  { 
    digitalWrite(4, !digitalRead(4));
    digitalWrite(chipSelect, LOW);
    //num1 = spi.transfer(0x00);
    //digitalWrite(chipSelect, HIGH);
    buffer[i] = (uint8_t)(num1 >> 5);
    i++; 
    interrupt_flag = 0;
    sample_counter++;
    Serial.println(sample_counter, DEC);
  }

  if(sample_counter == 10)
  {
    // Disable interrupts from Timer 2
    IEC0bits.T2IE = 0;
    // Disable the peripheral
    T2CONbits.TON = 0;

    for(i = 0; i < 10; i++)
    {
      Serial.print(buffer[i], BIN);
      Serial.print("\t");
      Serial.println(buffer[i], DEC);
    }
    while(1);
  }

}

 

This code doesn't work as intended, it seems to halt. The problem is the "if(interrupt_flag == 1)" part, which is only being called once, and then nothing more happens.  Instead, if my routine in the main loop, in case of an interrupt, looks like this:

 

  if(interrupt_flag == 1)
  { 
    digitalWrite(4, !digitalRead(4));
    //digitalWrite(chipSelect, LOW);
    //num1 = spi.transfer(0x00);
    //digitalWrite(chipSelect, HIGH);
    buffer[i] = (uint8_t)(num1 >> 5);
    i++; 
    interrupt_flag = 0;
    sample_counter++;
    Serial.println(sample_counter, DEC);
  }

it works. Here I use GPIO 4 to give a square pulse train which I can monitor on an oscilloscope, and the serial monitor prints out all 0s, as expected. I've tested the Timer2 interrup as well as the external ADC reading through SPI separately, and they both work on their own. It just seems to fail when I combine them.

Any ideas?

Edited by JColvin
tags
Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 0

Hi,

Thanks, but I figured it out, I think. If using Timer3 instead it all works as expected. I think there's a conflict with Timer2 (and some PWM thing which is 'on' on default) and pin 10, which is used as SPI chip select.

Link to post
Share on other sites
  • 0

That's what I was initially thinking as well, but when I was looking through at what pins the Timer2 and SPI used, they didn't appear to have any conflict (Timer2 seemed to use pin 5), so I wasn't sure what the problem might have been. But if Timer3 works out for you, then go for it.

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now