The code you posted was still not as simple as it should be. The file hal.h was not needed, and there were many unused macro definitions.
I simplified your code down to this:
#include <wixel.h>
#include <usb.h>
#include <usb_com.h>
#include <stdio.h>
#define T1CCTL0_IM 0x40
#define T1CCTL1_IM 0x40
#define T1CCTL2_IM 0x40
#define T1CTL_CH0IF 0x20
#define T1CCTL2_CMP 0x38
#define MAX_BUF_SZ 32
#define DATA_AQU_TIME 10
#define COOLOFF_PERIOD 6000
uint32 DATA volatile captureWindow = 0;
uint8 XDATA report[1024];
uint16 DATA reportLength = 0;
uint16 DATA reportBytesSent = 0;
uint16 DATA volatile timer1Count = 0;
void initDSM(void)
{
P1SEL = 0x02;
PERCFG = 0x40;
P1DIR = 0x02;
T1CTL = T1CTL & ~0x03;
T1CNTL = 0x00;
T1CC0H = 0x25;
T1CC0L = 0x22;
T1CTL = T1CTL & ~0x10;
T1CCTL0 = (T1CCTL0 | 0x04);
T1CCTL0 = T1CCTL0 & ~T1CCTL0_IM;
T1CCTL1 = T1CCTL1 & ~T1CCTL1_IM;
T1CCTL2 = T1CCTL2 & ~T1CCTL2_IM;
T1CC1L = 0;
T1CC1H = 0;
T1CTL = T1CTL | 0x02;
T1CCTL1 = T1CCTL1 & ~0x07;
}
void enableDSM(void)
{
EA = 0;
T1CNTL = 0x00;
T1CC1L = 0;
T1CC1H = 0;
IEN1 = IEN1 & ~0x11111101;
T1IE = 1;
OVFIM = 1;
EA = 1;
T1CCTL1 = (T1CCTL1 | 0x38);
}
void disableDSM(void)
{
EA = 0;
T1CTL &= ~0x03;
T1CCTL1 &= ~0x07;
OVFIM = 0;
T1CCTL1 = (T1CCTL1 & ~T1CCTL1_IM);
T1CCTL1 = T1CCTL1 & ~0x38;
IEN1 = IEN1 & ~0x00000010;
T1IE = 0;
EA = 1;
}
ISR(T1, 0)
{
setDigitalOutput(14, 1);
timer1Count++;
T1CTL = (T1CTL | 0xF0) & ~0x20; // Clear CH0IF.
setDigitalOutput(14, 0);
}
void updateLeds()
{
usbShowStatusWithGreenLed();
LED_YELLOW(0);
LED_RED(getMs() >> 9 & 1);
}
void putchar(char c)
{
report[reportLength] = c;
reportLength++;
}
void sendReportIfNeeded()
{
static uint32 lastReport;
uint8 bytesToSend;
// Create reports.
if (getMs() - lastReport >= 100 && reportLength == 0)
{
lastReport = getMs();
reportBytesSent = 0;
printf("hi\r\n");
}
// Send the report to USB in chunks.
if (reportLength > 0)
{
bytesToSend = usbComTxAvailable();
if (bytesToSend > reportLength - reportBytesSent)
{
// Send the last part of the report.
usbComTxSend(report + reportBytesSent, reportLength - reportBytesSent);
reportLength = 0;
}
else
{
usbComTxSend(report + reportBytesSent, bytesToSend);
reportBytesSent += bytesToSend;
}
}
}
void main()
{
uint32 triggerTime;
systemInit();
usbInit();
initDSM();
triggerTime = getMs();
while(1)
{
boardService();
updateLeds();
usbComService();
sendReportIfNeeded();
if (getMs() - triggerTime > COOLOFF_PERIOD)
{
captureWindow = triggerTime = getMs();
enableDSM();
}
if (captureWindow && ((getMs() - captureWindow) > DATA_AQU_TIME))
{
disableDSM();
}
}
}
By adding the line LED_RED(getMs() >> 9 & 1);
in updateLeds and observing the red LED, I found out that something went wrong after the program had been running for a few seconds: either the main loop stopped running or the getMs() function stopped working.
I noticed the following incorrect lines of code in your program:
IEN1 = (IEN1 & ~0x11111101); // Enable T1 int mask
IEN1 = (IEN1 & ~0x00000010); // Disable Timer 1 Interrupt
I think these lines are attempting to set or clear the T1IE bit in the IEN1 register, but there are many problems with them.
To write a binary constant in C, you should use the 0b
prefix instead of 0x
. To set a bit, you should use the binary OR operator (|
) instead of using &
and ~
. To enable the Timer 1 interrupt, you need to set the bit to 1, not 0. With all that advice taken together, the correct lines would have been:
IEN1 = (IEN1 & 0b11111101); // Disable Timer 1 interrupt
IEN1 = (IEN1 | 0b00000010); // Enable Timer 1 Interrupt
However, IEN1 is a special register: because its address is a multiple of 8, the 8051 architecture allows us to directly read and write from individual bits inside it, such as T1IE. So you can simply write:
T1IE = 0;
T1IE = 1;
You already have lines of code that are writing to T1IE this way, so the problematic lines of code that attempt to modify IEN1 are not needed. Removing those lines makes the problem go away.
The first problematic line has many unintended side effects, such as clearing T4IE. Clearing T4IE would prevent the Wixel’s timing functions like getMs from working, and that could be what caused the issue.
–David