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
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 =)
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
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.
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
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;
}