реклама на сайте
подробности

 
 
> Отправляю пакет пр SPI
glebka
сообщение May 9 2006, 13:14
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 199
Регистрация: 22-06-05
Пользователь №: 6 217



не могу понять,отправляю пакет через SPI, теряются биты.

AT91PS_SPI pSpi = AT91C_BASE_SPI;
AT91PS_AIC pAic = AT91C_BASE_AIC;

unsigned int temp;
unsigned int spib;

temp = pAic->AIC_IMR;

while(pSpi->SPI_SR & AT91C_SPI_TDRE==0);
pSpi->SPI_TDR = (data & 0xFFFF) | (CS << 16);

while(pSpi->SPI_SR & AT91C_SPI_RDRF==0);

pAic->AIC_IECR = temp;
spib=((pSpi->SPI_RDR) & 0xFFFF);
return spib;
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 9)
GetSmart
сообщение May 9 2006, 16:22
Сообщение #2


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(glebka @ May 9 2006, 19:14) *
не могу понять,отправляю пакет через SPI, теряются биты.

Если у вас теряются именно биты, а не байты, например первые или последние несколько бит, то возможно это из-за того, что два устройства (процессор и что-то внешнее) настроены неправильно по отношению друг к другу. Обычно есть 4 режима SPI плюс ещё порядок следования бит. И не все из них совместимы друг с другом. Из сообщения много непонятно о проблеме. Неясно что стоит снаружи проца (на шине SPI) и неясно как настроен SPI. Ещё может быть проблема в очень длинных проводах между устройствами (от полуметра и более), но это тоже связано с высокой скоростью обмена.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
Edmundo
сообщение May 9 2006, 16:55
Сообщение #3


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Насколько я понял, SPI замкнут сам на себя.

У меня тоже есть подобная проблема, но я пока грешу на передатчик. В чем дело у меня, отпределю уже только на работе (дома ни осциллоскопа, ни даже мультиметра). Но симптомы похожие: при приеме пропадает первый бит данных (MSB), количество бит и их положение в байте корректные (пробовал и опрос в цикле, и по DMA).

Все-таки поддерживаю GetSmart, конкретизируйте немного, как настроен SPI, как подключен.


--------------------
شامل
Go to the top of the page
 
+Quote Post
GetSmart
сообщение May 9 2006, 17:46
Сообщение #4


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Насколько я знаю, передавать на себя и в большинство внешних устройств можно только в режимах 0 и 3. Другие режимы очень специфичные и мало для чего пригождаются. То есть в режимах 1 и 2 так и должно быть пропадение одного бита. Это нормально. Режим 0 => CPHA = CPOL = 0, режим 3 => CPHA = CPOL = 1.
Ещё меня удивило, что в одной процедуре анализируются два флага готовности. Я так никогда не делаю. Достаточно проверки одного флага.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
glebka
сообщение May 9 2006, 17:54
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 199
Регистрация: 22-06-05
Пользователь №: 6 217



Прошу прощения. за неправильно сформулированый вопрос. отправляю пакет из 48 битов(команду)в сторону sd карты.во время передачи видно как на осциллографе первый бит команды сдвигается на 1 байт по отношению к началу clk и плюс при по байтной отправке между отправленными байтами паузы во время которых проподает chip select . я грешу на неправильную установку spi.хотя пользуюсь примером кода взятого с форума и сайта Lamerka и работающего в другом устройстве.
может кто-нибудь подскажет. или где посмотреть пример кода. пример с olimex есть ,разобрал попробовал теже грабли.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение May 9 2006, 18:32
Сообщение #6


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Даю вырезки для работы с SPI LPC213x. Подойдёт и ко многим другим. С AT91 не знаком, так что немного переделаете. Вообще, процедуры написаны так, чтобы максимально использовать скорость процессора. То есть во время передачи байта можно выполнять другие действия.

Процедуры инициализации:

#define PCLKFREQ 14745600*4

void LPC213xInitSPI0Master()
{
PINSEL0 = (PINSEL0 & ~0xff00) | 0x1500; // for SCK0, MISO, MOSI, SSEL-
SPCCR0 = PCLKFREQ / 921600; // скорость = 0.6912 MHz (~80 КБ/сек)
SPCR0 = 0x20;
if (SPSR0) {}; // просто чтение для сброса флага SPIF
SPDR0 = '!'; // это чтобы изначально бит SPIF (TDRE) установился
}

void txByteSPI0(long byte)
{
if (SPSR0) {} // просто чтение для сброса флага SPIF
SPDR0 = byte;
}

long rxtxByteSPI0(long byte)
{
for(uInt i=0; i<0x10000; i++) // 1/50 sec - это на всякий случай. Всё бывает на свете!
if (SPSR0_bit.SPIF) // это бит завершения передачи байта в мастере (и приёма в слэйве)
{
long j = SPDR0;
if (byte >= 0) SPDR0 = byte;
return(j);
}
LPC213xInitSPI0Master();
return(0);
}

Рабочие процедуры:

void READ_ADS1218(uInt cmd, uInt cnt, uByte *ptr)
{
_ON_CS_ADS1218;
txByteSPI(cmd);
rxtxByteSPI(cnt-1);
_WAIT(_50Tosc);
rxtxByteSPI(0);
while (cnt--)
if (cnt) *ptr++ = rxtxByteSPI(0);
else *ptr = rxtxByteSPI(-1); // завершение передачи
_OFF_CS_ADS1218;
}

Пояснение:
В моей схеме был режим мастер, а вывод SSEL вообще не использовался. Сначала вручную сбрасывается сигнал ~CS на нужное внешнее устройство. Затем вызывается процедура передачи первого байта без анализа флагов (txByteSPI0(long byte)). После сколько угодно раз процедуру уже анализирующую флаги (rxtxByteSPI0(long byte)). Однако в конце нужно вызывать её же с параметром (-1). Она при этом ничего не передаёт, а просто ждёт завершения передачи последнего байта. После этого уже можно обратно вручную устанавливать вывод ~CS в еденицу (_OFF_CS_ADS1218).

Если не выжимать из процессора максимум скорости, то можно было бы сделать немного попроще. Но мне так больше нравится.

Если нужно просто выкинуть в SPI 6 байт то вот пример:

void Write6bytesSPI(uByte *ptr)
{
_ON_CS_ADS1218;
txByteSPI(*ptr++);
for (uInt i=0; i<5; i++) // здесь выкинуть именно 5, а не 6 байт. т.к. один уже выкинут
rxtxByteSPI(*ptr++);
rxtxByteSPI(-1); // завершение передачи
_OFF_CS_ADS1218;
}

Кстати, процедура (rxtxByteSPI0(long byte)) передаёт новый байт в SPI, но возвращает как бы предыдущий принятый байт. Осторожно!


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
GetSmart
сообщение May 9 2006, 20:07
Сообщение #7


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



glebka
Возможно мне показалось, но возможно у вас SPI настроен на 16 бит, а записываете вы в него байты. Если это так и сначала передаются старшие биты, то первые 8 старших бит как бы не видно. А chip select, не понимаю, аппаратный что ли? Вроде не видел таких, если только это не SSEL.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
glebka
сообщение May 10 2006, 10:09
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 199
Регистрация: 22-06-05
Пользователь №: 6 217



У меня SPI init так: может что не так

void SPI_Init(unsigned char BitsPerTransfer)
{
volatile unsigned int data_temp;
unsigned char i;

// Enable peripheral clocks for SPI mode
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_SPI ) ;

// Configure Periphery I/O, SPI mode enable.
AT91F_PIO_CfgPeriph(AT91C_BASE_PIOA,AT91C_PA11_NPCS0 |AT91C_PA13_MOSI | AT91C_PA14_SPCK | AT91C_PA12_MISO,AT91C_PA9_NPCS1|AT91C_PA10_NPCS2);
AT91F_SPI_Enable(AT91C_BASE_SPI);

// Mode register (Mode:Master/Slave), Peripherial select (0-Fixed,1-variable),Delay between chip selects)
//AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_PS_VARIABLE | (AT91C_SPI_DLYBCS & (0x15<<24));
AT91C_BASE_SPI->SPI_MR = 0x15000003;



AT91C_BASE_SPI->SPI_IER = AT91C_SPI_RDRF | AT91C_SPI_MODF | AT91C_SPI_OVRES;
AT91C_BASE_SPI->SPI_CSR[0]= AT91C_SPI_NCPHA|(AT91C_SPI_BITS & AT91C_SPI_BITS_8)|(AT91C_SPI_SCBR & (0x15 <<8 )) | (AT91C_SPI_DLYBS & (0x5 << 16))|(AT91C_SPI_DLYBCT &(0x20<< 24));
AT91C_BASE_SPI->SPI_CSR[1]= AT91C_SPI_NCPHA|(AT91C_SPI_BITS & AT91C_SPI_BITS_8)|(AT91C_SPI_SCBR & (0x15 <<8 )) | (AT91C_SPI_DLYBS & (0x5<< 16))|(AT91C_SPI_DLYBCT & (0x20<< 24));
AT91C_BASE_SPI->SPI_CSR[2]= AT91C_SPI_NCPHA|(AT91C_SPI_BITS & AT91C_SPI_BITS_8)|(AT91C_SPI_SCBR & (0x15 <<8 )) | (AT91C_SPI_DLYBS & (0x5 << 16))|(AT91C_SPI_DLYBCT &(0x20<< 24));


AT91F_PDC_Open((AT91PS_PDC) &(AT91C_BASE_SPI->SPI_RPR));

data_temp = AT91C_BASE_SPI->SPI_RDR; // Read data from Receive Data Register for prevent Overrun error
}
Go to the top of the page
 
+Quote Post
Edmundo
сообщение May 10 2006, 19:26
Сообщение #9


Мастер
****

Группа: Свой
Сообщений: 730
Регистрация: 18-02-06
Из: Москва
Пользователь №: 14 474



Итак, я провел анализ на работе, у меня, как и предполагалось, "виноват" передатчик. SAM'овский SPI отрабатывает на прием все как задумано. Могу привести свои исходники, но они для Slave-режима и только на прием (без передачи). Вряд ли Вам будет это интересно.

Однако для справки могу сказать, что когда писал свою программу, ориентировался на пример отсюда. Скорректировал под себя, разумеется (пришлось подробно ознакомиться с даташитом), но заработало с первого раза (SPI под ARM вообще делаю первый раз smile.gif ).


--------------------
شامل
Go to the top of the page
 
+Quote Post
glebka
сообщение May 12 2006, 08:22
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 199
Регистрация: 22-06-05
Пользователь №: 6 217



Благодарю Edmundo, GetSmart. но я делаю сделал всё правильно.Обнаружил,что в DEBUG режиме и когда устройство работает самостоятельно - картинка разная, причем при самостоятельной работе такая какя должна быть.
Пользуюсь IAR+ j-link. При отладке программу загружаю в флеш.Если не секркт почему картина такая разня.Может не успевает дебаггер?
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 23:10
Рейтинг@Mail.ru


Страница сгенерированна за 0.02113 секунд с 7
ELECTRONIX ©2004-2016