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

 
 
 
Reply to this topicStart new topic
> Помогите разобраться с SSP LPC2366 в режиме SLAVE
Yaumen
сообщение Aug 18 2015, 09:21
Сообщение #1


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

Группа: Свой
Сообщений: 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
}


Что я делаю не так?
Go to the top of the page
 
+Quote Post
Gorby
сообщение Aug 18 2015, 09:54
Сообщение #2


Местный
***

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



Цитата(Yaumen @ Aug 18 2015, 13:21) *
Что я делаю не так?


Разберитесь с условием while (SSP0MIS_RXMIS & SSP0MIS).
Очевидно же, что следующий байт придет только через достаточно большой интервал времени (относительно скорости процессора). Получается, вы несколько раз считываете один и тот же байт. Убедитесь, что при чтении первого байта сбрасывается флаг готовности.

А вообще как-то стремно: прерывание вызывается для каждого принятого байта отдельно, но внутри прерывания вы пытаетесь вычитать более одного. Разберите более подробно как работает m_SSP0.Read().


--------------------
Умею молчать на 37 языках...
Go to the top of the page
 
+Quote Post
Yaumen
сообщение Aug 18 2015, 10:01
Сообщение #3


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

Группа: Свой
Сообщений: 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 может уже прийти несколько байт, вот и вычитываю, пока входной буфер не опустеет. Нормальная практика!!!
Go to the top of the page
 
+Quote Post
Gorby
сообщение Aug 18 2015, 10:58
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 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 языках...
Go to the top of the page
 
+Quote Post
Yaumen
сообщение Aug 18 2015, 11:05
Сообщение #5


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

Группа: Свой
Сообщений: 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-ом. Вот засада!!! Кто же знал!?
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 20 2015, 07:57
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 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.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 23 2015, 12:14
Сообщение #7


.
******

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



Цитата(jcxz @ Aug 20 2015, 11:57) *
Всё прекрасно умеет LPC работать в любом режиме.

В режимах приёмника с CPHA=0 действительно после каждого переданного байта нужно "дрыгать" SSEL через HIGH состояние.

Сообщение отредактировал GetSmart - Aug 23 2015, 12:19


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 23 2015, 14:30
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(GetSmart @ Aug 23 2015, 18:14) *
В режимах приёмника с CPHA=0 действительно после каждого переданного байта нужно "дрыгать" SSEL через HIGH состояние.

Разговор идёт о slave-SPI, который по определению не может управлять SSEL.
И в одном из проектов у меня был slave-SPI на LPC (правда LPC17xx, но он совпадает с тем что был в LPC23xx насколько я помню).
Так вот - не помню какой там у меня был CPHA, но SSEL просто посадили на GND и всё (мастер не выдавал CS) и каждый байт ни чем не дрыгали.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 23 2015, 15:03
Сообщение #9


.
******

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



Цитата(jcxz @ Aug 23 2015, 18:30) *
Так вот - не помню какой там у меня был CPHA, но SSEL просто посадили на GND и всё (мастер не выдавал CS) и каждый байт ни чем не дрыгали.

Не помню - железный аргумент.
Цитата
PS: Читайте внимательнее мануал на SSP LPC.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 23 2015, 17:13
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(GetSmart @ Aug 23 2015, 21:03) *
Не помню - железный аргумент.

И что Вы этим хотели сказать?
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Aug 24 2015, 11:06
Сообщение #11


.
******

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



Цитата(jcxz @ Aug 23 2015, 21:13) *
И что Вы этим хотели сказать?

Вторая часть поста.

"Дрыгать" должен мастер из-за аппаратных особенностей слэйва, работающего в режиме CPHA=0. Если по какой-то причине слэйв не может работать в режиме с CPHA=1. Слово "приёмник" в моём посте следует читать как "слэйв". Слегка ошибся.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 18th July 2025 - 20:11
Рейтинг@Mail.ru


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