Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91SAM7S32 + AT45DB161C
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Tcom
Доброго времени суток!!
Связываю вышеупомянутыеи МС.
Записываю массив в буфер 1 at45, а потом читаю массив с буфера 1.
Почемуто все значения оказываются делёнными на 2.

инициализация SPI:
Код
void initSPI (void)
{
  AT91C_BASE_PIOA->PIO_PDR =  AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK;
  AT91C_BASE_PIOA->PIO_ASR =  AT91C_PA12_MISO | AT91C_PA13_MOSI | AT91C_PA14_SPCK;
  AT91C_BASE_PIOA->PIO_BSR = 0;
  AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;

  /****  Fixed mode ****/
  AT91C_BASE_SPI->SPI_CR      = 0x81;              //SPI Enable, Sowtware reset
  AT91C_BASE_SPI->SPI_CR      = 0x01;              //SPI Enable


  //AT91C_BASE_SPI->SPI_MR      = 0xE0011;          //Master mode, fixed select, disable decoder, FDIV=0 (MCK), PCS=1110
  *AT91C_SPI_MR = AT91C_SPI_MODFDIS | AT91C_SPI_PS_FIXED | AT91C_SPI_MSTR | (0x0E<<16);
  AT91C_SPI_CSR[0] = AT91C_SPI_NCPHA|AT91C_SPI_BITS_8|(SPI_SCKDIV<<8);
}


Чтение /запись:
Код
unsigned char spiSendByte(const unsigned char data)
{
     // wait for transmit completion/ready
     while(!(*AT91C_SPI_SR & AT91C_SPI_TDRE));
     // write data to be transmitted
     *AT91C_SPI_TDR = data;
     // wait for completion
     while(!(*AT91C_SPI_SR & AT91C_SPI_RDRF));
     // return received data
     return *AT91C_SPI_RDR;

}
aaarrr
Цитата(Tcom @ Jun 26 2008, 11:49) *
Почемуто все значения оказываются делёнными на 2.

Странно, у меня с примерно теми же установками все работает нормально:
Код
    AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;
    AT91C_BASE_SPI0->SPI_MR = AT91C_SPI_MODFDIS | AT91C_SPI_MSTR;        // Master, Fixed mode

    AT91C_BASE_SPI0->SPI_CSR[0x00] = (0x03 << 0x08) | (0x00 << 0x04)
        | AT91C_SPI_NCPHA;                                                // AT45: SPI Mode 0, MCK/3, 8 bits


Из spiSendByte можно убрать проверку TDRE.
Tcom
Добавлю функции чтения буферов
Код
void Buffer_Read_Str (unsigned char BufferNo, unsigned int IntPageAdr, unsigned int No_of_bytes, unsigned char *BufferPtr)
{
    unsigned int i;
                                //make sure to toggle CS signal in order
    DF_CS_active;                        //to reset dataflash command decoder
    if (1 == BufferNo)                    //read byte(s) from buffer 1
    {
                DF_SPI_RW(Buf1Read);                //buffer 1 read op-code
        DF_SPI_RW(0x00);                //don't cares
        DF_SPI_RW((unsigned char)(IntPageAdr>>8));      //upper part of internal buffer address
        DF_SPI_RW((unsigned char)(IntPageAdr));            //lower part of internal buffer address
        DF_SPI_RW(0x00);                //don't cares
        for( i=0; i<No_of_bytes; i++)
        {
            *(BufferPtr) = DF_SPI_RW(0x00);        //read byte and put it in AVR buffer pointed to by *BufferPtr
            BufferPtr++;                //point to next element in AVR buffer
        }
    }
    else
    if (2 == BufferNo)                    //read byte(s) from buffer 2
    {
        DF_SPI_RW(Buf2Read);                //buffer 2 read op-code
        DF_SPI_RW(0x00);                //don't cares
        DF_SPI_RW((unsigned char)(IntPageAdr>>8));      //upper part of internal buffer address
        DF_SPI_RW((unsigned char)(IntPageAdr));            //lower part of internal buffer address
        DF_SPI_RW(0x00);                //don't cares
        for( i=0; i<No_of_bytes; i++)
        {
            *(BufferPtr) = DF_SPI_RW(0x00);        //read byte and put it in AVR buffer pointed to by *BufferPtr
            BufferPtr++;                //point to next element in AVR buffer
        }
    }
        DF_CS_inactive;    
}


Код
void Buffer_Write_Str (unsigned char BufferNo, unsigned int IntPageAdr, unsigned int No_of_bytes, unsigned char *BufferPtr)
{
    unsigned int i;
                                    //make sure to toggle CS signal in order
    DF_CS_active;                            //to reset dataflash command decoder
    if (1 == BufferNo)                        //write byte(s) to buffer 1
    {
        DF_SPI_RW(Buf1Write);                    //buffer 1 write op-code
        DF_SPI_RW(0x00);                    //don't cares
        DF_SPI_RW((unsigned char)(IntPageAdr>>8));              //upper part of internal buffer address
        DF_SPI_RW((unsigned char)(IntPageAdr));                    //lower part of internal buffer address
        for( i=0; i<No_of_bytes; i++)
        {
            DF_SPI_RW(*(BufferPtr));            //write byte pointed at by *BufferPtr to dataflash buffer 1 location
            BufferPtr++;                    //point to next element in AVR buffer
        }
    }
    else
    if (2 == BufferNo)                        //write byte(s) to buffer 2
    {
        DF_SPI_RW(Buf2Write);                    //buffer 2 write op-code
        DF_SPI_RW(0x00);                    //don't cares
        DF_SPI_RW((unsigned char)(IntPageAdr>>8));              //upper part of internal buffer address
        DF_SPI_RW((unsigned char)(IntPageAdr));                    //lower part of internal buffer address
        for( i=0; i<No_of_bytes; i++)
        {
            DF_SPI_RW(*(BufferPtr));            //write byte pointed at by *BufferPtr to dataflash buffer 2 location
            BufferPtr++;                    //point to next element in AVR buffer
        }
    }
        DF_CS_inactive;
}
aaarrr
А статусный регистр правильно читается, или тоже со сдвигом?
Tcom
Могу предположить что читается правельно
Код
const unsigned char DF_pagebits[]  ={  9,  9,  9,  9,  9,  10,  10,  11};    
unsigned char Read_DF_status (void)
{
    unsigned char result,index_copy;    //make sure to toggle CS signal in order
    DF_CS_active;                //to reset dataflash command decoder
    result = DF_SPI_RW(StatusReg);        //send status register read op-code
    result = DF_SPI_RW(0x00);        //dummy write to get result
    index_copy = ((result & 0x38) >> 3);    //get the size info from status register
    PageBits   = DF_pagebits[index_copy];    //get number of internal page address bits from look-up table
    DF_CS_inactive;    
    return result;                //return the read status register value
}


Пробывал считывать статус регистр всегда получаю 0b11010110
aaarrr
Нет, он тоже сдвинут.

Какая ревизия все-таки у AT45? AT45DB161C в природе не существует, если верить атмеловскому сайту.
Tcom
AT45DB161D пардон ошибся.
Не могли бы вы кинуть пример инициализации SPI или библиотеку для dataflash
перепаял другую память, картина таже.
aaarrr
Цитата(Tcom @ Jun 26 2008, 12:49) *
Не могли бы вы кинуть пример инициализации SPI или библиотеку для dataflash
перепаял другую память, картина таже.

Всю библиотеку не могу - дюже сложная, да и не поможет.

Код
#define    at45_force_cs()        AT91C_BASE_PIOB->PIO_CODR = CS45;
#define    at45_release_cs()    AT91C_BASE_PIOB->PIO_SODR = CS45;
#define    AT45_CMD_READ_SR    0xd7


Код
//**************************************
//*    PIO

    AT91C_BASE_PIOB->PIO_SODR = CS45;
    AT91C_BASE_PIOB->PIO_OER = CS45;
    AT91C_BASE_PIOB->PIO_PER = CS45;

//**************************************
//*    SPI

    AT91C_BASE_PIOA->PIO_ASR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;
    AT91C_BASE_PIOA->PIO_PDR = SPI0_MISO | SPI0_MOSI | SPI0_SCK;


    AT91C_BASE_PMC->PMC_PCER = (0x01 << AT91C_ID_SPI0);

    AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SPIEN;
    AT91C_BASE_SPI0->SPI_MR = AT91C_SPI_MODFDIS | AT91C_SPI_MSTR;        // Master, Fixed mode

    AT91C_BASE_SPI0->SPI_CSR[0x00] = (0x03 << 0x08) | (0x00 << 0x04)
        | AT91C_SPI_NCPHA;                                                // AT45: SPI Mode 0, MCK/3, 8 bits


Код
__inline u_int spi0_trans(u_int data)
{
    AT91C_BASE_SPI0->SPI_TDR = data;
    while(!(AT91C_BASE_SPI0->SPI_SR & AT91C_SPI_RDRF));
    return (AT91C_BASE_SPI0->SPI_RDR);
}


Код
u_char at45_read_sr(void)
{
    u_char sr;

    at45_force_cs();
    spi0_trans(AT45_CMD_READ_SR);
    sr = spi0_trans(0x00);
    at45_release_cs();
    return sr;
}
prottoss
Попробуйте мою либу.Все рабочее, правда под РТОС, но легко переправить на неРТОС проект. Комментарий есть.
Tcom
Цитата(aaarrr @ Jun 26 2008, 12:10) *
Код
u_char at45_read_sr(void)
{
    u_char sr;

    at45_force_cs();
    spi0_trans(AT45_CMD_READ_SR);
    sr = spi0_trans(0x00);
    at45_release_cs();
    return sr;
}


Считало статус как 0b1010 1100 я так полагаю что ето правельно, это мой результат только сдвинутый влево, то есть гуд.
aaarrr
Да, это правильно. Отличий в коде только нет никаких, кроме, возможно, частоты SPI.
Tcom
Получается как,
Код
    Buffer_Write_Str(1,0,19,BUF2);
    Buffer_Read_Str(1,0,19,BUF1);


если #define Buf1Read 0x54
то читает со сдвигом

если #define Buf1Read 0xЕ4
то читается всё как 0xFF

но если вернуть потом
если #define Buf1Read 0x54
всё читается как нужно!!!
Как так??
aaarrr
У AT45DB161D код команды Buffer 1 Read 0xD4.
Tcom
Всё проблема решена, у меня в библиотеке использовались комманды с другой датафлеши
ёмкостью 32 Мбит. Глянул даташит на 45DB161D там совсем другие.
Спасибо всем за ваши ответы!!!!
Тема закрыта.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.