pokk 0 8 декабря, 2016 Опубликовано 8 декабря, 2016 · Жалоба Добрый день, изучая AD9859 решил сделать инициализацию в виде все настроенные значения занести в один массив и его с помощью DMA перегнать а AD9859, но возникла проблема, как дергать CS ? его надо надо переключать то через 5 байт то через 3 байта. // ASF AD9859_CS_LOW Write_DDS(0x02); // ADDRESS Write_DDS(0x00); // DEFAULT Write_DDS(0x00); AD9859_CS_HIGH AD9859_UPDATE_HIGH delay_us(1); AD9859_UPDATE_LOW // CFR1 AD9859_CS_LOW Write_DDS(0x00); // ADDRESS Write_DDS(0x00); // DEFAULT Write_DDS(0x00); Write_DDS(0x00); Write_DDS(0x00); AD9859_CS_HIGH AD9859_UPDATE_HIGH delay_us(1); AD9859_UPDATE_LOW Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 8 декабря, 2016 Опубликовано 8 декабря, 2016 · Жалоба но возникла проблема, как дергать CS ?Инициализацию разбить на команды, на каждую команду запускать DMA, перед запуском DMA и в прерывании окончания персылки дергать CS. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 183 8 декабря, 2016 Опубликовано 8 декабря, 2016 · Жалоба Добрый день, изучая AD9859 решил сделать инициализацию в виде все настроенные значения занести в один массив и его с помощью DMA перегнать а AD9859, но возникла проблема, как дергать CS ? его надо надо переключать то через 5 байт то через 3 байта. В некоторых МК имеются полнофункциональные SPI-интерфейсы, в которых есть управления линиями CS в слове передаваемых данных к примеру. Например Infenion такое умеет. Также в Тексасовских МК такое есть (Tiva, OMAP L-13x). Так что, если есть возможность - возьмите такой МК. В других МК, имеющих полнофункциональные DMA-контроллеры, такое можно сделать заведя события запуска DMA не от SPI, а от какого либо таймера. Запрограммировав DMA в режиме передачи "свЯзных списков", можно разными пересылаемыми DMA-блоками внутри одного списка, управлять и линиями CS (через GPIO например) и загружать в SPI данные. Я реализовывал такой метод на LPC17xx. Многие другие МК также имеют DMA с функционалом "свЯзных списков" В STM32 с его бедной периферией, нет ни того ни другого. Выбирать его для каких-то серьёзных операций с периферией - глупо. Сомневаюсь что на нём можно как-то реализовать это аппаратно. Так что если ещё не поздно - поменяйте на что-то другое, где есть более мощная периферия. Инициализацию разбить на команды, на каждую команду запускать DMA, перед запуском DMA и в прерывании окончания персылки дергать CS. Вопрос-то был как раз в том - "как не разбивать?" PS: На STM32 можно извратиться - сэмулировать недостающий в его DMA режим свЯзных списков (с помощью доп. канала DMA и таймера). Тогда да - получится без задействования CPU передать весь массив, дёргая внутри него CS-ом в нужных местах. Но такая реализация получается очень громоздкой B) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 8 декабря, 2016 Опубликовано 8 декабря, 2016 · Жалоба Вопрос-то был как раз в том - "как не разбивать?"Я вопрос понял иначе - "как прикрутить DMA вместо отсылки каждого байта вручную, но при этом дергать CS". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 183 8 декабря, 2016 Опубликовано 8 декабря, 2016 · Жалоба Я вопрос понял иначе - "как прикрутить DMA вместо отсылки каждого байта вручную, но при этом дергать CS". Как я понял - ТС хочет один раз запустить некий процесс при помощи CPU и только в конце его получить одно прерывание завершения. ТС нас рассудит как появится ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 9 декабря, 2016 Опубликовано 9 декабря, 2016 (изменено) · Жалоба Да jcxz прав хочу все скопищем что бы отправлялось, хотя в данном случае это не сильно принципиально, но просто было интересно узнать как такое можно сделать, хотя бы на данном примере. В некоторых МК имеются полнофункциональные SPI-интерфейсы, в которых есть управления линиями CS в слове передаваемых данных к примеру. Это типа в данных дополнительным битом указываешь когда CS переключить? У STM есть вывод CS(NSS) но он там переключается через каждый байт, по этому не когда не использовал его. такое можно сделать заведя события запуска DMA не от SPI, а от какого либо таймера Такое есть в STM планирую сделать для записи частоты (там будет фиксированная длинна и от сигнала CS можно будет запускать передачу) Можно подробнее про режим связанных списков ? в Stm32f446 есть режим Double buffer mode это не то ? я еще с ним толком не разобрался. по этому и спрашиваю Кстати есть МК с режимом DMA периферия-> периферия это типа когда из пзу передаешь контент. Так что если ещё не поздно - поменяйте на что-то другое, где есть более мощная периферия. Уже поздно так что буду извращаться "с помощью доп. канала DMA и таймера" заодно и разберусь с dma досконально. Изменено 9 декабря, 2016 пользователем pokk Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 62 9 декабря, 2016 Опубликовано 9 декабря, 2016 · Жалоба Добрый день, изучая AD9859 решил сделать инициализацию в виде все настроенные значения занести в один массив и его с помощью DMA перегнать а AD9859, но возникла проблема, как дергать CS ? его надо надо переключать то через 5 байт то через 3 байта. Если AD9859 понимает незначащие нули, то можно выровнять нулями в начале блоки данных на 5 и запустить таймер с периодом передачи блоков. А у таймера на одном из каналов формировать ШИМом CS. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 183 9 декабря, 2016 Опубликовано 9 декабря, 2016 · Жалоба Это типа в данных дополнительным битом указываешь когда CS переключить? У STM есть вывод CS(NSS) но он там переключается через каждый байт, по этому не когда не использовал его. Можно подробнее про режим связанных списков ? в Stm32f446 есть режим Double buffer mode это не то ? я еще с ним толком не разобрался. по этому и спрашиваю В DMA STM32 нет режима связных списков - это самый главный минус его DMA. Так как режим "свЯзных списков" имеет самые большие возможности из всех других режимов DMA. Можно даже сказать, что все другие режимы - это частные случаи режима связных списков. Имея только этот режим, все остальные режимы DMA (и двойной буфер и циклический и пр.) можно реализовать через связные списки. Режим "связных списков" - это когда указываешь DMA не один блок для пересылки, а цепочку (произвольной длины) таких блоков, у каждого блока - свой размер, свои адреса целевой/источник и своё слово управления. Таким списком можно например управлять сразу разной периферией в одной пересылке (например GPIO и SPI). А в Вашем случае можно попытаться реализовать какое-то подобие этого режима на STM32 из говна и палок на нескольких таймерах + неск. каналов DMA. Ключевое тут то, что у Вас SPI-мастер и не очень важна времянка. NSS тут не при чём. CS управлять через GPIO. Общий алгоритм такой же, как в связных списках. Но реализовывать придётся через известное место. И почитайте немного как работает DMA, узнайте что такое целевой адрес периферии при пересылке и что такое запрос от периферии и чем они отличаются. Так вот - запросы на пересылки надо брать от таймера, а не SPI. Блок-схема: Таймер с определённым периодом дёргает 1-й DMA канал, который на каждое такое событие выполняет пересылку в регистры управления 2-го DMA-канала - программирует его для очередной передачи. Каждый такой блок программирует 2-й DMA канал на очередную пересылку. 1-я пересылка блока конфигурации - в регистры GPIO, чтобы установить CS=0. 2-я пересылка блока конфигурации в регистры управления 3-го DMA-канала, которая запрограммирует его на обслуживание SPI (только передача) и пересылку в SPI (по его запросам) очередного блока данных. 3-я пересылка блока конфигурации - в регистры GPIO, чтобы установить CS=1. И так далее через интервалы времени, определяемые таймером. Синхронизация 1-го DMA - от событий таймера; второй DMA - без синхры, режим память-память; 3-й DMA - синхра от SPI. Как-то примерно так. Это примерная схема. Подробно - уже сами, изучив как следует матчасть (SPI, таймеры, DMA, их взаимосвязи). PS: Да - в терминологии юзермануала STM32 следует читать "каналы DMA" как "потоки DMA". А "запросы DMA" как "каналы DMA" ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 9 декабря, 2016 Опубликовано 9 декабря, 2016 · Жалоба jcxz, Благодарю за ответ, что-то даже и в мыслях не было что можно DMA настраивать периферию, теперь возможности гораздо расширились. Пока еще не совсем въехал в алгоритм, конкретно буду в понедельник с разбираться. Таким образом можно передавать и считывать блоками по SPI N- количество байт от 1-65535? Просто есть другая задача не думал что этот вопрос затронет её там мне как раз надо передать данные в размере от 1-65535 байт, потом щелкнуть CS что данные закончились и дальше надо передать 1-2 байта команды что бы данные уже отправились. Пока приходилось решать это программным путем но, это оказался дикий геморрой, если получиться данный алгоритм применить и туда это будет круто, ещё раз спасибо за идею =) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 183 9 декабря, 2016 Опубликовано 9 декабря, 2016 · Жалоба Пока еще не совсем въехал в алгоритм, конкретно буду в понедельник с разбираться. Таким образом можно передавать и считывать блоками по SPI N- количество байт от 1-65535? Конечно можно. У Вас же SPI-мастер. И если тактирование его идёт от того-же источника (это важно!), что и таймер, то можно по таймеру определять когда регистр передачи SPI.DR опустошается (с небольшим запасом брать) и можно писать новые данные в него. И флаги статуса SPI можно не смотреть. А соответственно и GPIO тоже управлять по этой же временной диаграмме. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 12 декабря, 2016 Опубликовано 12 декабря, 2016 · Жалоба Разбираюсь с алгоритмом, пока понял что таймером мы генерируем сигналы CS а потом между ними вставляет передачу SPI так ? Пока не могу понять, 1-я пересылка блока конфигурации, вторая и третья посылка закидываются от каждого события таймера? Или все скопищем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 183 12 декабря, 2016 Опубликовано 12 декабря, 2016 · Жалоба Разбираюсь с алгоритмом, пока понял что таймером мы генерируем сигналы CS а потом между ними вставляет передачу SPI так ? Нет, не так. Я же вроде подробно разжевал в сообщении N8... Таймер генерирует только события 1-му DMA каналу. А уже по этим событиям 1-й канал управляет другим DMA-каналом который всё и делает. Но сейчас посмотрел на карту регистров DMA и понял что тут так не получится - в STM32 у DMA регистр управления идёт первым, до регистра кол-ва пересылок и регистров адресов. И адрес внутри DMA-пересылки можно только инкрементировать, а декрементировать - нельзя. Так что - не получится их одним пакетом запрограммировать... :((( Можно наверное изменить алгоритм: Один DMA канал сконфигурить на пересылку в циклическом режиме в регистр управления GPIO (управление GPIO). Синхронизировать его от таймера. Каждая пересылка его будет менять состояние CS на противоположное. А дальше - думать можно-ли на взаимных соединениях таймеров и DMA-каналов сделать автоматику. Вроде в STM32 таймеры могут посылать event-ы друг другу и разрешать работу друг друга. Возможности DMA в STM32 очень бедные - трудно что-то сложное с помощью него сделать :(( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 13 декабря, 2016 Опубликовано 13 декабря, 2016 · Жалоба Нет, не так. Я же вроде подробно разжевал в сообщении N8... Да подробно, но я так и не понял как вы хотели с каждым новым тактом записывать разные данных, без участия прерываний(процессора). Теперь понемногу доходит что имели ввиду, заложить все настройки в DMA1 и что бы каждом событии от таймера помощью авто инкремента, второй канал DMA программировался по разному. И адрес внутри DMA-пересылки можно только инкрементировать, а декрементировать - нельзя Это нужно было для того что бы выключить DMA канал перед записью размера транзакции ? записать и включить ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 183 13 декабря, 2016 Опубликовано 13 декабря, 2016 · Жалоба Теперь понемногу доходит что имели ввиду, заложить все настройки в DMA1 и что бы каждом событии от таймера помощью авто инкремента, второй канал DMA программировался по разному. Это нужно было для того что бы выключить DMA канал перед записью размера транзакции ? записать и включить ? Да, главная идея в том, чтобы всё делать при помощи DMA-каналов (stream-ов DMA в терминологии STM). Чтобы DMA-канал что-то сделал, его надо запрограммировать через его регистры конфигурации канала (через AHB-slave-интерфейс). Это может сделать любой AHB-bus-master: либо процессор либо другой DMA-канал либо ещё кто. Значит если без CPU, то будем использовать для такого программирования другой DMA-канал (1-й), ему тоже должен кто-то толкнуть когда это надо делать (например - таймер). Но толчок (event) от таймера один и значит запрограммировать надо одним пакетом (от одного события таймера). Поэтому - одна пакетная пересылка должна быть. На NXP-шных МК я такое делал - там регистры конфигурации канала идут одним блоком и регистр управления (в котором и стоит бит разрешения канал) среди них последний. На Tiva такое тоже теоретически возможно (хотя не пробовал), там тоже регистр управления последний в блоке. А вот на STM32 сделали неудобно - он первый. Да если бы хотя-бы был режим не автоинкремента, а автодекремента - но тоже нету :((( Вобщем - кругом одни вилы тут, обрезано всё донельзя в этом STM32... Можно конечно порыть в направлении - генерить два последовательных события от таймера двум разным DMA-каналам чтобы сначала записать регистры управления канала 2-у каналу DMA, а потом вторым событием - отдельно записать регистр DMA_SxCR с установленным битом разрешения работы. Но будет уже очень кучеряво ;) Хотя - дело Ваше ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pokk 0 14 декабря, 2016 Опубликовано 14 декабря, 2016 · Жалоба Благодарю за помощь, теперь буду иметь ввиду, не записывать DMA_SxCR другим DMA точно не буду, да и сейчас задача чуть по проще выдать 120(const) байт с помощью дма и через каждые 5ть байт переключать CS (сам сигнал cs подается на вход(ETR) тактирование таймера ). В идеале бы настроить DMA так что бы передача шла постоянно и без прерываний, сначала одни массив передали, потом другой и вернуться обратно на выдачу первого массива, вот с переключением обратно на первый массив есть вопросы можно ли сделать это аппаратно? Так как тут количество байт между переключением CS константа, то это все можно настроить заранее и тогда надо будет только DMA включить, что и можно сделать другим DMA. PS: интересно как поведет себя DMA если во время передачи менять регистр адресов, в даташите нечего не написано про то что DMA канал надо выключить при перезаписи адреса. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться