Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: SPI на SAM7X256
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Metal
Привет, нужны примеры исходников взаимодействия 2х sam7x256 по SPI, и вообще любые примеры использования SPI на этом или сходных МК. Заранее спасибо! мое мыло: strelokk@hotmail.ru
Shuuura
//конфигурировать SPI
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_SPI ) ;
AT91F_SPI_Reset(AT91C_BASE_SPI);

//определяет регистр SPI_MR
AT91F_SPI_CfgMode(AT91C_BASE_SPI,
AT91C_SPI_MSTR | //мастер
AT91C_SPI_PS_FIXED | //фиксирования периферия
AT91C_SPI_MODFDIS | //Mode fault detection is disabled.
((0x00 << 24) & AT91C_SPI_DLYBCS)
);

AT91C_BASE_SPI->SPI_CR = AT91C_SPI_LASTXFER | AT91C_SPI_SPIEN;
AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER;


//использую аппартный CS, хотя можно использовать и любые ножки.
//при использовании аппаратных СS заранее сконфигурировать соответствующие функции PIO контроллера
//устанавливает биты PCS в регистре SPI_MR
for(i=0;i<4;i++){
//определяет регистры SPI_CSR0... SPI_CSR3
AT91F_SPI_CfgCs(AT91C_BASE_SPI,
i,//номер регистра
// AT91C_SPI_CPOL | //SPI mode 3
AT91C_SPI_BITS_16 |//Передаем по 16 бит
// AT91C_SPI_CSAAT | //оставить СS активным после окончания передачи
((0x02 << 8) & AT91C_SPI_SCBR) | //Serial Clock Baud Rate (делитель мастер клока)
((0x01 << 24) & AT91C_SPI_DLYBCT)|
((0x10 << 16) & AT91C_SPI_DLYBS)
); //Delay Between Consecutive Transfers
}


AT91F_PDC_EnableRx(AT91C_BASE_PDC_SPI);
AT91F_PDC_EnableTx(AT91C_BASE_PDC_SPI);
AT91F_PDC_Open(AT91C_BASE_PDC_SPI);


//отправка слова данных (отпарвлять можно от 8 до 16 бит)

//0x0e - выбор ножки CS
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
//здесь выбирается ножка CS
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0x0E);
AT91F_SPI_PutChar(AT91C_BASE_SPI,data, 0x0E));


// отправка через PDC
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0x0E);
AT91F_SPI_SendFrame(AT91C_BASE_SPI, (char*)(data_pointer),data_size , 0, 0);
while(!AT91F_PDC_IsRxEmpty(AT91C_BASE_PDC_SPI));

пользуйтесь PDC - отличная вешь (особенно после работы с AVR)

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

Смотрите ww.AT91.com - там есть хороший форум
Metal
спасибо, на at91.com я смотрел, но по работе SPI на SAM7 к сожалению не слишком много инфы представлено ((
Metal
если не сложно, не могли бы Вы выложить так же код для приема, ибо в этом деле я новичек, и довольно сложно сразу во все вникнуть
Master
Цитата(Metal @ May 18 2006, 11:46) *
спасибо, на at91.com я смотрел, но по работе SPI на SAM7 к сожалению не слишком много инфы представлено ((

Согласен с высказавшимися.

От себя задам ещё один вопрос. Возможно, его надо вынести в отдельную тему...
В моём устройстве заложена возможность использования нескольких устройств SPI-шине (один Master, остальные четыре - Slave).
Вопрос такой: каким образом (из какого регистра) можно определить, с каким устройством я работаю?
Поясню. Обработчик прерывания от SPI - общий. А дальнейшая работа с SPI разбита на обработчики соответствующих их номеру CS устройств. Вот этот номер CS я и хочу получить.
Есть два регистра - SPI_MR и SPI_RDR, в которых есть поле PCS. C последним можно работать только после первой передачи, а первый почему-то теряет значение PCS после передачи более 16 байт (передачу веду побайтно).
Можно конечно объявить глобальную переменную, и в ней держать номер... Но это имхо не красиво.
Shuuura
код для приема через PDC

AT91F_SPI_CfgPCS(AT91C_BASE_SPI,cs_data_recive);
AT91F_SPI_ReceiveFrame(AT91C_BASE_SPI, (char *)(&data_mas[0], read_size, 0, 0);
//тут надо что-нибудь отправить, все-равно что, только заданное кол-во байт
AT91F_SPI_SendFrame(AT91C_BASE_SPI, (char *)(&data_mas[0]), read_size, 0, 0);

для "разматыватывания" API функций (при разборках как она работает и что ей надо) пользуйтесь функцией IAR goto definiton . Вызывается то правому клику на функции.

Цитата
Вопрос такой: каким образом (из какого регистра) можно определить, с каким устройством я работаю?

А в чем проблема? Когда SAM7S мастер, то он сам знает с чем работает, т.к вы сами инициируете передачу. А когда он slave - то другой мастер должен знать с чем работать. Т.е. вы пишете свой менеджер SPI, и все настройки храните в отдельных переменных. Все равно его делать придется , если хотите работать с несколькими Slave через PDC.
Master
Цитата
Цитата
Вопрос такой: каким образом (из какого регистра) можно определить, с каким устройством я работаю?
А в чем проблема? Когда SAM7S мастер, то он сам знает с чем работает, т.к вы сами инициируете передачу. А когда он slave - то другой мастер должен знать с чем работать. Т.е. вы пишете свой менеджер SPI, и все настройки храните в отдельных переменных. Все равно его делать придется , если хотите работать с несколькими Slave через PDC.
Отмечу ещё раз, что передачу веду ПОБАЙТНО (=без PDC).
А вопрос был о том, нужно ли хранить CS в переменной или каким-то образом можно использовать значения регистров.
Master
Цитата(Shuuura @ May 17 2006, 10:48) *
//конфигурировать SPI
AT91F_PMC_EnablePeriphClock ( AT91C_BASE_PMC, 1 << AT91C_ID_SPI ) ;
AT91F_SPI_Reset(AT91C_BASE_SPI);
Здесь было бы неплохо сконфигурировать ноги:
Код
    AT91F_PIO_CfgPeriph( AT91C_BASE_PIOA,         // PIO controller base address
        ((UINT) AT91C_PA11_NPCS0    ) |
        ((UINT) AT91C_PA12_MISO        ) |
        ((UINT) AT91C_PA13_MOSI        ) |
        ((UINT) AT91C_PA14_SPCK        ) |
        ((UINT) AT91C_PA31_NPCS1    ),    // Peripheral A
        ((UINT) AT91C_PA3_NPCS3        ) |
        ((UINT) AT91C_PA30_NPCS2    ) );    // Peripheral B
А до этого включить частоту на PIO (впрочем, здесь не уверен).
Цитата
//определяет регистр SPI_MR
AT91F_SPI_CfgMode(AT91C_BASE_SPI,
AT91C_SPI_MSTR | //мастер
AT91C_SPI_PS_FIXED | //фиксирования периферия
AT91C_SPI_MODFDIS | //Mode fault detection is disabled.
((0x00 << 24) & AT91C_SPI_DLYBCS)
);

AT91C_BASE_SPI->SPI_CR = AT91C_SPI_LASTXFER | AT91C_SPI_SPIEN;
AT91C_BASE_SPI->SPI_TDR = AT91C_SPI_LASTXFER;


//использую аппартный CS, хотя можно использовать и любые ножки.
Можно-то оно конечно можно. Только выбирать CS придётся. Да так, чтобы одна из ног опускалась. Возразите, если сможете.
Цитата
//при использовании аппаратных СS заранее сконфигурировать соответствующие функции PIO контроллера
//устанавливает биты PCS в регистре SPI_MR
for(i=0;i<4;i++){
//определяет регистры SPI_CSR0... SPI_CSR3
AT91F_SPI_CfgCs(AT91C_BASE_SPI,
i,//номер регистра
// AT91C_SPI_CPOL | //SPI mode 3
AT91C_SPI_BITS_16 |//Передаем по 16 бит
// AT91C_SPI_CSAAT | //оставить СS активным после окончания передачи
((0x02 << 8) & AT91C_SPI_SCBR) | //Serial Clock Baud Rate (делитель мастер клока)
((0x01 << 24) & AT91C_SPI_DLYBCT)|
((0x10 << 16) & AT91C_SPI_DLYBS)
); //Delay Between Consecutive Transfers
}


AT91F_PDC_EnableRx(AT91C_BASE_PDC_SPI);
AT91F_PDC_EnableTx(AT91C_BASE_PDC_SPI);
AT91F_PDC_Open(AT91C_BASE_PDC_SPI);


//отправка слова данных (отпарвлять можно от 8 до 16 бит)

//0x0e - выбор ножки CS
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
//здесь выбирается ножка CS
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0x0E);
AT91F_SPI_PutChar(AT91C_BASE_SPI,data, 0x0E));


// отправка через PDC
while (!((AT91C_BASE_SPI->SPI_SR) & AT91C_SPI_TXEMPTY));
AT91F_SPI_CfgPCS(AT91C_BASE_SPI,0x0E);
AT91F_SPI_SendFrame(AT91C_BASE_SPI, (char*)(data_pointer),data_size , 0, 0);
while(!AT91F_PDC_IsRxEmpty(AT91C_BASE_PDC_SPI));

пользуйтесь PDC - отличная вешь (особенно после работы с AVR)

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

Смотрите ww.AT91.com - там есть хороший форум
Shuuura
Цитата
Здесь было бы неплохо сконфигурировать ноги:

Так я же писал, "при использовании аппаратных СS заранее сконфигурировать соответствующие функции PIO контроллера". Частоту на PIO, конечно, надо включить раньше работы с его регистрами.

Цитата
Можно-то оно конечно можно. Только выбирать CS придётся. Да так, чтобы одна из ног опускалась. Возразите, если сможете.

А что тут возражать? Хотите используете аппаратный СS, хотите просто ножки PIO. Если на шине один slave и ног мало можно вообще без CS обойтить (если slave позволяет). Зависит от частоты SPI, разводки платы, количества свободных ног.... Хотя оптимальный вариант - аппаратные CS, т.к максимальная частота SPI 25Мгц, а от PIO, судя по отзывам, больше нескольких МГц не добиться. Обратно же, аппаратные задержки тоже вещь нужная.
Master
Цитата(Shuuura @ May 19 2006, 11:50) *
Цитата
Здесь было бы неплохо сконфигурировать ноги:
Так я же писал, "при использовании аппаратных СS заранее сконфигурировать соответствующие функции PIO контроллера". Частоту на PIO, конечно, надо включить раньше работы с его регистрами.
Правда Ваша, как-то упустил из виду.
Цитата
Цитата
Можно-то оно конечно можно. Только выбирать CS придётся. Да так, чтобы одна из ног опускалась. Возразите, если сможете.
А что тут возражать? Хотите используете аппаратный СS, хотите просто ножки PIO. Если на шине один slave и ног мало можно вообще без CS обойтить (если slave позволяет).
Вот здесь, если можно, пожалуйста поподробнее. Каким образом начать передачу, не опустив одну из ног NCS0..NCS3? Сам бьюсь, пока результат нулевой. Для Fixed Periph режим с PCS=1111 описан как forbidden. И передача действительно не начинается. С Variable пока разбираюсь.
Кстати, в Variable режиме с использованием PDC тратится почти попусту память, т.к. для буферов нужны значения шириной 32 бита. В Fixed Mode, насколько я понимаю, размер элемента буфера определяется размером посылаемых данных: поле BITS регистров SPI_CSR0..3.
Возвращаясь к ногам, Вы ведь понимаете, что при невозможности передачи без опускания одной из упомянутых ног использование "программных" CS бессмыслено?
Цитата
Зависит от частоты SPI, разводки платы, количества свободных ног....
Частота SPI зависима от способа выбора CS? Это как это? smile.gif . Про количество свободных ног - вопрос выше. А вот если Вы считаете, что способ выбора CS зависит от разводки, то я думаю, Вы либо недооцениваете, либо переоцениваете труд разводчиков ПП. В угоду разводке жертвовать ногой безрассудно.
Цитата
Хотя оптимальный вариант - аппаратные CS, т.к максимальная частота SPI 25Мгц, а от PIO, судя по отзывам, больше нескольких МГц не добиться. Обратно же, аппаратные задержки тоже вещь нужная.
Частично согласен. Если у Вас есть код, доказывающий ограниченность работы PIO по частоте, поделитесь пожалуйста.
Shuuura
Цитата
Каким образом начать передачу, не опустив одну из ног NCS0..NCS3?

Сам не пробовал, но думаю что можно не задействовать CS в PIO контроллере. Тогда можно активировать любой CS, но на аппартную ножку он не дойдет. А перед началом передачи активировать любую програмную.

Цитата
Частота SPI зависима от способа выбора CS? Это как это?

Если нужна большая скорость перечачи данных (я использую 24 Мгц) то из-за "тормознутости" PIO контроллера выставленый "программый" СS может появиться после начала данных. Т.е надо делать програмную задерку - а это потеря быстродействия. Выводы о его тормознутости сделал в результате чтения всех доступных конференций. Где-то пробегала цифра что больше 3 МГц "ногодрыганием" не получить

Цитата
А вот если Вы считаете, что способ выбора CS зависит от разводки,


Разводки разные бывают. Мы вплотную подошли к необходимости перехода с двухстононней платы на 4 слоя, т.к. иногда сложно с одной стороны ARMа на другую Cyclona лишний проводник бросить (мало места). Я бы активно пользовался програмными СS, чтобы упростить разводку, если бы быстродействие позволяло.
Master
Цитата(Shuuura @ May 19 2006, 18:32) *
Цитата
Каким образом начать передачу, не опустив одну из ног NCS0..NCS3?

Сам не пробовал, но думаю что можно не задействовать CS в PIO контроллере. Тогда можно активировать любой CS, но на аппартную ножку он не дойдет. А перед началом передачи активировать любую програмную.
Совершенно точно мыслите любезнейший! Я как раз только что пробовал именно так передавать - с использованием неподключенного CS в PIO - и передача проходила!
Цитата
Цитата
Частота SPI зависима от способа выбора CS? Это как это?

Если нужна большая скорость перечачи данных (я использую 24 Мгц) то из-за "тормознутости" PIO контроллера выставленый "программый" СS может появиться после начала данных. Т.е надо делать програмную задерку - а это потеря быстродействия. Выводы о его тормознутости сделал в результате чтения всех доступных конференций. Где-то пробегала цифра что больше 3 МГц "ногодрыганием" не получить
И всё-таки не понятно. Даже если и так, с чем связана такая тормознутость...
Цитата
Цитата
А вот если Вы считаете, что способ выбора CS зависит от разводки,
Разводки разные бывают. Мы вплотную подошли к необходимости перехода с двухстононней платы на 4 слоя, т.к. иногда сложно с одной стороны ARMа на другую Cyclona лишний проводник бросить (мало места). Я бы активно пользовался програмными СS, чтобы упростить разводку, если бы быстродействие позволяло.
Может имеет смысл сменить производителя ПП?
Metal
с этим разобрался, осталось теперь сделать такую цепочку, считывание по SPI с другого устройства и передача на ПК по USB, посоветуйте как это лучше организовать?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.