Author Topic: Periodic Interrupt Simulation  (Read 10295 times)

Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Periodic Interrupt Simulation
« on: November 06, 2009, 12:22:14 PM »
Hello,
I want to use the simulator for an RTC component, delivering periodic signal on interrupt pin.
How can I do that with simulator ?
Thanks

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Periodic Interrupt Simulation
« Reply #1 on: November 06, 2009, 02:03:04 PM »
Hi Hervé

There is no fully integrated simulation of this type but it is quite easy to add.

1) In fnSimTimers() in LPC23XXSim.c (or equivalent for any other target), which will be entered on each TICK, add

    if (fnCheckRTC()) {                                                // check external RTC
        TOGGLE_RTC_INPUT();
    }


2) Check in IIC_dev.c and you will find the fnCheckRTC() routine (maybe it is not correct for your RTC device but you can adapt it to suit - it simply checks whether the RTC output has been programmed and generates the periodic signal at the correct rate).

3) Define TOGGLE_RTC_INPUT() accordingly so that each periodic interrupt period causes the corresponding interrupt pin to be changed (you will then see the periodic interrupt toggling the processor port and, assuming interrupts correctly configured, you will also get the interrupt handler being called).

An example of the define is (assuming the IRQ input is on port 2, bit 17)
#define TOGGLE_RTC_INPUT() fnSimulateInputChange(PORT_2, fnMapPortBit(PORT2_BIT17), TOGGLE_INPUT)




An alternative (but not very practical method) is to use a port input simulation. For example, create a file called something like
simRTC_int.sim with content

+0     PORT-2-17      0                  // set input to '0'
+500 PORT-2-17      1                  // set input to '1'
+500 PORT-2-17      0                  // set input to '0'
+500 PORT-2-17      1                  // set input to '1'
+500 PORT-2-17      0                  // set input to '0'
+500 PORT-2-17      1                  // set input to '1'
+500 PORT-2-17      0                  // set input to '0'
+500 PORT-2-17      1                  // set input to '1'

etc.

When the file is loaded it will then cause the single input to be toggled once every 500ms.

Finally, if simply a quick test of the interrupt is required, you can click on the corresponding port to cause it to toggle and so test single interrupts.

Regards

Mark

P.S. If I remember correctly you are using an LPC. Why don't you use its internal RTC? (assuming you are using one with an internal RTC). This will also generate periodic interrupts (seconds, minutes, hours etc.) which I have also fully integrated into the development project.

« Last Edit: November 06, 2009, 02:04:58 PM by mark »

Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: Periodic Interrupt Simulation
« Reply #2 on: November 09, 2009, 03:17:22 PM »
Hello Mark,

Thanks a lot for your help, it's so easy when you explained it.
Every thing is mostly working....for this part atleast

In fact I'm using some PIA_I2C on channel 1 and RTC_I2C on channel 2
There's a problem with the simulator which doesn't allow simultaneous communication (even if on different channel) :
In fact the following function resets the internal state of the component no matter the channel it used....
Code: [Select]
       fnResetOthers((unsigned char)(ucData & ~0x01)); I think another parameter is required on both function and structure, to reset only the other components of the same channel ? Isn't it?


(I use external RTC because of higher power consumption of the lpc23xx)



Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3236
    • View Profile
    • uTasker
Re: Periodic Interrupt Simulation
« Reply #3 on: November 09, 2009, 05:12:59 PM »
Hi Hervé

Yes you are right about the simulator. It only handles full operation of one single I2C interface. If you have multiple I2C devices connected to one I2C bus there is no problem but putting devices on different buses cause a problem when they are accessed at the same time. Furthermore, putting the same device on more than one I2C interface would result in each interface communicating with the same device...

The solution would be to make in 'incarnation' of each device for each I2C bus so that they are fully independent. It shouldn't be difficult to do - just make an array of each device and select the device using its I2C number from the array.

i will put this on the 'to do' list because there are several processor types in the uTasker project which do have multiple I2C buses and it would be useful to be able to fully simulate them.

Regards

Mark

PS. I believe that each I2C device can also only be present on each bus once (with a fixed address). It would of course be even better if multiple parts of the same type (eg. multiple EEPROMs) could be used, each configured with its own I2C address.....

Offline hervé

  • Jr. Member
  • **
  • Posts: 98
    • View Profile
Re: Periodic Interrupt Simulation
« Reply #4 on: November 09, 2009, 05:53:06 PM »
Thanks Mark,

Do continue my test I made the following changes :

Code: [Select]
unsigned char fnSimIIC_devices(QUEUE_HANDLE Channel,unsigned char ucType, unsigned char ucData) { //add Channel parameter
....
        fnResetOthers(Channel,(unsigned char)(ucData & ~0x01));//CHG//HP//091109//
....
        fnResetOthers(Channel,0);
....
}

and

Code: [Select]
static void fnResetOthers(QUEUE_HANDLE Channel,unsigned char ucAddress) { //add Channel parameter
....
    if ((ucAddress != simDS1340.address)&&(Channel == simDS1340.channel)) {
        simDS1340.ucState = 0;
    }
    if ((ucAddress != simPCF8574[0].address)&&(Channel == simPCF8574[0].channel)) {
        simPCF8574[0].ucState = 0;
    }
    if ((ucAddress != simPCF8574[1].address)&&(Channel == simPCF8574[1].channel)) {
        simPCF8574[1].ucState = 0;
    }
    if ((ucAddress != simPCF8574[2].address)&&(Channel == simPCF8574[2].channel)) {
        simPCF8574[2].ucState = 0;
    }
...
}
Of course I also added the same variable name on the differents structures :

Code: [Select]
typedef struct stDS1340
{     
unsigned char  channel; //<< added
unsigned char  address;
unsigned char  ucState;
unsigned char  ucRW;
unsigned char  ucInternalPointer;

    TIME_BLOCK     bTime;
} DS1340;

static DS1340 simDS1340 = {0,0xd0, 0};//<< channel 0:


#define ADDRESS_PCF8574_1  0x40
#define ADDRESS_PCF8574_2  0x42
#define ADDRESS_PCF8574_3  0x44

typedef struct stPCF8574
{     
unsigned char  channel;   // << added
unsigned char  address;
unsigned char  ucState;
unsigned char  ucRW;
unsigned char  ucOutput;
} PCF8574;

static PCF8574 simPCF8574[3] = {  //<< channel 1 for all
{1,ADDRESS_PCF8574_1, 0},
{1,ADDRESS_PCF8574_2, 0},
{1,ADDRESS_PCF8574_3, 0} };


Thanks for your comments.