![]() |
Специальные цены | новые товары | ![]() |
![]() |
![]() |
Тема раздела Квадрокоптеры. Общие вопросы в категории Квадрокоптеры и мультироторы; Сообщение от Drinker Или если совсем времени не будет давай в комнате летану? Да, достаточно повисеть 15 сек, и график ...
Я поизучаю вопрос нащщет пидов. Конфиг рамы конечно спорный. Раздвинуты ноги гыгы.
Пиды возможно и трогать не придётся (если рама примерно 450-я и 10-е пропы), а вот сменить тип рамы на X надо будет (но это даже без перепрошивки) там скорей всего V тип стоит....
DMA в F4 - беда, и как-то надо её решать...
Проблема с 1-м Usart - вроде бы всё красиво, но зачем rx и tx вешать на один канал? хоть и потоки разные, канал один и тотже, (кстати для всей периферии такой маразм) а что происходит? а происходит следующее - потоки "деруться" за канал и побеждает естественно поток с младшим номером, в частности для Usart1 побеждает rx т.к. он либо stream2, либо stream5 тогда как tx stream7... Вопрос - как их разрулить? занизить приоритет одного из потоков - дык он потухнет
![]()
Последний раз редактировалось rual; 25.11.2013 в 09:36.
Вот я действительно не понял что за беда происходит, когда нужно временно отключить ПДП, а потом возобновить. Не могу нормально ПОВТОРНО инициализировать поток, хотя остановку ПДП делаю по руководству, дожидаюсь снятия бита DMA_SxCR_EN.
Может у вас с этим же проблема?DMA_Cmd (DMA2_Stream3, DISABLE);
while(DMA_GetCmdStatus(DMA2_Stream3) != DISABLE);
Показывай код.
Вот старая версия https://github.com/SergDoc/Nev_Multi...src/drv_uart.c
Вот новая https://github.com/SergDoc/Nev_Multi...src/drv_uart.c
а итог один - тормоза в цыклеа у Саши вообще не запустился....
или тут надо:
хоть ты плату снимай....Код:/* Î÷èùàåì áèò îáðàáîòêè ïðåðûâàíèÿ */ DMA_ClearITPendingBit(DMA2_Stream7,DMA_IT_TCIF7); DMA_Cmd(DMA2_Stream7, DISABLE); while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE) { };//добавить? if (txBufferHead != txBufferTail) uartTxDMA(); else txDMAEmpty = true; }
Не наверно пока новую не соберу снимать не буду, а потом уже на старой буду эксперименты экспериментировать
Логи можно и неразбирая скачать через терминал в планнене...
Последний раз редактировалось SergDoc; 25.11.2013 в 14:17.
Так как нелётная погода и настроение вообще аховое, незнал чем заняццо, ну ничего не получается сегодня, решил под бубунтой Mission Planner запустить:
И так что для этого надо?
установить mono runtime
как это сделать?Mono — это платформа для выполнения и разработки программ на основе стандартов ECMA/ISO. Mono — реализация стандарта с открытым исходным кодом от Novell. Mono предоставляет полную среду CLR (Common Language Runtime), включая компилятор и среду выполнения, с помощью которых можно создавать и исполнять байт-код CIL (Common Intermediate Language), а также библиотеку классов.
Этот пакет содержит виртуальную машину, JIT-компилятор и AOT-генератор кода «mono». «mono» выполняет приложения для CLI (Common Language Infrastructure). В настоящий момент Mono поддерживает только архитектуры X86, PowerPC, ARM, SPARC, S/390, AMD64 и IA64. Опционально этот пакет настраивает поддержку BINFMT.
в консоли набираем:
после установки лезем сюда и скачиваем сам планнер в архиве!!! не msi.Код:sudo apt-get install mono-runtime libmono-winforms2.0-cil libmono-corlib2.0-cil libmono-system-web4.0-cil libmono-system-management4.0-cil
распаковываем его куда-нибудь (папки без пробелов в названии и не кириллицей)
далее лезем в ту папку находим ArdupilotMegaPlanner10.exe правой клавишей ->свойства -> права ставим галочку - на разрешения запуска как приложение, открыть с помощью -> mono-runtime. Закрываем всё это дело и двойным кликом запускаем экзешник (тут есть нюанс - попросил обновится и перестал работать, так что я всё это убил и распаковал заново) и вуаля, под винду лазать больше не надо![]()
Странно... как работает новая версия я понять не могу, ибо не вижу инициализации потока ПДП
видимо умолчательные значения совпадают с нужными ))) хотя почему круговой режим изменен на нормальный? особо плохо что закоментина строка//DMA_InitStructure.DMA_Channel = DMA_Channel_4;
//DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)txBuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
//DMA_InitStructure.DMA_BufferSize = UART_BUFFER_SIZE;
//DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
//DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
//DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
//DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
//DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
//DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
//DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_1QuarterFull;
//DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
//DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;и вообще там есть режим ФИФО, его и надо пользовать.//DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
Если будет желание и возможность, завтра перепишу.
нее, библиотеки тут не при чем
Последний раз редактировалось rual; 25.11.2013 в 21:30.
я на дискавери-F4 пробовал + GY-86... т.е. мот какая специфика, типа на PA9,PA10 уже чего нить навешено... хотя простой примерчик (USART без DMA) из тырнета заработал... в одном из примеров видел версию 1.0.2, хотя на stm оф. сайте сходу ее не нашел...
upd: еще можно глянуть в старом порте вия на F4 https://code.google.com/p/uavp-mods/...8.zip&can=2&q=
MWArmF4\src\harness\harness.c
MWArmF4\src\harness\serial.c
там вполне структурировано и не коряво с виду написано...
Код:// Rewritten from AQ original Copyright © 2011 Bill Nesbitt
Там оно работает, я проверял, но вот вопрос с dma или без?
с dma, но нюансы я пока не понимаю
pins.c
serial.cКод:SerialPortDef SerialPorts[MAX_SERIAL_PORTS] = { // Tx, Rx { true, USART1, GPIO_AF_USART1, GPIOA, GPIO_Pin_9, GPIO_PinSource9, GPIO_Pin_10, GPIO_PinSource10, true, USART1_IRQn, false, DMA_Channel_4, DMA2_Stream7, DMA2_Stream7_IRQn, DMA2_Stream5, 115200 }, { false, USART2, GPIO_AF_USART2, GPIOA, GPIO_Pin_2, GPIO_PinSource2, GPIO_Pin_3, GPIO_PinSource3, false, USART2_IRQn, false, DMA_Channel_4, DMA1_Stream6, DMA1_Stream6_IRQn, DMA1_Stream5, 115200 // SBus 110000 } };
harness.cКод:#include "harness.h" // Rewritten from AQ original Copyright © 2011 Bill Nesbitt volatile uint8 TxQ[MAX_SERIAL_PORTS][SERIAL_BUFFER_SIZE] __attribute__((aligned(4))); volatile int16 TxQTail[MAX_SERIAL_PORTS]; volatile int16 TxQHead[MAX_SERIAL_PORTS]; volatile int16 TxQNewHead[MAX_SERIAL_PORTS]; volatile uint8 RxQ[MAX_SERIAL_PORTS][SERIAL_BUFFER_SIZE] __attribute__((aligned(4))); volatile int16 RxQTail[MAX_SERIAL_PORTS]; volatile int16 RxQHead[MAX_SERIAL_PORTS]; volatile int16 RxQNewHead[MAX_SERIAL_PORTS]; uint8_t TxCheckSum = 0; void serialTxDMA(uint8 s) { SerialPorts[s].TxDMAStream->M0AR = (uint32) &TxQ[s][TxQHead[s]]; if (TxQTail[s] > TxQHead[s]) { // Tail not wrapped around yet DMA_SetCurrDataCounter(SerialPorts[s].TxDMAStream, TxQTail[s] - TxQHead[s]); TxQNewHead[s] = TxQTail[s]; } else {// Tail has wrapped do balance from Head to end of Buffer DMA_SetCurrDataCounter(SerialPorts[s].TxDMAStream, SERIAL_BUFFER_SIZE - TxQHead[s]); TxQNewHead[s] = 0; } DMA_Cmd(SerialPorts[s].TxDMAStream, ENABLE); } // serialTxDMA boolean serialAvailable(uint8 s) { boolean r; if (SerialPorts[s].DMAUsed) { RxQTail[s] = SERIAL_BUFFER_SIZE - DMA_GetCurrDataCounter( SerialPorts[s].RxDMAStream); r = RxQHead[s] != RxQTail[s]; } else if (SerialPorts[s].InterruptsUsed) r = RxQTail[s] != RxQHead[s]; else { r = (USART_GetFlagStatus(SerialPorts[s].USART, USART_FLAG_RXNE) == SET); } return (r); } // serialAvailable uint8 RxChar(uint8 s) { uint8 ch; if (SerialPorts[s].DMAUsed || SerialPorts[s].InterruptsUsed) { ch = RxQ[s][RxQHead[s]]; RxQHead[s] = (RxQHead[s] + 1) & (SERIAL_BUFFER_SIZE - 1); } else ch = USART_ReceiveData(SerialPorts[s].USART); return (ch); } // RxChar uint8 PollRxChar(uint8 s) { uint8 ch; if (serialAvailable(s)) { ch = RxChar(s); return (ch); } else { return (0); } } // PollRxChar void TxChar(uint8 s, uint8 ch) { int16 NewTail; TxCheckSum ^= ch; if (SerialPorts[s].DMAUsed || SerialPorts[s].InterruptsUsed) { NewTail = (TxQTail[s] + 1) & (SERIAL_BUFFER_SIZE - 1); while (NewTail == TxQHead[s]) { }; TxQ[s][TxQTail[s]] = ch; // tail points to NEXT free slot TxQTail[s] = NewTail; if (SerialPorts[s].DMAUsed) { if (DMA_GetCmdStatus(SerialPorts[s].TxDMAStream) == DISABLE) serialTxDMA(s); } else { // if TXE then interrupt will be pending USART_ITConfig(SerialPorts[s].USART, USART_IT_TXE, ENABLE); } } else { while (USART_GetFlagStatus(SerialPorts[s].USART, USART_FLAG_TXE) == RESET) { }; USART_SendData(SerialPorts[s].USART, ch); } } // TxChar void serialISR(uint8 s) { uint8 ch; if (USART_GetITStatus(SerialPorts[s].USART, USART_IT_RXNE) == SET) { ch = USART_ReceiveData(SerialPorts[s].USART); RxQ[s][RxQTail[s]] = ch; RxQTail[s] = (RxQTail[s] + 1) & (SERIAL_BUFFER_SIZE - 1); if (RxQTail[s] == RxQHead[s]) { // full //USART_ITConfig(SerialPorts[s].USART, USART_IT_RXNE, DISABLE); } } if (USART_GetITStatus(SerialPorts[s].USART, USART_IT_TXE) == SET) { if (TxQTail[s] != TxQHead[s]) { ch = TxQ[s][TxQHead[s]]; USART_SendData(SerialPorts[s].USART, ch); TxQHead[s] = (TxQHead[s] + 1) & (SERIAL_BUFFER_SIZE - 1); } if (TxQHead[s] == TxQTail[s]) USART_ITConfig(SerialPorts[s].USART, USART_IT_TXE, DISABLE); } } // serialISR void InitSerial(void) { //TODO: serialPortInit(0, 115200); } // InitSerial
Код:void InitSerialPort(uint8 s) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; DMA_InitTypeDef DMA_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; SerialPortDef * u; u = &SerialPorts[s]; if (u->Used) { GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; #ifdef STM32F1 GPIO_InitStructure.GPIO_Pin = u->TxPin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(u->Port, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = u->RxPin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(u->Port, &GPIO_InitStructure); #else GPIO_StructInit(&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = u->TxPin | u->RxPin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(u->Port, &GPIO_InitStructure); GPIO_PinAFConfig(u->Port, u->TxPinSource, u->USART_AF); GPIO_PinAFConfig(u->Port, u->RxPinSource, u->USART_AF); #endif USART_StructInit(&USART_InitStructure); //USART_InitStruct->USART_Parity = USART_Parity_No; USART_InitStructure.USART_BaudRate = u->Baud; USART_Init(u->USART, &USART_InitStructure); NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; TxQTail[s] = TxQHead[s] = TxQNewHead[s] = 0; if (u->DMAUsed) { // Common DMA_StructInit(&DMA_InitStructure); DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; DMA_InitStructure.DMA_Priority = DMA_Priority_Medium; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32) &u->USART->DR; DMA_InitStructure.DMA_BufferSize = SERIAL_BUFFER_SIZE; // Receive DMA DMA_DeInit(u->RxDMAStream); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32) &u->USART->DR; DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; #ifdef STM32F1 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32) RxQ[s]; #else while (DMA_GetCmdStatus(u->RxDMAStream) != DISABLE) { }; DMA_InitStructure.DMA_Channel = u->DMAChannel; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32) RxQ[s]; #endif DMA_Init(u->RxDMAStream, &DMA_InitStructure); DMA_Cmd(u->RxDMAStream, ENABLE); USART_DMACmd(u->USART, USART_DMAReq_Rx, ENABLE); RxQTail[s] = RxQHead[s] = SERIAL_BUFFER_SIZE - DMA_GetCurrDataCounter(u->RxDMAStream); // Transmit DMA NVIC_InitStructure.NVIC_IRQChannel = u->TxDMAISR; NVIC_Init(&NVIC_InitStructure); DMA_DeInit(u->TxDMAStream); #ifdef STM32F1 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; #else while (DMA_GetCmdStatus(u->TxDMAStream) != DISABLE) { }; DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; // DMA_InitStructure.DMA_Memory0BaseAddr = (uint32) TxQ[s]; #endif DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; DMA_Init(u->TxDMAStream, &DMA_InitStructure); DMA_SetCurrDataCounter(u->TxDMAStream, 0); DMA_ITConfig(u->TxDMAStream, DMA_IT_TC, ENABLE); USART_DMACmd(u->USART, USART_DMAReq_Tx, ENABLE); } else if (u->InterruptsUsed) { RxQTail[s] = RxQHead[s] = 0; NVIC_InitStructure.NVIC_IRQChannel = u->ISR; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(u->USART, USART_IT_RXNE, ENABLE); } USART_Cmd(u->USART, ENABLE); } } // InitSerialPort
Видишь кругом задержки:
while (DMA_GetCmdStatus(u->TxDMAStream) != DISABLE) {
};
также я в старом драйвере делал....
мне тут подумалось, там же вий 2.1 протокол, может уже чё поменяли? или 2.2 ? блин уже почти год кодятнику - как время летит...
Найдите 10 отличий как говорится : https://code.google.com/p/aq32plus/s...rv_telemetry.c
прикол что у товарищей то работает, и у меня работало![]()
Последний раз редактировалось SergDoc; 25.11.2013 в 23:08.
как там говорят: "дьявол в деталях"... а может именно с дискавери платой какая особенность... хз...
кстати попробуй проект открыть мой (точнее твой, но адаптированный под мпу6050), может там в настройках самого проекта что нить не то... собери мне хекс-у и почтой кинь... проверю...
Часиков в 12 ночи по нашему...
а оказалось дабомба в дискавери-Ф4 на PA9 висит
че блин сразу не залез в схему, раз догадки были... кондер блин на 4.7мкф на лапе сидит...
http://www.micromouseonline.com/2013...#axzz2liCmKZvc
https://my.st.com/public/STe2ecommun...rrentviews=399
перевесил USART1 на PB6, PB7 и все пошло, но пока мучился уже успел портануть USART+DMA из MWArmF4
терь покрасивше чуток... конфиг такой вышел
Код:SerialPortDef SerialPorts[MAX_SERIAL_PORTS] = { // Tx, Rx { true, USART1, GPIO_AF_USART1, GPIOB, GPIO_Pin_6, GPIO_PinSource6, // PB6 GPIO_Pin_7, GPIO_PinSource7, // PB7 true, USART1_IRQn, false, DMA_Channel_4, DMA2_Stream7, DMA2_Stream7_IRQn, DMA2_Stream5, 115200 }, ... };
а цыфирку то 115200 зачем там переменная speed есть через cli можно любую скорость ставить...
для baseflight это критично, для прошивки через терминал загоняется R - ппроц спускается до лодыря, а лодырь у тебя на других лапах усарт ищет
на новой плате он тамно по другим причинам...
А нафига они там кондёр то повесили? я на старой плате закоротил, теперь если шиться через usart1 припрёт (лодырь залить с полным стиранием) только шнурок от usb отцепить дабы питание на pa9 не шло - и прекрасно работает.... гы у тебя похоже не получалось через usart1 лодырь залить по той же причине- я считаю косяк проца в этом (неудобство для пользователя) не ну конечно есть DFU через USB - но чёт я так и не понял как через него всю флеш стереть
Там же по моему даже питание на плату с того USB не идёт? (discovery)
вот и вывод - хочешь USB, либо делай лодырь, либо вешай 1.5К на VBUS - D+ и используй программно свободную лапу...
Последний раз редактировалось SergDoc; 26.11.2013 в 13:41.
Дык, usb та там ОТГ, нужно ж в некоторых демках от него внешнее устройства питается.
да нее, не косяк, тут либо-либо. если есть USB то нах усарт? Если нет USB? тогда пожалуста usart.
То что всё стереть нельзя, дык это в демо софте. Если сильно надо протокол открытый.
А кстати, зачем надо? У нас с тобой проблема прошивки не в этом была.
Сергей, из чего такой вывод? При формировании ДФУ из нормального HEX это нафиг не надо.
Лодырь для Ф4 нужен только для одного, чтоб шится шифрованной прошивкой, это всё... Других применений собственного лодыря придумать не могу.
Через демку не сотрёшь - а это однозначный косяк при перезаписи!!! т.е. как выход надо делать свою софтину DFU, или каждому в довесок к плате St-Link собирать? ну или как вариант покупать discovery ибо отдельно программатор как-то не по вкусной цене. Выход для простого пользователя - лодырь (ну тот-же арду - залился планера и привет - новая прошивка) да была бы USB демка такая-же как uploader по Usart да цены б ей небыло и вопросов бы не возникало USB или Usart. Ну вот зачем простому пользователю лишние телодвижения, в той же baseflightGUI всё встроено загоняет проц в режим лодыря и запускает прошивальшик без дёрганий втыкания BOOT0...
Кстати надо поработать над техникойПри формировании ДФУ из нормального HEX это нафиг не надо.по идее можно заставить компилятор сразу создавать DFU займусь новым лодырем (ну под новую плату) поэкспериментирую...
А вот я пробовал залить арду (vrbrain) а потом обратно baseflight - и усё не стартует....
Последний раз редактировалось SergDoc; 26.11.2013 в 15:56.
DFUse ? она не даёт стирать флеш....
попробую...