Контроллер SAM7x256
Флэшка AT45DB321D
Сделал простую программу для опроса статуса флэшки, чтения данных, записи.
При начале работы контроллера, читаю статус флэшки, определяю её тип, чтобы проверить, нужная ли поставлена. Статус возвращается корректный. Затем читаю какие то блоки данных, записываю. Тоже все хорошо. Но при записи, для определения готовности флэшки к следующей записи данных, читаю статус ( в нем 7 бит), он у меня был всегда в единице. Но данные иногда не записывались. Посмотрел в отладочной что мне возвращает флэшка в статусе. Оказалось 0xFF! Встал осцилографом на ножки SPI, обнаружил следующее:
при самом первом чтении статуса все сигналы нормальные, идут когда нужно и что нужно. После этого считываю одну страницу с данными (не важно по какому адресу она записана), затем читаю снова статус - FF. При этом дерганье чипселекта идет нормально, данные тоже идут хорошо, а вот клока нет. При самом первом чтении он есть, а при последующих нет. При этом если делать чтение данных, он появляется. Делаю чтение статус - пропадает .... В регистрах пдс все нормально, данные уходят и приходят (FF).
инициализация SPI
Код
#define AT91C_SPI_FDIVDIS ((unsigned int) 0x0 << 3)
#define DLYBCS ((unsigned int) 0x5 << 24)
#define PCSDECDIS ((unsigned int) 0x0 << 2)
#define LLBDIS ((unsigned int) 0x0 << 7)
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,
AT91C_PA16_SPI0_MISO |
AT91C_PA17_SPI0_MOSI |
AT91C_PA18_SPI0_SPCK |
AT91C_PA12_SPI0_NPCS0 ,
0);
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI0);
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SWRST;</DIV> <DIV> </DIV> <DIV> AT91F_SPI_CfgMode(AT91C_BASE_SPI0,
AT91C_SPI_MSTR |
AT91C_SPI_PS_FIXED |
PCSDECDIS |
AT91C_SPI_FDIVDIS |
AT91C_SPI_MODFDIS |
LLBDIS |
AT91C_SPI_PCS |
(DLYBCS & AT91C_SPI_DLYBCS)
);
AT91C_BASE_SPI0->SPI_CR = (AT91C_SPI_LASTXFER | AT91C_SPI_SPIEN);
AT91C_BASE_SPI0->SPI_TDR = AT91C_SPI_LASTXFER;
//Flash AT45DB
AT91F_SPI_CfgCs(AT91C_BASE_SPI0,
0,
((0x1 << 0) & AT91C_SPI_CPOL) |
((0x1 << 1) & AT91C_SPI_NCPHA) |
((0x0 << 3) & AT91C_SPI_CSAAT) |
((0x0 << 4) & AT91C_SPI_BITS) |
((0x20 << 8) & AT91C_SPI_SCBR) |
((0x10 << 16) & AT91C_SPI_DLYBS) |
((0x2 << 24) & AT91C_SPI_DLYBCT)
);
#define DLYBCS ((unsigned int) 0x5 << 24)
#define PCSDECDIS ((unsigned int) 0x0 << 2)
#define LLBDIS ((unsigned int) 0x0 << 7)
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,
AT91C_PA16_SPI0_MISO |
AT91C_PA17_SPI0_MOSI |
AT91C_PA18_SPI0_SPCK |
AT91C_PA12_SPI0_NPCS0 ,
0);
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI0);
AT91C_BASE_SPI0->SPI_CR = AT91C_SPI_SWRST;</DIV> <DIV> </DIV> <DIV> AT91F_SPI_CfgMode(AT91C_BASE_SPI0,
AT91C_SPI_MSTR |
AT91C_SPI_PS_FIXED |
PCSDECDIS |
AT91C_SPI_FDIVDIS |
AT91C_SPI_MODFDIS |
LLBDIS |
AT91C_SPI_PCS |
(DLYBCS & AT91C_SPI_DLYBCS)
);
AT91C_BASE_SPI0->SPI_CR = (AT91C_SPI_LASTXFER | AT91C_SPI_SPIEN);
AT91C_BASE_SPI0->SPI_TDR = AT91C_SPI_LASTXFER;
//Flash AT45DB
AT91F_SPI_CfgCs(AT91C_BASE_SPI0,
0,
((0x1 << 0) & AT91C_SPI_CPOL) |
((0x1 << 1) & AT91C_SPI_NCPHA) |
((0x0 << 3) & AT91C_SPI_CSAAT) |
((0x0 << 4) & AT91C_SPI_BITS) |
((0x20 << 8) & AT91C_SPI_SCBR) |
((0x10 << 16) & AT91C_SPI_DLYBS) |
((0x2 << 24) & AT91C_SPI_DLYBCT)
);
чтение статуса
Код
AT91C_BASE_PDC_SPI0->PDC_PTCR =(AT91C_PDC_TXTDIS | AT91C_PDC_RXTDIS);
AT91C_BASE_PDC_SPI0->SPI_MR &= 0xFFF0FFFF;
AT91C_BASE_PDC_SPI0->SPI_MR |= ( (0xE<<16) & AT91C_SPI_PCS );
AT91C_BASE_PDC_SPI0->PDC_RPR = (unsigned int) &BUFF_IN[0];
AT91C_BASE_PDC_SPI0->PDC_RCR = 2;
AT91C_BASE_PDC_SPI0->PDC_TPR = (unsigned int) &BUFF_OUT[0];
AT91C_BASE_PDC_SPI0->PDC_TCR = 2;
AT91C_BASE_PDC_SPI0->PDC_PTCR=(AT91C_PDC_TXTEN | AT91C_PDC_RXTEN);
AT91C_BASE_PDC_SPI0->SPI_MR &= 0xFFF0FFFF;
AT91C_BASE_PDC_SPI0->SPI_MR |= ( (0xE<<16) & AT91C_SPI_PCS );
AT91C_BASE_PDC_SPI0->PDC_RPR = (unsigned int) &BUFF_IN[0];
AT91C_BASE_PDC_SPI0->PDC_RCR = 2;
AT91C_BASE_PDC_SPI0->PDC_TPR = (unsigned int) &BUFF_OUT[0];
AT91C_BASE_PDC_SPI0->PDC_TCR = 2;
AT91C_BASE_PDC_SPI0->PDC_PTCR=(AT91C_PDC_TXTEN | AT91C_PDC_RXTEN);
Жду конца обмена и смотрю второй байт в буфере BUFF_IN. После первого чтения там то, что нужно, в последующих случаях FF. Если полность переинициализировать SPI, то опять один раз читает нормально.