Sequential programming and waits


#1

I’m used to write programs for wavecom modules as tied together timers. It looks to me like the only way to make pauses between some actions. Is it right? Now I’m using SPI exchange with external processor and I have to organize process as:

  1. Write SPI data
  2. Pause for a while (10 ms is enough)
  3. Read SPI data

Now with wavecom’s timers I’ve got a very messy code which looks like timer to write data, timer called from within write for delay, timer called from delay to read data. Or a bit better option to have an FSM like timer calling itself and using STEP variable to pass from one step of algorithm to another.
I cannot use WHILE loops to make a pause from read to write since it blocks the entire module and I do not see a way to give execution to OS while staying in the while loop.

What can I do to make my program look better and what is the way to organize short and long delays in OpenAT?


#2

Definitely the FSM!

but note that there is now adl_ctxSleep() - see: viewtopic.php?f=53&t=3890&p=15211&hilit=adl_ctxSleep#p15211


#3

I’m not sure that adl_ctxSleep will help but thank you anyway.


#4

Not knowing your code, neither am I - but it may be worth a look.

It does allow you to have inline waits, though - without tripping the watchdog (because it allows the rest of the system to continue - unlike a loop).


#5

and is also using the same 18ms system granularity


#6

Is that a problem for you?


#7

You can use endless while loop as you wish if your OAT app use multi-tasks. It is not a good idea to use fixed delay for SPI bus. SPI concerns how many cycles to interface external devices, say SD card, AT45XX flash, etc. For simplisity, you may implement software SPI by yourself by using any 3 GPIO pins. However, software SPI is slow and it may be less than 1Mb/s compareing with hardware SPI 13Mb/s.

You may have several solutions to solve your issues as follows:

  1. Use alarm clock for single task app: TCU timer can achieve 1ms resolution. So you can write your own alarm clock to trigger events at predefined interval (your case is 10ms). Please use high level interrupt to implement TCU timer.
  2. Use endless while loop for multi-task app. Wavecom have multi-task timers example, but you may need TCU timer also because ADL timer only have 18.5ms resolution.
  3. You may use RTC to figure out time elapse, say 10ms, in while loop, and then trigger events you want

#8

No, you can’t: if any task “hangs” in a loop - deliberately or otherwise - it will trip the watchdog.

The OP was talking about delays between SPI operations - not timing the SPI transfer itself!


#9

I have three endless while loop subtasks and never trigger watchdog. Of course, your have to put some pause before going to next loop. The following pseudo code is one of subtasks in my OAT app.

void RTasks::AudioTask()
{
while(1) {
PauseLittleTime();
MenuStatus menuStatus = GetMenuStatus();
switch (menuStatus) {
case MS_IDLE: DoIdle(); break;
case MS_STOP: DoStop(); break;
case MS_START: DoStart(); break;
case MS_VOICECALL: DoVoiceCall(); break;
case MS_SPEAKER: DoSpeaker(); break;
}
}
}