AnsweredAssumed Answered

Interfacing a K61 to an external SRAM

Question asked by gorakk on Apr 4, 2013
Latest reply on Oct 17, 2014 by Carlos Candido

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" );  

 

 

Outcomes