Keil v4.60 and lpc18xx libraries

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Keil v4.60 and lpc18xx libraries

540 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Cusko on Mon Oct 08 07:13:34 MST 2012
Just for information.
I had some problems with an USART on my board with the LPC1820. After 2 days I found bug with the new version of Keil compiler. In the file Lpc18xx_cgu.c in line 637 there is condition
( if((CGU_PERIPHERAL_Info[Clock].PerBranchOffset!= 0) && !(CGU_PER_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)) return 0; )
that is  not evaluated correctly in the last Keil uVision v4.60. So USART only works when you comment this line.

Probably there is more of these bugs with the new version of Keil compiler.
Labels (1)
0 Kudos
4 Replies

505 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Cusko on Mon Nov 19 06:25:16 MST 2012
Yes, I got the same answer today. So NXP, fix the bug for the next release!

FIX:
#define CGU_REG_BRANCH_STATUS(x) (*(volatile uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].RegBranchOffset+4))
#define CGU_PER_BRANCH_STATUS(x) (*(volatile uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].PerBranchOffset+4))
0 Kudos

505 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by alindvall on Fri Nov 16 00:40:47 MST 2012
I have seen the same problem on LPC4357 on 4.60. I talked to Keil's support and got the following answer:

For your information, the problem was in the lpc43xx_cgu.c file:

--------------
(CGU_REG_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)

in case of armcc CGU_BRANCH_STATUS_ENABLE_MASK is

#define CGU_BRANCH_STATUS_ENABLE_MASK  0x01

and CGU_REG_BRANCH_STATUS is:

#define CGU_REG_BRANCH_STATUS(x)
(*(uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].RegBranchOffset+0))

Seems like, because CGU_REG_BRANCH_STATUS(Clock) is not volatile, compiler loads only a byte
from this address, which is ok, as only 8 bit get tested. Other bits don't care.

But this address is in SFR space and byte access might be a problem, so wrong data is loaded.

To fix this, make CGU_REG_BRANCH_STATUS(Clock) dereferencing a volatile address:

#define CGU_REG_BRANCH_STATUS(x) (*(volatile
uint32_t*)(CGU_CGU_ADDR+CGU_PERIPHERAL_Info[x].RegBranchOffset+0))

----------------

When applying the fix to the CGU_REG_BRANCH_STATUS define I found that I had to do the same with the CGU_PER_BRANCH_STATUS define.
0 Kudos

505 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by Cusko on Mon Oct 22 01:40:09 MST 2012
I also find out that with an ADC there is a problem few lines below with line 642 :
if((CGU_PERIPHERAL_Info[Clock].RegBranchOffset!= 0) && !(CGU_REG_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)) return 0;

I am working with the Keil support team on this problem, so when I will have any answers I will let you know. Till then just comment those lines.
0 Kudos

505 Views
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by diederichs on Mon Oct 15 14:19:40 MST 2012
We just had the same issue developing on the LPC4350 using Keil 4.60. 

The same line:
if((CGU_PERIPHERAL_Info[Clock].PerBranchOffset!= 0) && !(CGU_PER_BRANCH_STATUS(Clock) & CGU_BRANCH_STATUS_ENABLE_MASK)) return 0;
located in CGU_GetPCLKFrequency() now evaluates true and causes a returned value of 0 Hz.  Commenting this line "corrects" the function of the routine.

We have confirmed (with our revision control system) that there has been no change to the LPCware routines or our firmware.  Only the compiler was modified in the update.

We are stumped as to what is causing this.  Anyone have some thoughts apart from compiler bug?
0 Kudos