Please advise me on which timer to use, resettable one shot?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
SaWa_284216
Level 4
Level 4

So I am implementing the comms protocol which terminates the end of message with a 1.04uS blank space.

   

My UART code is working fine but what I need is to implement the following scenario

   

UART-READ BYTE IN

   

RESET 1.04US TIMER

   

then when the timer overflows it must mean that the UART has stopped receiving and the message is over as every new character resets the timer.

   

So I would need a timer interrupt which just said

   

EndOfMessageFlag = 1;

   

I read the following thread but it is 2 years old and based on the PSoC3 so wanted to get some more up to date advice on what timer use.

   

http://www.cypress.com/?app=forum&id=2232&rID=63168

0 Likes
15 Replies
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Assuming you want to reset timer byte to byte, like WDT behaviour, then a simple

   

fixed function timer running continuously should do the job. The clock rate of the

   

timer determines its resolution, and its width total range. Set isr to rising edge.

   

 

   

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Or use the systick timer and its associated interrupt.

   

 

   

    

   

          http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/Bhccjgga.html

   

 

   

Use the system Refernece guide and the TRM for additional info.

   

 

   

Regards, Dana.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

In the register TRM there are several registers to control the systick timer -

   

 

   

M0_SYST_xxxx

   

 

   

    

   

          http://www.cypress.com/?rID=78807

   

 

   

Regards, Dana.

0 Likes
SaWa_284216
Level 4
Level 4

 Hi Dana

   

I tried it with the fixed function timer (my preferred way) but I couldn't figure out how to keep resetting the value back to zero every time a byte comes in.

0 Likes
SaWa_284216
Level 4
Level 4

 Just realised I was using the TCPWM timer not the UDB timer. I will try it with the UDB one now it looks easier

0 Likes
lock attach
Attachments are accessible only for community members.
SaWa_284216
Level 4
Level 4

 Dana you have been so helpful to me lately if you get time can you have a look at the workspace bundle and see where I am going wrong

   

I have a continuously running timer which works, the interrupt fires every 104uS as I want. I have a UART interrupt which stores the received byte and increments a message length variable.

   

In the timer interrupt if the message length variable has not changed for 5 interrupts it must mean no bytes have been received and the timer stops.

   

It all makes sense in my head but it seems that instead of coming out of the timer interrupt to get the next byte it just keeps looping in the timer interrupt. Maybe there is a problem with interrupt priorities. Anyway it is just not working, I have tried to be clear in my code so it should be readable.

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

The first thing I noicticed is both ISRs are set to "Derived". Set them to

   

rising edge.

   

 

   

I will look over rest of project.

   

 

   

Regards, Dana.

0 Likes
SaWa_284216
Level 4
Level 4

 Thanks, I tried changing them both from derived but the build fails on anything but derived.

0 Likes
Bob_Marlowe
Level 10
Level 10
First like given 50 questions asked 10 questions asked

I've got an idea: since the timer clock is relative slow it might happen that the timer is stopped at terminal count thus keeping the interrupt line high. I would suggest that you insert a line in interrupts.c after the line containing

   

MessageTimer_Stop();  // Near line 87

   

MessageTimer_WriteCounter(0);  // Now not at terminal count (TC)

   

 

   

Bob

0 Likes
SaWa_284216
Level 4
Level 4

 Hi bob, Thanks for your assistance

   

I tried that but it didnt help. The loop at line 87 is the last loop (the 5 blank space loop), by the time we get to this loop there should have been all the bytes received and 5 blank spaces.

   

The code is failing before this loop because if I set a breakpoint in it, only the first character will be caught and the rest are zeroes.

   

If I take out the timer, the message logic works with breakpoints and I get a full message out. However I need the timer in the real world.

   


It seems that by adding the timer interrupt the first character comes in which sets the timer going, then the timer just stays in its own little loop totally ignoring the remaining character interrupts.

   

The even more confusing bit though is that if I set breakpoints in all the loops and step through the program appears to work as expected, then when I press run it goes back to just getting the first one and looping. CONFUSED!

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

You might consider filing a CASE on this -

   

 

   

    

   

          

   

To file a tech case -

   

 

   

www.cypress.com

   

“Support”

   

“Technical Support”

   

“Create a MyCase”

   

 

   

Regards, Dana

0 Likes
SaWa_284216
Level 4
Level 4

 Hi dana

   

i have filed a tech, thanks. I must admit I am not sure how the tech case thing works. Am I allowed to just bring any problem I have to them. Seems like a fantastic service if so.

   

I don't want to bother them if this isn't the case

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

I tried it with the fixed function timer (my preferred way) but I couldn't figure out how to keep resetting the value back to zero every time a byte comes in.

   

 

   

Normally for UDB timer you have to stop it, in the case of TCPWM it also has to be stopped,

   

this is the API call (UDB, there is one for the TCPWM as well) you would do that -

   

 

   

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Your UART is running slow enough should not be a problem in

   

ISR to stop timer and update it. However, look at .lst file to get an estimate

   

of clocks/instructions it will take inside ISR to do this. Keep in mind calling

   

functions inside ISR results in a lot of stack push above and beyond instructions

   

to do the actual job. So to Bob's point, carefully examine this.

   

 

   

Another quick way of testing is start with a super slow baud rate and ramp it up

   

doing some testing. Or just construct a toggle pin test inside ISR to measure

   

the time its taking to update timer. Beauty of PSOC and Creator, how fast you can

   

construct a test project.....

   

 

   

Regards, Dana.

0 Likes
SaWa_284216
Level 4
Level 4

  Hi Guys, well it took a while but it is working now.

   

A few things were making it not work, first of all the continuous timer, I replaced this with a oneshot and then just kept restarting it every interrupt. 

   

The next thing is, I had the timing completely wrong, for a 9600 baud rate, that is 104uS per BIT, not BYTE, I was needing to restart the timer after every byte, changing this to 833.33uS (8*104uS) fixed that.

   

The last thing was interrupt priority, the timer needed a higher priority interrupt than the UART. I got help from the applications engineers and it is all working now.

   

I really appreciate Dana and Bob, your help is invaluable, I will now add my modbus functions and upload the finished PSoC Modbus Slave to Github and here.

0 Likes