I have a product I have designed using the 5507. I want to use the address lines of the EMIF as GPIOs. It seems it should be easy enough to do:
1) Make sure GPIO0 is pulled LOW at RESET
2) Set bits 0 and 1 of ESBR to "00" or "11" to ensure the address lines can be configured as GPIOs
3) Enable whichever AGPIO lines I want to use - in my case, those are AGPO 0-7.
4) Set the direction of the enabled I/Os, either input or output
5) Read/write from the input/output
Sounds easy, but after a week of banging my head against the wall, I am still unable to read the inputs properly. I have a hex-coded rotary switch on AGPIO (0:3), but when I read the port, it does not correspond to the values on the pins.
I am using CCS 3.1 (yes, it is old, I know - but licensed). I modified my .gel file to add the I/O space for the AGPIO:
/* IO Space */
GEL_MapAdd(0x0000,2,0x0400,1,1); /* RHEA 1KW */
GEL_MapAdd(0x0400,2,0x0300,1,1); /* EMULATION */
GEL_MapAdd(0x0800,2,0x0400,1,1); /* EMIF 1KW */
GEL_MapAdd(0x0C00,2,0x0400,1,1); /* DMA 1KW */
GEL_MapAdd(0x1000,2,0x0400,1,1); /* TIMER#0 1KW */
GEL_MapAdd(0x1400,2,0x0400,1,1); /* ICACHE 1KW */
GEL_MapAdd(0x1C00,2,0x0400,1,1); /* CLKGEN 1KW */
GEL_MapAdd(0x2000,2,0x0400,1,1); /* TRACE FIFO 1KW */
GEL_MapAdd(0x2400,2,0x0400,1,1); /* TIMER#1 1KW */
GEL_MapAdd(0x2800,2,0x0400,1,1); /* SERIAL PORT#0 1KW */
GEL_MapAdd(0x2C00,2,0x0400,1,1); /* SERIAL PORT#1 1KW */
GEL_MapAdd(0x3000,2,0x0400,1,1); /* SERIAL PORT#2 1KW */
GEL_MapAdd(0x3400,2,0x0400,1,1); /* GPIO 1KW */
GEL_MapAdd(0x3800,2,0x0400,1,1); /* ID 1KW */
// GEL_MapAdd(0x3800,2,0x0400,1,1); /* ID 1KW */
GEL_MapAdd(0x4400,2,0x0006,1,1); /* AGPIO */
GEL_MapAdd(0x5800,2,0x2800,1,1); /* USB Regs and Buffer */
This didn't seem to enable the I/O memory space by itself inside CCS, so I added the following in the OnTargetConnect section:
OnTargetConnect()
{
GEL_MemoryFill(0x6C00,2,1,0x0203); //set ESBR parallel bits to binary 11 - allows for AGPIO
GEL_MemoryFill(0x4400,2,1,0xFFFF); //enable all the address lines as AGPIO
GEL_MemoryFill(0x4401,2,1,0xFFC0); //set the direction (input/output) so that bits 0-5 are inputs and 6-7 are outputs
GEL_MemoryFill(0x4402,2,1,0xFFFF); //set the AGPIO data port to 0xFFFF
init_emif();
}
The "init_emif()" was a section I had added before, when I had thought I would require an external SDRAM for storage. I have removed the SDRAM from my board. If I try to remove init_emif(), I can't get the target to connect properly in CCS:
init_emif()
{
*( unsigned int* )0x0801@IO = 0x0; // EMI_RST
*( unsigned int* )0x0800@IO = 0x0220; // EGCR
*( unsigned int* )0x0803@IO = 0x3FFF; // EMIF CE0_1
*( unsigned int* )0x0804@IO = 0x5FFF; // EMIF CE0_2
*( unsigned int* )0x0805@IO = 0x0; // EMIF CE0_3
*( unsigned int* )0x0806@IO = 0x3FFF; // EMIF_CE1_1
*( unsigned int* )0x0807@IO = 0x5FFF; // EMIF_CE1_2
*( unsigned int* )0x0808@IO = 0x0000; // EMIF_CE1_3
*( unsigned int* )0x0809@IO = 0x3FFF; // EMIF_CE2_1
*( unsigned int* )0x080A@IO = 0x5FFF; // EMIF_CE2_2
*( unsigned int* )0x080B@IO = 0x0000; // EMIF_CE2_3
*( unsigned int* )0x080C@IO = 0x3FFF; // EMIF_CE3_1
*( unsigned int* )0x080D@IO = 0x5FFF; // EMIF_CE3_2
*( unsigned int* )0x080E@IO = 0x0000; // EMIF_CE3_3
*( unsigned int* )0x080F@IO = 0x3522; // SDC1
*( unsigned int* )0x0810@IO = 0x0100; // SDPER
//*( unsigned int* )0x0811@IO = 0x0FFF; // SDCNT
*( unsigned int* )0x0812@IO = 0x0000; // INIT
*( unsigned int* )0x0813@IO = 0x0242; // SDC2
// *( unsigned int* )0x0814@IO = 0x0003; // SDC2
}
When I open CCS and connect to the target (leaving init_emif in the .gel), it works fine, but I/O address space 0x4400 is inaccessible, all dashes. Curiously, if I then "Load GEL" and load the exact same .gel file I used to connect, 0x440x is then accessible.
However, when I step through my code and read the data from pins AGPIO 0-4, the reading is in no way related to the setting of the hex switch. I have tried doing both GPIO_pinRead commands:
Gpin0 = GPIO_pinRead(AGPIO_PIN0);
Gpin1 = GPIO_pinRead(AGPIO_PIN1);
Gpin2 = GPIO_pinRead(AGPIO_PIN2);
Gpin3 = GPIO_pinRead(AGPIO_PIN3);
and have defined a variable to read the memory location at 0x4402, which is supposed to contain the values on the pins:
ioport volatile Uint16 * AGPIODATA = (ioport volatile Uint16 *)0x4402; //variable definition
hex_switch_input = *AGPIODATA; //reading the data at I/O port 0x4402
Neither method works. I am so puzzled and frustrated. Does anybody have ideas what I might be doing wrong? Thank you.