Interfacing a K61 to an external SRAM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Interfacing a K61 to an external SRAM

Jump to solution
2,991 Views
gorakk
Contributor IV

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

Labels (1)
1 Solution
1,503 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Allen,

//#define SRAM_MEMORY_WORDS   0x00040000   // this gives a hard fault

for( n = 0x00000000; n <= SRAM_MEMORY_WORDS; n++ )  // address offset

  {

    *(volatile uint32_t*)( &SRAM_START_ADDRESS + n ) = 0x00;  // write

  }

From the above code, you  access the external memory with 32 bits data, so all the memory byte space you accessed is 0x40000*4=0x10 0000, it exceeds the space you defined by the

FB->CS[0].CSMR  =   FB_CSMR_BAM(0x000F) which is from 0x6000 0000 to 0x600F FFFF,

that is why there is hard fault.

BR

XiangJun Rong

View solution in original post

0 Kudos
8 Replies
1,503 Views
gorakk
Contributor IV

Just for reference - here is the current configuration that I am using for the ISSI IS62WV51216BLL SRAM.  The init_hw.c file contains these two functions that I adapted for our custom board.


/*FUNCTION*---------------------------------------------------------------------

*

* Function Name    : _bsp_flexbus_setup

* Returned Value   :  none

* Comments         :

*    Setup FlexBus pins for early SRAM operation. SRAM is an ISSI IS62WV51216BLL.

*

*END*-------------------------------------------------------------------------*/

static void _bsp_flexbus_setup (void)

{

    #define ALT5                    0x05

    #define ALT6                    0x06

    #define OFF_CHIP_ACCESS_ALLOW   3

    PORT_MemMapPtr  pctl;

    SIM_MemMapPtr   sim = SIM_BASE_PTR;

    FB_MemMapPtr    fb_ptr = FB_BASE_PTR;

    /* Enable clock to FlexBus module */

    sim->SCGC7 |= SIM_SCGC7_FLEXBUS_MASK; 

    sim->CLKDIV1 |= SIM_CLKDIV1_OUTDIV3(0x3);

    sim->SOPT2 |= SIM_SOPT2_FBSL(OFF_CHIP_ACCESS_ALLOW);    

    pctl = (PORT_MemMapPtr)PORTB_BASE_PTR;

    pctl->PCR[6] =  PORT_PCR_MUX( ALT5 ); // fb_ad[23]  used as d[7]

    pctl->PCR[7] =  PORT_PCR_MUX( ALT5 ); // fb_ad[22]  used as d[6]

    pctl->PCR[8] =  PORT_PCR_MUX( ALT5 ); // fb_ad[21]  used as d[5]

    pctl->PCR[9] =  PORT_PCR_MUX( ALT5 ); // fb_ad[20]  used as d[4]  

    pctl->PCR[10] = PORT_PCR_MUX( ALT5 ); // fb_ad[19]  used as d[3]

    pctl->PCR[11] = PORT_PCR_MUX( ALT5 ); // fb_ad[18]  used as d[2]

    pctl->PCR[16] = PORT_PCR_MUX( ALT5 ); // fb_ad[17]  used as d[1]

    pctl->PCR[17] = PORT_PCR_MUX( ALT5 ); // fb_ad[16]  used as d[0]

    pctl->PCR[18] = PORT_PCR_MUX( ALT5 ); // fb_ad[15]  used as a[15]

    pctl->PCR[19] = PORT_PCR_MUX( ALT5 ); // fb_oe_b

    pctl->PCR[20] = PORT_PCR_MUX( ALT5 ); // fb_ad[31]  used as d[15]

    pctl->PCR[21] = PORT_PCR_MUX( ALT5 ); // fb_ad[30]  used as d[14]

    pctl->PCR[22] = PORT_PCR_MUX( ALT5 ); // fb_ad[29]  used as d[13]

    pctl->PCR[23] = PORT_PCR_MUX( ALT5 ); // fb_ad[28]  used as d[12]

   

    pctl = (PORT_MemMapPtr)PORTC_BASE_PTR;

    pctl->PCR[0]  = PORT_PCR_MUX( ALT5 ); // fb_ad[14]  used as a[14]

    pctl->PCR[1]  = PORT_PCR_MUX( ALT5 ); // fb_ad[13]  used as a[13]

    pctl->PCR[2]  = PORT_PCR_MUX( ALT5 ); // fb_ad[12]  used as a[12]

    pctl->PCR[4]  = PORT_PCR_MUX( ALT5 ); // fb_ad[11]  used as a[11]

    pctl->PCR[5]  = PORT_PCR_MUX( ALT5 ); // fb_ad[10]  used as a[10]

    pctl->PCR[6]  = PORT_PCR_MUX( ALT5 ); // fb_ad[9]   used as a[9]

    pctl->PCR[7]  = PORT_PCR_MUX( ALT5 ); // fb_ad[8]   used as a[8]

    pctl->PCR[8]  = PORT_PCR_MUX( ALT5 ); // fb_ad[7]   used as a[7] 

    pctl->PCR[9]  = PORT_PCR_MUX( ALT5 ); // fb_ad[6]   used as a[6]

    pctl->PCR[10] = PORT_PCR_MUX( ALT5 ); // fb_ad[5]   used as a[5]

    pctl->PCR[11] = PORT_PCR_MUX( ALT5 ); // fb_rw_b

    pctl->PCR[12] = PORT_PCR_MUX( ALT5 ); // fb_ad[27]  used as d[11]

    pctl->PCR[13] = PORT_PCR_MUX( ALT5 ); // fb_ad[26]  used as d[10]

    pctl->PCR[14] = PORT_PCR_MUX( ALT5 ); // fb_ad[25]  used as d[9] 

    pctl->PCR[15] = PORT_PCR_MUX( ALT5 ); // fb_ad[24]  used as d[8]     

    pctl->PCR[16] = PORT_PCR_MUX( ALT5 ); // fb_BE_23_16 

    pctl->PCR[17] = PORT_PCR_MUX( ALT5 ); // fb_BE_31_24 

   

    pctl = (PORT_MemMapPtr)PORTD_BASE_PTR;

    pctl->PCR[1]  = PORT_PCR_MUX( ALT5 );  // fb_cs0_b                  

    pctl->PCR[2]  = PORT_PCR_MUX( ALT5 );  // fb_ad[4]  used as a[4]    

    pctl->PCR[3]  = PORT_PCR_MUX( ALT5 );  // fb_ad[3]  used as a[3]    

    pctl->PCR[4]  = PORT_PCR_MUX( ALT5 );  // fb_ad[2]  used as a[2]    

    pctl->PCR[5]  = PORT_PCR_MUX( ALT5 );  // fb_ad[1]  used as a[1]        

    pctl->PCR[6]  = PORT_PCR_MUX( ALT5 );  // fb_ad[0]  used as a[0]   

    pctl->PCR[8]  = PORT_PCR_MUX( ALT6 );  // fb_a[16]  used as a[16]

    pctl->PCR[9]  = PORT_PCR_MUX( ALT6 );  // fb_a[17]  used as a[17]

    pctl->PCR[10] = PORT_PCR_MUX( ALT6 );  // fb_a[18]  used as a[18]

   

    // Enable BE signals

    fb_ptr->CSPMCR = FB_CSPMCR_GROUP2(2);  

    fb_ptr->CSPMCR |= FB_CSPMCR_GROUP3(2); 

}

/*FUNCTION*---------------------------------------------------------------------

*

* Function Name    : _bsp_flexbus_sram_setup

* Returned Value   :

* Comments         :

*    Setup FlexBus for SRAM operation

*

*END*-------------------------------------------------------------------------*/

static void _bsp_flexbus_sram_setup (const uint_32 base_address)

{

    #define ALT1                    0x01

    FB_MemMapPtr fb_ptr = FB_BASE_PTR;

    PORT_MemMapPtr pctl;

    /* Enable external MRAM mapped on CS0 */

    /* CS0 base address */

    fb_ptr->CS[0].CSAR = base_address;

   

    /* CS0 control */

    fb_ptr->CS[0].CSCR = FB_CSCR_AA_MASK     |  

                         FB_CSCR_ASET( 0x1 ) |   // assert chip select on second clock edge after address is asserted

                         FB_CSCR_WS( 0x1 )   |   // wait state

                         FB_CSCR_PS( 2 )     |   // 16-bit data port width

                         FB_CSCR_BEM_MASK;      

    /* CS0 address mask and enable */

    FB_CSMR0 = FB_CSMR_BAM( 0x0007 ) |  // Set base address mask  

               FB_CSMR_V_MASK;          // Enable cs signal   

    // External SRAM CS2 control line.               

    // Control the ISSI CS2 line as a GPIO - set it high and leave it there.   

    pctl = (PORT_MemMapPtr)PORTD_BASE_PTR;

    pctl->PCR[0] = PORT_PCR_MUX(ALT1);     // Set pin for GPIO    

    GPIOD_PDOR |= ( 1UL << 0 );            // set output off

    GPIOD_PDDR |= ( 1UL << 0 );            // enable/set as Output

    GPIOD_PSOR = ( 1UL << 0 );             // set the output high

}

1,504 Views
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi, Allen,

//#define SRAM_MEMORY_WORDS   0x00040000   // this gives a hard fault

for( n = 0x00000000; n <= SRAM_MEMORY_WORDS; n++ )  // address offset

  {

    *(volatile uint32_t*)( &SRAM_START_ADDRESS + n ) = 0x00;  // write

  }

From the above code, you  access the external memory with 32 bits data, so all the memory byte space you accessed is 0x40000*4=0x10 0000, it exceeds the space you defined by the

FB->CS[0].CSMR  =   FB_CSMR_BAM(0x000F) which is from 0x6000 0000 to 0x600F FFFF,

that is why there is hard fault.

BR

XiangJun Rong

0 Kudos
1,503 Views
CCandido
Contributor V

hello,

with this configuration, the DMA can work in 8bits of writing?

source_8bits:    DMA to  Sram_8bits ?

thanks,

Carlos.

0 Kudos
1,503 Views
gorakk
Contributor IV

XiangJun Rong,


Thank you for the explanation


Regards,

Allen

0 Kudos
1,503 Views
CCandido
Contributor V

hi gorakk,

I need to modify to use your example in 8bits ?.

DMA_8bits to Sram ( IS62WV10248 ).

or  IS62WV51216  also works with 8bit?

thanks,

Carlos.

0 Kudos
1,503 Views
gorakk
Contributor IV

Carlos,

To access with 8 bits you would do something like this:

  printf( "\nClearing memory area...\n" );

  for( n = 0x00000; n < 0x04FF; n++ )  // address offset

  {

    *(volatile uint8_t*)( &MRAM_START_ADDRESS + n ) = 0x00;  // write

  }

  printf( "Memory clear complete\n" );

Regards,

Allen

0 Kudos
1,503 Views
gorakk
Contributor IV

An update on this issue - changing the Base Address Mask to 0x001F corrected the issue.  I can now address the entire SRAM. :smileyhappy:

I still don't understand why setting it to 0x000F as shown in the original post  didn't work.  The correct bits should have been masked?  If anyone has some insight to share it would be appreciated. 

1,503 Views
dieterteuchert
Contributor IV

Some processors decode the lower address bit(s) into byte selection lines. Maybe the flexbus address is a 32 bit word address and you could wire your SRAM in a way that lets you access bytes using those byte selection lines.

0 Kudos