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" );
Solved! Go to Solution.
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
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
}
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
hello,
with this configuration, the DMA can work in 8bits of writing?
source_8bits: DMA to Sram_8bits ?
thanks,
Carlos.
XiangJun Rong,
Thank you for the explanation
Regards,
Allen
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.
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
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.
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.