I am having some problem to pass parameter into subroutine.
I have defined:
BOOLEAN CRC_Message_Verify(UINT8 nbyte);
in my program, I have this line:
crc_ok = CRC_Message_Verify(SpiLoadIndex);
in which, SpiLoadIndex is defined as UINT8 xdata type,
when I single step debugging, before calling CRC_Message_Verify function, SpiLoadIndex = 5, and inside the subroutine, nbyte = 95. How come nbyte is totally different? Any ideas?
when I single step debugging, before calling CRC_Message_Verify function, SpiLoadIndex = 5, and inside the subroutine, nbyte = 95. How come nbyte is totally different? Any ideas? 1) which chip - reflects on what debug is available 2) 'debugging'? how (WHICH simulator/emulator.JTAG) ???? 3) some 'dehuggers' can not 'see' a value if you click on it in the function header, only if you click on it where it is used inside the function 4) I assume that "inside the subroutine" means while stepping inside the function, not looking at the variable while stepping somewhere else (scope)
Erik
The chip is Analog device ADuC848, and the debugger is USpear from accutron ltd, it is a two-pin emulator. I put SpiLoadIndex and nbyte in the watch window and I can see these two numbers do not match. And yes, I am stepping inside the function and there is only one place calling this function. It is very strange.
One thing I forgot to mention is that this whole thing is inside SPI interrupt. Would that cause any problem?
you answered 1) and 2) what about 3) and 4)?
One thing I forgot to mention is that this whole thing is inside SPI interrupt. Would that cause any problem? It shouldn't; however calling subroutines inside ISRs ia generally bad practice.
also, I recall someone stating that the USpear is not exactly the greatest thing ever.
try 3) did it make a difference answer 4)
I am not quite sure I understand your 3)
What I did is setting a break point at
and when the program hit break point, I add SpiLoadIndex to watch window and check the value, then click "step into" a couple time so I am truly inside CRC_Message_Verify routine and then check the nbyte value in watch window. I think this answer both your 3) and 4) (?)
USpear is not good at all, but it is the only tool I have to work with analog device chip.
I also know calling subroutine inside ISR is bad, but at the other side of SPI, I have an ARM processor expecting data, so I have to prepare the next byte right away. Do you have any suggestion?
A lot of people make use of send and receive buffers, and limit the ISR to just pick up the next byte to send, or store the just received byte.
An RTOS task or a super-loop (mor likely choice for a C51) then scans the receive buffer for commands and/or answers to process, and fills the transmit buffer with commands and/or answers to send.
This makes the ISR lightning-quick. In some situations, it can be meaningful to let the ISR have a minimal state-machine, to have it look at start-of-message or end-of-message if the data is transmitted in packet form. But in general, it is advantageous to keep the ISR short. Then you don't have to think about interrupt response times and if there will be need for nested interrupts.
Another thing: you can compute the CRC a byte at a time, or wait until you have a full message. With a really fast processor, it may not matter, but at lower processor speeds a byte-at-a-time algorithm can speed up the response time by reducing the time from the reception of the last byte until you have fully decoded and accepted it and are ready to send back an answer.
From your example, I'm not really sure if your CRC is evaluated a byte at a time or a packet at a time.
The name seems to imply a full packet, but does the parameter then point out which - of many received and cached messages - message to compute the CRC for?
So, have you asked Accutron about this, then?
It is a common mistake to equate "low cost" with "good value"; you may be lucky, and get a "bargain" - or you may just get what you pay for...
;-)
Is the variable wrong or the debugger just reports it wrong? Beside limitations of the debugger this could be a limitation of the optimizer. The variable may be used directly and not exist where it is placed. Or, the location may be shared. This means it can be over written to save space.
Can you recommend something go with Analog device ADuC8xx? The reason I have to use Analog device chip is that they are the only one has 25 bit ADC. And I asked their support before and they told me USpear is the only debugger tool.
I will turn off optimizer and run some more test tomorrow. The bottom line is that the CRC result is not correct. This subroutine has been verified in other test program.
Last week, I even had problem with assigning variable in the same ISR routine, I had " A = B; " and after executing that line, value stored in A and B are not same. I have to use static to define them to make the equation right. Now I am wondering if these are related somehow.
I use send/receive buffer for serial command handler, but like I said it is different for SPI case. When master processor query data through SPI, my C51 need to have the data ready. If I use send/receive buffer for SPI, that just means I have to put more delay to query each byte of data, which is not desired for my application.
I do use mini state machine for this SPI ISR routine right now. It is kind complicated error checking/hand shaking processing, but I am still not comfortable with the long term reliability.
Your idea on CRC calculated by byte is an excellent one. I will change to that, and maybe if I break my CRC routine into this big ISR instead of calling it as a subroutine at the end can eliminate my problem. thanks,
this may be a pure coincidence, but have you noticed that 5 = 101 and 95 = 101 1111 ? did you check your assembly code? are you sure there are no implicit casts involved in the call...?
Just to close the issue. The problem is caused by the size of my data. The data memory of this chip is 2k. My original way of designing SPI command structure is to include everything into one structure. And the command array is fairly big, so my data is bigger than 2k. The compiler did not complain, but I think they just overwrite each other during my debug session.
I solved the problem by separating command structure into several structures, some of them can be set as constant and reside in code space.
Thank you all for the help.