Здравствуйте.
Использую ADSP BF533 + SDRAM + OLED Display (подключен к EBIU 16 бит).
Программа загружена в SDRAM, кэширование включено: для данных и программ, политика write back.
Дисплей не прокеширован.
Периодически нужно отрисовывать кадр на дисплей, как можно быстрее.
Видеопамять дисплея - 16 бит на пиксел, адрес автоматически увеличивается на +1 пиксел после отрисовки точки.
Есть буфер в котором строистя изображение - источник. Кодировка цветов через палитру.
Приемником выступает сам дисплей.
Палитру засунул в L1_DATA_B, чтобы ускорить доступ к ней (попиксельно идет обращение).
Буфер источника находится в SDRAM (кеширована).
За один присест сразу рисую 2 пиксела по 16 бит, по сути формирую 32-битное обращение к памяти дисплея: #define OLED_Data_32 (*(volatile u32*) 0x20010000)
Хотя он подключен к 16-битной шине.
Фрагмент кода:
//u8, u16, u32 - char, short и long соответственно 1 2 4 байта
UINT16* palette_16bit_lookup=(UINT16*)0xFF900000; //L1_DATA_B 16KB Тут палитра
#define SRC_PITCH 544 /* Ширина источника */
#define DST_HEIGHT 224 /* Высота приемника */
#define SCR_WIDTH 320 /* Ширина дисплея */
#define SCR_HEIGHT 240 /* Высота дисплея */
#define OLED_Data_32 (*(volatile u32*) 0x20010000) /* Это регистр данных дисплея с автоинкрементом адреса, подключен к EBIU Blackfin - разрядность 16 бит */
#define PIXEL OLED_Data_32=(palette_16bit_lookup[src[1]]<<16)|palette_16bit_lookup[src[0]];src+=2; /* выводим сразу 2 пиксела(по 16 bit) на дисплей, цвет берем из палитры */
#define PIXELLAST OLED_Data_32=(palette_16bit_lookup[src[1]]<<16)|palette_16bit_lookup[src[0]];src+=(SRC_PITCH-SCR_WIDTH+2); /* последние 2 пиксела */
void Draw_Window(struct BITMAP *bitmap) //Отправка буфера на дисплей
{
register u16* src=(u16*)(((u32)bitmap->base)+17536+64); //Стартовый адрес источника
register u32 y=DST_HEIGHT;
OLED_Rectangle(0,(SCR_HEIGHT-DST_HEIGHT)>>1,SCR_WIDTH-1,((SCR_HEIGHT+DST_HEIGHT)>>1)-1); //Задаёт прямоугольную область 320x224 по центру дисплея (сам дисплей 320x240)
while(y--) //цикл по Y, цикл по X развернут на 320 точек (160 слов)
{
PIXEL /* 159 раз */
PIXEL
PIXEL
/* ... */
PIXEL
PIXEL
PIXELLAST /* 160-й раз */
}
}
Цикл по X развернут макросами для ускорения.
Компилировал это дело в Visual DSP++ 5.1.2 - пробовал такую оптимизацию: Speed 100, Interprocedural optimization, Frame-pointer optimization.
Код работает как нужно , но подозреваю, что можно сделать быстрее!
Дает ли прирост скорости 32-битное обращение к регистру данных дисплея, когда он подключен к 16-битной шине?
Фактически это 2 операции подряд по 16 бит с увеличением адреса (не используются).
Как можно сделать ещё быстрее?
Рассмотрю любые способы: от изменения алгоритма, до системного управления процессором (кеширование, выравнивание).
Пробовал изменить тайминги шины EBIU, ничего не меняется. Как можно пере-инициализировать контроллер асинхронной шины, когда он уже работает?