Создание собственной системы стабилизации
Не вижу проблемы
Тогда я вобще не понимаю в чём беда? Mahowik сказат что у него не та, не другая версия драйвера вообще по tx не запустилась…
хотел сегодня вылететь, даже с планшетом договорился, а тут мокрый снег с дождём и ветер 😦
Тогда я вобще не понимаю в чём беда?
Вот я действительно не понял что за беда происходит, когда нужно временно отключить ПДП, а потом возобновить. Не могу нормально ПОВТОРНО инициализировать поток, хотя остановку ПДП делаю по руководству, дожидаюсь снятия бита DMA_SxCR_EN.
DMA_Cmd (DMA2_Stream3, DISABLE);
while(DMA_GetCmdStatus(DMA2_Stream3) != DISABLE);
Может у вас с этим же проблема?
Показывай код.
Вот старая версия github.com/SergDoc/…/drv_uart.c
Вот новая github.com/SergDoc/…/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;
}
хоть ты плату снимай…
Не наверно пока новую не соберу снимать не буду, а потом уже на старой буду эксперименты экспериментировать:)
Товарищ серг поведал, что в хавк должна быть вставлена симка.
Логи можно и неразбирая скачать через терминал в планнене…
Логи можно и неразбирая скачать через терминал в планнене…
Попробую. Спасибо. Только ткни куда тыкать.
И чего-то я запуталсо - две версии планнера есть что-ли? На сцайте у 3др версия 2.0, у меня какаято старая и по виду не похожая.
а итог один - тормоза в цыкле а у Саши вообще не запустился… или тут надо:
Попробуйте напрямую с регистрами работать. Говорят в STM32F4xx_StdPeriph_Driver косяки проскакивают.
Есть apm planner (Qt)
и есть Mission planner (net) но по сути они похожи, во вкладке терминал выбрать PX4/PIXHAWK > connect > скачать лог , у меня винда на этом ноуте тормознутая, так что не удивляйтесь - там видно несколько раз тыкался в connect
Говорят в STM32F4xx_StdPeriph_Driver косяки проскакивают
Скорей всего 😦
Говорят в STM32F4xx_StdPeriph_Driver косяки проскакивают.
Пока не встречал, правда один раз пытался на индусов всё свалить… не вышло😁 Библиотеками надо уметь пользоваться, код открытый - читай не хочу 😉
Ещё кейл всё сильно оптимизирует, так что работу с периферией построчно не отладить.
Ещё кейл всё сильно оптимизирует, так что работу с периферией построчно не отладить.
Пару раз натыкался на то что он выкидывал нужный кусок кода. Помогала установка пустой строки в области кода. Так и не понял почему так случалось.
Может библиотеки заменить? вроде STM32F4xx_StdPeriph_Driver по свежее уже есть?
Пару раз натыкался на то что он выкидывал нужный кусок кода. Помогала установка пустой строки в области кода. Так и не понял почему так случалось.
да есть такое…
Так как нелётная погода и настроение вообще аховое, незнал чем заняццо, ну ничего не получается сегодня, решил под бубунтой 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.
как это сделать?
в консоли набираем:
sudo apt-get install mono-runtime libmono-winforms2.0-cil libmono-corlib2.0-cil libmono-system-web4.0-cil libmono-system-management4.0-cil
после установки лезем сюда и скачиваем сам планнер в архиве!!! не msi.
распаковываем его куда-нибудь (папки без пробелов в названии и не кириллицей)
далее лезем в ту папку находим ArdupilotMegaPlanner10.exe правой клавишей ->свойства -> права ставим галочку - на разрешения запуска как приложение, открыть с помощью -> mono-runtime. Закрываем всё это дело и двойным кликом запускаем экзешник (тут есть нюанс - попросил обновится и перестал работать, так что я всё это убил и распаковал заново) и вуаля, под винду лазать больше не надо:)
Вот старая версия github.com/SergDoc/Nev_Multi...src/drv_uart.c
Вот новая github.com/SergDoc/Nev_Multi...src/drv_uart.c
а итог один - тормоза в цыкле а у Саши вообще не запустился…
Странно… как работает новая версия я понять не могу, ибо не вижу инициализации потока ПДП
//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;
и вообще там есть режим ФИФО, его и надо пользовать.
Если будет желание и возможность, завтра перепишу.
Может библиотеки заменить? вроде STM32F4xx_StdPeriph_Driver по свежее уже есть?
нее, библиотеки тут не при чем
Может библиотеки заменить? вроде STM32F4xx_StdPeriph_Driver по свежее уже есть?
а итог один - тормоза в цыкле а у Саши вообще не запустился…
я на дискавери-F4 пробовал + GY-86… т.е. мот какая специфика, типа на PA9,PA10 уже чего нить навешено… хотя простой примерчик (USART без DMA) из тырнета заработал…
Может библиотеки заменить? вроде STM32F4xx_StdPeriph_Driver по свежее уже есть?
в одном из примеров видел версию 1.0.2, хотя на stm оф. сайте сходу ее не нашел…
особо плохо что закоментина строка
умолчательные значения да совпадают
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR; // смотрел в примерах - оно один раз только выбирается, зачем два раза?
upd: еще можно глянуть в старом порте вия на F4 code.google.com/p/uavp-mods/downloads/detail?name=…
MWArmF4\src\harness\harness.c
MWArmF4\src\harness\serial.c
там вполне структурировано и не коряво с виду написано…
// Rewritten from AQ original Copyright © 2011 Bill Nesbitt
Там оно работает, я проверял, но вот вопрос с dma или без?
но вот вопрос с dma или без?
с dma, но нюансы я пока не понимаю
pins.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
}
};
serial.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
harness.c
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 отличий как говорится : code.google.com/p/aq32plus/…/drv_telemetry.c
прикол что у товарищей то работает, и у меня работало 😃
как там говорят: “дьявол в деталях”… а может именно с дискавери платой какая особенность… хз…
кстати попробуй проект открыть мой (точнее твой, но адаптированный под мпу6050 😃), может там в настройках самого проекта что нить не то… собери мне хекс-у и почтой кинь… проверю…
Часиков в 12 ночи по нашему…
как там говорят: “дьявол в деталях”…
это да
а может именно с дискавери платой какая особенность…
это нет
там вполне структурировано и не коряво с виду написано…
Да, компоновка настроек неплохая, и код написан для абстрактного порта, описанного в структуре. Но сами алгоритмы ничем не отличаются.
это нет
а оказалось да 😃 бомба в дискавери-Ф4 на PA9 висит 😃 че блин сразу не залез в схему, раз догадки были… кондер блин на 4.7мкф на лапе сидит…
micromouseonline.com/…/using-usart1-on-the-stm32f4…
my.st.com/public/STe2ecommunities/…/Flat.aspx?Root…
перевесил 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
},
...
};