Hi guys,
working on a project here with a TLC5917 and need to drive it at a particular rate to be compatible with other equipment. The code works, but the ISR is too slow. I need this to fire off every 17uS but getting the execution time below this is proving difficult. (I can see that the interrupts are stacking up on the oscilloscope by monitoring the frequency of the CLK pin which as you will see, toggles on every call to the the ISR). By throwing my ISR into a loop on it's own, it seems to take around 100us give-or-take to execute.
Any tips or advice would be most appreciated.
#include <TimerOne.h>
#define SDI 2
#define CLK 3
#define LE 4
#define OE 5
uint8_t DATA_LENGTH = 3;
uint8_t DATA_BUF[3] = {0x55, 0x55, 0x55};
unsigned long cycleNo = 0;
uint8_t oddCycle = 0;
void setup()
{
pinMode(SDI, OUTPUT);
pinMode(CLK, OUTPUT);
pinMode(LE, OUTPUT);
pinMode(OE, OUTPUT);
//Timer1.initialize(17);
}
void loop()
{
Timer1.attachInterrupt( sendDataISR );
delay(1000);
}
void sendDataISR()
{
if(cycleNo == (240 * DATA_LENGTH)) //(24 cycles per bit, 10 bits per byte)
{
Timer1.detachInterrupt();
bitClear(PORTD, SDI);
bitClear(PORTD, CLK);
bitClear(PORTD, LE);
bitSet(PORTD, OE);
cycleNo = 0;
return;
}
//CLK
oddCycle = cycleNo % 2;
if(oddCycle) //If odd cycle
bitSet(PORTD, CLK);
else
bitClear(PORTD, CLK);
//SDI
uint8_t rawBitNo = cycleNo / 24; //when bytes are combined
uint8_t curBitNo = rawBitNo % 10; //10 bits per byte
uint8_t curByteNo = rawBitNo / 10; //^^^^
switch(curBitNo)
{
case 0:
bitClear(PORTD, SDI);
break;
case 9:
bitSet(PORTD, SDI);
break;
default:
if(DATA_BUF[curByteNo] & (1 << curBitNo - 1))
bitSet(PORTD, SDI);
else
bitClear(PORTD, SDI);
break;
}
//LE
uint8_t div = cycleNo % 24;
if(div >= 20 && div < 22)
bitSet(PORTD, LE);
else
bitClear(PORTD, LE);
//OE
if((cycleNo > 24) && oddCycle)
bitClear(PORTD, OE);
else
bitSet(PORTD, OE);
cycleNo++;
}