Gpio3 as INT0

Hiya,

Apologies for my earlier post indicating I had it working - I had misunderstood your problem (I thought that the adl_extIntSubscribe() call was failing). Sorry about that.

I’ve got your code working now on a Q2686H and dev kit.

First, INT0/GPIO3 is 1V8 tolerant I/O.

Second, I modified your MyExtIntIrqHandler() code to remove ALL the references to adl_atSendResponse(). See the code below:

static bool MyExtIntIrqHandler ( adl_irqID_e Source, 
								adl_irqNotificationLevel_e NotificationLevel, 
								adl_irqEventData_t * Data )
{
	// WARNING: low level execution context
//   adl_atSendResponse ( ADL_AT_UNS, "\r\n i am in interrupt  handlers \r\n" );
	// Increase counter
	irq_EXTINTCounter++;
	adl_extintInfo_t * pData = (adl_extintInfo_t*)Data->SourceData;

	TRACE (( 1, "Entering EXTINT interrupt handler (notified %d times)", irq_EXTINTCounter ));
/*
	if (pData->PinState)
	   adl_atSendResponse ( ADL_AT_UNS, "\r\n interrupt 1 handlers \r\n" );
	else
	   adl_atSendResponse ( ADL_AT_UNS, "\r\n  interrupt 0 handlers \r\n" );
*/
	return FALSE;
}

Note that the ADL user guide for R7.4 says in section 3.3.3.4 that the adl_atSendResponse() function will fail with a return code of ADL_RET_ERR_SERVICE_LOCKED if the function was called from a low level interrupt handler.
Remember that this is a low level interrupt handler and time is tight - so just do the bare essentials that are required. In my code where I have used the IRQ, I simply send message with the appropriate data (using adl_msgSend()) to myself where further processing is done.

Finally, to get the traces from the interrupt handler to appear, you have to enable trace level 1 in the LLH trace flow.

ciao, Dave

a bundle of thanks , now it is running fine .

u really taught me one more things I didn’t know about LLH traces before and how to enable it

regards

Yes - it caught me out, too: viewtopic.php?f=21&t=3462&p=15429&hilit=llh+hlh#p15429 :blush:

Hiya,

Cool. Glad that we managed to work it out.

Trace flow LLH & HLH are only for the M2M studio Target Management Perspective. If you are using the old TMT from an early version of Oasis, then the Interrupt traces come out on some non-intuitive flow. Not 100% certain, but there’s a cryptic note in my code indicating that it’s either the EXT2 or EXT4 flow…

ciao, Dave

I was finding them on LLH and HLH in TMT!

That was the most recent TMT before M2MS - maybe you’re thinking of an earlier version?
Or maybe it’s different in older firmware versions?

Hiya,

Probably an earlier version. Certainly in EXT2 or EXT4 in Oasis 2.02 - which is where I first started testing my external interrupt code. I myst have done something right with the code, as it’s continued to work through all the OpenAT 2.xx revisions :wink: Maybe I shouldn’t say to much though…

ciao, Dave

hi Dave,

i am trying to use IRQ_Measure.c in my own application,bUt The problem is that after regular intervals its restart. displaying msg watchdog timer reset.please tell me where i m doing wrong “i havent made any change in IRQ_Measure.c”,
just try to use it.
On the other Hand IRQ_Measure is used alone it works fine but when try to use it in my Own application and calling it as i did it it gives me watch dog reset msg.

void adl_main ( adl_InitType_e InitType )
{
    TRACE (( 1, "Embedded Application : Main" ));
    ascii a[2] = "2";
    ascii b[2] = "5";
   // write_i2c("01","FF");
    irq_main (  ADL_INIT_POWER_ON ); //void irq_main ( adl_InitType_e InitType )

    while(1)
    {
     if(INT_EN)
     {
    	TRACE (( 1, "INT ENABLE" ));
        read_i2c(a,b);
        write_i2c("01","FF");
        INT_EN = 0 ;
     }
    }

    // TO DO : Add your initialization code here
}

that’s because your application hangs the module.
Open AT is event driven. you can’t do the above!

sorry i am confused what you are saying

I have initialize IRQ earlier and then wait in while(1) loop,and in “while(1)” loop i am waitng for INTEN to occur.

Hiya,

You CANNOT use the following constructs in OpenAT without causing a watchdog reset on the module:

while(1)
{
    // do something
}

or

do
{
    // do something
} while (1);

or any other type of busy-wait (polling) loop.

Open AT is an event driven application, as the CPU shares the time between the GSM Radio firmware and your application. As there are strict criteria for dealing with the GSM network, your application gets runs when the CPU is not busy servicing the Radio firmware.

If you are used to programming microcontrollers, you can compare an application in the OpenAT environment to writing a completely interrupt driven application in the embedded micro. You have to register event handlers (interrupt handlers) and service the events (interrupts) when they arrive - not sit and tie up the CPU doing nothing while waiting. If you must poll (i.e. looking at an input), set up a timer and check the state each time the timer times out.

Hope this helps.

ciao, Dave

If it’s specifically for an input, then the ADL GPIO service can do the polling for you - and raises an event when any change is detected

Hiya,

I knew you were going to say that :slight_smile:
You’re right - there is NO reason to BUSY/WAIT or POLL in OpenAT.
Everything can (must :exclamation: ) be done using events.

And another one for the FAQ: viewtopic.php?f=7&t=3766&p=16098#p16098

ciao, Dave

Now me freeze now
plz give me some idea, i have to read from data from Micro controller via I2C,
from where i should call that?
previously i had declare a variable in Interrupt handler,when it is set i made a plan to call my i2c readfunction.

while(1)
{
if(INT_EN)
readi2c();
}

then tell me any idea when INT comes then i call my readi2c function …

Look at the sample!

You get an Event when the GPIO changes state - so start your I2C operation in the Handler for that Event!

I think you need to go back and take a look through several samples to see how this Event-Driven stuff works.

It’s all to do with Events, so everything needs to be done in the Handlers for those Events.

I am using IRQ_measure.c application to encounter any Interrupt occur on INTO . I am not using GPIO SERVICE…
can i call that (I2C READ)function from MyExtIntIrqHandle ,
i am trying to do so but it doesnt read ?

Hiya,

I mentioned this before.

Your extInt handler needs to be as short and tight as possible. In your extInt handler, send a message (using adl_msgSend()) to yourself when the GPIO fires the interrupt. In the message event handler, do your I2C read/Write

Anyway, you can’t do an adl_busSubscribe() or adl_busRead() from inside an interrupt handler - both functions will return ADL_RET_ERR_SERVICE_LOCKED if the function was called from a low level interrupt handler in synchronous mode. Check out the API doco for more details.

Or give up on the extInt service, and use the GPIO change event to do the same thing (as awneil suggests). Since your I2C is running at a maximum of 400kHz, you should have plenty of time to service your I2C device.

ciao, Dave

I still don’t think you’ve explained why you’re not using the GPIO Service :question:

Given that at least some of your problems seem to be specifically due to using the Interrupt Service, perhaps you should review this choice :question:

If you would explain why you feel the need for an interrupt, people may be able to confirm whether you are correct, or if you have misunderstood and are just causing yourself unnecessary grief!

i have done exactly same that as u told me but now “drv_I2C_E2P_M24CXX_Read ( ReadBuff, AsyncReadCtxt” in I2C is giving me error. ? ? ? or if i run I2C code alone it is ok.

What error, precisely, is it giving you?? :unamused:

actually by calling this function “drv_I2C_E2P_M24CXX_Read ( ReadBuff, AsyncReadCtxt” it has to return me zero “0” on return but it is returning positive value .