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,
Three WE pulses for one write instruction indicates that the external memory space is configured in normal mode. Which version of Halcogen tool do you use? Can you try the assembly code I in the project I sent earlier?
Thanks and regards,
Zhaohong
Hi Zhaohong,
The version of Halcogen I'm using is 03.01.01
I'll try your code again once I get to the lab later.
When you say normal mode you mean the Normal/Strobe option in A1CR register? Last night I also tried the strobe mode, I cant remember exactly but I'm pretty sure the WE pulses were the same, only the CE pulse changed.
Can you explain why there are 3 WE pulses, only 16 bits are being written to D0-16 at a single address, which to me should be one pulse.
Regards,
When the code is loaded it runs straight away but there are no signals observed on the line CE,WE,OE or A0.
When halt is clicked in CCS it halts at:
void pabort(void){ while(1); /* Do not return ... */}
a break point placed at
Set_MPU_Region (0, 0, 0x2B, 0x308); // 4MB
or
*(int *)0x60000000 = 0x12345678;*(int *)0x60000000 = 0x0;*(short *)0x60000001 = 0x12;
does not result in the code halting, further investigation shows that the system halts after running void System_Init(void)
I can confirm that the EMIF was in normal mode in the previous image.
For Normal A1CR is 0x4C466231, while for Strobe it is 0xCC466231
The following image is of the TMS570 writing to the same three addresses but in strobe mode.
I am sorry that I did not explain clearly in my earlier email.
You observed 3 WE pulses for one 16 bit write to Norflash. It is not an EMIf issue. It is caused by R4 CPU. As we discussed earlier in this thread, you have to set R4 MPU to "strongly ordered" or "device" modes for CPU to access norflash correctly. By default, external memory region is considered as "normal" by R4 CPU. It could generate more than one access for one read/write instruction because CPU considers the memory as RAM.
Please check your MPU seting for the norflash region. You see 3 WE pulses because it is set to "normal".
There could be numerous reasons for a test to become in-consistent. First of all, I would recommend performing a "system reset" before each test run. Another thing I normally do in debugging is to replace "b _cint00" at address 0x0 by "b #-8". Every time after reset, I want to make sure to see CPU is locked to address 0x0 without any intervention of debugger. It can be considered one indicator of if CPU is boot up correctly.
Would you please check the reset signals (poower-on-reset and nreset) along with 1.2 and 3.3V supplies. I did see that device could boot up partially (some modules do not come out of reset correctly) if the rising edge of reset signals is too long. It is normally an intermittent behavior. You may want use TI EVM as a reference for H/W design.
In one of my early replies, I messed up OE with the ready signal. Sorry for the confusion.
Since recommended in one of the first posts in this thread I set up the NOR flash MPU region to be device non-shareable, since WE started functioning I've also tried with the region set to strongly ordered and device shareable with no change to the waveform of EMIF_WE.
The project you posted uses variables to set up the MPU, as I can't get that working can you send me the equivalent assembly code?
Within sys_mpu.asm I have the following for region 5
; Setup region 5 mov r0, #4 mcr p15, #0, r0, c6, c2, #0 ldr r0, r5Base mcr p15, #0, r0, c6, c1, #0 mov r0, #0x0000 orr r0, r0, #0x1300 mcr p15, #0, r0, c6, c1, #4 movw r0, #((0 << 15) + (0 << 14) + (0 << 13) + (0 << 12) + (0 << 11) + (0 << 10) + (1 << 9) + (0 << 8) + (0x17 << 1) + (1)) mcr p15, #0, r0, c6, c1, #2
Here is my Halcogen file and the full .asm file.
8737.EB-EMIF-TI - 21.zip
I will check the reset signals now.
Cheers,
So the important line in the assembly code is:
mov r0, #0x0000
For the different options the following assembly code is produced by Halcogen
STRONGLYORDERED_SHAREABLE -> mov r0, #0x0000
DEVICE_SHAREABLE -> mov r0, #0x0001
NORMAL_OINC_NONSHARED -> mov r0, #0x0008
NORMAL_OINC_SHARED -> mov r0, #0x000C
DEVICE_NONSHAREABLE -> mov r0, #0x0010
Which all matches up to the table 7.3 in the ARM TRM, however on the TMS570 I can not locate the address of the register written too, so i can not check its values after the TMS570 has been programmed. Can you let me know where it it located.
CP15 register is not memory mapped. You can read the value back using "mrc" instruction. For example, "mcr p15, #0, r0, c6, c1, #4" is used to set up the memory type. You can read the programmed value back in r0 using "mrc p15, #0, r0, c6, c1, #4".
I've placed the code asm (" mrc p15, #0, r0, c6, c1, #4 "); in a few locations within my code.
before main() in the sys_startup.c file the code returns the value 0x00000F24, this is seen in the Registers window next to R0 within "Core Registers"
-this value does not match up to the ARM TRM where bit 5 is only high for "Cacheable memory", in other runs its also retunred the values 0x00000F2C
The other locations (after statement of variables in main(), after initialisation of EMIF and after the first three EMIF writes) all give a 0x0 return, tough i dont believe it is returning the register I'm hoping for.
I've also tried another way of writing to the NOR flash using the coding below:
volatile unsigned short *NOR_UNLK_555 = (volatile unsigned short *)0x60001554;volatile unsigned short *NOR_UNLK_2AA = (volatile unsigned short *)0x60000AA8;
with the following to write to the addresses
*NOR_UNLK_555 = Cycle1; //Cycle 1 *NOR_UNLK_2AA = Cycle2; //Cycle 2 *NOR_UNLK_555 = Cycle3; //Cycle 3
this produced the following waveforms:
which as you can see only has two WE pulses for the first and last CE pulse, while the middle (writing to NOR_UNLK_2AA) still has 3 pulses.
This is compared to the way I coded before:
#define NOR_UNLK_555 *(volatile unsigned short *)(FLASH_BASE + 0x00001554)#define NOR_UNLK_2AA *(volatile unsigned short *)(FLASH_BASE + 0x00000AA8)
with the following code to write to the NOR addresses
NOR_UNLK_555 = Cycle1; //Cycle 1 NOR_UNLK_2AA = Cycle2; //Cycle 2 NOR_UNLK_555 = Cycle3; //Cycle 3
which produces
This was all carried out in strongly ordered & PRIV_RW_USER_RW_NOEXEC mode.
MPU region ID needs to be set before reading the memory type. You can call the following assembly function from C-code.
.global Read_MPU_MEMORY_TYPE
Read_MPU_MEMORY_TYPE MCR p15, #0, r0, c6, c2, #0 MRC p15, #0, r0, c6, c1, #4 MOV pc, lr
In C-code,
extern unsigned int Read_MPU_MEMORY_TYPE(unsigned int region);
unsigned int temp;
temp = Read_MPU_MEMORY_TYPE(0);
Thanks and reagrds,
I placed the assembly at the end of one of the .asm files.
When I run the code it runs through the asembly, i can see the 5 being passed but it still returns 0x00000000, this is with region 5 set up as device nonshareable, chosen as it is a non-zero value.
Again i ran the code at different places within my project, specifically I used
temp = Read_MPU_MEMORY_TYPE(5);
cheers,
alex
You may wan to use "MRC p15, #0, r0, c1, c0, #0" to see if MPU is enabled. If MPU is not enabled, the memory type for external memory region is "normal".