S25FL032P NOR Interfaz flash sobre SPI Bit Banging

0

Estoy trabajando con un chip de memoria Flash NOR: S25FL032P fabricado por Spansion. Estoy conectando el NOR Flash sobre SPI con Bit Banging, ya que voy a utilizar el motor SPI dedicado para algún otro periférico.

No puedo leer / escribir los datos en Flash por algún motivo. Adjunto las capturas de pantalla de las hojas de datos y lo que he implementado hasta ahora. Mirando la publicación, puede que parezca que gran parte de los datos encuentran algo que ha ido mal con la implementación, pero esa es la forma en que podría pensar. Cualquier ayuda es muy apreciada.

voidWrite_Enable(void){signedcharcmd=WRITE_ENABLE;inti=0;SPI_CS_H();for(i=0;i<8;i++){_delay_us(100);//MakeSCKLowSPI_SCK_H();//MaketheMOSI(Master-Out-Slave-In)pinhighorlowdependingonbit7ofthedataif(cmd&0x80){SPI_MOSI_H();#ifdefDEBUG_Ouart_print("1");
            #endif // DEBUG
        }
        else
        {
            SPI_MOSI_L();
            #ifdef DEBUG_O
                uart_print("0");
            #endif // DEBUG
        }

        _delay_us(100);
        //Make SCK High
        SPI_SCK_L();
        //Left shift the next data to send the next bit
        cmd = cmd << 1;
    }
    SPI_CS_L();
    #ifdef DEBUG_O
        uart_print(" ");
    #endif // DEBUG
}

voidSector_Erase(void){signedcharcmd=SECTOR_ERASE;charaddr[4];inti=0,j=0;addr[0]=0x1E;addr[1]=0x00;addr[2]=0x00;addr[3]=0x00;SPI_CS_H();for(i=0;i<8;i++){_delay_us(100);//MakeSCKLowSPI_SCK_H();//MaketheMOSI(Master-Out-Slave-In)pinhighorlowdependingonbit7ofthedataif(cmd&0x80){SPI_MOSI_H();#ifdefDEBUG_Ouart_print("1");
            #endif // DEBUG
        }
        else
        {
            SPI_MOSI_L();
            #ifdef DEBUG_O
                uart_print("0");
            #endif // DEBUG
        }

        _delay_us(100);
        //Make SCK High
        SPI_SCK_L();
        //Left shift the next data to send the next bit
        cmd = cmd << 1;
    }
    #ifdef DEBUG_O
        uart_print(" ");
    #endif // DEBUG

    for( j = 0; j < 3 ; j++)
    {
        for(i = 0; i < 8; i++)
        {
            _delay_us(100);
            //Make SCK Low
            SPI_SCK_H();
            //Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data
            if(addr[j] & 0x80)
            {
                SPI_MOSI_H();
                #ifdef DEBUG_O
                    uart_print("1");
                #endif // DEBUG
            }
            else
            {
                SPI_MOSI_L();
                #ifdef DEBUG_O
                    uart_print("0");
                #endif // DEBUG
            }

            _delay_us(100);
            //Make SCK High
            SPI_SCK_L();
            //Left shift the next data to send the next bit
            addr[j] = addr[j] << 1;
        }
    }
    #ifdef DEBUG_O
        uart_print(" ");
    #endif // DEBUG
    SPI_CS_L();
}

voidWrite_Page(void){signedcharcmd=PAGE_PROG;inti=0,j=0;charaddr[4];chardata[4]={0xAA,0x55,0xAA,0x55};//unsignedintaddr=0x1E000000;addr[0]=0x1E;addr[1]=0x00;addr[2]=0x00;addr[3]=0x00;SPI_CS_H();for(i=0;i<8;i++){_delay_us(100);//MakeSCKLowSPI_SCK_H();//MaketheMOSI(Master-Out-Slave-In)pinhighorlowdependingonbit7ofthedataif(cmd&0x80){SPI_MOSI_H();#ifdefDEBUG_Ouart_print("1");
            #endif // DEBUG
        }
        else
        {
            SPI_MOSI_L();
            #ifdef DEBUG_O
                uart_print("0");
            #endif // DEBUG
        }

        _delay_us(100);
        //Make SCK High
        SPI_SCK_L();
        //Left shift the next data to send the next bit
        cmd = cmd << 1;
    }
    #ifdef DEBUG_O
        uart_print(" ");
    #endif // DEBUG
    for( j = 0; j < 3 ; j++)
    {
        for(i = 0; i < 8; i++)
        {
            _delay_us(100);
            //Make SCK Low
            SPI_SCK_H();
            //Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data
            if(addr[j] & 0x80)
            {
                SPI_MOSI_H();
                #ifdef DEBUG_O
                    uart_print("1");
                #endif // DEBUG
            }
            else
            {
                SPI_MOSI_L();
                #ifdef DEBUG_O
                    uart_print("0");
                #endif // DEBUG
            }

            _delay_us(100);
            //Make SCK High
            SPI_SCK_L();
            //Left shift the next data to send the next bit
            addr[j] = addr[j] << 1;
        }
    }

    #ifdef DEBUG_O
        uart_print(" ");
    #endif // DEBUG
    for( j = 0; j < 4 ; j++)
    {
        for(i = 0; i < 8; i++)
        {
            _delay_us(100);
            //Make SCK Low
            SPI_SCK_H();
            //Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data
            if(data[j] & 0x80)
            {
                SPI_MOSI_H();
                #ifdef DEBUG_O
                    uart_print("1");
                #endif // DEBUG
            }
            else
            {
                SPI_MOSI_L();
                #ifdef DEBUG_O
                    uart_print("0");
                #endif // DEBUG
            }

            _delay_us(100);
            //Make SCK High
            SPI_SCK_L();
            //Left shift the next data to send the next bit
            data[j] = data[j] << 1;
        }
    }
    #ifdef DEBUG_O
        uart_print(" ");
    #endif // DEBUG
    SPI_CS_L();
}

voidRead_Page(void){signedcharcmd=READ;inti=0,j=0;charaddr[4];signedcharval[32];signedcharpinState=0;addr[0]=0x1E;addr[1]=0x00;addr[2]=0x00;addr[3]=0x00;SPI_CS_H();for(i=0;i<8;i++){_delay_us(100);//MakeSCKLowSPI_SCK_H();//MaketheMOSI(Master-Out-Slave-In)pinhighorlowdependingonbit7ofthedataif(cmd&0x80){SPI_MOSI_H();#ifdefDEBUG_Ouart_print("1");
            #endif // DEBUG
        }
        else
        {
            SPI_MOSI_L();
            #ifdef DEBUG_O
                uart_print("0");
            #endif // DEBUG
        }

        _delay_us(100);
        //Make SCK High
        SPI_SCK_L();
        //Left shift the next data to send the next bit
        cmd = cmd << 1;
    }
    #ifdef DEBUG_O
        uart_print(" ");
    #endif // DEBUG
    for( j = 0; j < 3 ; j++)
    {
        for(i = 0; i < 8; i++)
        {
            _delay_us(100);
            //Make SCK Low
            SPI_SCK_H();
            //Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data
            if(addr[j] & 0x80)
            {
                SPI_MOSI_H();
                #ifdef DEBUG_O
                    uart_print("1");
                #endif // DEBUG
            }
            else
            {
                SPI_MOSI_L();
                #ifdef DEBUG_O
                    uart_print("0");
                #endif // DEBUG
            }

            _delay_us(100);
            //Make SCK High
            SPI_SCK_L();
            //Left shift the next data to send the next bit
            addr[j] = addr[j] << 1;
        }
    }
    #ifdef DEBUG_O
        uart_print(" ");
    #endif // DEBUG

    for(i = 0; i < 32; i++)
    {
        for(j = 0; j < 8 ; j++)
        {
            _delay_us(100);

            //Make SCK Low
            SPI_SCK_L();
            //Make the MOSI (Master-Out-Slave-In) pin high or low depending on bit 7 of the data

            pinState = CHECK_BIT(SPI_PIN, SPI_MISO_BIT);
            if( pinState )
            {
                #ifdef DEBUG_O
                    uart_print("1");
                #endif // DEBUG
            }
            else
            {
                #ifdef DEBUG_O
                    uart_print("0");
                #endif // DEBUG
            }
            _delay_us(100);
            //Make SCK High
            SPI_SCK_H();
            val[i] = (pinState << j)|(val[i]);
        }
    }
    #ifdef DEBUG_O
        uart_print(" ");
    #endif // DEBUG
    SPI_CS_L();
}

El orden en que se llaman es:

    Write_Enable();
    Sector_Erase();
    Read_Page();
    Write_Page();
    Read_Page();
    
pregunta WedaPashi

1 respuesta

0

Lo tengo para trabajar. No estaba sincronizando el dispositivo correctamente. El tema tenía raíces en los tiempos. Estaba siguiendo la secuencia exactamente bien, pero, según la forma en que lo implementé, la sincronización era demasiado teórica y necesaria para gestionar el tiempo de subida y la caída de manera más práctica que la forma en que comprendía los diagramas de temporización.

Las siguientes son las funciones para leer y escribir un byte.

void SPI_Transmit(unsigned char data)
{

    // Does not explicitly selects and deselects the Slave
    // device since this function may be called up upon
    // requirement for sending more than one byte.

    int i = 0;

    // send data in bits
    for (i = 0; i < 8; i++)
    {
        SPI_SCK_L();
        _delay_us(2);

        // Consider leftmost bit, set line high if bit is 1, low if bit is 0
        if(data & 0x80)
        {
            SPI_MOSI_H();
        }
        else
        {
            SPI_MOSI_L();
        }

        _delay_us(5);
        // Pulse clock to indicate that bit value should be read
        SPI_SCK_H();
        // shift byte left so next bit will be leftmost
        data <<= 1;
        _delay_us(5);
    }
}

unsigned char SPI_ReadByte(void)
{
    int i = 0;
    unsigned char data = 0x00;

    for(i = 0; i < 8; i++)
    {
        data = (CHECK_BIT(SPI_PIN, SPI_MISO_BIT) & (1<<SPI_MISO_BIT) );
        _delay_us(10);
        SPI_SCK_H();
        _delay_us(10);
        SPI_SCK_L();
        data = data << 1;
        _delay_us(2);
    }
    return data;
}
    
respondido por el WedaPashi

Lea otras preguntas en las etiquetas