- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello,
I was struggled days for my project, but I can't either get a clue out of these problems or find a way go around of them.
Here I post what I encountered and looking for someone else who has any thought.
(1)
When I tried to read timer values, I always got the compare values I set in the module parameters, like:
Timer8_ms with a period/compare value of 99/49, when I call "Timer8_ms_bReadTimer()", I always got a constant 49 returned.
Same problem occurrs when I utilitizing Timer16 module. I've tried to copy values from register like "Timer8_ms_COUNTER_REG" "Timer8_ms_COMPARE_REG" but they are all constant as well.
code is like this:
tmp_ten_us = Timer8_ms_bReadTimer();
RTC.ten_us = 99 - tmp_ten_us; // converting count-down 10us value to count-up for easier human reading
tmp_ms = Timer16_min_wReadTimer();
RTC.ms = 59999 - tmp_ms; // converting count-down ms value to count-up for easier human reading
(2)
When ever I tried to manipulated or referencing an "unsigned int" inside an ISR--like "ms++" or "if ( ms > 999 )", the MCU hangs and I could only re-active it via setting XRES high. Is it normal, or am I missing something important?
Any idea? Thanks.
- Labels:
-
PSoC 1
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Welcome in the forum!
As usual: best will be to post your complete project here, so that we can look at all of your settings.
To do so, use Designer -> File -> Archive Project and then attach the resulting file.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Forgot to say, this project is performance required, and I need an UART as fast as possible, like at least 500kbps or higher for transferring ADC values and timing back to a host computer.
So adding anything inside the ISR to work around problems will be my last option..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The UART runs in internal hardware (thanks PSoC!!!) so you have time for your interrupt executing about 250 instructions while one byte is transmitted. That is fairly enough to handle an interrupt.
Again: Post your project and we will have a look at.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Bob, thanks for your quick reply. But, since I am away from computer right now, I cannot post the complete code immediately.
Even though, it will be a great help if you can tell me
1.read the current timer counter value should be working via calling "Timer16_wReadTimer()" or so.
2.16bit variables are compatible in ISR mostly.
I don't have much firmware coding experience so it was composed mainly in C code..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1) bReadTimer() and wReadTimer() are the right routines.
2) Of course you may use global or local int16 within interrupt handlers
Do you use an ICE-Cube or why are you sure that accessing an int16 stalls your handler?
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Read carefully the API calls you are using, I think you should
use the Timer8_bReadTimerSaveCV API to get value.
Did you declare your ISR variable as volatile ?
http://www.barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword Volatile
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Did you ever consider using a PSoC4 CY8C42XX? Fmax 48MHz, UART 1Mbps, ADC 12-Bit, I2C and more...
The Pioneer Kit offers debugging capabilities, the Prototype Board (for $4) can be programmed via BootLoader with a Pioneer-tested project.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What part are you using ?
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just sit back to my computer.
To Bob,
Thanks for telling me UART didn't take much resource away from MCU core. I have to take care that while I was using another 8051. Will see how much I can push it..
To your question regarding int16 problem in ISR: the system running as expect once I commented all lines that have int16 variables within. When uncommented, it halts immediately while timer w/ interrupt enabled starts. No ICE cube was used..though I wish there is one in hand.
And I was planning moving on to one that with easier debugging capability..after I was familiar enough to these 8-bit ones and basic C programming. Thanks for suggesting PSoC4(LP).
To Dana,
Yes, I have tried volatile on my variables that need to be handled in my ISR. Results are the same w/o it. Not sure extern or not matters? I think I've tried using "extern unsigned int" as well..
I'm using CY8C29466PXI on C3210 kit. Coding space and RAM is still under 60% after compiling.
Please check attached archive..since I tried many things so it is veeeeeery messy. Sorry for that.
It was under developement and control interface is UART. if it runs correctly and select option 4, there should be a continuous ADC converting after a 100ms waiting--Tmr_wait ( 100 ). But in this code, the RTC.ms and RTC.ten_us can't get correct values so the wait-function hangs..you can check the information returned from UART.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You use external when you are using a variable in another file.
Example
in main.c you declare
uint16 myvar = 0;
in mycile.c then you declare
extern myvar;
if its used in an ISR in mycfile.c then
extern volatile myvar;
and in main.c it becomes
uint16 volatile myvar = 0;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
To Dana,
I've tried ReadTimerSaveCV. But it will cause a system hang or mal-function to other codes--like error in getting input--, so I goes back to ReadTimer. I don't know why.
I thought counter register is what I really care, not compare reg, so it doesn't matter if SaveCV or not..since I want to use it as a hardware-like time clock. Hope I didn't get the idea wrong..
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Dana,
I use substitue "#define EXT" or "#define EXT extern" for switching global variable or external one in main_vars.h. As you can see in the first few lines in every .c files. And there's only main.c has "#define __GLOBALS__" that declares the variables' home is here. It was working in Keil C51..and IMAGECRAFT didn't cry about it.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do not see where you have set up your C interrupts with
the required ljmp (in boot.tpl which is in root project directory) -
http://www.cypress.com/?id=4&rID=36720
I thought counter register is what I really care, not compare reg, so it doesn't matter if SaveCV or not..since I want to use it as a hardware-like time clock. Hope I didn't get the idea wrong..
You are correct here.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just as an aside thought maybe this ref material might be useful, attached.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dana,
The code was using the "C ISR Declaration" way in the link you provided: using #pragma directive and inserts a "ljmp _C_func" between appointed lines in Timer[what-ever]INT.asm. It has no problem if the code is relatively simpler. I also tried lcall along with PRESERVE_CPU_CONTEXT and RESTORE_CPU_CONTEXT but int16 still causing hang if interrupt sources started, like timer8 or timer16.
I will give boot.tpl another try as you suggested here and in many other discussions.
Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your EXT-mimic takes a bit of getting used to...
Interrupt handling in PSoC1 is a bit complicated. You successfully declared your handlers using #pragma, but you did not yet connect one of the handlers to the correct interrupt number.
When you look into boot.asm you find at the beginning a hint to make required changes in a file named "boot.tpl" from which the file boot.asm will be generated.
You have to insert the correct LJMP _YourHandler into the right places (mark the leading "_")
I would suggest you to try that on a smaller project to get it right.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That part of the link does NOT apply to the Imagecraft #pragma implementation,
continue reading down in the page.
You have to code the ISR vector into the jump table in boot.tpl
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Bob and Dana,
I saw the boot.asm has correct "ljmp _[C-func]"-s, like _Tmr_10uS/ms/min_INT, in correlating positions. I don't think I have to change it? I bought the idea of EXT defines from a former college..and found it useful if the codes has to be somewhat big and complex..meanwhile there are a lot of data needed to be shared between functions..
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
But anyway..after save-as the whole workspace and re-editing the "boot.tpl" (change `@INTERRUPT_14` to ljmp _[xxxx] and then back to `@INTERRUPT_14`)..int16 in ISRs are working again..wired. Is there something I should take care for preventing possible compiling corruption?
However, reading counters with ReadTimer function still get constants.. 😕
At least I got a working solution for my RTC.
Big thanks to both of you. :))
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Verify that you can get a breakpoint in the C ISR, the setup still seems
baffling to me, especially why your boot.asm file seems to have the
ljmps in the C ISR w/o modifiying boot.tpl.
Something is wacky.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The entries in the interrrupt-table are done automatically when a component is used that -like a Timer- has an interrupt defined. The target lies within one of the generated files and could be filled with your own asm instructions. Saving and restoring the environment is user's duty.
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have reviewed the codes and there is a mistake in my post has to be addressed:
The auto-generated routine like "ljmp _Timer8_ms_ISR" or so in boot.asm actually redirect to Timer8_msINT.asm.
Once I have placed a custom routine like "ljmp _Tmr_ms_INT" in the appointed section within Timer8_msINT.asm, custom C interrupt code like "void Tmr_ms_INT ( void )" should be compiled as expected. Though I already read related posts over and over again, I still forgot this basic. Maybe too many codes have overflowed my eyes and mind. 😕
Even though, I still hope for clarifying:
1.Why int16s have caused problems then went normal afterward? Shouldn't it the IDE's (PSOC Designer) duty to keep the compiling clean enough? I mean itself should be able to make a clean compilation every time a full compiling is executed.
2.Why ReadTimer-s are still failed? And can I take a direct copy from REG like "a = Timer8_ms_COUNTER_REG;" for getting a correct current count-down value from "Timer8_ms"? I failed to do both of above. And that makes timers lack something important IMHO..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In your file c_isr.c there is a "return" keyword at the end of each function. An interrupt doesn't not return a value hence the void at the begenning of the line. Remove the return keyword, it should help.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am not sure that matters, in fact Imagecraft and HiTech do not
complain when encountering a simple return;
Return Statement
A function can return a value of any type, using the return statement,- Syntax:
- return exp;
- return ( exp);
- return;
The return statement can occur anywhere in the function, and will immediately end that function and return control to the function which called it. If there is no return statement, the function will continue execution until the closing of the function definition, and return with an undefined value.
The type of the expression returned should match the type of the function; C will automatically try to convert exp to the return-type.
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can be darn sure that the compiler is able to handle 16bit integers in an interrupt handler, I did that several times so far! The reason for the not-working project is related to something different.
You mentioned that you changed the boot.tpl-file? In the project you submitted was nothing changed in that file, so can you supply us with your actual project version?
Bob
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
dannaknight,
I tried removing the return keyword from the functions in the interrupt handler and it does make a difference in the list file. There is one of the return (the last one I think) that generate a "pop", so that will generate an overflow.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Eric, maybe I do not understand something. All returns from ISRs result
in a POP unless user executes a jump out of the ISR. I looked at C standard
to see if a return on a void f() was any different then a f() just ending in braces,
and thats where I drew the info I posted from.
Of course a POP in main() restarts, not sure.......
So maybe I have something to learn here ?
Regards, Dana.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Danaa, maybe you are right, I can't say. Maybe it doesn't change anything but I would avoid placing a return since an interrupt handler is not a regular function. How can we be sure the compiler will interpret it correctly. (Just a thought)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was told today (I'm at embedded world meeting all the Cypress staff) that ther was an error with a 16bit integer in former times, nobody knew for sure if that kind of bug was cured or even pops up anew:
When a 16bit integer was allocated on a page boundary, so that one byte resides on page n and the other half on page n+1, there were errors when that var got accessed. I am positively sure that a bug like that has been fixed.
Regarding the pop instruction on end of an interrupt handler:
There are at end of a handler some instructions needed to restore the original processor state:
Some memory locations that are used as pseudo-registers for C are pushed on the stack, of course CPU-registers A and X and additionally the page register and some more special function registers. When no call to other functions is made within the handler, the C-compiler will keep track of used pseudo-registers and of saving only those. A handler is always finished by a pop of the A-register and a RETI (not only a RET) instruction which pops from stack the processor state (flags etc) and the formerly saved program counter.
Bob