Bug in IMX28 WINCE BSP NAND interface

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

Bug in IMX28 WINCE BSP NAND interface

1,776 Views
MarcCoussement
Contributor I

hi all,

I found and solved a very nasty bug in the IMX28 WINCE BSP initialization code for the NAND flash interface.

The RDN (read) signal is faulty driven by 1V8 signal level all other signals to the NAND have 3V3 signal levels. With this some NAND device will give read errors as the spec is 70% of VCC gives 2V4 as specification for high signal.

The prototype of the function in source

“C:\WINCE600\PLATFORM\COMMON\SRC\SOC\MX28_FSL_V2_PDK1_9\INC\mx28_ddk.h”

BOOL DDKIomuxSetPadConfig(DDK_IOMUX_PIN pin,
DDK_IOMUX_PAD_DRIVE drive,
DDK_IOMUX_PAD_PULL pull,
DDK_IOMUX_PAD_VOLTAGE voltage)

The enum type to set the voltage of the outputs in source

“C:\WINCE600\PLATFORM\COMMON\SRC\SOC\MX28_FSL_V2_PDK1_9\INC\mx28_ddk.h”

typedef enum
{
DDK_IOMUX_PAD_VOLTAGE_RESERVED = 0,
DDK_IOMUX_PAD_VOLTAGE_1V8 = 0,
DDK_IOMUX_PAD_VOLTAGE_3V3 = 1
} DDK_IOMUX_PAD_VOLTAGE;

The Faulty code line in source “C:\WINCE600\PLATFORM\iMX28-EVK-PDK1_9\SRC\COMMON\NANDFMD\nandbsp.cpp”

// Set the pin drive for the RDN pin to 8mA.
DDKIomuxSetPadConfig(DDK_IOMUX_GPMI_RDN,DDK_IOMUX_PAD_DRIVE_8MA,(DDK_IOMUX_PAD_PULL)0,(DDK_IOMUX_PAD_VOLTAGE)0);

The Change I made

DDKIomuxSetPadConfig(DDK_IOMUX_GPMI_RDN,DDK_IOMUX_PAD_DRIVE_8MA,(DDK_IOMUX_PAD_PULL)0,DDK_IOMUX_PAD_VOLTAGE_3V3);

The strange about this is, the programmer made a nice enum type for the voltage of the outputs, but is not using the enum type in the function call. The programmer did use a cast of a numeric “0” value ???!!!

 

I have a call for help to the community for the following:

There is still one question about timing:

The Micron “MT29F8G08ABABA” has different timing modes (mode 0 tot mode 5) after reset the nand starts with default timing “mode 0” this is a very slow timing with read cycles of 100ns.
The chip can be set to another timing mode by writing into the “feature” register. I don‘t have an example of a DMA sequence to write into the “feature register”. 

The sequence is

<Command><Adress> <DataIn><DataIn><DataIn><DataIn>

This is different than the program page sequence  

<Command> <Adress> <Adress> <Adress> <Adress> <Adress> <DataIn><DataIn><DataIn><DataIn> ... <Command>

help is appreciated

Marc Coussement

Labels (1)
0 Kudos
5 Replies

1,104 Views
fear_nada
Contributor II

in i.MX28 Applications Processor Reference Manual, Rev. 1, 2010

9.2.2.2 Pin Voltage Selection
Each GPIO (non-EMI) pin can be programmed to operate at either 1.8 V or 3.3 V by setting
the bit corresponding to that pin in one of the HW_PINCTRL_DRIVEx registers. 

as i remember if we use DDK_IOMUX_PAD_VOLTAGE_RESERVED we got 1.8v

yep=)

look at this

typedef enum
{
    DDK_IOMUX_PAD_VOLTAGE_RESERVED      = 0,
    DDK_IOMUX_PAD_VOLTAGE_1V8           = 0,
    DDK_IOMUX_PAD_VOLTAGE_3V3           = 1
} DDK_IOMUX_PAD_VOLTAGE;

 for AUART_TX's i need 3.3v so i put DDK_IOMUX_PAD_VOLTAGE_3V3 in code permanently =)

0 Kudos

1,104 Views
MarcCoussement
Contributor I

Hi Andrew,

Just to inform ... did you get this information from the

Function: DDKIomuxSetPadConfig the function comment

// Note that some register does not have support for volatge settings so it

// is the caller Responsibility to pass DDK_IOMUX_PAD_VOLTAGE_RESERVED when

// Pin does not have voltage settings.

Marc

0 Kudos

1,104 Views
fear_nada
Contributor II

Hi, no i don't know.

try check this folder:

MX28_FSL_V2_PDK1_9\MEDIA\NAND\*.*

and in file

cspnand.c we can see

BOOL WriteNand()

i think you need understand how it working.

0 Kudos

1,104 Views
MarcCoussement
Contributor I

hi Andrew,

 

Thanks for your aditional input..... do you have i idea on how to solve the following :

The Micron “MT29F8G08ABABA” has different timing modes (mode 0 tot mode 5) after reset the nand starts with default timing “mode 0” this is a very slow timing with read cycles of 100ns. The chip can be set to another timing mode by writing into the “feature” register. I don‘t have an example of a DMA sequence to write into the “feature register”.

The sequence is

<Command><Adress> <DataIn><DataIn><DataIn><DataIn>

This is different than the program page sequence 

<Command> <Adress> <Adress> <Adress> <Adress> <Adress> <DataIn><DataIn><DataIn><DataIn> ... <Command>

 

help is appreciated

Marc Coussement

0 Kudos

1,104 Views
fear_nada
Contributor II

Hi, I also advise
add this:

    // Set the pin drive for the RDN pin to 8mA.

//EAI got fr erro here and add init rdn wrn
DDKIomuxSetPadConfig(DDK_IOMUX_GPMI_RDN,DDK_IOMUX_PAD_DRIVE_8MA,(DDK_IOMUX_PAD_PULL)0,(DDK_IOMUX_PAD_VOLTAGE)DDK_IOMUX_PAD_VOLTAGE_3V3);
DDKIomuxSetPadConfig(DDK_IOMUX_GPMI_WRN,DDK_IOMUX_PAD_DRIVE_8MA,(DDK_IOMUX_PAD_PULL)0,(DDK_IOMUX_PAD_VOLTAGE)DDK_IOMUX_PAD_VOLTAGE_3V3);
//EAI

and we have errors in bspserial.c


//-----------------------------------------------------------------------------
// Local Functions
//-----------------------------------------------------------------------------
//
// Function: BSPUartConfigureGPIO
//
// This function is used to configure the GPIO.
//
// Parameters:
// HWAddr
// [in] Physical IO address.
//
// Returns:
// TRUE if successfully performed the required action.
//
//-----------------------------------------------------------------------------
BOOL BSPUartConfigureGPIO(ULONG HWAddr)
{
BOOL ret = TRUE;

switch (HWAddr)
{
// AUART0
case CSP_BASE_REG_PA_UARTAPP0:
DDKIomuxSetPinMux(DDK_IOMUX_AUART0_TX, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART0_TX, //eai here was DDK_IOMUX_AUART1_TX - fr bug
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART0_RX, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART0_RX,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART0_RTS, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART0_RTS,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART0_CTS, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART0_CTS,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

//while(HWAddr==CSP_BASE_REG_PA_UARTAPP0);
break;

// AUART1
case CSP_BASE_REG_PA_UARTAPP1:
DDKIomuxSetPinMux(DDK_IOMUX_AUART1_TX, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART1_TX,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3); //eai here was DDK_IOMUX_PAD_VOLTAGE_RESERVED - fr bug

DDKIomuxSetPinMux(DDK_IOMUX_AUART1_RX, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART1_RX,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART1_RTS, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART1_RTS,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART1_CTS, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART1_CTS,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

break;

// AUART2
case CSP_BASE_REG_PA_UARTAPP2:
DDKIomuxSetPinMux(DDK_IOMUX_AUART2_TX_1, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART2_TX_1,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3); //eai here was DDK_IOMUX_PAD_VOLTAGE_RESERVED - fr bug

DDKIomuxSetPinMux(DDK_IOMUX_AUART2_RX_1, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART2_RX_1,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART2_RTS, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART2_RTS,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART2_CTS, DDK_IOMUX_MODE_00); //eai here ! was DDK_IOMUX_AUART1_CTS - fr bug!
DDKIomuxSetPadConfig(DDK_IOMUX_AUART2_CTS, //eai here ! was DDK_IOMUX_AUART1_CTS - fr bug!
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

break;

// AUART3
case CSP_BASE_REG_PA_UARTAPP3:
DDKIomuxSetPinMux(DDK_IOMUX_AUART3_TX_1, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART3_TX_1,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3); //eai here was DDK_IOMUX_PAD_VOLTAGE_RESERVED - fr bug

DDKIomuxSetPinMux(DDK_IOMUX_AUART3_RX_1, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART3_RX_1,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART3_RTS, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART3_RTS,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART3_CTS, DDK_IOMUX_MODE_00);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART3_CTS,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

break;

//EAI here
// AUART4
case CSP_BASE_REG_PA_UARTAPP4:
DDKIomuxSetPinMux(DDK_IOMUX_AUART4_TX_2, DDK_IOMUX_MODE_02);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART4_TX_2,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART4_RX_2, DDK_IOMUX_MODE_02);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART4_RX_2,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART4_RTS_1, DDK_IOMUX_MODE_02);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART4_RTS_1,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

DDKIomuxSetPinMux(DDK_IOMUX_AUART4_CTS_1, DDK_IOMUX_MODE_02);
DDKIomuxSetPadConfig(DDK_IOMUX_AUART4_CTS_1,
DDK_IOMUX_PAD_DRIVE_8MA,
DDK_IOMUX_PAD_PULL_ENABLE,
DDK_IOMUX_PAD_VOLTAGE_3V3);

break;

default:
ret=FALSE;
break;
}

return ret;
}



0 Kudos