esaulenka 7 13 ноября, 2015 Опубликовано 13 ноября, 2015 · Жалоба Я после настроек USART делаю NVIC_ClearPendingIRQ(USART3_IRQn); потом NVIC_EnableIRQ(USART3_IRQn); Не знаю, надо ли. Может, прерывание возникает при освобождении буфера, а не когда он пустой. Да, когда нужно послать массив, посылаю байт, разрешаю прерывание TXE. Остальные байты посылаются по прерыванию. При передаче последнего байта запрещаю прерывание TXE. Ну так дело именно в запрещении/разрешении TXE, а не магических пассах с ClearPending. И прерывание возникает при пустом буфере, и сбрасывается только его заполнением. Это в документации написано, можно ничего самостоятельно не изобретать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 13 ноября, 2015 Опубликовано 13 ноября, 2015 · Жалоба Странно, если в обработчике прерываний вставляю условие (USART_GetITStatus(UART5, USART_IT_TXE) != RESET) то все работает а если делаю так ((UART5->SR & USART_SR_TXE) != 0) то не работает что-то не так разве? раньше у меня было ((UART5->SR & USART_SR_TC) != 0) и работало... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 ноября, 2015 Опубликовано 13 ноября, 2015 · Жалоба Ну так дело именно в запрещении/разрешении TXE, а не магических пассах с ClearPending. И прерывание возникает при пустом буфере, и сбрасывается только его заполнением. Это в документации написано, можно ничего самостоятельно не изобретать. Да. Значит, очищать отложенный запрос не нужно. Прерывание возникает не при пустом буфере. Вот что написано в документации на STM32F2xx. This bit is set by hardware when the content of the TDR register has been transferred into the shift register. An interrupt is generated if the TXEIE bit =1 in the USART_CR1 register. It is cleared by a write to the USART_DR register. 0: Data is not transferred to the shift register 1: Data is transferred to the shift register) Поэтому в начале, когда буфер пустой, прерывание не возникает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AHTOXA 18 13 ноября, 2015 Опубликовано 13 ноября, 2015 · Жалоба а если делаю так ((UART5->SR & USART_SR_TXE) != 0) то не работает Потому что надо делать вот так: if ((UART5->SR & USART_SR_TXE) && (UART5->CR1 & USART_CR1_TXEIE)) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 13 ноября, 2015 Опубликовано 13 ноября, 2015 · Жалоба Потому что надо делать вот так: if ((UART5->SR & USART_SR_TXE) && (UART5->CR1 & USART_CR1_TXEIE)) спасибо, заработало) USB у меня заместился UART-ом, поэтому есть желание перейти на чистый CMSIS, тем более в прерываниях почти нигде не использую SPL функции Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 13 ноября, 2015 Опубликовано 13 ноября, 2015 · Жалоба После перехода на прерывание TXE стало нормально работать на скорости 2 Мбит/с. Но вылез новый глюк - стали где то теряться данные. Посмотрел осциллографом работу прерываний DMA - вроде все четко работает, пропусков нет. То есть запись в буфер идет нормально. Как теперь этот глюк выловить, непонятно... Обнаружил пропуски отправок данных. То есть приходит запрос "Передать данные", а их вдруг почему то нет (вычисляю наличие данных по неравенству указателей записи и чтения из буфера) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 5 13 ноября, 2015 Опубликовано 13 ноября, 2015 · Жалоба По поводу прерываний. Вы говорили что у вас есть прерывания с меньшим приоритетом. По умолчанию вложенные прерывания запрещены. Поэтому если вы висите в каком то прерывании с низким приоритетом, то никакие другие прерывания (даже с большим приоритетом) в этом время не будут обслужены. Если при нахождении в низкоприоритетном прерывании контроллер получил еще несколько других прерываний, то они будут обслужены только после выхода из прерывания. Именно здесь приоритеты начинают работать. Обслужены они будут в порядке приоритетов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 13 ноября, 2015 Опубликовано 13 ноября, 2015 · Жалоба По умолчанию вложенные прерывания запрещены. Поэтому если вы висите в каком то прерывании с низким приоритетом, то никакие другие прерывания (даже с большим приоритетом) в этом время не будут обслужены. Разве? По-моему, вы ошибаетесь. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
uriy 5 13 ноября, 2015 Опубликовано 13 ноября, 2015 · Жалоба Хотел найти подтверждение того что вложенные прерывания запрещены по-умолчанию. Не могу найти. Неужели и правда неправильно отложилось в голове. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба Потеря данных оказалась в другом контроллере. Теперь иногда вылазит такой баг - конец одного пакета как бы затирает начало первого. Еще раз обрисую ситуацию. Есть кольцевой буфер, на 512 байт. В него раз в 1,125 мс пишут 4 DMA. Размер одной посылки по DMA - 19 байт. Обработка прерывания одного DMA занимает примерно 22 мкс. Раз в 1 мс приходит запрос данных и если есть данные - они передаются по UART. Прерывания DMA и UART имеют одинаковый приоритет, поэтому вычисление количества данных и манипуляции с указателями выполняются вроде как атомарно. Смотрел осциллографом - скорость передачи такова, что частота опроса в 1 мс нормальна. Данные передаются самое большее где то за 0,5 - 0,6 мс. Тем не менее, по истечению какого то времени (минут 15-20) возникает непонятный баг - конец одного пакета затирает начало другого. И еще более странно, затирает не предыдущий пакет! Я добавил в начало и конец каждого пакета байтовый счетчик. Прикладываю скрин с этим багом, разложил все по пакетам. 7 пакетов, начало первого пакета затер конец 7-го пакета. Может быть у кого то есть идеи из-за чего такое может быть? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rudy_b 1 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба ... Есть кольцевой буфер, на 512 байт. В него раз в 1,125 мс пишут 4 DMA. ... Нельзя тупо писать в кольцевой буфер через DMA. Если в буфер пишут (и, соответственно, читают) несколько источников, а уж, тем более, разные канала DMA, необходима блокировка операций чтения/записи от наложений, а само DMA этого сделать не может. Т.е., перед началом операции чтения/записи (неважно, по DMA или нет) необходимо заблокировать другим доступ к буферу (кто первый встал - того и тапки, пусть другие ждут освобождения пока я не закончил), а по завершении операции - разблокировать. Т.е. сделать стандартный Lock|Unlock, причем аккуратно - с запретом прерываний на время чтения и изменения Lock|Unlock. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба Нельзя тупо писать в кольцевой буфер через DMA. Если в буфер пишут (и, соответственно, читают) несколько источников, а уж, тем более, разные канала DMA, необходима блокировка операций чтения/записи от наложений, а само DMA этого сделать не может. Т.е., перед началом операции чтения/записи (неважно, по DMA или нет) необходимо заблокировать другим доступ к буферу (кто первый встал - того и тапки, пусть другие ждут освобождения пока я не закончил), а по завершении операции - разблокировать. Т.е. сделать стандартный Lock|Unlock. Если я правильно понял, то у меня все правильно. DMA пишут в свои, отдельные, массивы. А в процедуре обработки прерывания от DMA я копирую из этих массивов в кольцевой буфер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
HardEgor 80 2 декабря, 2015 Опубликовано 2 декабря, 2015 · Жалоба DMA пишут в свои, отдельные, массивы. А в процедуре обработки прерывания от DMA я копирую из этих массивов в кольцевой буфер. У DMA есть хорошее прерывание на половину буфера. Т.е. настраиваешь DMA на запись всего буфера, пока DMA пишет в первую половину, разрешаешь чтение из второй половины. Когда приходит прерывание от DMA о заполненности половины буфера, разрешаешь чтение первой половины буфера, DMA в это время начинает писать во вторую половину. Главное чтобы чтение было быстрее записи :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 234 3 декабря, 2015 Опубликовано 3 декабря, 2015 · Жалоба DMA пишут в свои, отдельные, массивы. А в процедуре обработки прерывания от DMA я копирую из этих массивов в кольцевой буфер. Если просто копируете, без какой-либо обработки/переупаковки, то это дерьмовая реализация. Зачем эти копирования туда-сюда, если DMA уже предназначен для перемещения память<->периферия? Никто не мешает писать DMA прямо в кольцевой буфер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dima1060 0 3 декабря, 2015 Опубликовано 3 декабря, 2015 · Жалоба Если просто копируете, без какой-либо обработки/переупаковки, то это дерьмовая реализация. Зачем эти копирования туда-сюда, если DMA уже предназначен для перемещения память<->периферия? Никто не мешает писать DMA прямо в кольцевой буфер. С трудом это представляю. При настройке DMA надо указать адреса в кольцевом буфере. Для 4-х DMA то есть будет 4 адреса со смещением на длину пакета. А если вдруг не придут данные от одной из DMA? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться