Haamu 0 20 декабря, 2013 Опубликовано 20 декабря, 2013 · Жалоба Ситуация такая... Оцифровываю несколько датчиков и через DMA сохраняю их показания в памяти. После записи энного количества показаний хочу передать их опять же через DMA по USART на компьютер, для дальнейшей обработки. Первую половину цепочки настроил, данный записываются в память. А вот передать их не получается. Подозреваю, что проблема где-то в настройках DMA. Вот так я настраиваю DMA на передачу данных: DMA_InitTypeDef DMA_InitStruct; DMA_InitStruct.DMA_Channel = DMA_Channel_4; DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&(USART1->DR); DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&sensors_data; DMA_InitStruct.DMA_DIR = DMA_DIR_MemoryToPeripheral; DMA_InitStruct.DMA_BufferSize = 30000; //Size of data in uint32_t sencors_data[] DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; DMA_InitStruct.DMA_Priority = DMA_Priority_High; DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream7, &DMA_InitStruct); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); USART_Cmd(USART1, ENABLE); Сомневаюсь в парвильности этих параметров: DMA_InitStruct.DMA_BufferSize = 30000; DMA_InitStruct.DMA_Mode = DMA_Mode_Normal; DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; Если у меня передаваемый массив состоит из 30000 16-битных значений, а передаю я его по одному байту, правильно ли я указал размер буфера? Я так понимаю, что при передаче HalfWord -> Byte без FIFO не обойтись. На что влияет его размер (FIFOThreshold)? Как правильно выбрать DMA_Mode? Что значат режим Circular и режим Normal? И что такое MemoryBurst и PeripheralBurst? И еще один момент. Как я понимаю, после команды DMA_Cmd(DMA2_Stream7, ENABLE); DMA сразу начинает передачу. Это так? В дебагере заметил, что при запуске этой команды в регистре DMA_S7CR устанавливается бит EN, но на следуещем же такте он сбрасывается. Почему? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Falkon_99 0 20 декабря, 2013 Опубликовано 20 декабря, 2013 (изменено) · Жалоба прочитайте тут, большинство вопросов отсеится Изменено 20 декабря, 2013 пользователем Falkon_99 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Haamu 0 20 декабря, 2013 Опубликовано 20 декабря, 2013 (изменено) · Жалоба прочитайте тут, большинство вопросов отсеится В том то и дело, что уже читал, но осталось непонимание. Хороший сайт, спасибо автору. Но в этой статье, как и в большинстве других есть указания, что и как настраивается, но не объясняется почему именно так. Кстати, по поводу моего кода. Когда проверил работу уже на железе, а не в дебагере, оказалось что всё работает. Видимо как-то не туда смотрел в дебагере. Единственный момент, который следует исправить - это размер буфера. Так как я отправляю 30000 HalfWord'ов по одному байту, то таких байт, а соответсвенно и запросов к DMA должно быть в два раза больше. Изменено 20 декабря, 2013 пользователем Haamu Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Haamu 0 21 декабря, 2013 Опубликовано 21 декабря, 2013 · Жалоба И все-же... DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte; DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Enable; DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_Full; DMA_InitStruct.DMA_MemoryBurst = ??????? DMA_InitStruct.DMA_PeripheralBurst = ??????? Какими доолжны быть последние два параметра при таких вот настройках DMA? Есть кто-нибудь, кто разобрался в параметрах Burst? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 83 21 декабря, 2013 Опубликовано 21 декабря, 2013 · Жалоба DMA_InitStruct.DMA_MemoryBurst = ??????? DMA_InitStruct.DMA_PeripheralBurst = ???????[/code] Какими доолжны быть последние два параметра при таких вот настройках DMA? Есть кто-нибудь, кто разобрался в параметрах Burst? Эхх... кто-бы знал, у меня для STM32F105 в настройках таких параметрок к сожалению нет. Вы бы уж написали какой конкретно процессор используете. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
esaulenka 7 21 декабря, 2013 Опубликовано 21 декабря, 2013 · Жалоба Burst mode - режим, когда за раз передаётся сразу несколько байт (или не байт, смотря на какую "ширину" настроено DMA). В данном случае он не нужен. А контроллер указан в заголовке темы (не полностью, но для понимания вопроса достаточно ;-) ) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Haamu 0 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба У меня STM32F407VG. На сколько я понял в STM32F10x в контроллере DMA вообще FIFO буфера нет, поэтому и Burst режима тоже нет. Хотя, как же тогда передаются данные разного размера (в памяте и в периферии)?.. Burst mode - режим, когда за раз передаётся сразу несколько байт (или не байт, смотря на какую "ширину" настроено DMA). В данном случае он не нужен. Вас не затруднит пояснить, в каких случаях он нужен и как им пользоваться? Правильно я понял, что для разных размеров данных в памяти и периферии без FIFO не обойтись? Я решил проблемму в лоб, без использования FIFO. Просто указал, что в памяти массив состоит из байтов и отключил FIFO. Передаю по одному байту, а наверху уже собираю в полуслова. Но ведь так поидее не правильно... Еще сбивает с толку, что при отладке в CoIDE сразу посли запуска DMA появляется флаг FIFO error. При том, если не ошибаюсь, и при отключенном FIFO он выскакивает. Не пойму, это глюк в настройках DMA или в CoIDE... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба На сколько я сейчас бегло глянул fifo используется если оба устройства находятся на одной шине AHB. То есть скорее всего для быстрых устройств, чтобы разгрузить шину и не затормаживать процессор. Использовать может та периферия, которая поддерживает такой обмен данными. DMA - это не совсем процессор, поэтому вы вряд ли корректно увидите отладчиком что-то. Да и зачем? Какая-то тенденция нехорошая, чуть ли не по шагам рассмотреть деятельность процессора. Одно время ряд спецов говорило, что вообще надо отказаться от отладчика. Я тогда не понимал зачем. Теперь вижу. Смотрите отладчиком только ключевые моменты. Правильность передачи буфера, к примеру. Например остановится по прерыванию, завершения передачи DMA и проверить правильность выполнения. Иначе зароетесь, и толком ничего не увидите, а будет только сумбур в голове, ИМХО. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Haamu 0 23 декабря, 2013 Опубликовано 23 декабря, 2013 · Жалоба Какая-то тенденция нехорошая, чуть ли не по шагам рассмотреть деятельность процессора. Одно время ряд спецов говорило, что вообще надо отказаться от отладчика. Я тогда не понимал зачем. Теперь вижу. Смотрите отладчиком только ключевые моменты. Правильность передачи буфера, к примеру. Например остановится по прерыванию, завершения передачи DMA и проверить правильность выполнения. Иначе зароетесь, и толком ничего не увидите, а будет только сумбур в голове, ИМХО. Может Вы и правы на счет того, что не стоит каждый шаг отслеживать. Я так пол дня убил на эксперименты с настройками ДМА и отслеживанием его работы в отладчике, пока на проверел на железе, оказалось все работает прекрасно. Так же было, когда с USART разбирался. Всё не мог понять, почему у меня регистр данных пустой, пока не увидел, что на самом деле всё работает. Я до STM32 c отладчиками не работал. AVRки в симуляторе гонял. Видимо в том и отличие отладчика от симулятора в том, что в симуляторе всё пошагово выполняется, а в отладчике только программа останавливается, а периферия, которая на автомате работает, продолжает выполнять свои действия. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 83 27 декабря, 2013 Опубликовано 27 декабря, 2013 · Жалоба Да, читайте Reference Manual - в DMA burst нужен для того, кто имеет у буфера FIFO: "Supports incremental burst transfers of 4, 8 or 16 beats. The size of the burst is software-configurable, usually equal to half the FIFO size of the peripheral" Т.е. например USART передает информацию побайтово, если нет FIFO, то DMA кладёт в буфер USART за каждую операцию только 1 байт, потом ждет окончания его передачи, кладёт следующий байт и т.д. Когда у буфера USART есть FIFO - тогда, DMA за одну операцию может сложить туда сразу несколько байт(в половину буфера), что разгружает шину. FIFO error - это или неправильная настройка DMA или ошибки в работе DMA, почитай Reference Manual там описано когда она возникает. Правильно я понял, что для разных размеров данных в памяти и периферии без FIFO не обойтись? Нет, DMA без разницы какой размер данных лежит в памяти, он просто читает указанное количество байт(DMA_InitStruct.DMA_Memory0BaseAddr) начиная с указанного адреса(DMA_InitStruct.DMA_Memory0BaseAddr) из памяти и передает их в буфер приемника, или наоборот. Количество передаваемых байт в каждом чтении должны совпадать с размером буфера приемника! Но если буфер приемника имеет FIFO, тогда они могут не совпадать: "Independent source and destination transfer width (byte, half-word, word): when the data widths of the source and destination are not equal, the DMA automatically packs/unpacks the necessary transfers to optimize the bandwidth. This feature is only available in FIFO mode" Я решил проблемму в лоб, без использования FIFO. Просто указал, что в памяти массив состоит из байтов и отключил FIFO. Передаю по одному байту, а наверху уже собираю в полуслова. Но ведь так поидее не правильно... А так все и делают, ведь USART передает данные побайтово. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться