EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Timer B

Started by james_r_hebert May 25, 2006
I am trying to write some code that will go to an interrupt and do
some I2C stuff. I cant seem to get the code to go anywhere past the

WrPortI(TBCSR, &TBCSRShadow, 0x02);

when I have the interrupt with the I2C stuff in there. When I use just
a simple increment it works. But not with I2C. any help would be
greatly appreciated. Code Below.

Ryan

Code:

#class auto

// Set equal to 1 to use fast interrupt in I&D space
#define FAST_INTERRUPT 0

//I2C config stuff
#define I2CSCLBit 4
#define I2CSDABit 5
#define i2cClockStretchDelay 2000
#use "i2c_devices.lib"

//number of milliseconds to wait between write operations
#define WAIT_TIME 1000

//I2C device address of EEPROM chip
#define EEPROM_WRITE_ADD 0xA2
#define EEPROM_READ_ADD 0xA3

void timerb_isr();
long count, t;
int retval;
char data[33];

long bcd2long(unsigned char * dst, unsigned char len)
{
long c;

c = 0;
while (len-- > 0) {
c = c * 100 + (*(dst+len) >> 4) * 10 + (*(dst+len) & 0x0F);
}

return c;
}

void main()
{
count = 0;
i2c_init();
memcpy(data,"\0",33);

WrPortI(SPCR, &SPCRShadow, 0x84); // enable port A for outputs
#if __SEPARATE_INST_DATA__ && FAST_INTERRUPT
interrupt_vector timerb_intvec timerb_isr;
#else
SetVectIntern(0x0B, timerb_isr); // set up ISR
SetVectIntern(0x0B, GetVectIntern(0xB)); // re-setup ISR to show
example of retrieving ISR address
#endif

WrPortI(TBCR, &TBCRShadow, 0x01); // clock timer B with (perclk/2) and
// set interrupt level to 1

WrPortI(TBM1R, NULL, 0x00); // set initial match!
WrPortI(TBL1R, NULL, 0x00);

WrPortI(TBCSR, &TBCSRShadow, 0x02); // enable timer B and B1 match
interrupts

while (count < 80000) {

printf("count = %ld\n", count);

}

WrPortI(TBCSR, &TBCSRShadow, 0x00); // disable timer B and its interrupts
}

/*
nodebug root void timerb_isr()
{
retval = I2CWrite(EEPROM_WRITE_ADD, 0, " ", 1);
retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);
t = MS_TIMER;
while((long)(MS_TIMER - t) < WAIT_TIME);
retval = I2CRead(EEPROM_WRITE_ADD, 0, data, 4);
count = bcd2long(&data[1],3);
retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);
}
*/

nodebug root void timerb_isr()
{
count++;
}





james_r_hebert wrote:
> I am trying to write some code that will go to an interrupt and do
> some I2C stuff. I cant seem to get the code to go anywhere past the
>
> WrPortI(TBCSR, &TBCSRShadow, 0x02);
>
> when I have the interrupt with the I2C stuff in there. When I use just
> a simple increment it works. But not with I2C. any help would be
> greatly appreciated. Code Below.
>
> Ryan
> nodebug root void timerb_isr()
> {
> retval = I2CWrite(EEPROM_WRITE_ADD, 0, " ", 1);
> retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);
> t = MS_TIMER;
> while((long)(MS_TIMER - t) < WAIT_TIME);
> retval = I2CRead(EEPROM_WRITE_ADD, 0, data, 4);
> count = bcd2long(&data[1],3);
> retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);
> }
> */
>
> nodebug root void timerb_isr()
> {
> count++;
> }
>
You ned to define the interrupt routine as an interrupt

nodebug interrupt timerb_isr()
{
}


------
| Scott G. Henion| s...@shdesigns.org |
| Consultant | Stone Mountain, GA |
| SHDesigns | PGP Key 0xE98DDC48 |
| http://www.shdesigns.org |
------
today's fortune
Which is worse: ignorance or apathy? Who knows? Who cares?





Scott Henion wrote:
>
> You ned to define the interrupt routine as an interrupt
>
> nodebug interrupt timerb_isr()
> {
> }
>
You also need to ack the interrupt by reading the TBCSR and load new
value in the TBM1R and TBL1R.

--
------
| Scott G. Henion| s...@shdesigns.org |
| Consultant | Stone Mountain, GA |
| SHDesigns | PGP Key 0xE98DDC48 |
| http://www.shdesigns.org |
------
today's fortune
Sooner or later you must pay for your sins.
(Those who have already paid may disregard this cookie).
Well after reading about your timerb library, I decided to give it a
try. When I use the interrupt with the simple counter++ it works no
problem. But when I try and use the interrupt with the i2c stuff, it
doesnt want to get past..

TimerBInit(ussec,2);
timer=TimerBRate();

this is what I have, any ideas?..

#class auto

// Set equal to 1 to use fast interrupt in I&D space
#define FAST_INTERRUPT 0

//I2C config stuff
#define I2CSCLBit 4
#define I2CSDABit 5
#define i2cClockStretchDelay 2000
#use "i2c_devices.lib"

//number of milliseconds to wait between write operations
#define WAIT_TIME 1000

//I2C device address of EEPROM chip
#define EEPROM_WRITE_ADD 0xA2
#define EEPROM_READ_ADD 0xA3

#use "timerb.lib"
#define TIMER_DEBUG

unsigned long count, t, ussec;
float timer;
int retval;
char data[33];

void TimerBRoutine();

long bcd2long(unsigned char * dst, unsigned char len)
{
long c;

c = 0;
while (len-- > 0) {
c = c * 100 + (*(dst+len) >> 4) * 10 + (*(dst+len) & 0x0F);
}

return c;
}

void main()
{
count = 0;
ussec = 10000;
i2c_init();
memcpy(data,"\0",33);

TimerBInit(ussec,2);
timer=TimerBRate();
printf("Actual Timer ints are: %f usec err=%f%%\n",timer,
100.0*(timer-ussec)/ussec);

while (count < 10000) {
printf("count = %ld\n", count);
}
TimerBUninit();
exit(0);
}
nodebug root void TimerBRoutine()
{
retval = I2CWrite(EEPROM_WRITE_ADD, 0, " ", 1);
retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);
t = MS_TIMER;
while((long)(MS_TIMER - t) < WAIT_TIME);
retval = I2CRead(EEPROM_WRITE_ADD, 0, data, 4);
count = bcd2long(&data[1],3);
retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);
}

/*
nodebug root void TimerBRoutine()
{
count++;
}
*/

James --

bad form to wait for MS_TIMER to increment inside an ISR.
Since interrupts are not serviced while in the ISR, the
variable's value will not change.

If you really want milliseconds, perhaps you could have a 1/0
indicator in your code. WHen 0, it does the first half,
when 1 does the second half... You've built a tiny state machine!
kindest regards,
*the other brian

long tbr_next_time;
int tbr_state = 0;

nodebug root void TimerBRoutine()
{
switch(tbr_state)
{
case 0 :
retval = I2CWrite(EEPROM_WRITE_ADD, 0, " ", 1);
retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);
tbr_next_time = MS_TIMER + WAIT_TIME; // Set a `done' time.
tbr_state = 1;
break;

case 1 :
/* Has enough time passed? if not, return. */
if((long)(MS_TIMER - tbr_next_time) < 0 ) return;

/* OK to read result! */
retval = I2CRead(EEPROM_WRITE_ADD, 0, data, 4);
count = bcd2long(&data[1],3);
retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);
tbr_state = 0;
}

} /* end TimerBRoutine() */

---------- Original Message ----------------------------------
From: "james_r_hebert"
Reply-To: r...
Date: Thu, 25 May 2006 20:51:28 -0000

>
>Well after reading about your timerb library, I decided to give it a

>try. When I use the interrupt with the simple counter++ it works no

>problem. But when I try and use the interrupt with the i2c stuff, it

>doesnt want to get past..

>

> TimerBInit(ussec,2);

> timer=TimerBRate();
>nodebug root void TimerBRoutine()

>{

> retval = I2CWrite(EEPROM_WRITE_ADD, 0, " ", 1);

> retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);

> t = MS_TIMER;

> while((long)(MS_TIMER - t) < WAIT_TIME);

> retval = I2CRead(EEPROM_WRITE_ADD, 0, data, 4);

> count = bcd2long(&data[1],3);

> retval = I2CWrite(EEPROM_WRITE_ADD, 1, "\0\0\0", 3);

>}

>



Sent via the KillerWebMail system at mail.value.net








Memfault Beyond the Launch