ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Понедельник
25 ноября
309671 Топик полностью
SciFi (23.02.2012 14:55, просмотров: 99) ответил B52 на сломал голову... STM32F217 + TFT LCD на S1D13A04 подключен к FSMC_Bank1_NORSRAM2. Read-Only регистр 0 считывается как 0x282C282C тогда как должен быть 0x2Cxx282c. С прочими регистрами тоже какая то муть, кроме SCratch Pad register A(адрес 0x80):
Помню, запускал S1D13A05 + STR710. Пришлось поломать голову над переходом Big Endian <-> Little Endian. Переход делался программно. Посмотрите на код, вдруг будет интересно: #include "epsgfx.h" #include "str710regs.h" #include <string.h> #define BYTESPERPIXEL 1 #define LCD_NUM_COLORS 256 #define LCD_PCLK (*(uint16_t volatile*)0x6200000A) #define LCD_GPO (*(uint16_t volatile*)0x6200006A) #define LCD_PANEL0 (*(uint16_t volatile*)0x6200000E) #define LCD_PANEL1 (*(uint16_t volatile*)0x6200000C) #define LCD_SET0 (*(uint16_t volatile*)0x62000012) #define LCD_SET1 (*(uint16_t volatile*)0x62000010) #define LCD_PSAVE (*(uint16_t volatile*)0x62000016) #define LCD_HT (*(uint16_t volatile*)0x62000022) #define LCD_HDP (*(uint16_t volatile*)0x62000026) #define LCD_HDPS (*(uint16_t volatile*)0x6200002A) #define LCD_FPLINE0 (*(uint16_t volatile*)0x6200002E) #define LCD_FPLINE1 (*(uint16_t volatile*)0x6200002C) #define LCD_VT (*(uint16_t volatile*)0x62000032) #define LCD_VDP (*(uint16_t volatile*)0x62000036) #define LCD_VDPS (*(uint16_t volatile*)0x6200003A) #define LCD_FPFRAME0 (*(uint16_t volatile*)0x6200003E) #define LCD_FPFRAME1 (*(uint16_t volatile*)0x6200003C) #define LCD_START0 (*(uint16_t volatile*)0x62000042) #define LCD_START1 (*(uint16_t volatile*)0x62000040) #define LCD_LAOFF (*(uint16_t volatile*)0x62000046) #define LCD_PWM_CTRL (*(uint16_t volatile*)0x62000072) #define LCD_PWM_DUTY (*(uint16_t volatile*)0x62000076) #define LCD_BLT_CONTROL (*(uint16_t volatile*)0x62008002) #define LCD_BLT_STATUS (*(uint16_t volatile*)0x62008006) #define LCD_BLT_COMMAND (*(uint16_t volatile*)0x6200800A) #define LCD_BLT_ROP (*(uint16_t volatile*)0x62008008) #define LCD_BLT_SRC0 (*(uint16_t volatile*)0x6200800E) #define LCD_BLT_SRC1 (*(uint16_t volatile*)0x6200800C) #define LCD_BLT_DST0 (*(uint16_t volatile*)0x62008012) #define LCD_BLT_DST1 (*(uint16_t volatile*)0x62008010) #define LCD_BLT_OFFSET (*(uint16_t volatile*)0x62008016) #define LCD_BLT_WIDTH (*(uint16_t volatile*)0x6200801A) #define LCD_BLT_HEIGHT (*(uint16_t volatile*)0x6200801E) #define LCD_BLT_BKCOLOR (*(uint8_t volatile*)0x62008022) #define LCD_BLT_COLOR (*(uint8_t volatile*)0x62008026) #define LCD_BLT_FIFO (*(uint16_t volatile*)0x62010000) #define LCD_PIP_START0 (*(uint16_t volatile*)0x62000052) #define LCD_PIP_LAOFF (*(uint16_t volatile*)0x62000056) #define LCD_PIP_XSTART (*(uint16_t volatile*)0x6200005A) #define LCD_PIP_XEND (*(uint16_t volatile*)0x62000058) #define LCD_PIP_YSTART (*(uint16_t volatile*)0x6200005E) #define LCD_PIP_YEND (*(uint16_t volatile*)0x6200005C) #define LCD_IDLE() (*(uint16_t volatile*)0x62000000 = 0) /* Текущие атрибуты выводимого текста */ static const epsgfx_font *current_font; static int16_t current_fgcolor; static text_align current_align; static bool current_transparent; static uint16_t current_bgcolor; /* текущая страница в видеопамяти */ static uint32_t VideoPage=0; /** * Установить (меняет) цвет в палитре * * @param index - индекс или порядковый номер цвета в палитре * @param colour - цвет в формате 0xBBGGRR */ void epsgfx_setcolor(uint8_t index, uint32_t colour) { uint8_t rgb[3]; /* * так как на дисплей нельзя выдавать чисто белый цвет, уменьшаем * яркость цветов в палитре */ rgb[0] = (((uint8_t*)&colour)[0] * 15) >> 4; rgb[1] = (((uint8_t*)&colour)[1] * 15) >> 4; rgb[2] = (((uint8_t*)&colour)[2] * 15) >> 4; *(uint16_t volatile*)0x6200001C = (uint16_t)index << 8; *(uint16_t volatile*)0x62000018 = ( (uint16_t)index << 8 ) | rgb[0]; *(uint16_t volatile*)0x6200001A = ( (uint16_t)rgb[1] << 8 ) | (uint16_t)rgb[2]; LCD_IDLE(); } /** * Установить палитру * * @param pal палитра (массив из 256 элементов-цветов в формате 0xBBGGRR) */ void epsgfx_setpalette(const uint32_t pal[256]) { uint16_t i; for (i = 0; i < LCD_NUM_COLORS; i++) { epsgfx_setcolor(i, pal[i]); } } /** * Выводит точку * * @param x Координата точки по горизонтали * @param y Координата точки по вертикали * @param col Цвет точки */ void epsgfx_putpixel(uint16_t x, uint16_t y, uint8_t col) { /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1){} *(volatile uint8_t*)((0x62040000 + VideoPage + SCREEN_W * y + x) ^ 1) = col; LCD_IDLE(); } /** * Выводит горизонтальную линию * * @param x0 Горизонтальная координата начальной точки прямой * @param y0 Вертикальная координата начальной точки прямой * @param x1 Горизонтальная координата конечной точки прямой * @param col Цвет прямой */ void epsgfx_drawhline(uint16_t x0, uint16_t y0, uint16_t x1, uint8_t col) { uint32_t dst; /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1){} /* 0------------1 */ /* Calculate the destination address */ dst = VideoPage + y0 * SCREEN_W * BYTESPERPIXEL + x0 * BYTESPERPIXEL; LCD_BLT_DST0 = (uint16_t)dst; LCD_BLT_DST1 = (uint16_t)(dst >> 16); /* Program the BitBLT Width Register */ LCD_BLT_WIDTH = x1 - x0; /* Program the BitBLT Height Register */ LCD_BLT_HEIGHT = 0; /* Program the BitBLT Foreground Color Register */ LCD_BLT_COLOR = col; /* Program the BitBLT Operation Register to select Solid Fill */ LCD_BLT_COMMAND = 0xC; /* Start the BitBLT operation */ LCD_BLT_CONTROL = 1; LCD_IDLE(); } /** * Выводит вертикальную линию * * @param x0 Горизонтальная координата начальной точки прямой * @param y0 Вертикальная координата начальной точки прямой * @param y1 Вертикальная координата конечной точки прямой * @param col Цвет прямой */ void epsgfx_drawvline(uint16_t x0, uint16_t y0, uint16_t y1, uint8_t col) { uint32_t dst; /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1){} /* 0-----------| * | | * |-----------1 */ /* Calculate the destination address */ dst = VideoPage + y0 * SCREEN_W * BYTESPERPIXEL + x0 * BYTESPERPIXEL; LCD_BLT_DST0 = (uint16_t)dst; LCD_BLT_DST1 = (uint16_t)(dst >> 16); /* Program the BitBLT Width Register */ LCD_BLT_WIDTH = 0; /* Program the BitBLT Height Register */ LCD_BLT_HEIGHT = y1 - y0; /* Program the BitBLT Foreground Color Register */ LCD_BLT_COLOR = col; /* Program the BitBLT Operation Register to select Solid Fill */ LCD_BLT_COMMAND = 0xC; /* Start the BitBLT operation */ LCD_BLT_CONTROL = 1; LCD_IDLE(); } /** * Выводит незакрашенный прямоугольник * * @param x0 Горизонтальная координата левой верхней точки прямоугольника * @param y0 Вертикальная координата левой верхней точки прямоугольника * @param x1 Горизонтальная координата правой нижней точки прямоугольника * @param y1 Вертикальная координата правой нижней точки прямоугольника * @param col Цвет прямоугольника */ void epsgfx_drawrect(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t col) { /* 0-----1-----| * | | * 4 2 * | | * |-----3-----1 */ epsgfx_drawhline(x0, y0, x1, col); /* 1 */ epsgfx_drawvline(x1, y0, y1, col); /* 2 */ epsgfx_drawhline(x0, y1, x1, col); /* 3 */ epsgfx_drawvline(x0, y0, y1, col); /* 4 */ } /** * Выводит закрашенный прямоугольник * * @param x0 Горизонтальная координата левой верхней точки прямоугольника * @param y0 Вертикальная координата левой верхней точки прямоугольника * @param x1 Горизонтальная координата правой нижней точки прямоугольника * @param y1 Вертикальная координата правой нижней точки прямоугольника * @param col Цвет прямоугольника */ void epsgfx_fillrect(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t col) { uint32_t dst; /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1) {} /* 0-----------| * | | * |-----------1 */ /* Calculate the destination address */ dst = VideoPage + y0 * SCREEN_W * BYTESPERPIXEL + x0 * BYTESPERPIXEL; LCD_BLT_DST0 = (uint16_t)dst; LCD_BLT_DST1 = (uint16_t)(dst >> 16); /* Program the BitBLT Width Register */ LCD_BLT_WIDTH = x1 - x0; /* Program the BitBLT Height Register */ LCD_BLT_HEIGHT = y1 - y0; /* Program the BitBLT Foreground Color Register */ LCD_BLT_COLOR = col; /* Program the BitBLT Operation Register to select Solid Fill */ LCD_BLT_COMMAND = 0xC; /* Start the BitBLT operation */ LCD_BLT_CONTROL = 1; /* Bug in the graphic controller */ LCD_IDLE(); } /** * Установка атрибутов текста, выводимого командой epsgfx_outputtext. * Устанавливаются шрифт, цвет, наличие фона, цвет фона, выравнивание * шрифта. * * @param font Шрифт выводимого текста. Шрифты подключаются к проекту * в отдельных файлах. Имена подключенных шрифтов прописываются * как extern в файле main.c. * @param transparent Прозрачность текста (наличие или отсутствие фона). * Если true - фон не рисуется, если false - рисуется. * @param fgcolor Цвет текста * @param bgcolor Цвет фона * @param align Выравнивание шрифта. Может принимать значения * ALIGN_LEFT (по левому краю), ALIGN_CENTRE (по центру), * ALIGN_RIGHT (по правому краю) */ void epsgfx_settextattr(const epsgfx_font* font, bool transparent, uint8_t fgcolor, uint8_t bgcolor, text_align align) { current_font = font; current_transparent = transparent; current_align = align; current_fgcolor = fgcolor; current_bgcolor = bgcolor; } /** * Выводит текст * * @param str выводимый текст * @param x Горизонтальная координата относительно которой выводится текст * @param y Вертикальная координата относительно которой выводится текст */ void epsgfx_outputtext(const char* str, uint16_t x, uint16_t y) { uint32_t dstAddr; uint16_t len, i; /* длина строки в символах */ len = strlen(str); /* расчёт выравнивания текста */ switch (current_align) { case ALIGN_CENTRE: x -= epsgfx_gettextwidth(str) / 2; break; case ALIGN_RIGHT: x -= epsgfx_gettextwidth(str); break; default: /* пусто */ break; } /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1) {} /* Program the BLT registers */ /* начинаем с младшего бита младшего байта */ LCD_BLT_ROP = 7; LCD_BLT_SRC0 = 0; /* Program the BitBLT Height Register */ LCD_BLT_HEIGHT = current_font->height-1; /* Program the BitBLT Foreground Color Register */ LCD_BLT_COLOR = current_fgcolor; /* Program the BitBLT Background Color Register */ LCD_BLT_BKCOLOR = current_bgcolor; /* Program the BitBLT Command Register: 9 == transparency */ LCD_BLT_COMMAND = 8 + current_transparent; /* вывод по символам */ for (i = 0; i < len; i++) { const uint16_t* ptr; uint16_t CharW, numwords; /* ширина в пикселах */ CharW = current_font->table[str[i] - current_font->first].width; dstAddr = VideoPage + (uint32_t)(x * BYTESPERPIXEL) + (uint32_t)(y * SCREEN_W * BYTESPERPIXEL); /* расчёт координаты х следующего символа */ x += CharW; /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1){} LCD_BLT_DST0 = (uint16_t)dstAddr; LCD_BLT_DST1 = (uint16_t)(dstAddr >> 16); /* Program the BitBLT Width Register */ LCD_BLT_WIDTH = CharW - 1; /* Start the BitBLT operation */ LCD_BLT_CONTROL = 1; /* указатель на начало массива битов символа */ ptr = ¤t_font->bitstream[ current_font->table[str[i] - current_font->first].index]; /* ширина в 16 битных словах */ numwords = (CharW + 15) / 16 * current_font->height; while (numwords > 0) { LCD_BLT_FIFO = *ptr; ptr++; numwords--; } } /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1) {} LCD_BLT_ROP = 0xC; LCD_BLT_BKCOLOR = 0; LCD_IDLE(); } void epsgfx_outputchar(char c, uint16_t x, uint16_t y) { char buf[2] = " "; buf[0] = c; epsgfx_outputtext(buf, x, y); } /** * Высота шрифта * * @return Возвращает высоту текущего шрифта */ uint16_t epsgfx_gettextheight(void) { return current_font->height; } /** * Ширина символа * * @param c Символ, ширину которго необходимо найти * @return Возвращает ширину символа в пикселях */ uint16_t epsgfx_getcharwidth(char c) { return current_font->table[c - current_font->first].width; } /** * Ширина текста * * @param str Текст * @return Ширина текста в пикселях */ uint16_t epsgfx_gettextwidth(const char* str) { uint16_t i, len=0, imax = strlen(str); /* подсчитываем общую длину букв */ for (i = 0; i < imax; i++) { len += current_font->table[str[i] - current_font->first].width; } return len; } /** * Выбор текущей страницы видеопамяти * * @param layer номер слоя (1 или 0) */ void epsgfx_selectlayer(uint8_t layer) { VideoPage = layer << 17; } /** * Копирование прямоугольника из одного слоя в другой. Копируется * всё, что оказалось в выбранном прямоугольнике, включая цвет фона. * * @param srclayer Слой, с которого происходит копирование * @param left Координата x левой стороны прямоугольника на исходном слое * @param top Координата y верхней стороны прямоугольника на исходном слое * @param right Координата x правой стороны прямоугольника на исходном слое * @param bottom Координата y нижней стороны прямоугольника на исходном слое * @param dstlayer Слой, на который происходит копирование * @param dst_left Координата x левой стороны прямоугольника на целевом слое * @param dst_top Координата y верхней стороны прямоугольника на целевом слое */ void epsgfx_copyrect(uint8_t srclayer, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom, uint8_t dstlayer, uint16_t dst_left, uint16_t dst_top) { uint32_t dst, src; /* Wait for the previous BitBLT operation to finish */ while ( LCD_BLT_STATUS & 1 ) {} /* куда */ dst = SCREEN_W * dst_top + dst_left; if (dstlayer == 1) { dst |= 1 << 17; } LCD_BLT_DST0 = (uint16_t)dst; LCD_BLT_DST1 = (uint16_t)(dst >> 16); /* откуда */ src = SCREEN_W * top + left; if (srclayer == 1) { src |= 1 << 17; } LCD_BLT_SRC0 = (uint16_t)src; LCD_BLT_SRC1 = (uint16_t)(src >> 16); /* Program the BitBLT Width Register */ LCD_BLT_WIDTH = right - left; /* Program the BitBLT Height Register */ LCD_BLT_HEIGHT = bottom - top; /* Program the BitBLT Command Register */ LCD_BLT_COMMAND = 2; /* Start */ LCD_BLT_CONTROL = 1; LCD_IDLE(); } /** * Инициализация функции картинка в картинке * * @param left Левая граница картинки * @param top Верхняя граница картинки * @param right Правая граница картинки * @param bottom Нижняя граница картинки */ void epsgfx_initlayer1(uint16_t left, uint16_t top, uint16_t right, uint16_t bottom) { LCD_PIP_START0 = (top * SCREEN_W + left) / 4 + 0x8000; LCD_PIP_XSTART = left / 4; LCD_PIP_XEND = right / 4; LCD_PIP_YSTART = top; LCD_PIP_YEND = bottom - 1; LCD_IDLE(); } /** * Разрешение отображения второго слоя * * @param enable разрешение отображения */ void epsgfx_enablelayer1(bool enable) { if (enable == true) { LCD_SET1 |= 1 << 3; /* Attempt to defeat bug: layer 1 doesn't come up sometimes */ LCD_SET1 |= 1 << 3; } else { LCD_SET1 &= ~(1 << 3); } LCD_IDLE(); } /** * Инициализация шаг 0 * После этого шага требуется пауза 40 мс затем шаг 1 (epsgfx_init1(void)) */ void epsgfx_init0(void) { IOPORT_PC2(2) |= (1 << 1);/* Configure CS1 as alternate function pin */ BCON(1) = 0x8000 | /* Enable bank 1 */ (15 << 2) | /* 15 wait states */ 0x0001; /* 16-bit bus */ LCD_IDLE(); LCD_GPO |= 8; LCD_IDLE(); } /** * Инициализация шаг 1 * После этого шага требуется пауза 40 мс затем включение дисплея (epsgfx_dispon()) */ void epsgfx_init1(void) { /* Memory clock configuration register kept in reset state: MCLK=BCLK, BCLK=CLKI */ LCD_PCLK = (3 << 4) | /* PCLK=ref/4 */ (2); /* PCLK ref=CLKI */ LCD_PANEL0 = (0 << 8) | /* HR-TFT PS mode: N.A. */ (0 << 7) | /* Panel data format: N.A. */ (1 << 6) | /* Color LCD */ (2 << 4) | /* Panel data width = 18 bits */ (1); /* Panel type = TFT */ LCD_SET0 = (8); /* Bits per pixel = 8 */ LCD_HT = 528 / 8 - 1; /* Horizontal total = 528 */ LCD_HDP = SCREEN_W / 8 - 1; /* Horizontal display period = 480 */ LCD_HDPS = 44 - 5; /* Horizontal display period start = 44 */ LCD_FPLINE1 = (0 << 7) | /* FPLINE pulse polarity = active low */ (41 - 1); /* FPLINE pulse width = 41 */ LCD_VT = 286 - 1; /* Vertical total = 286 */ LCD_VDP = SCREEN_H - 1; /* Vertical display period = 272 */ LCD_VDPS = 10; /* Vertical display period start = 10 */ LCD_FPFRAME1 = (0 << 7) | /* FPFRAME pulse polarity = active low */ (8 - 1); /* FPFRAME pulse width = 8 */ LCD_LAOFF = SCREEN_W / (32 / 8); /* Main window line address offset */ LCD_BLT_OFFSET = SCREEN_W / 2; /* Set BitBLT memory offset in advance */ LCD_BLT_ROP = 0x0C; /* Set BitBLT ROP code to COPY in advance */ LCD_PIP_LAOFF = SCREEN_W / (32 / 8); /* Set PIP line address offset in advance */ LCD_PWM_CTRL = 0xA1; /* PWM ~150 Hz for brightness control */ LCD_IDLE(); epsgfx_fillrect(0, 0, SCREEN_W, SCREEN_H, 0); epsgfx_selectlayer(1); epsgfx_fillrect(0, 0, SCREEN_W, SCREEN_H, 0); epsgfx_selectlayer(0); LCD_GPO |= 0x2; /* Set U/D */ LCD_IDLE(); LCD_PSAVE = 0; } /** * Включение подсветки * * @param enable true чтобы включить, false чтобы выключить */ extern void epsgfx_backlight(bool enable) { if (enable == true) { LCD_GPO |= 4; } else { LCD_GPO &= ~4; /*Set to 0 4th bit GPO*/ } LCD_IDLE(); } /** * Регулировка яркости подсветки * @param brightness Яркость (от 0 - 255) */ void epsgfx_brightness(uint16_t brightness) { LCD_PWM_DUTY = brightness; LCD_IDLE(); } /** * Включение дисплея * После включения дисплея требуется пауза ~140мс, * только затем можно включить подсветку */ void epsgfx_dispon(void) { LCD_GPO |= 1; LCD_IDLE(); } /** * Вывод многоцветного рисунка (256 цветов) * * @param bitmap Выводимая картинка * @param x Горизонтальная координата правого верхнего края картинки * @param y Вертикальная координата правого верхнего края картинки */ void epsgfx_show_bitmap8bpp(const epsgfx_bitmap8bpp* bitmap, uint16_t x, uint16_t y) { uint16_t i; const uint8_t *ptr; ptr = bitmap->bitmap; for (i=0; i < bitmap->height; i++) { uint16_t j; for (j=0; j < bitmap->width; j++) { epsgfx_putpixel(x + j, y + i, *ptr); ptr++; } } } /** * Ускоренный вывод монохромного рисунка * * @param bitmap Выводимая картинка * @param x Горизонтальная координата правого верхнего края картинки * @param y Вертикальная координата правого верхнего края картинки * @param fg Цвет картинки * @param bg Цвет фона * @param trsp Прозрачность фона, если = true, цвет фона игнорируется */ void epsgfx_show_bitmap1bpp(const epsgfx_bitmap1bpp* bitmap, uint16_t x, uint16_t y, uint8_t fg, uint8_t bg, bool trsp) { uint32_t dstAddr; uint16_t i = 0; uint16_t numwords; /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1){} /* Program the BLT registers */ /* начинаем с младшего бита младшего байта */ LCD_BLT_ROP = 7; LCD_BLT_SRC0 = 0; /* Program the BitBLT Height Register */ LCD_BLT_HEIGHT = bitmap->height - 1; /* Program the BitBLT Width Register */ LCD_BLT_WIDTH = bitmap->width - 1; /* Program the BitBLT Foreground Color Register */ LCD_BLT_COLOR = fg; /* Program the BitBLT Background Color Register */ LCD_BLT_BKCOLOR = bg; /* Program the BitBLT Command Regoster */ LCD_BLT_COMMAND = 8 + (uint8_t)trsp; /* 9 - transparency */ dstAddr = VideoPage + (uint32_t)(x * BYTESPERPIXEL) + (uint32_t)(y * SCREEN_W * BYTESPERPIXEL); /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1) {} LCD_BLT_DST0 = (uint16_t)dstAddr; LCD_BLT_DST1 = (uint16_t)(dstAddr >> 16); /* Start the BitBLT operation */ LCD_BLT_CONTROL = 1; numwords = (bitmap->width + 15) / 16 * bitmap->height; for (i = 0; i < numwords; i++) { LCD_BLT_FIFO = bitmap->bitmap[i]; } /* Wait for the previous BitBLT operation to finish */ while (LCD_BLT_STATUS & 1){} LCD_BLT_ROP = 0xC; LCD_BLT_BKCOLOR = 0; LCD_IDLE(); }
ส็็็็็็็็็็็็็็็็็็็็็็็็็༼ ຈل͜ຈ༽ส้้้้้้้้้้้้้้้้้้้้้้้