|
|
View previous topic :: View next topic |
Author |
Message |
rooney
Joined: 28 Aug 2004 Posts: 8
|
External Memory Interface on a PIC18F8722 |
Posted: Sun Jan 01, 2006 7:50 am |
|
|
Strange things are happening with my external memory bus.
I'm doing a project where I need to increase my program and data memory.
Therefore I connected two 32kB memories via the 16 bit byte write mode (as shown in the datasheet of the PIC18F8722) to the external memory bus. By the way, the right wiring to the controller has been proofen by manually writing and reading to the external SRAM memory (pin toggling).
I set the fuses ABW20 and BW16 as well as EMCU.
Set the correct value for the MEMCON register and disabled everything that is not relevant for the external memory interface.
As latches I use two 74HC574 and two high speed SRAMs (15ns). FCPU = 10MHz.
When I use the CCS functions write_external_memory/read_external_memory and use the SRAM base address 0x20000 I get all necessary signals (CS_n, OE_n, WRL_n, WRH_n - proofen with an oscilloscope).
That's what the code look like:
unsigned char buffer[4];
unsigned char readData[4];
buffer[0] = 0xAA;
buffer[1] = 0xBB;
buffer[2] = 0xCC;
buffer[3] = 0xDD;
write_external_memory(0x20000, buffer, 4);
read_external_memory(0x20000, readData, 4);
If it would work, the readData should hold the same data as buffer, but it doesn't. It holds 0xDD 0xCC 0xDD 0xCC.
It seems as the controller do a very strange writing.
Does anybody have ideas? Source Code available? |
|
|
Ttelmah Guest
|
|
Posted: Sun Jan 01, 2006 9:05 am |
|
|
First thing, try changing the patterns you write, to something like:
0x11,0x22,0x33,0x44
The fault you are seeing, looks like address line 1, is stuck (either high or low), or shorted to line 0. With your data pattern, you cannot tell if the data bus is also stuck (since bit 0, and bit 1, are the same in all the patterns - this would narrow down the problem to before or after the latches). Now you say you have tested it, but would the test you have done, 'find' a short between RD0, and RD1?. If you only accessed single bytes, and the data pattern was like your current test pattern, this would not be visible. The other obvious difference with bit toggling, is the speed of operation, and a resistive connection, or a lot of capacitance on the line, might show in normal use, and not using bit I/O.
Best Wishes |
|
|
rooney
Joined: 28 Aug 2004 Posts: 8
|
|
Posted: Wed Jan 11, 2006 5:26 am |
|
|
Changed the pattern but no difference, even proofed each line for shorts.
Resistance and capacitance would be a point for change. But how to do? The traces are relatively short from controller to sram. By the way, used pull-ups for address/data lines. But anyway, pull-ups don't have an effect on my problem.
Any suggestions? |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Wed Jan 11, 2006 8:46 am |
|
|
rooney wrote: | Changed the pattern but no difference, even proofed each line for shorts.
Resistance and capacitance would be a point for change. But how to do? The traces are relatively short from controller to sram. By the way, used pull-ups for address/data lines. But anyway, pull-ups don't have an effect on my problem.
Any suggestions? |
You say you checked for shorted lines. Did you also check for open lines? An open address line can take on the value of its neighbor during operation due to the high input impedance of the line. _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Wed Jan 11, 2006 9:10 am |
|
|
Using a complementery data pattern 0xAA / 0x55 you can test R/W cycles dynamically
while looking with the scope every single data line expecting a symetrical square wave
if the line involved is OK, otherwise you'll see an unsymetrical square wave.
Use the ALE as oscilloscope trigger.
Humberto |
|
|
rooney
Joined: 28 Aug 2004 Posts: 8
|
|
Posted: Mon Jan 16, 2006 12:15 am |
|
|
Thanks to Humberto, tried to trigger on the ALE signal and prooved the timing. As I've seen the address couldn't be loaded into the latches (74HC574) as the address changes at the same moment as the ALE signal. The 74HC574 is positive edge-triggered and would loade its latches on the 0 to 1 transition of the ALE signal.
The reason is clear, Microchip suggests the transparent latch 74HC373 anyway that is not edge triggered but level triggered. To do a workaround till I get some 74HC373 I invert the ALE signal to produce a delay of 1 TCY.
But there is still a problem...
Imaging following situation.
#int_CCP2
CCP2_isr{
//some code
}
void main (void)
{
unsigned char buffer[100];
setup_ccp2(...);
enable_interrupts(INT_CCP2);
enable_interrupts(GLOBAL);
setup_external_memory(EXTMEM_DISABLE|EXTMEM_BYTE_WRITE|EXTMEM_WAIT_3);
while(1)
{
read_external_memory(EXT_MEM_BASE_ADR, buffer, 100);
}
}
I know this code is absolutely stupid, but anyway...
One of the capture inputs (CCP2) generates periodically an interrupt (about every 20ms) performing some writing/reading from an HDD that is mapped on the same pins as occupied by the external memory bus. As information, the EMI has been configured just to use the EMI port functions if reads and writes are performed to the external memory otherwise the port pins are in "normal" mode. If I do so the interrupt will not be served or sometimes will be served several times but will than stop after some time. Tried to changed the priority of the interrupt to high priority but no difference.
If I insert a Delay of about 10ms after the read_external_memory it works... Can't the reading/writing function not be halted due to an interrupt?
By the way, I use the external memory just for data memory (RAM), data read out from the HDD. |
|
|
rooney
Joined: 28 Aug 2004 Posts: 8
|
...still having problems |
Posted: Mon Jan 16, 2006 12:15 am |
|
|
Thanks to Humberto, tried to trigger on the ALE signal and prooved the timing. As I've seen the address couldn't be loaded into the latches (74HC574) as the address changes at the same moment as the ALE signal. The 74HC574 is positive edge-triggered and would loade its latches on the 0 to 1 transition of the ALE signal.
The reason is clear, Microchip suggests the transparent latch 74HC373 anyway that is not edge triggered but level triggered. To do a workaround till I get some 74HC373 I invert the ALE signal to produce a delay of 1 TCY.
But there is still a problem...
Imaging following situation.
#int_CCP2
CCP2_isr{
//some code
}
void main (void)
{
unsigned char buffer[100];
setup_ccp2(...);
enable_interrupts(INT_CCP2);
enable_interrupts(GLOBAL);
setup_external_memory(EXTMEM_DISABLE|EXTMEM_BYTE_WRITE|EXTMEM_WAIT_3);
while(1)
{
read_external_memory(EXT_MEM_BASE_ADR, buffer, 100);
}
}
I know this code is absolutely stupid, but anyway...
One of the capture inputs (CCP2) generates periodically an interrupt (about every 20ms) performing some writing/reading from an HDD that is mapped on the same pins as occupied by the external memory bus. As information, the EMI has been configured just to use the EMI port functions if reads and writes are performed to the external memory otherwise the port pins are in "normal" mode. If I do so the interrupt will not be served or sometimes will be served several times but will than stop after some time. Tried to changed the priority of the interrupt to high priority but no difference.
If I insert a Delay of about 10ms after the read_external_memory it works... Can't the reading/writing function not be halted due to an interrupt?
By the way, I use the external memory just for data memory (RAM), data read out from the HDD. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Mon Jan 16, 2006 12:09 pm |
|
|
Quote: |
If I insert a Delay of about 10ms after the read_external_memory it works... Can't the reading/writing function not be halted due to an interrupt?
|
It seems something wrong related to delays involved in the data transfer.
If you had set the waits bits 4 (WAIT0) and 5 (WAIT1) in the MEMCON register,
you will be aware that there is a Microchip errata involving all PIC18F8xxx
devices warning for an incorrect increment of the Stack Pointer during a table read
operation if those bits are set.
To workaround this, you should disable the GLOBAL (GIE/GIEH) interrupt and the
(PEIE/GIEL) bits prior to executing any TBLRD operation.
Code: |
{
disable_interrupts(GLOBAL);
read_external_memory(EXT_MEM_BASE_ADR, buffer, 100);
enable_interrupts(GLOBAL);
}
|
Humberto |
|
|
rooney
Joined: 28 Aug 2004 Posts: 8
|
|
Posted: Thu Jan 19, 2006 4:44 am |
|
|
Well, I've already thought on disabling the interrupts, but didn't know the information provided by the errata. I think I will download it and read...
I'm now disabling the interrupts. If an interrupt occurs while reading or writing to external memory, the flag will be set and the interrupt will be served as soon as the interrupt enable bit will be set again (after reading/writing). Well that's just a workaround. Still not a very good solution, because if the read/write operation would exceed a specified period - period of the pulses on the CCP2 input - than the whole system will crash. The interrupt tells me when the MP3 decoder that is running in my system needs new data. If I don't provide the data at this moment than the MP3 file will not be played correctly. If no other solution, I will have to keep the access times to external memory very low...
As I don't really know, what's about this stack pointer increment?
What really happens when an interrupt occurs? |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Mon Jan 23, 2006 5:53 pm |
|
|
Quote: |
Still not a very good solution, because if the read/write operation would exceed a specified period - period of the pulses on the CCP2 input - than the whole system will crash.
|
Don't understand what you mean with "would exceed a specific period.." am I wrong but
does this procedure shouldn't spent the same cycles/time every time is used?
I mean, once defined, the byte read or write mode timming shouldn't be the same ?
Quote: |
As I don't really know, what's about this stack pointer increment?
|
During a call instruction, the Program Counter is stored temporary (Pushed) onto the Stack Pointer.
The Stack Pointer increments before values are pushed onto the stack and decrements after values
are popped off the stack. This pointer can get values from 0 to 31, when it reach to its maximum value,
(31) the STKFUL bit is set. Similarly, when the pointer is 0, the STKUNF bit is set.
The action that take place when the stack is full, depends of the STVR (bit0) Stack Full/Underflow
Reset Enable bit in the Configuration Register CONFIG4L. This is usefull while debugging to know
if the reset was caused by the Program Counter.
Humberto |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|