beer_warrior
Jul 1 2006, 20:19
Вожусь с AT45DB081. Проинитил SPI вроде правильно - времянки заказанные, CS дергается как надо.
Пишу/читаю следующим кодом
Код
BYTE SPI_byte(BYTE b)
{
while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE));
AT91C_BASE_SPI->SPI_TDR = b;
return AT91C_BASE_SPI->SPI_RDR;
}
Запускаю простейшее - чтение статуса
Код
BYTE ReadStat(void)
{
SYNC_HI();SYNC_LO(); //это синхроимпульс для осцилла
SPI_byte(READ_STATUS);
return SPI_byte(0);
}
И что вижу - команда проходит нормально, а порожняковый байт нет.
Вставка еще одного SPI_byte(0); дает 16 клоков, но на SO Z-состояние - данных нет.
Что делать?
Цитата(beer_warrior @ Jul 2 2006, 00:19)

Пишу/читаю следующим кодом
Код
BYTE SPI_byte(BYTE b)
{
while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE));
AT91C_BASE_SPI->SPI_TDR = b;
return AT91C_BASE_SPI->SPI_RDR;
}
Этот код вернет состояние RDR от предыдущей записи, т.е. при чтении статуса:
Код
BYTE ReadStat(void)
{
SYNC_HI();SYNC_LO(); //это синхроимпульс для осцилла
SPI_byte(READ_STATUS);
return SPI_byte(0);
}
результат будет содержать данные, полученные во время передачи команды READ_STATUS,
а не во время передачи пустого байта.
Цитата(beer_warrior @ Jul 2 2006, 00:19)

И что вижу - команда проходит нормально, а порожняковый байт нет.
Вставка еще одного SPI_byte(0); дает 16 клоков, но на SO Z-состояние - данных нет.
Не понял, что значит "не проходит порожняковый байт"?
beer_warrior
Jul 2 2006, 05:54
Ну кто бы мне еще ответил

Спасибо.
Еще раз внимательно пересмотрел.Надо делать так?
Код
BYTE SPI_byte(BYTE b)
{
while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE));
AT91C_BASE_SPI->SPI_TDR = b;
while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF));
return AT91C_BASE_SPI->SPI_RDR;
}
beer_warrior
Jul 2 2006, 10:01
Блин, этот SPI сведет меня в могилу. Подправил, не пашет, мертвый вис.Лечиться только установкой MR->PS = 1 и CSR[0]->CSAAT = 0, при этом CS дергается и хрен я что-то из 45-й прочитаю. Танцы с бубном результата не дают.
Я без прерываний работал так:
Код
u_char spi_trans(u_char data)
{
*AT91C_SPI_TDR = data;
while(!(*AT91C_SPI_SR & AT91C_SPI_TXEMPTY));
return (*AT91C_SPI_RDR);
}
Вот только CS формировал руками - так удобнее было.
Что-то с Поиском местные админы намудрили, раньше был лучше.
Цитата
Блин, этот SPI сведет меня в могилу. Подправил, не пашет, мертвый вис.Лечиться только установкой MR->PS = 1 и CSR[0]->CSAAT = 0, при этом CS дергается и хрен я что-то из 45-й прочитаю. Танцы с бубном результата не дают.
Попробуйте почитать
эту ветку, в ней достаточно подробно изложена работа по SPI.
Насчёт "времянок заказанных" - попробуйте сначала на низких скоростях, например выставив бит AT91C_SPI_FDIV в регистре SPI_MR.
beer_warrior
Jul 4 2006, 06:21
Спасибо. То что надо.
И самое интересное, читал же эту ветку, забыл, а поиск не выдал
SpiritDance
Jul 4 2006, 13:12
beer_warrior
А как вы проблему решили? У меня вот тоже сейчас завис. PDC и прерывания пользовать не хочется - надо всего 2 регистра пару раз в микрухе записать.
beer_warrior
Jul 4 2006, 18:33
Никак. Извел два дня на борьбу, плюнул, пошел купил 24с512, благо работаю с макеткой и 45-ю закладывал на будущее. TWI вроде бы пока без проблем. SPI займусь на досуге
nameless
Jul 25 2006, 12:48
А вот у меня другая проблема - нижеприведенный кусок работает из main - а, но не работает в прерывании от таймера. Понимаю, что не в тему, но все-же почему флаг AT91C_SPI_TXEMPTY не сбрасывается если я его проверяю в теле обработчика. Такая же ерунда с флагом результатом от АЦП и TWI ????
А вот это работает:
u8 at45_check(u8 CS_num)
{
SPI_tr8(0x84, CS_num, 0);
BUFFER 0 write
SPI_tr8(0, CS_num, 0);
SPI_tr8(0, CS_num, 0);
SPI_tr8(0, CS_num, 0);
SPI_tr8(0xAA, CS_num, 1);
SPI_tr8(0xD4, CS_num, 0);
SPI_tr8(0, CS_num, 0);
SPI_tr8(0, CS_num, 0);
SPI_tr8(0, CS_num, 0);
SPI_tr8(0, CS_num, 0);
u8 read_test = SPI_tr8(0,CS_num,1);
if(read_test == 0xAA)return 1;
else return 0;
}//at45_check
u8 SPI_tr8(u8 byte, u8 cs_num, u8 last)
{
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
//AT91F_SPI_CfgPCS(AT91C_BASE_SPI, 0x0E);
AT91F_SPI_PutChar(AT91C_BASE_SPI, (u16)byte, cs_num, last);
u8 returned = (u8)AT91F_SPI_GetChar(AT91C_BASE_SPI);
return returned;
}
Модифицированный AT91F_SPI_PutChar:
__inline void AT91F_SPI_PutChar (
AT91PS_SPI pSPI,
unsigned int character,
unsigned char cs_number,
unsigned char last)
{
unsigned int value_for_cs;
value_for_cs = (~(1 << cs_number)) & 0xF;
pSPI->SPI_TDR = (character & 0xFFFF) | (value_for_cs << 16) | (last << 24);
}