AnsweredAssumed Answered

STM32F2 and two nand targets

Question asked by redfield.morgan on Feb 5, 2015
Latest reply on Feb 5, 2015 by waclawek.jan
Hi,

I'm working on a board that interfaces an STM32F2 with a 4GB nand flash from Micron MT29F32G08AFABAWP:B.

That nand flash is split up internally to two different dies. They use most of the same data and control signals, but the NCE signals for each die are different. The idea is that you can select which die you're working with by selecting which NCE signal you use.

I'm trying to interface with that nand chip using the STM32's FSMC controller. I've found that as long as I use only NCE3, everything works. When I try to switch to NCE2 to use the other die on the nand chip, I can't read it correctly. It seems like I'm still looking at the first die, even though I've changed the NCE pin.

I want to make sure it makes sense to just switch NCE lines halfway through using the FSMC. Is there a special way to do this?

Right now whenever I need to read or write to the nand, I interpret the address to determine which die to use. I currently do that this way:

static unsigned int selectTargetByAddr(unsigned int addr)
{
    GPIO_InitTypeDef gpio_init;

    gpio_init.GPIO_Speed = GPIO_Speed_100MHz;
    gpio_init.GPIO_OType = GPIO_OType_PP;
    gpio_init.GPIO_PuPd  = GPIO_PuPd_UP;

    // div by 2 since each target has half the blocks
    if ((addr >> 8) < NAND_BLOCK_MAX/2)
    {
      if (_nandTarget == 0)
        return addr;

      _nandTarget = 0;

      //NCE3 no longer a control line
      gpio_init.GPIO_Mode = GPIO_Mode_OUT;
      gpio_init.GPIO_Pin = GPIO_Pin_9;
      GPIO_Init(GPIOG, &gpio_init);
      // drive NCE3 high to make sure that die sleeps
      GPIO_WriteBit(GPIOG, GPIO_Pin_9, Bit_SET);

      //Control line NCE2
      gpio_init.GPIO_Mode = GPIO_Mode_AF;
      gpio_init.GPIO_Pin = GPIO_Pin_7;
      GPIO_Init(GPIOD, &gpio_init);

      FSMC_NANDInit( &_nand );
      FSMC_NANDCmd(FSMC_Bank3_NAND, ENABLE);

      return addr;
    } else
    {
      if (_nandTarget == 1)
    return addr - ((NAND_BLOCK_MAX/2) << 8);

      _nandTarget = 1;

      //NCE2 no longer a control line
      gpio_init.GPIO_Mode = GPIO_Mode_OUT;
      gpio_init.GPIO_Pin = GPIO_Pin_7;
      GPIO_Init(GPIOD, &gpio_init);
      // drive NCE2 high to make sure that die sleeps
      GPIO_WriteBit(GPIOD, GPIO_Pin_7, Bit_SET);

      //Control line NCE3
      gpio_init.GPIO_Mode = GPIO_Mode_AF;
      gpio_init.GPIO_Pin = GPIO_Pin_9;
      GPIO_Init(GPIOG, &gpio_init);

      FSMC_NANDInit( &_nand );
      FSMC_NANDCmd(FSMC_Bank3_NAND, ENABLE);

      return addr - ((NAND_BLOCK_MAX/2) << 8);
    }
}

Outcomes