Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Смещён приём через PDC для SPI
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Goofy
Последовательность функция для запуска передчи команды по SPI (для dataflash)
Код
    DFChipSelect();

    AT91F_PDC_DisableRx(pPdc);
    AT91F_PDC_SetRx(pPdc, (char *) &(), bCmdSize);
    AT91F_PDC_SetNextRx(pPdc, pData, dDataSize);

    AT91F_PDC_DisableTx(pPdc);    
    AT91F_PDC_SetTx(pPdc, (char *) &(pDataFlash->commandS), bCmdSize);
    AT91F_PDC_SetNextTx(pPdc, pData, dDataSize);

    AT91F_PDC_EnableRx(pPdc);
    AT91F_PDC_EnableTx(pPdc);

В качестве команды засылается запрос на статус регистр (0xD7) размер команды 2 (bCmdSize=2)
Глядя на диаграмму передачи со статус регистра видно, что статус регистр должен передаваться по MISO сразу же после 8го тика SCK. Судя по всему так и происходит. Но сам статус регист оказывается не в ((char*)pDataFlash->command) [1], а в ((char*)pDataFlash->command) [0] !!! Как будто датафлэш передаёт данные во время прохождения запроса. Как будто PDC для приёма курит один байт, перед тем как начать приём.
Что не учёл, где накосячил?
Процессор sam7s256 код из атмеловского апноута для sam7x.

Очевидно, что это проявляется не только с датафлэш, тк для АЦП запросы короткие то там я тупо подстроился под эту систему и заставил всё работать. Но это ведь может плохо кончиться!
prottoss
Цитата(Goofy @ Feb 9 2008, 16:02) *
Код
AT91F_PDC_SetRx(pPdc, (char *) &(), bCmdSize);
Это куда? 07.gif
Goofy
Цитата(prottoss @ Feb 9 2008, 16:54) *
Это куда? 07.gif


это накосячил, когда постил.

AT91F_PDC_SetTx(pPdc, (char *) &(pDataFlash->command), bCmdSize);
так должно быть
prottoss
Цитата(Goofy @ Feb 9 2008, 17:11) *
это накосячил, когда постил.AT91F_PDC_SetTx(pPdc, (char *) &(pDataFlash->command), bCmdSize);так должно быть


Да Вы и счас накосячили smile.gif Я спрашивал про AT91F_PDC_SetRx(...), а Вы мне про Ерему
Goofy
Цитата(prottoss @ Feb 9 2008, 17:22) *
Да Вы и счас накосячили smile.gif Я спрашивал про AT91F_PDC_SetRx(...), а Вы мне про Ерему



smile.gif это опять же опечатка... спешил...
AT91F_PDC_SetRx(pPdc, (char *) &(pDataFlash->command), bCmdSize);
prottoss
Цитата(Goofy @ Feb 10 2008, 15:05) *
smile.gif это опять же опечатка... спешил...
AT91F_PDC_SetRx(pPdc, (char *) &(pDataFlash->command), bCmdSize);


Я так понимаю command в pDataFlash определена как чтото типа

command[CMD_BUF_SIZE]. Если так, тогда зачем в функции AT91F_PDC_SetRx/Tx Вы подсовываете адрес указателя, а не сам указатель???

По моему надо так:

Код
...

AT91F_PDC_SetTx(pPdc, pDataFlash->command, bCmdSize);

...

AT91F_PDC_SetRx(pPdc, pDataFlash->command, bCmdSize);
Goofy
Структура на которую ссылается pDataFlash имеет вид
typedef struct _AT91S_DF
{
AT91PS_SPI pSpi;
AT91S_DF_SEM bSemaphore;
unsigned int command;
unsigned int commandS;
AT91S_DF_DESC dfDescription;
unsigned char chipSelect;
}
prottoss
Цитата(Goofy @ Feb 10 2008, 17:35) *
Структура на которую ссылается pDataFlash имеет вид
typedef struct _AT91S_DF
{
AT91PS_SPI pSpi;
AT91S_DF_SEM bSemaphore;
unsigned int command;
unsigned int commandS;
AT91S_DF_DESC dfDescription;
unsigned char chipSelect;
}
Я конечно не знаю, как там все у вас посылается, но почему команды имеют такой тип - unsigned int? Команды для DataFlash имеют размер от 1 до 8-и байт. Я, к примеру, их и объявляю, как массив 8-и битных элементов, ну а PDC уже сообщаю адрес массива-источника и адрес массива-приемника (обычно совпадают или приемник не указываю елси не читаю статус) и количество байт, которые хочу отправить и ожидаю принять
Goofy
А можно попросить код? Именно с sam7s стыковали датафлэш?
prottoss
Цитата(Goofy @ Feb 10 2008, 20:34) *
А можно попросить код? Именно с sam7s стыковали датафлэш?
Можно:-)

В приложении драйвер SPI под uc/OS-II и драйвер для AT45DB - думаю разберетесь. Драйвер SPI править не надо - достаточно подключить хедер для соответсвующего МК - он сам разберется, скока SPI у чипа на борту



там, правда, еще не совсем решенный вопрос по блокировке интерфейса - использовать как есть счас - с семафорами или использовать общую группу флагов. Думаю, в понедельник-вторник решится, когда будем испытывать на рабочем девайсе. Я думаю, что и с группой флагов работать будет - т.е. без семафоров
Goofy
За код спасибо большое!


Но то что у меня происходит с SPI я вообще отказываюсь понимать. Процедура выполняющаяся при запуске:
Код
AT91PS_PDC pPdc;

DFChipSelect();

DataFlash.pSpi=AT91C_BASE_SPI;

pPdc = (AT91PS_PDC) &(DataFlash.pSpi->SPI_RPR);


    AT91F_PDC_DisableRx(pPdc);
    AT91F_PDC_DisableTx(pPdc);

Buf[0]=0xD7;    //запрос на статус регистр
Buf[1]=0xFF;
Buf[2]=0xFF;
Buf[3]=0xFF;

SPI_Rx( Bufr, 4);  // тоже самое что sendframe
SPI_Tx( Buf, 4);


AT91F_PDC_EnableRx(pPdc);
AT91F_PDC_EnableTx(pPdc);

while (!(DataFlash.pSpi->SPI_SR & AT91C_SPI_ENDRX) );

USART0_SendData(Bufr,4);


буферы - глобальные переменные
Код
char Buf[10];
char Bufr[10];


результат на скриншоте. Мало того что помеха в первом байте, так ещё и порядок мягко говоря странный. По датащиту в ответе at45db161d должно быть 0xFF, потом повторяющееся содержание статус регистра, на остальные 24 тика SCK.
Даже если помеха и ловиться на старте, то должна поганить 0xFF. Битый DF ?

SPI инициализирован на 8бит.
prottoss
Цитата(Goofy @ Feb 11 2008, 15:39) *
За код спасибо большое!
не зачтоsmile.gif

А что, мой тоже не работает?

Цитата(Goofy @ Feb 11 2008, 15:39) *
Битый DF
Возможно большая скорость передачи и некачественная разводка ПП. Кстати у меня в исходиках установлена скрость 10МГц
Goofy
Цитата(prottoss @ Feb 11 2008, 15:55) *
не зачтоsmile.gif

А что, мой тоже не работает?

Возможно большая скорость передачи и некачественная разводка ПП. Кстати у меня в исходиках установлена скрость 10МГц


Драйвер Ваш нет смысла подключать, тк PDC сам по себе работает наистраннейшим образом. Весь код этой беды выше представлен. Скорость 4мгц, уменьшал до 500кГц, результат тот же. Чёрт с ней с помехой, плата там и правда вся в соплях из проводов, однако с АЦП на этой скорости SPI работает прекрасно. Но как понимать последовательность то такую ?
defunct
Goofy
Сдается мне проблема не с RX DMA.
Попробуйте настроить RX DMA на прием и в ручную (без TX DMA) передать 4 байта.

Цитата
тк PDC сам по себе работает наистраннейшим образом.

PDC сам по себе работает прекрасно.
Goofy
Код
for (i=0;i<4;i++) Bufr[i]=AT91_spi(Buf[i]);


Вообще без PDC, эффект тот же. sad.gif
Какому либо объясненью вообще не поддаётся, что чаще всего говорит о банальности причины...


twak.gif

инициализация SPI

Код
AT91F_SPI_CfgPMC();

AT91F_SPI_Reset(ptrSPI);



    AT91F_PIO_CfgPeriph(
        AT91C_BASE_PIOA, // PIO controller base address
        ((unsigned int) AT91C_PA13_MOSI    ) |
        ((unsigned int) AT91C_PA14_SPCK    ) |
        ((unsigned int) AT91C_PA11_NPCS0   ) |
        ((unsigned int) AT91C_PA12_MISO    ), // Peripheral A
        ((unsigned int) AT91C_PA10_NPCS2   )); // Peripheral B



AT91F_SPI_CfgMode(ptrSPI, AT91C_SPI_MSTR |   AT91C_SPI_MODFDIS | (10<<24)  |  (0x0F<<16)  );  

AT91F_SPI_CfgCs(ptrSPI, 0,  AT91C_SPI_NCPHA |    ( (MCK/SPI_CLOCK) << 8)   );
AT91F_SPI_CfgCs(ptrSPI, 1,  AT91C_SPI_CPOL| ( (MCK/SPI_CLOCK) << 8) );

AT91F_SPI_CfgCs(ptrSPI, 2,    AT91C_SPI_CPOL | ( (MCK/ SPI_CLOCK ) << 8) );// (5<<24) | (5<<16)|



ptrSPI->SPI_CR = AT91C_SPI_SPIEN;


(unsigned short)ptrSPI->SPI_RDR;
(unsigned short)ptrSPI->SPI_SR;
(unsigned short)ptrSPI->SPI_RDR;
Goofy
Это баг самого sam7s. Проявляется видимо не у всех, но

http://www.at91.com/phpbb/viewtopic.php?p=...2fa6260ff26533e

Судя по моим наблюдениям сбойно работает shift register SPI, все данные проходящие через него смещенны на байт вправо, очевидны глюки с переключением размера регистра. (я работал с 8битным). Проявляется в том, что при начале новой передачи, в буффер приёма попадает байт от конца предыдущей. От этого, кстати, при работе через PDC, RCR сразу потеряет единичку.

Уже жалею что с этим чипом связался, походу его и с производства сняли. Это первый в моей практике ARM и через такие стенодробительные процедуры... Закаляет однако smile.gif
prottoss
Цитата(Goofy @ Feb 14 2008, 17:33) *
Это баг самого sam7s.


1.Только что сравнил баги SPI SAM7S и SAM7X - все одно и тоже... Похоже баг только в вашем контроллере smile.gif включая "...плата там и правда вся в соплях из проводов..."

2.А как Вы узнали, что его сняли с производства? Вроде как продакшн везде написано 07.gif

http://www.atmel.com/dyn/products/param_ta...p;Direction=ASC

http://www.atmel.com/dyn/products/devices.asp?family_id=605

3. Чип и вправду кривоватый - кстати, тоже мой первенец 05.gif Но работать с ним, зная баги, можно.
Goofy
Цитата(prottoss @ Feb 14 2008, 18:03) *
1.Только что сравнил баги SPI SAM7S и SAM7X - все одно и тоже... Похоже баг только в вашем контроллере smile.gif включая "...плата там и правда вся в соплях из проводов..."

2.А как Вы узнали, что его сняли с производства? Вроде как продакшн везде написано 07.gif

http://www.atmel.com/dyn/products/param_ta...p;Direction=ASC

http://www.atmel.com/dyn/products/devices.asp?family_id=605

3. Чип и вправду кривоватый - кстати, тоже мой первенец 05.gif Но работать с ним, зная баги, можно.


На плату грешить не надо. На осцилографе всё прекрасно наблюдается. А уж на один байт тем паче не сдвигается smile.gif Почитайте ссылку, что я дал, те же самые проблемы буржуи излагают.
http://electronix.ru/forum/index.php?showtopic=17676 нечто похожее тут.
Может дело только в какой то ранней партии, которая умудрилась меня дождаться.

Про снятие наврал twak.gif оЧитался
prottoss
Кстати, а как Вы управляете чипселектом? Через железные NPCS или PIO?
Goofy
Цитата(prottoss @ Feb 14 2008, 20:21) *
Кстати, а как Вы управляете чипселектом? Через железные NPCS или PIO?


Через железные, дёргаются без проблем.
prottoss
Цитата(Goofy @ Feb 14 2008, 20:46) *
Через железные, дёргаются без проблем.
Ну вот и все проблемы от этого. Сам Atmel в errata говорит - используете PDC? - НЕ ИСПОЛЬЗУЙТЕ NPCS
Goofy
Цитата(prottoss @ Feb 14 2008, 22:18) *
Ну вот и все проблемы от этого. Сам Atmel в errata говорит - используете PDC? - НЕ ИСПОЛЬЗУЙТЕ NPCS


Работа идёт в Fixed PCS. И было сказано что при работе без PDC проблема не исчезает.
Скачал последний датащит, в эррате несколько другая ситуация изложена. У меня все устройства на шине работают в 8 бит режиме.
prottoss
Цитата(Goofy @ Feb 14 2008, 22:54) *
Работа идёт в Fixed PCS. И было сказано что при работе без PDC проблема не исчезает.Скачал последний датащит, в эррате несколько другая ситуация изложена. У меня все устройства на шине работают в 8 бит режиме.
Хотите головной боли? Продолжайте свои исследования, нет - забейте на железные выборки и используйте софтовое управление слэйвами

Кстати, я же Вам дал рабочий драйвер, работающий на ВСЕХ SAM7(на 9 не проверял). Почему бы не испытать? smile.gif А уже потом делать выводы про неработающий SPI. Там (в драйвере) вроде бы все просто и понятно написано.
Goofy
Цитата(prottoss @ Feb 14 2008, 23:08) *
Хотите головной боли? Продолжайте свои исследования, нет - забейте на железные выборки и используйте софтовое управление слэйвами


Давайте убедимся что говорим об одном и том же.
То есть всё что мне нужно сделать, отцепить ногу NPCS от модуля SPI? Сконфигуривароть интерфейс в SPI_CSR0. И работать с той лишь разницей что переключать CS слэйвов программно?
prottoss
Цитата(Goofy @ Feb 14 2008, 23:14) *
угу

Посмотрите в spi.c на

SPI_RESULT SPI_Init(AT91PS_SPI spi) - ИМХО там все, что нужно сделать
Goofy
Подправил
Код
void InitSPI(void)
{
AT91F_SPI_CfgPMC();

AT91F_SPI_Reset(ptrSPI);

*AT91C_PIOA_PER = AT91C_PIO_PA11|AT91C_PIO_PA10;

*AT91C_PIOA_OER = AT91C_PIO_PA11|AT91C_PIO_PA10;// |  // CS

    AT91F_PIO_CfgPeriph(
        AT91C_BASE_PIOA, // PIO controller base address
        ((unsigned int) AT91C_PA13_MOSI    ) |
        ((unsigned int) AT91C_PA14_SPCK    ) |    
        ((unsigned int) AT91C_PA12_MISO    ), 0);
    
AT91C_PA10_NPCS2;

csADC1high;

csFLASHhigh;

AT91F_SPI_CfgMode(ptrSPI, AT91C_SPI_MSTR |   AT91C_SPI_MODFDIS |   |  (0x0F<<16)  );
AT91F_SPI_CfgCs(ptrSPI, 0,  AT91C_SPI_CPOL|    ( (MCK/SPI_CLOCK) << 8)   );

ptrSPI->SPI_CR = AT91C_SPI_SPIEN;

(unsigned short)ptrSPI->SPI_RDR;
(unsigned short)ptrSPI->SPI_SR;
(unsigned short)ptrSPI->SPI_RDR;

AT91F_SPI_CfgPCS(ptrSPI, 0x0E);
}


#define csFLASHhigh *AT91C_PIOA_SODR = AT91C_PIO_PA10
#define csFLASHlow *AT91C_PIOA_CODR = AT91C_PIO_PA10

{
csFLASHlow;
csADC1high;

Buf[0]=0xD7;
Buf[1]=0xFF;
Buf[2]=0xFF;
Buf[3]=0xFF;
Buf[4]=0xFF;
Buf[5]=0xFF;

Bufr[0]=AT91_spi(Buf[0]);
Bufr[1]=AT91_spi(Buf[1]);
Bufr[2]=AT91_spi(Buf[2]);
Bufr[3]=AT91_spi(Buf[3]);
Bufr[4]=AT91_spi(Buf[4]);
Bufr[5]=AT91_spi(Buf[5]);

Bufr[6]=0;

USART0_SendData(Bufr,7);

csFLASHhigh;

}


Код
unsigned char AT91_spi(unsigned char bsend)
{
while( !(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE )){;}
// wait until all transfers are completed
AT91C_BASE_SPI->SPI_TDR =(unsigned short)  bsend;
//transmit
while( !(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE )){;}
// wait for received char
return (unsigned char)( AT91C_BASE_SPI->SPI_RDR );
}


100раз \ сек опрашивается статус регистр датафлэша
результат в териминале:

...
0
173
255
172
172
172
172
0
173
255
172
172
172
172
0
...
(ноль передаётся только через УАРТ, для наглядности конца пакета)
с 255 всё должно бы начаться, а тут...


sad.gif
prottoss
Цитата(Goofy @ Feb 15 2008, 01:01) *
Код
unsigned char AT91_spi(unsigned char bsend)
{
while( !(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE )){;}
// wait until all transfers are completed
AT91C_BASE_SPI->SPI_TDR =(unsigned short)  bsend;
//transmit
while( !(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE )){;}
// wait for received char
return (unsigned char)( AT91C_BASE_SPI->SPI_RDR );
}
Вот это не понятно. вы какие то не те флаги ждете:-)



Попробуйте вот так:

Цитата
while((AT91C_BASE_SPI->SPI_SR & (AT91C_SPI_TXBUFE | AT91C_SPI_TXEMPTY)) != (AT91C_SPI_TXBUFE | AT91C_SPI_TXEMPTY)){;};



/* Read rx data register and status register for
clear previos transfers flag */
(UINT32)AT91C_BASE_SPI->SPI_RDR;
(UINT32)AT91C_BASE_SPI->SPI_SR;
(UINT32)AT91C_BASE_SPI->SPI_RDR;
Мы жждем флаг окончания передатчи PDC (AT91C_SPI_TXBUFE ) и опустошения внутреннего сдвигающего регистра SPI (AT91C_SPI_TXEMPTY)
Goofy
Цитата(prottoss @ Feb 15 2008, 01:12) *
Вот это не понятно. вы какие то не те флаги ждете:-)



Попробуйте вот так:

Мы жждем флаг окончания передатчи PDC (AT91C_SPI_TXBUFE ) и опустошения внутреннего сдвигающего регистра SPI (AT91C_SPI_TXEMPTY)


Если приглядеться, то заметно что работа идёт не через PDC wink.gif
prottoss
Блин smile.gif Название то теме Вы придумали? Что то вы экспериментируете не там. Ну что Вы пытаетесь сделать как то не в то место. Используйте ПДЦ. НЕ использкйте хардварные ноги. Будет вам счастие:-)



И посмотрите вот эту ветку, я когда начал SPi курить, тоже головой бился о че попало

http://electronix.ru/forum/index.php?showtopic=35141&hl=
Goofy
Цитата(prottoss @ Feb 15 2008, 01:27) *
Блин smile.gif Название то теме Вы придумали? Что то вы экспериментируете не там. Ну что Вы пытаетесь сделать как то не в то место. Используйте ПДЦ. НЕ использкйте хардварные ноги. Будет вам счастие:-)
И посмотрите вот эту ветку, я когда начал SPi курить, тоже головой бился о че попало

http://electronix.ru/forum/index.php?showtopic=35141&hl=


Ну начинал то я с ПДЦ
ключевое слово TXEMPTY, получается что передача не закочена и процедура возвращает предыдущий принятый байт, не вывалившийся из сдв. регистра.
twak.gif twak.gif

for (i=0;i<1000;i++) printf("БУДУ ВСЕГДА ВНИМАТЕЛЬНЕЙ ЧИТАТЬ ДАТАЩИТ, МЕЛОЧЕЙ ТУТ НЕБЫВАЕТ")

Большое спасибо! a14.gif Выпинали Вы меня, наконец, на путь истинный!

Ради интереса проверил, заработает ли пофиксенная процедура с аппаратным CS.
Не заработала.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.