STM32 новичку в ARM что к чему

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3920623#p3920623"]но я могу таблицу выровнять __attribute__((aligned(1024))) ?[/uquote]
Регистры 32-х битные, достаточно по границе 4-х байт выровнять.
можно поподробнее?

Код: Выделить всё

const uint64_t table[256];
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Reflector писал(а):Регистры 32-х битные, достаточно по границе 4-х байт выровнять.
что 4 что 1024 не помогло.
Reflector писал(а):

Код: Выделить всё

const uint64_t table[256];
Говорил же, поподробнее.
Сделал так
Спойлер

Код: Выделить всё

	*((volatile uint64_t*)&DMABuffer[0]) = tablica[pixeld[pixel_cnt].g];
	*((volatile uint64_t*)&DMABuffer[8]) = tablica[pixeld[pixel_cnt].r];
	*((volatile uint64_t*)&DMABuffer[16]) = tablica[pixeld[pixel_cnt].b];
Теперь таблица
Спойлер

Код: Выделить всё

#define HIGH      26	//38=0x26			
#define LOW       13	//19=0x13

#define _CONCAT_(x,a,s,d,f,g,h,j,k)		x ## a ## s ## d ## f ## g ## h ## j ## k
#define CONCAT(x,a,s,d,f,g,h,j,k)		_CONCAT_(x,a,s,d,f,g,h,j,k)
const uint64_t tablica [256] =
{
		CONCAT(0x,LOW,LOW,LOW,LOW,LOW,LOW,LOW,LOW),
		CONCAT(0x,LOW,LOW,LOW,LOW,LOW,LOW,LOW,HIGH),
		CONCAT(0x,LOW,LOW,LOW,LOW,LOW,LOW,HIGH,LOW),
		CONCAT(0x,LOW,LOW,LOW,LOW,LOW,LOW,HIGH,HIGH),
		CONCAT(0x,LOW,LOW,LOW,LOW,LOW,HIGH,LOW,LOW),
		CONCAT(0x,LOW,LOW,LOW,LOW,LOW,HIGH,LOW,HIGH),
		CONCAT(0x,LOW,LOW,LOW,LOW,LOW,HIGH,HIGH,LOW),
		CONCAT(0x,LOW,LOW,LOW,LOW,LOW,HIGH,HIGH,HIGH),
		CONCAT(0x,LOW,LOW,LOW,LOW,HIGH,LOW,LOW,LOW),
Что на F100 что и на F030, одинаковая картина: к примеру если красный то обязательно на максимуме то есть FF. А так цвета совпадают. Но ... что то не так.

А так Вариант_2 выдает 4мкс.
Реклама
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3920732#p3920732"]Говорил же, поподробнее.
Сделал так

Код: Выделить всё

	*((volatile uint64_t*)&DMABuffer[0]) = tablica[pixeld[pixel_cnt].g];
[/uquote]
Нужно всего-то скопировать несколько элементов из одного массива в другой, подробнее - это разве что самому все написать :) DMABuffer надеюсь тоже выровнял?
Последний раз редактировалось Reflector Сб ноя 07, 2020 22:24:40, всего редактировалось 2 раза.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Reflector писал(а):Нужно всего-то скопировать несколько элементов из одного массива в другой
Только сейчас глянул, он переворачивает байты. Поменял так

Код: Выделить всё

#define _CONCAT_(x,a,s,d,f,g,h,j,k)		x ## k ## j ## h ## g ## f ## d ## s ## a
и все встало на свои места.
Ваш этот вариант 5мкс выдает.
Reflector писал(а):DMABuffer надеюсь тоже выровнял?
Нет, когда игрался c F100, добился стабильности только тогда когда между светиками делаю паузу, то есть вот так
Спойлер

Код: Выделить всё

	*((volatile uint64_t*)&DMABuffer[0]) = tablica[pixeld[pixel_cnt].g];
	*((volatile uint64_t*)&DMABuffer[8]) = tablica[pixeld[pixel_cnt].r];
	*((volatile uint64_t*)&DMABuffer[16]) = tablica[pixeld[pixel_cnt].b];
	DMABuffer[24] = 0;
    }
    else
    {
так и дальше использую.
Ваш вариант все равно выдает предупреждение
warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
Реклама
Эиком - электронные компоненты и радиодетали
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3920603#p3920603"]Кроме всего прочего на F030 отказалась работать конструкция[/uquote]
Я знал, я знал :)

Как же дорого обходится не слушать советы бывалых.
Реклама
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

VladislavS писал(а):Как же дорого обходится не слушать советы бывалых.
И чем это обошлось? МК, лента и компутер?

Reflector, выровнял буфер дма и таблицу

Код: Выделить всё

__attribute__((aligned(4)))
Ваш вариант
Спойлер

Код: Выделить всё

	*((volatile uint64_t*)&DMABuffer[0]) = tablica[pixeld[pixel_cnt].g];	
	*((volatile uint64_t*)&DMABuffer[8]) = tablica[pixeld[pixel_cnt].r];
	*((volatile uint64_t*)&DMABuffer[16]) = tablica[pixeld[pixel_cnt].b];
до выравнивания выдавал 5мкс, после выравнивания 2мкс. Осталось убрать warning?

Так же с выравниванием 2мкс выдает этот вариант, до выравнивания было 9мкс
Спойлер

Код: Выделить всё

   memcpy(&DMABuffer[0], &tablica[pixeld[pixel_cnt].g], 8);	
	memcpy(&DMABuffer[8], &tablica[pixeld[pixel_cnt].r], 8);	
	memcpy(&DMABuffer[16], &tablica[pixeld[pixel_cnt].b], 8);
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2562
Зарегистрирован: Вт май 01, 2018 19:44:47

Сообщение VladislavS »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3921011#p3921011"]
VladislavS писал(а):Как же дорого обходится не слушать советы бывалых.
И чем это обошлось?[/uquote]Болью. Больно смотреть на эти мучения. :cry: Вот думаю, предложить или нет добавить преобразование HSV->RGB на лету?
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

VladislavS писал(а): Вот думаю, предложить или нет добавить преобразование HSV->RGB на лету?
У на уже есть преобразование HSV->RGB.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3921011#p3921011"]Осталось убрать warning?[/uquote]
У меня на gcc 9.2 даже если добавить -Wstrict-aliasing никаких предупреждений нет. Попробуй так:
Спойлер

Код: Выделить всё

	volatile uint64_t* p = (uint64_t*)DMABuffer;
	p[0] = tablica[pixeld[pixel_cnt].g];
	p[1] = tablica[pixeld[pixel_cnt].r];
	p[2] = tablica[pixeld[pixel_cnt].b];
И паузы между диодами не нужны, в документации про них ничего не сказано и если работает только с паузой, значит она маскирует какую-то ошибку, которая все равно может проявляться, только реже.

Добавлено after 37 minutes 15 seconds:
[uquote="Dimon456",url="/forum/viewtopic.php?p=3921022#p3921022"]У на уже есть преобразование HSV->RGB.[/uquote]
Есть функция для 8-ми биток где целых 8 делений и это запускается на мк без аппаратного деления. Ее раза в 3 спокойно можно ускорить.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

Reflector писал(а):Попробуй так:
Работает, 2мкс, warning нету.
Держит паяльник хвостом
Аватара пользователя
Сообщения: 954
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда

Сообщение GARMIN »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3921022#p3921022"]У на уже есть преобразование HSV->RGB.[/uquote]

А оно у вас точно правильное?
Потому что пока я не написал своё правильное преобразование HSV > RGB, ни один глупый пример из инета не заработал как надо.
Проверьте ненасыщенные цвета около перехода синий - красный.
Контактная информация:
Собутыльник Кота
Аватара пользователя
Сообщения: 2516
Зарегистрирован: Пт июл 12, 2019 22:52:01

Сообщение Eddy_Em »

Пытаюсь сократить количество конечных точек в USB CDC, неиспользуемую INTERRUPT IN назначил десятым номером, все работало. Затем решил объединить OUT и IN bulk. И вот здесь-то непонятно что происходит: данные по USB принимаются до тех пор, пока не начнется передача. Началась передача — все, данные приниматься перестают.
Обработчик такой сейчас (для опытов пока обе точки IN3 и OUT3):

Код: Выделить всё

static void rxtx_Handler(){
    uint16_t epstatus = KEEP_DTOG(USB->EPnR[3]);
    if(RX_FLAG(epstatus)){
        rxNE = 1;
        epstatus = (epstatus & ~(USB_EPnR_STAT_TX | USB_EPnR_CTR_RX)) ^ USB_EPnR_STAT_RX; // set valid RX, clear RX ctr
    }else{
        tx_succesfull = 1;
        epstatus = (epstatus & ~(USB_EPnR_CTR_TX|USB_EPnR_STAT_TX|USB_EPnR_STAT_RX)); // clear TX ctr
    }
    USB->EPnR[3] = epstatus;
}
Fixed: сам рукожоп, во втором случае забыл valid RX!
Последний раз редактировалось Eddy_Em Пн ноя 09, 2020 11:06:30, всего редактировалось 1 раз.
Linux rules! Windows must die. Здравомыслящий человек добровольно будет пользоваться мастдаем лишь в двух случаях: под дулом автомата или под влиянием анального зонда.
Я на гитхабе, в ЖЖ
Контактная информация:
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="GARMIN",url="/forum/viewtopic.php?p=3921067#p3921067"]А оно у вас точно правильное?[/uquote]
Скорее всего. Я делал по-другому и результаты были полностью идентичны функции из проекта ARV.
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

GARMIN писал(а):А оно у вас точно правильное?
Не совсем.
Я могу оперировать параметром H, S и V всегда равны FF.
Вот картинка
СпойлерИзображение
Я зажёг светики с шагом H=5, то есть от 0 до FF.
Последние два светика должны быть чисто красные, а они не красные, а FF0010.
Про это я знал, но как-то было "до лампочки".
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

С чего вы взяли, что последние должны быть чисто красные? Это первые красные, а последние еще чуть-чуть сиреневые. Цветовой круг замкнут, все верно.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

ARV писал(а):С чего вы взяли, что последние должны быть чисто красные?
Так онлайн-конвертеры говорят и ваша программа.
Вот для анализа:
Вариант_1
Спойлер

Код: Выделить всё

mData mHSVfast(uint8_t h, uint8_t s, uint8_t v) {	
	// быстрый HSV
	uint8_t r, g, b;
	uint8_t value = ((24 * h / 17) / 60) % 6;
	uint8_t vmin = (long)v - v * s / 255;
	uint8_t a = (long)v * s / 255 * (h * 24 / 17 % 60) / 60;
	uint8_t vinc = vmin + a;
	uint8_t vdec = v - a;
	switch (value) {
	case 0: r = v; g = vinc; b = vmin; break;
	case 1: r = vdec; g = v; b = vmin; break;
	case 2: r = vmin; g = v; b = vinc; break;
	case 3: r = vmin; g = vdec; b = v; break;
	case 4: r = vinc; g = vmin; b = v; break;
	case 5: r = v; g = vmin; b = vdec; break;
	}

    rgb_temp2.R = r;
    rgb_temp2.G = g;
    rgb_temp2.B = b;

	return 0;
}
Вариант_2
Спойлер

Код: Выделить всё

mData mHSV(uint8_t h, uint8_t s, uint8_t v) {	
	// обычный HSV
	float r, g, b;
	
	float H = h / 255.0;
	float S = s / 255.0;
	float V = v / 255.0;
	
	int16_t i = (int16_t)(H * 6);
	float f = H * 6 - i;
	float p = V * (1 - S);
	float q = V * (1 - f * S);
	float t = V * (1 - (1 - f) * S);
	
	switch (i % 6) {
	case 0: r = V, g = t, b = p; break;
	case 1: r = q, g = V, b = p; break;
	case 2: r = p, g = V, b = t; break;
	case 3: r = p, g = q, b = V; break;
	case 4: r = t, g = p, b = V; break;
	case 5: r = V, g = p, b = q; break;	
	}
	r *= 255.0;
	g *= 255.0;
	b *= 255.0;

    rgb_temp2.R = (uint8_t)r;
    rgb_temp2.G = (uint8_t)g;
    rgb_temp2.B = (uint8_t)b;

	return 0;
}
Вариант_3 (функция из проекта ARV)
Спойлер

Код: Выделить всё

void hsv_to_rgb(uint8_t h, uint8_t s, uint8_t v){
    unsigned char region, remainder, p, q, t;

    if (s == 0){
        rgb_temp2.R = v;
        rgb_temp2.G = v;
        rgb_temp2.B = v;
        return;
    }


    region = h / 43;
    remainder = (h - (region * 43)) * 6;

    p = (v * (256 - s)) >> 8;
    q = (v * (256 - ((s * remainder) >> 8))) >> 8;
    t = (v * (256 - ((s * (256L - remainder)) >> 8))) >> 8;

    switch (region){
	case 0:
		rgb_temp2.R = v; rgb_temp2.G = t; rgb_temp2.B = p;
		break;
	case 1:
		rgb_temp2.R = q; rgb_temp2.G = v; rgb_temp2.B = p;
		break;
	case 2:
		rgb_temp2.R = p; rgb_temp2.G = v; rgb_temp2.B = t;
		break;
	case 3:
		rgb_temp2.R = p; rgb_temp2.G = q; rgb_temp2.B = v;
		break;
	case 4:
		rgb_temp2.R = t; rgb_temp2.G = p; rgb_temp2.B = v;
		break;
	default:
		rgb_temp2.R = v; rgb_temp2.G = p; rgb_temp2.B = q;
		break;
    }
}
Все коды приукрасить можно, но в данном случае не важно.
Сравнительный анализ, таблица
СпойлерИзображение
У кого что есть еще, так сказать потестить?
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18678
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

сравните в своей таблице последнюю строку с первой - поскольку между строками таблицы должен быть примерно одинаковый шаг изменения цвета, вы можете видеть, что последня строка минус этот самый шаг будет равна первой, что и есть правильно. если у вас будут одинаковыми первая и последняя строки, значит, алгоритм работает с ошибкой: двум разным (а 00 и FF - это разные цвета) цветам в HSV-модели должны соответствовать РАЗНЫЕ RGB-цвета. так что мой алгоритм работает правильно (с учетом погрешности 8-битной арифметики), а что там показывают другие алгоритмы или конвертеры - мне неведомо.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Держит паяльник хвостом
Аватара пользователя
Сообщения: 954
Зарегистрирован: Вс дек 02, 2012 16:58:33
Откуда: от туда

Сообщение GARMIN »

Проверьте работу алгоритмов с ненасыщенными цветами, то есть S < 255, например 128 или вообще 16. В моём случае была проблема именно с этим.
Контактная информация:
Мудрый кот
Сообщения: 1849
Зарегистрирован: Вс дек 25, 2016 08:34:54

Сообщение Dimon456 »

ARV писал(а):сравните в своей таблице последнюю строку с первой
Точно, 255 это примерно 358 градусов.
GARMIN, вот таблица
СпойлерИзображение
В первых двух вариантах кода фигурирует в арифметике число 255, в варианте ARV число 256.
Поставщик валерьянки для Кота
Сообщения: 2089
Зарегистрирован: Вс июн 19, 2016 09:32:03

Сообщение Reflector »

[uquote="Dimon456",url="/forum/viewtopic.php?p=3921440#p3921440"]

Код: Выделить всё

   // быстрый HSV
   uint8_t r, g, b;
   uint8_t value = ((24 * h / 17) / 60) % 6;
[/uquote]
Это, кстати, неплохой подход, только на ARM так лучше не делать. Вместо h = 24 * h / 17 лучше написать:

Код: Выделить всё

h = h * uint32_t(65536 * (360.0f / 256) + 0.5f) >> 16;
Будет быстрее, т.к. нет деления, и точнее тоже. А делают так потому что 256/6 не делится нацело и накапливает погрешность, у меня максимум получалось 12 для одного из цветов. Перейдя к диапазону [0..360) можно делить и брать остаток от деления на ровно 60.
Ответить

Вернуться в «ARM»