Создание собственной системы стабилизации

SergDoc

Там оно работает, я проверял, но вот вопрос с dma или без?

mahowik
SergDoc:

но вот вопрос с 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
SergDoc

Видишь кругом задержки:
while (DMA_GetCmdStatus(u->TxDMAStream) != DISABLE) {
};
также я в старом драйвере делал…
мне тут подумалось, там же вий 2.1 протокол, может уже чё поменяли? или 2.2 ? блин уже почти год кодятнику - как время летит…
Найдите 10 отличий как говорится : code.google.com/p/aq32plus/…/drv_telemetry.c
прикол что у товарищей то работает, и у меня работало 😃

mahowik

как там говорят: “дьявол в деталях”… а может именно с дискавери платой какая особенность… хз…

кстати попробуй проект открыть мой (точнее твой, но адаптированный под мпу6050 😃), может там в настройках самого проекта что нить не то… собери мне хекс-у и почтой кинь… проверю…

rual
mahowik:

как там говорят: “дьявол в деталях”…

это да

mahowik:

а может именно с дискавери платой какая особенность…

это нет

mahowik:

там вполне структурировано и не коряво с виду написано…

Да, компоновка настроек неплохая, и код написан для абстрактного порта, описанного в структуре. Но сами алгоритмы ничем не отличаются.

mahowik
rual:

это нет

а оказалось да 😃 бомба в дискавери-Ф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
        },

    ...
    };
SergDoc

а цыфирку то 115200 зачем там переменная speed есть через cli можно любую скорость ставить…

mahowik:

перевесил USART1 на PB6, PB7 и все пошло

для baseflight это критично, для прошивки через терминал загоняется R - ппроц спускается до лодыря, а лодырь у тебя на других лапах усарт ищет 😃

mahowik:

перевесил USART1 на PB6, PB7

на новой плате он там:) но по другим причинам…

rual
mahowik:

перевесил USART1 на PB6, PB7 и все пошло, но пока мучился уже успел портануть USART+DMA из MWArmF4

)))) нудык! этаж не дискавери, этаж надо смотреть

SergDoc:

на новой плате он там но по другим причинам…

По этим же причинам, VBUS там.

SergDoc
rual:

По этим же причинам, VBUS там.

А нафига они там кондёр то повесили? я на старой плате закоротил, теперь если шиться через usart1 припрёт (лодырь залить с полным стиранием) только шнурок от usb отцепить дабы питание на pa9 не шло - и прекрасно работает… гы у тебя похоже не получалось через usart1 лодырь залить по той же причине 😃 - я считаю косяк проца в этом (неудобство для пользователя) не ну конечно есть DFU через USB - но чёт я так и не понял как через него всю флеш стереть😵
Там же по моему даже питание на плату с того USB не идёт? (discovery)
вот и вывод - хочешь USB, либо делай лодырь, либо вешай 1.5К на VBUS - D+ и используй программно свободную лапу…

rual
SergDoc:

А нафига они там кондёр то повесили?

Дык, usb та там ОТГ, нужно ж в некоторых демках от него внешнее устройства питается.

SergDoc:

я считаю косяк проца в этом (неудобство для пользователя)

да нее, не косяк, тут либо-либо. если есть USB то нах усарт? Если нет USB? тогда пожалуста usart.

SergDoc:

но чёт я так и не понял как через него всю флеш стереть

То что всё стереть нельзя, дык это в демо софте. Если сильно надо протокол открытый.
А кстати, зачем надо? У нас с тобой проблема прошивки не в этом была.

SergDoc:

вот и вывод - хочешь USB, либо делай лодырь,

Сергей, из чего такой вывод? При формировании ДФУ из нормального HEX это нафиг не надо.

Лодырь для Ф4 нужен только для одного, чтоб шится шифрованной прошивкой, это всё… Других применений собственного лодыря придумать не могу.

SergDoc
rual:

То что всё стереть нельзя, дык это в демо софте. Если сильно надо протокол открытый.
А кстати, зачем надо? У нас с тобой проблема прошивки не в этом была.

rual:

Сергей, из чего такой вывод? При формировании ДФУ из нормального HEX это нафиг не надо.

Лодырь для Ф4 нужен только для одного, чтоб шится шифрованной прошивкой, это всё… Других применений собственного лодыря придумать не могу.

Через демку не сотрёшь - а это однозначный косяк при перезаписи!!! т.е. как выход надо делать свою софтину DFU, или каждому в довесок к плате St-Link собирать? ну или как вариант покупать discovery ибо отдельно программатор как-то не по вкусной цене. Выход для простого пользователя - лодырь (ну тот-же арду - залился планера и привет - новая прошивка) да была бы USB демка такая-же как uploader по Usart да цены б ей небыло и вопросов бы не возникало USB или Usart. Ну вот зачем простому пользователю лишние телодвижения, в той же baseflightGUI всё встроено загоняет проц в режим лодыря и запускает прошивальшик без дёрганий втыкания BOOT0…

При формировании ДФУ из нормального HEX это нафиг не надо.

Кстати надо поработать над техникой 😃 по идее можно заставить компилятор сразу создавать DFU займусь новым лодырем (ну под новую плату) поэкспериментирую…

rual:

А кстати, зачем надо? У нас с тобой проблема прошивки не в этом была.

А вот я пробовал залить арду (vrbrain) а потом обратно baseflight - и усё не стартует…

rual
SergDoc:

А вот я пробовал залить арду (vrbrain) а потом обратно baseflight - и усё не стартует…

Серёг, это косяк НЕ ПРОЦЕССОРА, это КОСЯК прошивки. Либо она заливается не в те адреса, либо что то ищет в не размеченной компиллером области и находит что-то не то.
Было бы не плохо вычислить что её надо, как это сделать не знаю.

Drinker
SergDoc:

Через демку не сотрёшь - а это однозначный косяк при перезаписи!!! т.е. как выход надо делать свою софтину DFU

Че за демка и что тут стираете? Чем дфу тестер не устраивает?

Стер всё им и прошился им-же

SergDoc
rual:

либо что то ищет в не размеченной компиллером области и находит что-то не то. Было бы не плохо вычислить что её надо, как это сделать не знаю.

Конечно ищет 😃 у неё ж там виртуалка 😃 так вот в том то и проблема что если мы что-то меняем в DFU через USB то только в том месте куда прошиву льём… при чём оно просто заменяет данные, а не стирает а потом записывает 😦

Drinker:

Че за демка и что тут стираете? Чем дфу тестер не устраивает?

через USB нативный…

Drinker
SergDoc:

через USB нативный…

Наверное я чето не понимаю. В чем проблема лить проши через усб? Я лична только так и шьюсь. И никак иначе.

Drinker
SergDoc:

DFUse ? она не даёт стирать флеш…

STDFU Tester я использую…

Стирает все к чертям.

SergDoc

Помню что оно у меня не пошло, а почему не помню, оказывается у меня версия STDFU Tester 3.0.0 а она зараза только видимость создаёт, по сей причине я и пользовал dfuse, сейчас скачаю новую посмотрю…
Скачал - побаловался, да действительно всё делает, но не удобно для тех кто привык нажимать одну кнопку…

Drinker

[quote=SergDoc;4646870]да действительно всё делает[/quo
Ну так.

SergDoc:

побаловался, да действительно всё делает, но не удобно для тех кто привык нажимать одну кнопку…

Все усилия брось на однокнопочнегоф! А если по делу, то самый вариант - это бут в мк и прога - запузыриватель прошы. Посмотри на форк либмапле и там есть бутлодер, занятная вещь.