Have a problem with sending data through SPI in Virtual Driver header. Symptoms are as same as I had when I just started to work with SPI and used wrong driver. Can't figure out how to solve it.
Shortly, what I need. I'm using OLED display in my design and since it has limited time of life, I want to switch off the display. So, after showing text on the display, I want to switch on the display, run virtual timer, dim the display after 1 sec and switch off after the next 1 sec.
Here is part of my code
Code: Select all
uint8_t dt_data[2];
void hDisplayTimer(void *arg);
static uint8_t DisplayState = DISPLAYOFF;
static struct VirtualTimer DisplayTimer;
void UI_Send(ui_msg *msg, uint8_t *data, int cnt, ...)
{
va_list ap;
uint8_t i, checkcmd = 0, tag;
int indata;
uint32_t address;
va_start(ap,cnt);
indata = va_arg(ap, int);
msg->tag = (uint8_t)indata;
tag = msg->tag;
switch (tag)
{
....
}
chMsgSend(UI_Console,(msg_t)msg);
if(tag==DISPLAY_TXT)
{
DisplayState = DISPLAYON;
dt_data[0] = DISPLAY_CMD;
dt_data[1] = DisplayState;
spiAcquireBus(&SPID2);
spiStart(&SPID2, &display_cfg);
UISendData(&SPID2, 2, dt_data); // <<<--- here it works without any problem
spiReleaseBus(&SPID2);
chVTSet(&DisplayTimer, S2ST(1), hDisplayTimer, NULL);
}
}
void hDisplayTimer(void *arg)
{
switch(DisplayState)
{
case DISPLAYON: DisplayState = DISPLAYDIM;
break;
case DISPLAYDIM: DisplayState = DISPLAYOFF;
break;
case DISPLAYOFF:
default: DisplayState = DISPLAYOFF;
break;
}
dt_data[0] = DISPLAY_CMD;
dt_data[1] = DisplayState;
spiAcquireBus(&SPID2);
spiStart(&SPID2, &display_cfg);
UISendData(&SPID2, 2, dt_data); // <<<--- here it does not work, data sent to SPI, but can't get back from this function
spiReleaseBus(&SPID2);
chSysLockFromIsr();
chVTSetI(&DisplayTimer, S2ST(1), hDisplayTimer, NULL);
chSysUnlockFromIsr();
}
Probably it happens because I send data to SPI from the timer interrupt handler (is it true?). So I tried to use chSysLockFromIsr() instead of chSysLock() (used in SPISend() anyway). It did not help.
What would be the solution for that?
And another problem related to that. Why after I ran the timer it calls the handler immediately, without actual waiting for one second? I watch window I see the values. Not sure that 0x205 (517d) is correct value for 1 second, though.
CH_FREQUENCY defined as 1000