cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 4 MCU

SaWa_284216
New Contributor II

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
Reply
15 Replies
ETRO_SSN583
Esteemed Contributor

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
Reply
ETRO_SSN583
Esteemed Contributor

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
Reply
ETRO_SSN583
Esteemed Contributor

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
Reply
SaWa_284216
New Contributor II

 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
Reply
SaWa_284216
New Contributor II

 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
Reply
SaWa_284216
New Contributor II

 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
Reply
ETRO_SSN583
Esteemed Contributor

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
Reply
SaWa_284216
New Contributor II

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

0 Likes
Reply
JoMe_264151
Expert II

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
Reply
SaWa_284216
New Contributor II

 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
Reply
ETRO_SSN583
Esteemed Contributor

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
Reply
SaWa_284216
New Contributor II

 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
Reply
ETRO_SSN583
Esteemed Contributor

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
Reply
ETRO_SSN583
Esteemed Contributor

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
Reply
SaWa_284216
New Contributor II

  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
Reply