- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In the register TRM there are several registers to control the systick timer -
M0_SYST_xxxx
http://www.cypress.com/?rID=78807
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just realised I was using the TCPWM timer not the UDB timer. I will try it with the UDB one now it looks easier
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks, I tried changing them both from derived but the build fails on anything but derived.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You might consider filing a CASE on this -
To file a tech case -
“Support”
“Technical Support”
“Create a MyCase”
Regards, Dana
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 -
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.