Hi Everyone,
I've connected a 64Mbit NOR flash to the EMIF (using CS0), this device needs to be programmed before any data can be written to its addresses, looking at the data sheet and TMR the EMIF should be able to handle this via the use of specially written functions.
However I need to be sure the TMS570 will not try and access this address range in any of its background routines (or as a result of array generation from my code) as data can not be stored at these addresses with out preparing the NOR flash.
Can you confirm that the TMS570 will not try and do this or alternatively indicate how the TMS570 can be set up to have this address range protected or access restricted?
Thanks in advance
Alex
Alex,
Would you please double check the PINMUX settings? You can use the following code to set up PINMUX for EMIF.
/* --------------------------------------------------------------------- *//* Configure the IOMM for EMIF pins *//* --------------------------------------------------------------------- *//*Unlock the IOMM Register*/ *(int *) 0xFFFFEA38 = 0x83E70B13; *(int *) 0xFFFFEA3C = 0x95A4F1E0;/*Configure the IOMM Register*/ *(int *) 0xFFFFFFA0 |= 0x80000000; *(int *) 0xFFFFEB14 = 0x02020101;//P1 //EMIF_DATA[5],EMIF_DATA[4] *(int *) 0xFFFFEB18 = 0x01010201;//P2 //EMIF_DATA[6] *(int *) 0xFFFFEB1C = 0x02010102;//P3 //EMIF_DATA[8],EMIF_DATA[7] *(int *) 0xFFFFEB20 = 0x01010201;//P4 //EMIF_DATA[9] *(int *) 0xFFFFEB24 = 0x02010101;//P5 //EMIF_DATA[10] *(int *) 0xFFFFEB28 = 0x02010201;//P6 //EMIF_DATA[12],EMIF_DATA[11] *(int *) 0xFFFFEB2C = 0x02010102;//P7 //EMIF_DATA[14],EMIF_DATA[13] *(int *) 0xFFFFEB30 = 0x02010101;//P8 //EMIF_DATA[15] *(int *) 0xFFFFEB38 = 0x02010201;//P10 //EMIF_DATA[2],EMIF_DATA[3] *(int *) 0xFFFFEB3C = 0x01020101;//P11 //EMIF_DATA[1] *(int *) 0xFFFFEB40 = 0x01010201;//P12 //EMIF_DATA[0]// *(int *) 0xFFFFEB48 = 0x01020101;//P14 // EMIF_RNW Read not Write *(int *) 0xFFFFEB50 = 0x02010102;//P16 //EMIF_nOE,EMIF_BA[0] *(int *) 0xFFFFEB54 = 0x02010201;//P17 //EMIF_ADDR[5],EMIF_nDQM[1] *(int *) 0xFFFFEB5C = 0x02020102;//P19 //EMIF_ADDR[3],EMIF_nDQM[0],EMIF_ADDR[4] *(int *) 0xFFFFEB68 = 0x02010101;//P22 //EMIF_ADDR[2] *(int *) 0xFFFFEB84 = 0x01010001;//P29 //EMIF_CLK writing 0 to the 8th bit of pinmux
Thanks and regards,
Zhaohong
Please ignore my reply. I forgot that you are using TMS570LS20216. Let me do some other checking. Sorry for the confusion.
Hi Zhaohong,
In my previous message I wrote
volatile unsigned short * p = (volatile unsigned short *)0x60000002;
this should have been
volatile unsigned int * p = (volatile unsigned int *)0x60000002;
As for the setup of the mpu, I've looked through the code and I don't believe Halcogen initiates the MPU, so I've tried including _mpuInit_(); and _mpuEnable_(); but this just causes the TMS570 to hang at the following line in sys_intvecs.asm
dataEntry b dataEntry
The only settings I have changed are in Region 5, I've attached the Halcogen file. 4336.EB-NOR.zip
Cheers,
I found a TMS570LS20216 EVM with external async RAM. I tried CPU and DMA write and reads. They all work correctly. I am guessing that you are accessing the NORFLASH control keys in wrong 16 bit address because the CPU is BIG Endian. Would you please send the model number of the NORFLASH so that we can make more specific suggestions?
The NOR flash is S29JL064H.
I'm having issues writing to RevCdStat (Revision Code and Status Register (RCSR)), using the method mentioned previously I seem to be able to write to Async1Cfg (Asynchronous Configuration Registers (A1CR)) but not RevCdStat, is there a reason for this?
Due to this I can't set the EMIF to half rate.
Though having said that, regardless of the endianness of the NOR.
I should still see the pins (especially the CE pin) moving but I'm not, CE,WE,OE,ADD0-21 and DAT0-15 are all stationary.
I Thought I would try and see what was happening to the pins while using the auto refresh in the memory window, it turns out this is able to exercise the NOR flash.
So, what is wrong with my setup or the way I am trying to write to the NOR flash?
EMIF does not support unaligned access. You are doing 32 bit access at 16 bit address boundary. As indicated in your email, it causes data abort. To access 0x60000002, you have to define you pointer as "short".
I assume that you are using the word (16 bit) mode of S29JL064H and following the EMIF/memory connection block diagram of TI TRM. You need to use following definition for accessing the Flash control keys.
#define FLASH_CTL555 *( volatile short * )( FLASH_BASE + 0xAAA )
#define FLASH_CTL2AA *( volatile short * )( FLASH_BASE + 0x554 )
The control addresses (0x555 and 0x2aa) in the S29JL064H spec need to be multiplied by 2 for R4 to access correctly.
When you enable MPU, you also have to set up EMIF and other memory mapped peripheral registers into a valid MPU region in device or strongly ordered mode. Otherwise,you will not be able to access them after MPU is enabled.
Please let me know if the above suggestions would solve your problem.
I understand the issue with the TMS being 32bit aligned (something I had not noticed, new to this...) , in order to write to only 16bits of the 32bit structure could I not use a OR mask to differentiate between the upper and lower 16bit.
Alternatively if the pointer option is easier/more efficient then I'll use that, however I don't understand how it works so could you explain?
Basically I don't understand how you can access an address with a 16 bit pointer when it is located at an address greater than the 16 bit range? As I understand it if I point to 0x60000002 with a "short" it will truncate and point to 0x0002 instead?
Would you please explicitly state what the value of FLASH_BASE is?
As for the multiplication I now understand why this is needed too.
Even with the pointers would I still not need a mask to write only 16bit? alternatively how would the TMS570 behave if I wrote a full 32bits to an aligned address, would it first access the lower address on the NOR to write the lower 16bits and then access the next address to write the upper 16bits?
Thanks in advance,
FLASH_BASE is the start address of the EMIF CS region used. Fro example, FLASH_BASE = 0x60000000 if CS0 is used.
Let me first explain the difference in pointer types in c-code. 32 bit and 16 bit pointers have the same range (32 bit) . C-compiler generates STR/LDR instructions from the C-code using 32 bit bit pointers. Data abort will be generated if the address is not 32 bit aligned (ending with 0, 4, 8,C). For C-code using 16 bit pointers, C-compiler generates STRH/LDRH instructions. Data abort will be generated if the address is not 16 bit aligned (ending with 0, 2,4,6 8,A,C,E).
If you write/read a full 32bit value to an aligned address, EMIF will automatically generate 2 16 bit accesses to external memory. It is OK for reading from Flash. You should not use such access in program/erase because additional access will mess up the program/erase command sequence.
If your Flash is in 16 bit mode, you have to use 16 bit access (STRH/LDRH) in any program/erase operations. Using 16 bit pointer will enable compiler to generate code correctly.
Please let me if the above answers your question.
Thanks for clarifying all that for me!
I have set up the following pointers and constants:
volatile unsigned short *FLASH_BASE = (volatile unsigned short *)0x60000000;unsigned short Cycle1 = 0x00AA; unsigned short Cycle2 = 0x0055; #define NOR_UNLK_555 *(volatile unsigned short *)(FLASH_BASE + 0xAAA)#define NOR_UNLK_2AA *(volatile unsigned short *)(FLASH_BASE + 0x554)
I can now see the NOR pins being exercised which is good but they don't seem to be quite right.
With the following code, I tried to test the data pins.
for (i=0;i<0xFFFFFFFF;i++) { NOR_UNLK_555 = Cycle1; NOR_UNLK_2AA = Cycle1; }This should have put 0x00AA on the data pins DAT0-15
While the program was running I observed some pins staying constant while others oscillated.
DATA0 - Oscillating, Low -> High
DATA1 - Oscillating, High -> Low
DATA2 - Constant Low
DATA3 - Oscillating, High -> Low
DATA4 - Constant Low
DATA5 - Constant High
DATA6 - Constant Low
DATA7 - Oscillating, High -> Low
I next tried the following code to write two different values in a consecutive manner to the same address.
for (i=0;i<0xFFFFFFFF;i++) { NOR_UNLK_555 = Cycle1; NOR_UNLK_555 = Cycle2; }This resulted in the TMS570 not exercising the NOR, all pins (CE,WE & Data) were constant. The address pins instead had the address 0x0002CA applied. This address was also being applied by the TMS570 when it was running the following code
for (i=0;i<0xFFFFFFFF;i++) { NOR_UNLK_2AA = Cycle1; NOR_UNLK_2AA = Cycle2; }
While in reality I will never be write to the same address, I don't understand the behaviour of the EMIF, why does it ignore consecutive writes to the same address and more importantly why do some data pins oscillate when they should not?
This seems to be the reason why I cant get the NOR flash into program mode.
Kind regards,
Would you please check (1) EMIF configuration and (2) your hardware? I am attaching a simple test which I have verified in reading and write to an external async RAM. You may want to compare the EMIF setting in this test and your test.
5344.EMIF_Throughput.zip
When you monitor EMIF signals with an oscilloscope, I would suggest checking CE,WE, EMIF CLK and one data pin. Use CE as the trigger to the oscilloscope. In this way, you can also check the timing of those important signals when you write to Flash. If needed, we can also help you in reviewing your schematics.
I've had a look at the files you attached, while the EMIF file was helpful the MPU files are in assembly code which I have no experience in.
I tried to compile the code to see if it works but it aborts straight away, I've then spent the last few days trying to integrate it into my code but without success due to the changes in naming between your code and the code generated by Halcogen, simple substitution has not worked, nor anything else I tried.
With halcogen, assembly code is generated within _mpuEnable_ and _mpuSetRegion_ etc now I cannot see where this is called and CCS does not know how to deal with it (coding errors) when I call it myself.
The timing of the pins looks to ok, Its the function of them that seems to be the proble (see previous posts for details) I have not checked the EMIF CLK as it is not accessible (due to fbga) or used. As for the connections, all are direct connections form one pin to its counterpart on the NOR flash with a a pull up on the NOR's reset pin. This setup has been used successfully with a PIC18.
Would you please double check the connection of address pins for 16 bit mode? It should to be following.
EMIF BA1 <-> Nor A0
EMIF A0 <-> Nor A1
EMIF A1 <-> Nor A2
... ...
EMIF A20 <-> Nor A21
You also need a pull up at BYTE# pin of norflash to enable 16 bit mode.
Unfortunately it seems I missed that tiny footnote on page 334. If TI are planning to update the TRM/Datasheet I highly recommend re-iterating and maybe expanding on this point, especially in the pin description of the datasheet which implies it is only for 8-bit access.
The hardware can not be changed so I am after a software solution, first I will have to change the MPU region to be a 16Mb device.
As for addressing there seems to be a bit of a mess, possibly due to how the EMIF interfaces/short/int etc
0xAAA on the TMS570 outputs 0x555 while for the other program address things do not work so well
0x552 produces 0x2A9
0x553 produces 0x2A9
0x554 produces 0x2AB
The address I need is between those two!
Can you confirm this for me?