I am attempting to use an ISSI external SRAM with a Kinetis K61. The SRAM is the IS62WV51216BLL - 8M bit organized as 512K words by 16 bits.
The connections are non-multiplexed - 16 bits data, 19 bits address.
It is partially working at this point - I can address data up to 0x6003FFFF. Attempting to access something at 0x60040000 or above fails - a hard fault. My first thought is that at 0x60040000 the FB_A16 line is used - and FB_A16 falls out of the "normal" FlexBus range.
I have code to configure pins as FB_A16, FB_A17, and FB_A18 but I am unsure if something else needs to be configured as well.
Does anyone have any suggestions?
MCU to SRAM connections:
Data Lines
MCU SRAM
FB_AD16 I/O0
FB_AD17 I/O1
FB_AD18 I/O2
FB_AD19 I/O3
FB_AD20 I/O4
FB_AD21 I/O5
FB_AD22 I/O6
FB_AD23 I/O7
FB_AD24 I/O8
FB_AD25 I/O9
FB_AD26 I/O10
FB_AD27 I/O11
FB_AD28 I/O12
FB_AD29 I/O13
FB_AD30 I/O14
FB_AD31 I/O15
Address Lines
MCU SRAM
FB_AD0 A0
FB_AD1 A1
FB_AD2 A2
FB_AD3 A3
FB_AD4 A4
FB_AD5 A5
FB_AD6 A6
FB_AD7 A7
FB_AD8 A8
FB_AD9 A9
FB_AD10 A10
FB_AD11 A11
FB_AD12 A12
FB_AD13 A13
FB_AD14 A14
FB_AD15 A15
FB_A16 A16 |
FB_A17 A17 | - notice these are connected to "FB_A" and not "FB_AD"
FB_A18 A18 |
Here is the initialization code - it is based upon a FlexBus example found in the CodeWarrior MCU 10.1 Software Examples.
#define SRAM_START_ADDRESS (*(volatile uint32_t*)(0x60000000))
//#define SRAM_MEMORY_WORDS 0x00040000 // this gives a hard fault
#define SRAM_MEMORY_WORDS 0x0003FFFF // this works
void FlexbusInit(void)
{
SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK; // Enable Clock to PORTB
SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK; // Enable Clock to PORTC
SIM->SCGC5 |= SIM_SCGC5_PORTD_MASK; // Enable Clock to PORTD
SIM->SCGC7 |= SIM_SCGC7_FLEXBUS_MASK; // Enable the FlexBus controller clock
// Set Base address
FB->CS[0].CSAR = (uint32_t)&SRAM_START_ADDRESS;
FB->CS[0].CSCR = FB_CSCR_PS(2) // 16-bit data port width
| FB_CSCR_AA_MASK // auto-acknowledge
| FB_CSCR_ASET(0x1) // assert chip select on second clock edge after address is asserted
| FB_CSCR_WS(0x1) // 1 wait state
| FB_CSCR_BEM_MASK // Byte-enable mode - byte enable signals are asserted
;
FB->CS[0].CSMR = FB_CSMR_BAM(0x000F) //Set base address mask for 1Mbyte address space
| FB_CSMR_V_MASK //Enable cs signal
;
// Enable BE signals
FB->CSPMCR = 0x02200000;
// fb clock divider 3
SIM->CLKDIV1 |= SIM_CLKDIV1_OUTDIV3(0x3);
// Address lines
PORTD->PCR[10] = (6UL << 8); // fb_a[18]
PORTD->PCR[9] = (6UL << 8); // fb_a[17]
PORTD->PCR[8] = (6UL << 8); // fb_a[16]
PORTB->PCR[18] = (5UL << 8); // fb_ad[15] < - able to address up to here right now...
PORTC->PCR[0] = (5UL << 8); // fb_ad[14]
PORTC->PCR[1] = (5UL << 8); // fb_ad[13]
PORTC->PCR[2] = (5UL << 8); // fb_ad[12]
PORTC->PCR[4] = (5UL << 8); // fb_ad[11]
PORTC->PCR[5] = (5UL << 8); // fb_ad[10]
PORTC->PCR[6] = (5UL << 8); // fb_ad[9]
PORTC->PCR[7] = (5UL << 8); // fb_ad[8]
PORTC->PCR[8] = (5UL << 8); // fb_ad[7]
PORTC->PCR[9] = (5UL << 8); // fb_ad[6]
PORTC->PCR[10] = (5UL << 8); // fb_ad[5]
PORTD->PCR[2] = (5UL << 8); // fb_ad[4]
PORTD->PCR[3] = (5UL << 8); // fb_ad[3]
PORTD->PCR[4] = (5UL << 8); // fb_ad[2]
PORTD->PCR[5] = (5UL << 8); // fb_ad[1]
PORTD->PCR[6] = (5UL << 8); // fb_ad[0]
// Data lines
PORTB->PCR[20] = (5UL << 8); // fb_ad[31] used as d[15]
PORTB->PCR[21] = (5UL << 8); // fb_ad[30] used as d[14]
PORTB->PCR[22] = (5UL << 8); // fb_ad[29] used as d[13]
PORTB->PCR[23] = (5UL << 8); // fb_ad[28] used as d[12]
PORTC->PCR[12] = (5UL << 8); // fb_ad[27] used as d[11]
PORTC->PCR[13] = (5UL << 8); // fb_ad[26] used as d[10]
PORTC->PCR[14] = (5UL << 8); // fb_ad[25] used as d[9]
PORTC->PCR[15] = (5UL << 8); // fb_ad[24] used as d[8]
PORTB->PCR[6] = (5UL << 8); // fb_ad[23] used as d[7]
PORTB->PCR[7] = (5UL << 8); // fb_ad[22] used as d[6]
PORTB->PCR[8] = (5UL << 8); // fb_ad[21] used as d[5]
PORTB->PCR[9] = (5UL << 8); // fb_ad[20] used as d[4]
PORTB->PCR[10] = (5UL << 8); // fb_ad[19] used as d[3]
PORTB->PCR[11] = (5UL << 8); // fb_ad[18] used as d[2]
PORTB->PCR[16] = (5UL << 8); // fb_ad[17] used as d[1]
PORTB->PCR[17] = (5UL << 8); // fb_ad[16] used as d[0]
// Control signals
PORTB->PCR[19] = (5UL << 8); // fb_oe_b
PORTC->PCR[11] = (5UL << 8); // fb_rw_b
PORTD->PCR[1] = (5UL << 8); // fb_cs0_b
PORTC->PCR[17] = (5UL << 8); // fb_BE15_8 UpperByte
PORTC->PCR[16] = (5UL << 8); // fb_BE7_0 LowerByte
// Control the ISSI CS2 line as a GPIO - set it high and leave it there.
PORTD->PCR[0] = (1UL << 8);
PTD->PDOR |= 1UL << 0;
PTD->PDDR |= 1UL << 0;
PTD->PSOR = 1UL << 0;
}
from the function that accesses the memory - hard fault once 0x60040000 is accessed...
FlexbusInit();
printf( "\nClearing memory area...\n" );
for( n = 0x00000000; n <= SRAM_MEMORY_WORDS; n++ ) // address offset
{
*(volatile uint32_t*)( &SRAM_START_ADDRESS + n ) = 0x00; // write
}
printf( "Memory clear complete\n" );