We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I have an Infineon SK-XC167CI Easy Kit V3 board, soldered with an Infineon XC167CI-32F40F microcontroller. I am using the Keil UVision 3 IDE. The board has been extended to include an external flash ROM module; the AMD AM29F400B unit (512 Kbytes). This external ROM module is wired into the chip select 1 (CS1) signal; port 6, pin 1 (pin 8 on the microcontroller).
I am trying to access the external ROM module, but am not having much success.
I believe that I have the CS1 area mapped onto the XC167s address space starting at 100000h, using the EBCMOD0, EBCMOD1, TCONCS0, FCONCS0, ADDRSEL1, TCONCS1, and FCONCS1 registers.
I am following the instructions given in the AM29F400B data sheet for requesting the manufacturer id and the device id from the flash ROM module.
I think that my problem lies in the way that I have the EBC setup (which I am doing in the start_v2.a66 file) rather than in the way that I am actually forming the address accesses (the flash ROM module interrogation requests), but I could be wrong.
Any direction that you might be able to give me at this point would be extremely gratefully received.
1. Are you sure that CS1 used for flash? 2. Usually flash chips use CS0 area. 3. You adjust bus timing for current CSx in start.a66 file? EBC must be configured before EINT instruction. Look Peripherials configuration in debug mode in Keil IDE.
Hi Oleg - thanks for your reply.
The external flash ROM module was wired to CS1 - deliberately because I wanted to be able to access the whole of the module. However, the XC167 has now been re-wired so that the external flash ROM module is wired to CS0, as you suggest. Even with the module wired to CS0, I am unable to get things working correctly.
I have tried various values in the TCONCS0 register, but the values that I am using right now are :
_PHA0 EQU 0 _PHB0 EQU 0 _PHC0 EQU 0 _PHD0 EQU 0 _PHE0 EQU 2 _RDPHF0 EQU 1 _WRPHF0 EQU 3
and I am adjusting these values in the Start_v2.a66 file prior to issuing an EINIT instruction.
Please tell me what result you see? - wrong data content - do you try to program/erase operation.
What happens is that I perform a set of writes followed by a single read in order to try to establish the manufacturer / device id.
This is the code :
HVAR( unsigned short, t_addr | 0x00 ) = 0xF0 ; /* bus cycle 1 - reset to read */ /* Autoselect command */ HVAR( unsigned short, t_addr | 0x555 ) = 0xAA ; /* bus cycle 1 - unlock step 1 */ HVAR( unsigned short, t_addr | 0x2AA ) = 0x55 ; /* bus cycle 2 - unlock step 2 */ HVAR( unsigned short, t_addr | 0x555 ) = 0x90 ; /* bus cycle 3 - autoselect command */ xyz = HVAR( unsigned short, t_addr | 0x0000 ) ; /* to get manufacturer id */
when I run the code as shown here, I get a class B trap giving an illegal word operand error.
If I change the code to use
HVAR( unsigned char, ...)
the code runs without error, but it does not return what I expect. It returns 0xFF, when I expect 0x01 (as per the AMD data sheet).
HVAR( unsigned short, t_addr | 0x555 ) = 0xAA ; this line is wrong, because you try to access to word with odd adress (0x555). In some cases 0x555 may relace with 0x554. What BUS-widht you use? If 16-bit you must sure that flash mode pulled-up(down) to WORD-mode. And A0 of flash must be connected to A1 MCU. And other adress pins must be coneected to flash with shifting too. If you use 8-bit BUS you may replace unsigned short to unsigned char.
P.S. The most powerfull way - see oscilloscope in adress pins. I speek English so so. I want to tell you my expirience with this problem, but I can't say right :(
Oleg,
Firstly, thank you for your time; it is proving very helpful.
The bus width that we are using is 16 bit.
Your reply has given me a direction to try.
Since yesterday (Thursday) afternoon, I have been playing around with the PLLCON register to alter the speed that the microcontroller is running at. The external oscillator is 8 MHz and as a result of teh settings on the PLLCON, the CPU is running at 40 MHz - I think that this is probably too fast for either the EBC or for the external flash module.
I will double check the wiring for the address pin connection.
When you say "... sure that flash mode pulled-up(down) to WORD-mode." are you talking about a resistor ?
Thank you again !
You can download a Excel spreadsheet to calculate the EBC setting that you need at the Infineon website.
-Chris
Excel link www.infineon.com/.../download.html
Pdf: www.infineon.com/.../download.html
Latest and greatest on this problem :
Infineon XC167-32F microcontroller 8 MHz oscillator AMD / Spansion AM29F400B (external) flash ROM module wired to CS0 of XC167 AM29F400B module wired into 'word' (16-bit) mode
In start_v2.a66, PLLCON settings are :
_PLLODIV EQU 8 _PLLIDIV EQU 0 _PLLVB EQU 0 _PLLMUL EQU 8 _PLLCTRL EQU 3 _PLLWRI EQU 0
In start_v2.a66, EBCMOD0 settings are :
_SAPEN EQU 4 _CSPEN EQU 5 _ARBEN EQU 0 _SLAVE EQU 0 _EBCDIS EQU 0 _WRCFG EQU 0 _BYTDIS EQU 0 _ALEDIS EQU 0 _RDYDIS EQU 1 _RDYPOL EQU 0
In start_v2.a66, EBCMOD1 settings are :
_APDIS EQU 0 _A0PDIS EQU 0 _ALPDIS EQU 0 _DHPDIS EQU 0 _WRPDIS EQU 0
In start_v2.a66, FCONCS0 settings are :
_ENCS0 EQU 1 _RDYEN0 EQU 0 _RDYMOD0 EQU 0 _BTYP0 EQU 2
In start_v2.a66, TCONCS0 settings are :
_PHA0 EQU 0 _PHB0 EQU 1 _PHC0 EQU 3 _PHD0 EQU 1 _PHE0 EQU 31 _RDPHF0 EQU 3 _WRPHF0 EQU 3
Given the settings of all of these registers, according to the Infineon spreadsheet tool, these values *should* work !
When I use the following code
/* Reset to read */ HVAR( unsigned short, 0x00 ) = 0xF0 ; /* bus cycle 1 - reset to read */ /* Autoselect command */ HVAR( unsigned short, 0x554 ) = 0xAA ; /* bus cycle 1 - unlock step 1 */ HVAR( unsigned short, 0x2AA ) = 0x55 ; /* bus cycle 2 - unlock step 2 */ HVAR( unsigned short, 0x554 ) = 0x90 ; /* bus cycle 3 - autoselect command */ xyz = HVAR( unsigned short, 0x0001 ) ; /* to get manufacturer id */
I get a returned value of 0x4111 - whilst I expect a return value of 0x22AB.
I have tried a variety of settings for PLLCON, and for TCONCS0, but to no avail.
Any thoughts at this point are gratefully received.
Yours,
Simon May
The PLL setting you have will NOT work as the VCO is set to low. Here is a correct setting for 40MHz cpu frequency when using a 8MHz external crystal.
PLLCON=0x6E02
You also have many unnecessary wait states but as you wish.
Perhaps this code example helps you, it is along the lines of what Oleg was telling you about even addresses...
#include <xc167.h> #include <intrins.h> volatile unsigned int xyz; void main(void) { /* Reset to read */ * (volatile unsigned int huge *)(0x000000 ) = 0xF0 ; /* bus cycle 1 - reset to read */ /* Autoselect command */ * (volatile unsigned int huge *)(0x000AAA ) = 0xAA ; /* bus cycle 1 - unlock step 1 */ * (volatile unsigned int huge *)(0x000554 ) = 0x55 ; /* bus cycle 2 - unlock step 2 */ * (volatile unsigned int huge *)(0x000AAA ) = 0x90 ; /* bus cycle 3 - autoselect command */ xyz = *(volatile unsigned int huge *)(0x000000 ) ; /* to get manufacturer id */ for (;;) { } }
Hi Chris - thank you for joining in. I am pulling out my hair with frustration so any and all help is appreciated.
Thank you for your comment on the value in PLLCON. I have previously been working with a value of 0x7844 giving fIN = 8 MHz, fVCO = 200 MHz, and fPLL = 40 MHz. In an attempt to slow things right down I started to use the PLLCON value of 0x6808 giving fIN = 8 MHz, fVCO = 72 MHz, and fPLL = 8 MHz. As a result of your post, I have used your suggested value for PLLCON of 0x6E02.
As for the wait states; as you have identified, they are set to their maximum values. This was in an attempt to allow the EBC sufficient time to complete whatever operations it required. As a result of your comment, I have returned to more sensible values :
TCONCS0.PHA0 EQU 0 TCONCS0.PHB0 EQU 1 TCONCS0.PHC0 EQU 0 TCONCS0.PHD0 EQU 0 TCONCS0.PHE0 EQU 4 TCONCS0.RDPHF0 EQU 0 TCONCS0.WRPHF0 EQU 3
In addition, rather than use the (Keil supplied) HVAR macro, I have used the native 'C' construct.
All of these changes have had no effect.
In addition to this, I have had some contact from a technical support guy at Spansion (AMD) with a couple of suggestions about addressing.
The XC167 operates in 16-bit bus mode, and the AM29F400B can operate in x8 or x16 mode. For some backwards compatibility reasons, the wiring of (XC167) address lines to (AM29F400B) address lines means that there is an offset to be taken into account. Therefore if the AM29F400B needs to see 0x555 on its address lines, then the software running on the XC167 must output ( 0x555 << 1 ) on its address lines.
I have made the changes necessary to implement this, but still no joy !!
As ever, any thoughts, please contribute !!
Hi Simon,
I created a project with this exact code sequence for the Keil MCB-XC167 board. The board contains an AM29F160DT, configured in word mode on /CS0. The clock is configured for 40MHz and here is what I get back after running the code from internal Flash (0xC00000): 0x0000: 0x0001 0x0002: 0x22D2
So manufacturer ID is 1, and the device ID is 0x22D2 just as the data sheet specifies.
I could send you the complete project if interested.
Just a comment to the addressing that seems to be confusing. Have a look to the schematic from Keil to see how to connect word memory to the external bus.
http://www.keil.com/mcbxc167/mcbxc167-schematics.pdf
You will see that A0 of the XC167 is not connected because you are reading words (A1 from the XC167 is connected to A0 of the AMD, and so forth). This is why you need to make the adjustment to the address from the perspective of the XC167 not for AMD. So when you write 0x0AAA you are indeed writing 0x0555 to the AMD. The XC167 will not allow word read/writes to odd addresses (you will get a trap).
Hope this helps.
Hi Chris,
Thank you very much for your help ! I was not in work yesterday (Wednesday), so have only now got around to replying.
Your offer of the project which you have set up is much appreciated. My email address is simon.may (at) apdcomms.com
With luck I should be able to see what it is that I am doing wrong, and when I figure that out, I will post back here to clarify.
Thanks,
Simon
As a result of Chris's project I now have this working.
The main item which seemed to be affecting how my code was working was that in my start_v2.a66 I had CS7 (the LXBus) enabled. When I disabled this, the code started to work.
I have not investigated this to try to work out why this should be.
Having said that, this morning, (Friday) I have the code working whether CS7 is enabled OR disabled.
At this point I am not sure that I mind which way things are - I am just happy that it is working.
As I do not see that I will be using the CS7 right now, I will leave it disabled.
Chris, and Oleg - both, many, many thanks for your help.
As a result of some problems which I have been having over the last few days, I wanted to post a short explanation of what I have got set up, and items which should be checked to ensure smooth operation !
Firstly, the hardware : I have an XC167CI-32F soldered onto an Infineon starter kit the starter kit has an 8 MHz external crystal in addition there is an AMD (Spansion) AM29F400B-70 external flash ROM module soldered on to the board the external flash ROM is wired into 'word' mode the external flash ROM is wired as a 16-bit demultiplexed bus the external flash ROM is wired on CS0 the address lines of the XC167 are mapped to the address lines of the AM29F400B as specified in the AMD data sheet, ie: A1 from the XC167 is connected to A0 of the AMD, and so forth
Secondly, the start up code. In start_v2.a66 :
PLLCON .PLLODIV EQU 4 .PLLIDIV EQU 0 .PLLVB EQU 1 .PLLMUL EQU 24 .PLLCTRL EQU 3 .PLLWRI EQU 0 /* these values give a system clock of 40 MHz (on an 8 MHz crystal), but check that VCO is within sensible limits */
EBCMOD0 .SAPEN EQU 4 .CSPEN EQU 5 .ARBEN EQU 0 .EBCDIS EQU 0 .WRCFG EQU 0 .BYTDIS EQU 0 .ALEDIS EQU 0 .RDYDIS EQU 1 .RDYPOL EQU 0
EBCMOD1 .APDIS EQU 0 .A0PDIS EQU 0 .ALPDIS EQU 0 .DHPDIS EQU 0 .WRPDIS EQU 0
FCONCS0 .ENCS0 EQU 1 .RDYEN0 EQU 0 .RDYMOD0 EQU 0 .BTYP0 EQU 2
TCONCS0 .PHA0 EQU 0 .PHB0 EQU 1 .PHC0 EQU 3 .PHD0 EQU 1 .PHE0 EQU 8 .RDPHF0 EQU 3 .WRPHF0 EQU 3
Lastly, the actual software.
The specifics of the writes / reads which need to be issued are detailed in the AMD data sheet, so I will not go into them here other than to say that when composing an address to use from the point of view of the XC167, if the AMD data sheet says that it needs an access to take place at address 0xAAA, then the software must use the base address of the flash ROM module from the point if view of the XC167 (which, if wired to CS0, will be 0x0 ) added to the address that the AM29F400B expects (for instance, 0xAAA) bit shift one position to the left. Thus
AMD expects to see 0xAAA XC167 must access ( base_address + ( 0xAAA << 1 ) )