Страница 1 из 1

Ссылка на PROGMEM

Добавлено: Пт янв 01, 2016 17:33:36
servmv
Народ помогите выбрать шрифт)

Шрифт лежит в PROGMEM

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

const unsigned char SmallFont[] PROGMEM={
	0x08,0x0C,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // <Space>
        ............
const unsigned char BigFont[] PROGMEM={
	0x10,0x10,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, .............
const unsigned char SevenSegNumFont[] PROGMEM={
	0x20,0x32,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x00,0x01,0xFF,0xFF ....
пока 3)

что нужно,

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

#define Font8x12		1
#define Font16x16		2
#define Font32x50		3

void UTFT_printChar(uchar sym, uint x, uint y, uchar font){
        uint FontSel;                      //             <------------------ 

        if(font == Font8x12){
		FontSel = SmallFont;  //              <------------------ 
	}
	if(font == Font16x16){
		FontSel = BigFont;     //              <------------------
	}
	if(font == Font32x50){
		FontSel = SevenSegNumFont; //  <------------------
	}
	
	cfont_x_size = pgm_read_byte(FontSel);    // Высота символа
	cfont_y_size = pgm_read_byte(FontSel+1);  // Ширина символа, число байт

правильно объявить переменную, куда сохранить адрес, правильно его сохранить и передать в pgm_read_byte

Re: Ссылка на PROGMEM

Добавлено: Сб янв 02, 2016 08:37:49
uk8amk
http://avr-libc.narod.ru/group__avr__pg ... ce430a587c

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

#define pgm_read_byte 	(	address_short 	) 	
   pgm_read_byte_near(address_short)
Считывает байт из памяти программ по 16-разрядно-му ("ближнему") адресу.
Примечание: адрес - адрес байта. Адрес находится в пространстве программ.
Исходя из этой информации надо действовать примерно так:

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

uint16_t FontSel; // для больших камней там u32 надо
FontSel = (uint16_t) &SmallFont[0]; // а вот это зависит от структуры массива

Re: Ссылка на PROGMEM

Добавлено: Сб янв 02, 2016 15:02:37
servmv
Чет у меня тут усложнилась ситуация, я почему то не могу прочесть PROGMEM как в учебнике, в симуляторе все работает на железе не работает. Размещение в первом посте расписано.

т.к. на железе некуда вывести байт для просмотра (хотя я уже думаю спаять макетку со светодиодами), я вывожу считанный байт на дисплей но так как шрифта еще нет, вывожу через функцию рисования линии, прочитанный байт используется в качестве длинны линии.

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

for (uchar x1=0; x1 < 12; x1++){
char dt = pgm_read_byte_far(SmallFont + x1);
UTFT_drawVLine(x1,0,dt,VGA_YELLOW);
}
то есть читаю 12 байт и рисую 12 линий.

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

const unsigned char SmallFont[1144] PROGMEM = {0x08,0x0C,
	0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
первая линия должна быть 1+8 = 9 пиксел
вторая 1+12=13пиксел
остальные по 1
все 12 линий по 256 пиксел :o
по поводу pgm_read_byte_far, обьем mega2560 256кбайт, а это 18 бит, uint16_t не логично использовать, pgm_read_byte_far принимает адрес uint32_t, последний контролер с которым я работал был ATMEGA16, проблем не было, да и сейчас нету, не пойму почему с этим контролером проблемы.

Re: Ссылка на PROGMEM

Добавлено: Сб янв 02, 2016 15:57:39
uk8amk
По поводу железки. В студии есть вполне годный симулятор, можно пройтись по проблемному куску кода и сверяя передаваемые значения определить причину.
Попробуйте также в map файле линкера посмотреть адреса массивов шрифта и потыкать их напрямую в функцию чтения. Быть может вы некорректно вычисляете адреса или преобразоваваете типы. Больше пока посмоветовать нечего поскольку с AVRGCC плотно не работал.

Re: Ссылка на PROGMEM

Добавлено: Сб янв 02, 2016 16:12:47
servmv
uk8amk писал(а):По поводу железки. В студии есть вполне годный симулятор, можно пройтись по проблемному куску кода и сверяя передаваемые значения определить причину.
Попробуйте также в map файле линкера посмотреть адреса массивов шрифта и потыкать их напрямую в функцию чтения. Быть может вы некорректно вычисляете адреса или преобразоваваете типы. Больше пока посмоветовать нечего поскольку с AVRGCC плотно не работал.
Я про это пишу, в симуляторе все отлично. Данные есть, адреса тоже совпадают, другим кодом пробовал

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

FontSel = (uint32_t) &SmallFont[0]; // а вот это зависит от структуры массива
а на железке не работает. Типы я не преобразовываю. В FontSel ложится адрес, по которому реально есть данные. Вот скриншет.

на железке в dt попадает 255 (пробовал туда в место dt прописать вручную "8") линии рисуются длинной в 9 пикс. Я четко нашел где проблема, но я не понимаю что не так.

дисасемблированный фрагмент

Re: Ссылка на PROGMEM

Добавлено: Сб янв 02, 2016 16:35:02
servmv
В результате вот этого кода:

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

for (uchar x1=0; x1 < 12; x1++){
		char dt = pgm_read_byte_far(SmallFont + x1);
		UTFT_drawVLine(x1,0,dt,VGA_YELLOW);
	}
дисплей работает так:скрин
В результате вот этого кода:

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

for (uchar x1=0; x1 < 12; x1++){
		char dt = pgm_read_byte_far(SmallFont + x1);
		UTFT_drawVLine(x1,0,8,VGA_YELLOW);
	}
дисплей работает так: скрин

как Вы понимаете на первом скрине 12 полосок по 256 пикселей

Re: Ссылка на PROGMEM

Добавлено: Сб янв 02, 2016 18:01:49
servmv
чет какие то танцы с бубном начинаются, нарыл статью
где чувак пишет:
When i try put char on display = reading from progmem, microcontroller Atmega2560 "STOP / FROZE" !!! - this is in my opinion very unusual.
I read some topics about "pgm_read_byte_far / _near", next topics about "trampolines" and after lots of hours I read progmem with following command:
"LcdCache[LcdCacheIdx++] = pgm_read_byte_far(0x20100+(uint8_t)&(FontLookup[ch - 32]));"
In original of this command, some people used 0x20000 (on Atmgea2560), but in my case I must experimentaly go to value 0x20100.
This command was used only for my "debug experimenting" - this is wrong way in this situation.

Я не очень шарю в инглиш, но тут чет ужасное пишут,
pgm_read_byte_far(0x20100+(uint8_t)&(FontLookup[ch - 32]));
people used 0x20000 (on Atmgea2560)
я конечно по пробовал оба варианта, не помогло, но выбесило в край.

Re: Ссылка на PROGMEM

Добавлено: Сб янв 02, 2016 19:04:16
Аlex
А попробовать отладку в железе есть возможность ?

Re: Ссылка на PROGMEM

Добавлено: Сб янв 02, 2016 19:34:59
servmv
Аlex писал(а):А попробовать отладку в железе есть возможность ?
Нет. Мне не найти бюджетный JTAG для atmelstudio6

поставил atmelstudio7, попробовал там скомпилировать, результат тот же.
нашел еще вот это:ссылка
I read the nice guide from wek :http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=708225 , but in his example he used 1 dimensional arrays, and he concludes that its not possible to use " GET_FAR_ADDRESS " or " pgm_get_far_address "( in newer versions of pgmspace.h)
сделал так:

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

FontSel = pgm_get_far_address(SmallFont); // а вот это зависит от структуры массива
for (uchar x1=0; x1 < 12; x1++){
	char dt = pgm_read_byte_far(SmallFont + x1);
	UTFT_drawVLine(x1,0,dt,VGA_YELLOW);
}
в симуляторе также все отлично, на железке, не работает. Гдето читал про косяки bootloader arduino. Стер на*ер, во фьюзах поставил старт с 0000.

не че не помогает, чю за жопа.


P.S.
По пробовал залить демку что шла в комплекте, все работает на ура (там есть в PGM шрифты) а значит в коде есть обращение к PGM и брак чего либо можно исключить.

Re: Ссылка на PROGMEM

Добавлено: Вс янв 03, 2016 17:28:37
codenamehawk
servmv писал(а): сделал так:

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

FontSel = pgm_get_far_address(SmallFont); // а вот это зависит от структуры массива
for (uchar x1=0; x1 < 12; x1++){
	char dt = pgm_read_byte_far(SmallFont + x1);
	UTFT_drawVLine(x1,0,dt,VGA_YELLOW);
}
А если попробовать заменить

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

char dt = pgm_read_byte_far(SmallFont + x1);
на

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

char dt = pgm_read_byte_far(FontSel + x1);
покажите ваш проект для отладчика.

Re: Ссылка на PROGMEM

Добавлено: Вс янв 03, 2016 18:03:58
ARV
я не пойму: зачем вы пользуете far-процедуры чтения из PROGMEM? по умолчанию данные в PROGMEM размещаются в первых 64К адресов, поэтому доступны по обычному, не far-указателю. в моей практике был случай, когда прилось задействовать более 64К памяти под константные данные, но то особый случай. что можно напихать в память, что в 64К не влезает?! :shock:

Re: Ссылка на PROGMEM

Добавлено: Пн янв 04, 2016 05:50:14
servmv
ARV писал(а):я не пойму: зачем вы пользуете far-процедуры чтения из PROGMEM? по умолчанию данные в PROGMEM размещаются в первых 64К адресов, поэтому доступны по обычному, не far-указателю. в моей практике был случай, когда прилось задействовать более 64К памяти под константные данные, но то особый случай. что можно напихать в память, что в 64К не влезает?! :shock:
Да по началу так и было, а про far даже незнал, это уже гугл помог. Тему можно закрыть. Что было не так я отписал тут