Замена порядка байтов RGB565 дисплеев ILI9341 и ST7735

Да. Правильно.
Причём если я spi и соответственно dma настрою на передачу байтов (8 бит соответственно) то все работает как надо, что логично.
Но на дисплей нужно отправить 320х240х2 байт, а счётчик dma может отправить за раз только 64к единиц данных. Вот и приходится делать 32х битную передачу.

Попробую полукадр преобразовать на выходе с камеры на след неделе. Думаю все взлетит.

Глянул асм для STM32, неслабо, конечно…жируете))
Есть инструкция REV -как раз реверс байт в слове.
Но я первый раз это вижу, не знаю, как сделать ассемблерную вставку , может кто подскажет, или я позже , если будет время, сам попробую

Любопытно, почитаю.

Если все дело только в этом - просто отправлять по дма последовательно несколько буферов

Это костыль получается, т к во время передачи части буфера, предыдущий кадр уже может измениться.
Да и опять же, в мк дури много, пусть сам работает и собственными dma перекидывает данные куда надо.

Вот так, примерно

uint32_t a = 0xF1F2F3F4;

void setup() {

  Serial.begin(115200);
  Serial.println("Hello, STM32!");
  Serial.println(a, HEX);
  __asm("LDR R0, =a");
  __asm("LDR R1, [R0]");
  __asm("REV R2, R1");
  __asm("STR R2, [R0]");

  Serial.println(a, HEX);

}

void loop() {

  delay(10); // this speeds up the simulation
}

Надо обменять байты в полусловах REV16 ! Судя по коду ТС …

И будет f2f1f4f3

А вот тут сложный вопрос.
С камеры dcmi dma берет строго по 32 бита (так в ДШ написано, по другому не работает), соответственно я не знаю поменяны ли пиксели в 32 битном слове, к сожалению на дисплее ili9341 сложно с его разрешением понять последовательность точек.
Но я обязательно проверю поменять пиксели местами и посмотрю как больше будет чёткость.

Это то вы проверили ? Тут именно байты в полусловах меняются, а не 1-4 2-3 ..

Конечно это рабочий код, выше фото, на экране изображение с камеры.
Вы не поняли, или я не так объяснил:
С камеры идёт последовательно поток байт по 8и битной шине.
Stm32 по dcmi с помощью dma загоняет этот поток в память. Dma работает строго по 32 бита. Какой из входящих от камеры байт будет старшим, какой младший я не знаю, документацию не нашёл или не понял (слаб в английском).
Соответственно в памяти видео буфера, в 32х разрядном слове находится два пикселя. Какой из них первый и второй я могу только догадываться или провести эксперимент и посмотреть в каком варианте будет более чёткая картинка.
Если я память видеобуфера вот как она есть отправляю по spi (8и битный режим) на дисплей - с картинкой все хорошо с точки зрения цветном и, но совсем не факт что корректная передача соседних по горизонтали пикселей.
Отпишу по результатам эксперимента.

Ну, тогда тот же самый код(#26) только инструкцию REV(стр.10 ) заменить на REV16.

Главное, логику работы точно понять , может асм и не нужен будет…

В результате замены на ассемблерную вставку скорость поднядась с 23 FPS до 28 FPS.
Отличный результат.
Всем спасибо!

void h743refreshILI9341byDMA(void) {
	static unsigned long timerILI = 0UL;
	static unsigned long iliFPS = 0UL;
	if (spWork) {
		if ((SPI2->SR & SPI_SR_TXC) && (DMA1->LISR & DMA_LISR_TCIF2)) { // проверка занятости потока DMA и интерфейса SPI
			h743stopSPI2DMA();
			unsigned long countWords = w_size*h_size*2/4;
			//ILI9341 28 FPS
			unsigned long * srcByte = (unsigned long *)h747hetPointerFrameCAMCDMI();
			unsigned long * dstByte = (unsigned long *)&iliDataBuf[0];
			while(countWords--){
				__asm volatile("rev %0, %1;" : "=r"(*(dstByte++)) : "r"(*(srcByte++)));
			}
			//ILI9341 23 FPS
			/*unsigned char * srcByte = h747hetPointerFrameCAMCDMI();
			unsigned char * dstByte = &iliDataBuf[0];
			while(countWords--){
				*(dstByte++) = *(srcByte+3);
				*(dstByte++) = *(srcByte+2);
				*(dstByte++) = *(srcByte+1);
				*(dstByte++) = *(srcByte);
				srcByte += 4;
			}*/
			// здесь можно выводить какое либо изображение поверх видео с камеры
			// перед выводом на дисплей
			h743sendILI9341ByDMA();
			++iliFPS;
			if ((millis() - timerILI) >= 10000UL) {
				timerILI = millis();
				iliFPS /= 10;
				printf("ILI9341 %d FPS\r\n", (unsigned int)iliFPS);
				iliFPS = 0UL;
			}
		}
	}
}

Добавил заполнение выходного буфера экрана в прерывании DMA Камеры, стало совсем хорошо.

extern "C" void DMA_STR1_IRQHandler(void) {
	static unsigned long camFPS = 0UL;
	static unsigned long camTimer = 0UL;
	if (DMA1->LISR & DMA_LISR_TCIF1) {
		DMA1->LIFCR |= DMA_LIFCR_CTCIF1;
		DMA1->LIFCR |= DMA_LIFCR_CHTIF1;
		// copy frame buf to external place
		if (outRGB565buf) {
			unsigned long countWords = _cam_size_x*_cam_size_y*2/4;
			unsigned long * srcByte = (unsigned long *)h747hetPointerFrameCAMCDMI();
			unsigned long * dstByte = (unsigned long *)outRGB565buf;
			while(countWords--){
				__asm volatile("rev %0, %1;" : "=r"(*(dstByte++)) : "r"(*(srcByte++)));
			}
		}
		// end copy
		++camFPS;
		if ((millis() - camTimer) >= 10000UL) {
			camTimer = millis();
			camFPS /= 10;
			printf("Camera %d FPS\r\n", (unsigned int)camFPS);
			camFPS = 0UL;
		}
	}
}

HSI 64000000
CLK 400000000
random A3A7C241 9B7018EE
micros 0000003B 0000003B
Camera OV7725 connected.
Resolution - QVGA
Output format control - RGB
RGB output format control - RGB565
Free RAM_D2 115712 bytes
Camera 69 FPS
ILI9341 42 FPS
Camera 82 FPS
ILI9341 51 FPS
Camera 82 FPS
ILI9341 51 FPS
Camera 82 FPS
ILI9341 51 FPS
Camera 82 FPS
ILI9341 51 FPS

А куда ты 31 fps с камеры деваешь?

Переводит в тепло

Дык я считаю по количеству передачи каждого канала dma, сколько там реальных кадров - хз.
И да, они же (dma) между камерой и дисплеем не синхронизированы и приоритеты у них разные, у камеры высший, большой экран - средний, маленький экран - минимальный приоритет.

Вопроса два:

  1. Какой в этом смысл?
  2. Дефекты на изображении заметны (при движении камеры)?
  1. Никакого. Работают сами по себе. Мне например не надо думать что там с камерой происходит во время рисования поверх изображения на экране, кадр вывелся, нарисовал что надо в буфере экрана, вывел.
  2. А вот это интересно, да, при быстром движении руками перед камерой, видно, что на экран выводится на доли секунд, на грани чувствительности зрения, горизонтальные полосы со старым изображением движущегося предмета, хотя быстродействия должно хватать :thinking: