|
|
  |
Помогите разобраться с SSP LPC2366 в режиме SLAVE |
|
|
|
Aug 18 2015, 09:21
|
Частый гость
 
Группа: Свой
Сообщений: 187
Регистрация: 22-06-05
Из: Минск, Беларусь
Пользователь №: 6 213

|
Есть некое устройство (МАСТЕР) которое каждые 20 мс по SPI (частота SCK = 50кГц) посылает команду состоящую из 4-х байт: [HEADER = 0x69] [СОСТОЯНИЕ 1] [СОСТОЯНИЕ 2] [КОНТРОЛЬНАЯ СУММА] В моем устройстве, выполненном на LPC2366, эта команда поступает на интерфейс SSP0, который я настроил на режим SLAVE. Код SSP0CPSR = ...;
SSP0CR0 = 0x107; //8bit, SPI, CPOL=CPHA=0, SCR=1
install_irq(SSP0_INT, (void*)SSP0Handler, HIGHEST_PRIORITY);
SSP0CR1 = SSP0CR1_SSE|SSP0CR1_MS; //SSP enabled in slave mode
SSP0IMSC = 0x04; // Enable Receive Interrupt (RXIM only) Прерывания от SSP срабатывают, однако сколько бы я не вычитывал SSP0DR, вычитывается только байт HEADER = 0x69, т.е весь массив bySpiData заполняется значениями 0x69 Код volatile BYTE bySpiData[256]; volatile BYTE bySpiIndex = 0; volatile DWORD dwSpiReceived = 0;
void SSP0Handler (void) __irq { while (SSP0MIS_RXMIS & SSP0MIS) { bySpiData[bySpiIndex++] = m_SSP0.Read() & 0xFF; dwSpiReceived++; } VICVectAddr = 0; // Acknowledge Interrupt } Что я делаю не так?
|
|
|
|
|
Aug 18 2015, 09:54
|

Местный
  
Группа: Свой
Сообщений: 449
Регистрация: 28-10-04
Из: Украина
Пользователь №: 1 002

|
Цитата(Yaumen @ Aug 18 2015, 13:21)  Что я делаю не так? Разберитесь с условием while (SSP0MIS_RXMIS & SSP0MIS). Очевидно же, что следующий байт придет только через достаточно большой интервал времени (относительно скорости процессора). Получается, вы несколько раз считываете один и тот же байт. Убедитесь, что при чтении первого байта сбрасывается флаг готовности. А вообще как-то стремно: прерывание вызывается для каждого принятого байта отдельно, но внутри прерывания вы пытаетесь вычитать более одного. Разберите более подробно как работает m_SSP0.Read().
--------------------
Умею молчать на 37 языках...
|
|
|
|
|
Aug 18 2015, 10:01
|
Частый гость
 
Группа: Свой
Сообщений: 187
Регистрация: 22-06-05
Из: Минск, Беларусь
Пользователь №: 6 213

|
Похоже, что проблема в том, что каждый байт передаваемый МАСТЕРОМ должен стробироваться сигналом SSEL, т.е. после каждого байта необходимо подымать SSEL в высокий, а затем опять ставить его в низкий. Мне такой режим не подходит, так как МАТЕР выставляет SSEL на время передачи всех 4-х байт и не стробирует каждый из них. Возможно надо использовать какой-либо другой режим работы SSP0, чтобы он был нечувствителен к стробированию сигналом SSEL? Цитата(Gorby @ Aug 18 2015, 12:54)  Разберитесь с условием while (SSP0MIS_RXMIS & SSP0MIS). Очевидно же, что следующий байт придет только через достаточно большой интервал времени (относительно скорости процессора). Получается, вы несколько раз считываете один и тот же байт. Убедитесь, что при чтении первого байта сбрасывается флаг готовности.
А вообще как-то стремно: прерывание вызывается для каждого принятого байта отдельно, но внутри прерывания вы пытаетесь вычитать более одного. Разберите более подробно как работает m_SSP0.Read(). А что тут стремного, для SSP есть буфер FIFO, пока я работаю с обработкой одного прерывания, по SSP может уже прийти несколько байт, вот и вычитываю, пока входной буфер не опустеет. Нормальная практика!!!
|
|
|
|
|
Aug 18 2015, 10:58
|

Местный
  
Группа: Свой
Сообщений: 449
Регистрация: 28-10-04
Из: Украина
Пользователь №: 1 002

|
Цитата(Yaumen @ Aug 18 2015, 14:01)  Похоже, что проблема в том, что каждый байт передаваемый МАСТЕРОМ должен стробироваться сигналом SSEL, т.е. после каждого байта необходимо подымать SSEL в высокий, а затем опять ставить его в низкий. Вот это действительно странно. Нет никакой необходимости стробировать с SSEL каждый байт. У вас верно сделано, SSEL на время передачи всех 4-х байт. Приемник обязан принимать. То, что первый байт принимается верно, подтверждает правильность выбранных режимов (там еще те грабли могут быть). Цитата А что тут стремного, для SSP есть буфер FIFO, пока я работаю с обработкой одного прерывания, по SSP может уже прийти несколько байт, вот и вычитываю, пока входной буфер не опустеет. Нормальная практика!!! А вот тут немного не так. На самом деле при SPI тактовой (сколько там у вас? 40 кГц?) принятие символа - очень редкое событие. Это не 2 и не 10 MHz. Попробуйте сделать одно прерывание на один байт.
--------------------
Умею молчать на 37 языках...
|
|
|
|
|
Aug 18 2015, 11:05
|
Частый гость
 
Группа: Свой
Сообщений: 187
Регистрация: 22-06-05
Из: Минск, Беларусь
Пользователь №: 6 213

|
Цитата(Yaumen @ Aug 18 2015, 13:01)  Похоже, что проблема в том, что каждый байт передаваемый МАСТЕРОМ должен стробироваться сигналом SSEL, т.е. после каждого байта необходимо подымать SSEL в высокий, а затем опять ставить его в низкий. Мне такой режим не подходит, так как МАТЕР выставляет SSEL на время передачи всех 4-х байт и не стробирует каждый из них. Возможно надо использовать какой-либо другой режим работы SSP0, чтобы он был нечувствителен к стробированию сигналом SSEL?
А что тут стремного, для SSP есть буфер FIFO, пока я работаю с обработкой одного прерывания, по SSP может уже прийти несколько байт, вот и вычитываю, пока входной буфер не опустеет. Нормальная практика!!! Да!!! Так и есть, каждый байт надо обязательно стробировать импульсом CS. Можно ли это отключить - не знаю, перепробовав различные режимы, так и не смог заставить работать как надо. Придется связываться с разработчиком МАСТЕРА, чтобы узнать возможно ли изменить его программу, чтобы каждый передаваемый байт стробировался CS. Если кто-то знает способ как заставить LPC2366 работать без этой фичи или еще лучше вообще без использования SSEL, буду весьма признателен!!! Цитата(Gorby @ Aug 18 2015, 13:58)  Вот это действительно странно. Нет никакой необходимости стробировать с SSEL каждый байт. У вас верно сделано, SSEL на время передачи всех 4-х байт. Приемник обязан принимать. То, что первый байт принимается верно, подтверждает правильность выбранных режимов (там еще те грабли могут быть).
А вот тут немного не так. На самом деле при SPI тактовой (сколько там у вас? 40 кГц?) принятие символа - очень редкое событие. Это не 2 и не 10 MHz. Попробуйте сделать одно прерывание на один байт. Пробовал делать и так и так. Коду в принципе все равно, сколько байт пришло 1 или несколько, примет столько сколько есть в буфере. Когда подключил к своему МАСТЕРУ и начал стробировать данные, все заработало как часы. Кстати в UserManual тоже нарисовано на графике Fig.93, что каждый байт должен стробироваться CS-ом. Вот засада!!! Кто же знал!?
|
|
|
|
|
Aug 20 2015, 07:57
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Yaumen @ Aug 18 2015, 15:21)  while (SSP0MIS_RXMIS & SSP0MIS) Что я делаю не так? С чего это Вы наличие данных в FIFO определяете по регистру запросов прерывания??? Он тут вообще не при чём. Наличие данных в FIFO определяется по регистру статуса SSP (и соотв. флагу в нём). А запрос прерывания надо просто сбросить через регистр сброса в начале ISR. Цитата(Yaumen @ Aug 18 2015, 17:05)  Да!!! Так и есть, каждый байт надо обязательно стробировать импульсом CS. Можно ли это отключить - не знаю, перепробовав различные режимы, так и не смог заставить работать как надо. Придется связываться с разработчиком МАСТЕРА, чтобы узнать возможно ли изменить его программу, чтобы каждый передаваемый байт стробировался CS. Если кто-то знает способ как заставить LPC2366 работать без этой фичи или еще лучше вообще без использования SSEL, буду весьма признателен!!! Оставьте разработчика мастера в покое. Всё прекрасно умеет LPC работать в любом режиме. Единственный косяк с которым сталкивался в slave-SPI LPC - сигнал SSEL необходимо обязательно посадить на GND, даже если он не используется. Ну, или, если мастер выдаёт этот сигнал, подать его на соотв. ногу LPC. PS: Читайте внимательнее мануал на SSP LPC.
|
|
|
|
|
Aug 23 2015, 15:03
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(jcxz @ Aug 23 2015, 18:30)  Так вот - не помню какой там у меня был CPHA, но SSEL просто посадили на GND и всё (мастер не выдавал CS) и каждый байт ни чем не дрыгали. Не помню - железный аргумент. Цитата PS: Читайте внимательнее мануал на SSP LPC.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|