Wait untill interrupt value changes

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Hi,

I am working on 8-bit microcontroller. I have to do data transfer when /INT value is high. After transfer of 16-bit , /INT will change high to low and then again high. Next 16-bit will be transferred only when /INT is high. My PIC is master and slave is handling the /INT. PIC has to watch this /INT to initiate data transfer. How to implement this ? My idea is
Code:
uint8_t exchange8bit(int data){
            SSPBUF = data;
            while(/INT ==1){
            while(SSPSTATAbits.BF ==  0x00)
            {
             }
              return SSPBUF;
       }
       return error; 
}
Is it sufficient. Above needs to be called two times to transfer 16-bits and then again check /INT has become high or not? Not sure how to keep watch on the high, low, high transition of /INT.

--Sarvanan.
 

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Hi Dannyf . . . Pic will keep watching the INT line and it will transfer data only when INT line is high . Once 16 bit data is transferred INT line will go low for minimum of 1 micro second. Pic will not be able to send or receive data . Once INT line goes high pic will start sending or receiving data . . Please let me know how to implement this as in code mentioned in my previous mail .

--Sarvanan
 

jpanhalt

Joined Jan 18, 2008
11,087
What else is the Master doing? Is the slave a sensor with only one function?

Some thoughts:
1) A simple approach, which will waste the master for other purposes, is simply to poll the interrupt flag that is set upon receipt of the interrupt or the signal line from the slave. Then get the data and transmit, print, or do whatever and return to the polling.
2) If the master will have other functions, then consider:
A. Create a loop to do that other stuff and test the flag and/or interrupt line periodically.
B. Use the interrupt signal as an interrupt and upon interrupt, either: (1) Get the data, do whatever and either return to the point at which the interrupt occurred; or (2) Upon interrupt do some quick house keeping and return to some other point in the program, e.g, getting the data, transmitting, etc. That latter approach (going to another point in the program) will require that you manage the stack, if that other point does not go to a reset that will fix the stack for you. The former (do everything within the interrupt) has the potential for spending a lot of time in the interrupt.
C. Set up periodic interrupts with one of the timers. Then test the interrupt signal from the slave and proceed by one of the methods described above.

John
 

dannyf

Joined Sep 13, 2015
2,197
Please let me know how to implement this as in code mentioned in my previous mail .
How you do it depends on your particular requirement.

The simplest would be something like this:

If fallingedge(int) then sendspi8(dat1), sendspi8(dat2)

You just need to fill in watch of the routines. And you are done.
 

dannyf

Joined Sep 13, 2015
2,197
Code:
If fallingedge(int) then sendspi8(dat1), sendspi8(dat2)
Here is an example of how this could work:

Code:
i
//read int, return 1 for falling edge
uint8_t intfalling(void) {
    static uint8_t int_port=0;                //previous value of int_port
    uint8_t tmp = int_port;                    //save previous port states

    int_port = IO_GET(INT_PORT, INT);        //retain current states
    return (tmp ^ int_port) & tmp;            //return 1 if tmp <> int_port and tmp is high -> falling edge
}

int main(void) {
    uint16_t dat = 0x1234;                    //spi data to be sent, msb first
    mcu_init();                                //reset the mcu
    spi_init();                                //reset the spi pins
    IO_IN(INT_DDR, INT);                    //INT as input
    while(1) {
        if (intfalling()) {                    //falling edge detected
            spi_write(dat >> 8);            //send msb
            spi_write(dat);                    //send lsb
            dat+=1;                            //increment dat
        }
    }

    return 0;
}
The code detects a falling edge on the INT pin and then sends out two bytes. After that, it waits for the INT pin to fall again.

the first picture shows the transmission of two bytes - you can see that the msb is 0x12;

the 2nd picture shows multiple transmission following their respective falling edges.

Again, how you implement it is specific to your application.

attiny85_spi.PNG attiny_spi2.PNG
 

Thread Starter

sarvanan

Joined Aug 8, 2016
45
Hi dannyf

Thanks a lot for the detailed explanation. I am using xc8 so I will modify the above code as given below .
Code:
//read int, return 1 for falling edge
uint8_t intfalling(void) {
    static uint8_t int_port=0;                //previous value of int_port
    uint8_t tmp = int_port;                    //save previous port states

    [COLOR=#ff4d4d]int_port = IO_RB0_GetValue();        //retain current states  (PORTBbits.RB0)[/COLOR]
    return (tmp ^ int_port) & tmp;            //return 1 if tmp <> int_port and tmp is high -> falling edge
}

int main(void) {
    uint16_t dat = 0x1234;                    //spi data to be sent, msb first
    mcu_init();                                //reset the mcu
    spi_init();                                //reset the spi pins
    [COLOR=#ff4d4d]INT = TRISBbits.TRISB0;                 //INT as input  (RB0 is the interrupt line)[/COLOR]
    while(1) {
        if (intfalling()) {                    //falling edge detected
            spi_write(dat >> 8);            //send msb
            spi_write(dat);                    //send lsb
            dat+=1;                            //increment dat
        }
    } 
    return 0;
}
I have marked the changes in red. Only two lines change. Let me know if any issue is there.
Also let me know if I have to send four different words after checking the INT line every 1 word transfer what modification needs to be done.

Thanks & regards,
Sarvanan.
 
Top