Перейти к содержанию
    

AndruLud

Участник
  • Постов

    26
  • Зарегистрирован

  • Посещение

Весь контент AndruLud


  1. Все выглядит достаточно логично, однако представляется маловероятным, что передача память-память запускается только вручную. Да и проведенные сегодня эксперименты показали, что память-память и память-переферия запускаются от таймера и работают совершенно идентично. Никаких манипуляций с DMACSoftBReq/DMACSoftSReq не проводил, менял TransferType. Если сконфигурировать переферия-память, не работает выдача в FIFO UART, в GPIO выдает нормально. На днях реализую предложенный Вами алгоритм, идея которого весьма хороша, благодарю.
  2. Согласен с Вами, что запросы DMA и пересылки - разные вещи, но их несвязанность на логическом уровне для меня не очевидна. Смущает следующая фраза из мануала (с.605), описывающая назначение бита, определяющего вроде как переферийный источник запроса: "Source peripheral. This value selects the DMA source request peripheral. This field is ignored if the source of the transfer is from memory...." Если бы не последнее предложение, то все прозрачно. Почему, согласно последнему предложению, контроллеру DMA становится все равно, откуда приходит запрос, если передача по DMA будет вестись из памяти?
  3. Я так понял, что "переферия"для DMA - это все, что может гененрировать запросы, остальное - "память", поправьте, если не так. Таким образом, когда я выставляю GPIO пакетом DMA - значит, пишу в память, когда отправляю данные в UART - пишу в переферию. Когда правлю управляющие регистры таймера - в память.
  4. Спасибо за ответ! У меня таймер генерит запрос к дма, который вываливает данные из RAM в UART FIFO, из FIFO они уже передаются UARTом своим чередом. Описанную Вами идею я в свое время пробовал реализовать в несколько упрощенном варианте (событие MR0 запускает пакет дма, переписывающий в GPIO единицу 100 раз (процесс занимает ~1мкс) далее запускается пакет, преписывающий данные в UART; по событию MR1 (конец пакета) запускается другой dma, сбрасывающий GPIO ), но не удачно. Либо молчит UART, либо не выставляется GPIO. Склонен полагать, проблема в том, что в LLI нельзя видоизменить конфигурационный регистр (DMAnConfig), в котором задается направление передачи. А мне надо сначала выдавать "память-память", потом "память-переферия".
  5. Может, у кого есть идеи как сгенерировать сигнал на ноге , устанавливающийся в 1 за 1мкс до начала передачи по UART и в 0 при ее окончании? Длина пакета, скорость передачи известны, передача инициируется таймером, генерирующим dma-запрос. Прерывания и дополнительные таймеры не хотелось бы использовать, UART интерфейс rs-485 не поддерживает.
  6. Привет всем! Ситуация следующая: 2 канала DMA lpc1768 сконфигурированы для предачи данных "память-память" и "память-перефирия" соответственно. Запрос на передачу генерит один и тот же таймер. Какой из каналов DMA начнет передачу первым? В мануале описана лишь ситуация, когда по одному каналу передача уже идет, а запрос поступает к другому каналу. Там же есть рекомендации использовать для передачи "память-память" каналы с более низким приоритетом, иначе другие каналы не запустятся. С уважением.
  7. тормозит DMA

    Не-а. Здесь все параллельно и перпендикулярно, без подтанцовок с бубном.
  8. источники NVIC

    Всем доброго здоровья! Есть контроллер LPC1768, использую его модуль PWM. Проблема в том, что PWM может быть источником нескольких прерываний одновременно, причем какой именно источник сгенерировал прерывание можно узнать только войдя в некоторый абстрактный "обработчик прерываний от PWM" и проанализировав соответствующий бит в нем. Если два источника в PWM сгенерировали прерывания одновременно, появляются непредсказуемые задержки в их обработке. Хотелось бы узнавать о наличии одного из прерываний по опросу, но не получается: запретишь соответствующий источник - флаг не выставляется, запретишь прерывание от PWM - естественно, умирают оба прерывания. МОжет, кто знает обходной маневр?
  9. тормозит DMA

    Проблема решена. Надо по таймеру после отключения мастера перейти в режим мастера и выпихнуть байт, застрявший в передающем регистре.
  10. тормозит DMA

    Я бы даже сказал, что сброс DMA после передачи каждого пакета вредит. Если убрать сброс, то при первом включении посылки идут нормально. Потом, если мастер отрубается, все включается вновь, но криво. Чтобы побороться с кривизной поставил сторожевой таймер, с частотой чуть меньшей, чем частота посылок. В прерывании по приему посылки от DMA таймер сбрасывается, если приема нет, срабатывает прерывание от таймра, в котором сбрасывается DMA. Результат достаточно скромный в 7 из 10 случаев отрубания мастера и срабатывания таймера имеется сдвиг на байт.
  11. тормозит DMA

    Теперь возникла задача передавать данные по SPI из s3c2440 в lpc1768 , причем последний по-прежнему работает мастером. Проблема опять та же: ведомый s3c2440 посредством DMA передает сначала конец предыдущей посылки, потом все остальное, кроме конца, т.е имеем сдвиг данных. Лекарство, использованное ранее для приема ведомым, - включать/выключать DMA после получения каждого пакета - не работает. Может, кто сталкивался?
  12. тормозит DMA

    Спасибо за совет, буду продолжать копать в предложенном направлении, хотя у меня уже первый пакет приходит вывернутый, когда DMA было только что инициализировано и по SPI еще ничего не передавалось.
  13. тормозит DMA

    Проблема по всей видимости аппаратная. Переключил все действо на другой SPI порт, задержка исчезла. Однако, осталась другая: последний байт, принятый по SPI через DMA оказывается первым байтом следующей посылки. Т.е послал 80 01 C0 03 E0 07 F0 0F, а принял 0F 80 01 C0 03 E0 07 F0. Может, кто-нибудь сталкивался?
  14. тормозит DMA

    Приветствую участников форума! У меня 2 контроллера (LPC1768 и s3c2440) соединены по протоколу SPI. При этом LPC1768 в роли ведущего выдает через свой SSP контроллер, сконфигурированный как SPI, посылку в 8 байт с частотой 10 кГц. Прием посылки в s3c2440 организован через DMA, сконфигурированный для чтения 8 байт, после этого должно возникать прерывание. Проблема в том, что прерывания начинают появляться ~через 15 сек после включения обмена, далее все вовремя, но байты оказываются сдвинутыми на 1. Данные из ведущего появляются вовремя (смотрел по осциллографу).
  15. mmu&stack

    Возьму на заметку,спасибо, но я с таймером разобрался. Сейчас в прерываниях UARTa ковыряюсь.
  16. mmu&stack

    Да я нормально отреагировал) Спасибо за ссылку, познавательно. Читал рекомендации, что оптимизировать надо там, где не пролезает по каким-то критериям. Вот тут и не пролезало: это ж надо в 2 раза меняется частота моргания, начал смотреть в дизассемблер.
  17. mmu&stack

    Спасибо, постараюсь руководствоваться Вашей рекомендацией. Компилятор в Keil 4. Но дело, по-видимому, в отсутствии оптимизации. Включил оптимизацию 3-го уровня и жизнь наладилась) Это да, я в тестовом примере не озаботился оптимальностью.
  18. mmu&stack

    Глобальная, но без volatile, т.е просто int a А что мешает считать ее в регистр из памяти один раз, обработать и записать обратно? Отсутствие оптимизации? Заняты все регистры? С volatile было бы понятно: "мол, не ты один имеешь доступ к переменной, так что изменяй ее там, где она есть"
  19. mmu&stack

    Реализовал предложенное, выяснилось что указатель стека имеет вполне вразумительное значение при наличии и в отсутствие MMU. Получается, что при отладке нельзя сильно верить H-JTAGу, если MMU включен. Спасибо, aaarrr! Осталась, правда непонятка: светодиоды моргают раза в 2 быстрее, если задержка реализована в виде функции void delay(int a) { for(;a!=0;a--) { } } ...... main { rGPBDAT = 0x01C0; delay(data); } по сравнению с ...... main { rGPBDAT = 0x01C0; a=data; for(;a!=0;a--) { } } Смотрел аасемблерный код без оптимизации, в первом случае цикл реализован 4-я инструкциями, во втором - 10-ю: 0x300003A4 EA000000 B 0x300003AC 0x300003A8 E2400001 SUB R0,R0,#0x00000001 0x300003AC E3500000 CMP R0,#0x00000000 0x300003B0 1AFFFFFC BNE 0x300003A8 и 0x3000051C EA000004 B 0x30000534 0x30000520 E59F0110 LDR R0,[PC,#0x0110] 0x30000524 E5900000 LDR R0,[R0] 0x30000528 E2400001 SUB R0,R0,#0x00000001 0x3000052C E59F1104 LDR R1,[PC,#0x0104] 0x30000530 E5810000 STR R0,[R1] 0x30000534 E59F00FC LDR R0,[PC,#0x00FC] 0x30000538 E5900000 LDR R0,[R0] 0x3000053C E3500000 CMP R0,#0x00000000 0x30000540 1AFFFFF6 BNE 0x30000520 Может, кто посветит?
  20. mmu&stack

    Что-то явно не чисто с адресацией: UART инициализируется вроде нормально (что-то выдает в нужное время), но выдает не то, что прошу (в "свободном полете" вместо тестовой константы 0х2710 в консоль приходит 0х38FC). Однако, когда смотрю в отладчике, массив для UARTa формируется правильно. Реализовал задержку моргания диодом в "свободном полете" без участия стека, визуально частота сильно изменилась по сравнению с использованием стека, видимо раньше она считывалась не оттуда, откуда надо.
  21. mmu&stack

    Я тоже чую, что чушь какая-то... Через H-JTAG смотрю.
  22. mmu&stack

    Запрещал, безуспешно.
  23. mmu&stack

    И там и там. Причем самое противное то, что, если поставить BreakPoint около MSR CPSR_c, #Mode_USR и по шагам дойти до LDR R0, =__main то стек в норме, если сразу остановить прогу в LDR R0, =__main то можно увидеть злополучное значение 0x20000000. Косяк с я нашел уже сегодня утром, не помогло...
  24. mmu&stack

    Спасибо, Ваше последнее замечание правомерно, мне напрасно казалось, что Stack_Mem указывает на конец области, а не на ее начало. Однако даже с учетом этой поправки ситуация мало изменилась: попрежнему выхожу в main с диким адресом 0х20000000. По правде говоря, ко входу в main я еще не успеваю напихать в стек что-либо, что могло привести к его переполнению, более того прога отлично работает с найденной Вами ошибкой, но без MMU. Ну а феерический глюкодром обеспечен в любом случае при переполнении стека, куда бы последний не наполз. Кстати, в моем случае он наползет на переменные, размещенные библиотекой libspace.o. Вектора я не стал копировать из кода в RAM, ремапнул посредством MMU всю область кода в 0х0000, а ОЗУ осталось на своем 0х31000000 месте.
  25. mmu&stack

    А в чем проблема? Я так понимаю, что стек расположен на расстоянии ISR_Stack_Size+USR_Stack_Size от начала памяти и в процессе записи в него командами с декрементом (типа STMFD) растет к 0х000-адресам.
×
×
  • Создать...