#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
// *** Биты контроллера FMC ***
// Программирование контроллера
#define FMC_ColumnBits_Number_8b ((uint32_t)0x00000000)
#define FMC_ColumnBits_Number_9b ((uint32_t)0x00000001)
#define FMC_ColumnBits_Number_10b ((uint32_t)0x00000002)
#define FMC_ColumnBits_Number_11b ((uint32_t)0x00000003)
#define FMC_RowBits_Number_11b ((uint32_t)0x00000000)
#define FMC_RowBits_Number_12b ((uint32_t)0x00000004)
#define FMC_RowBits_Number_13b ((uint32_t)0x00000008)
#define FMC_NORSRAM_MemoryDataWidth_8b ((uint32_t)0x00000000)
#define FMC_NORSRAM_MemoryDataWidth_16b ((uint32_t)0x00000010)
#define FMC_NORSRAM_MemoryDataWidth_32b ((uint32_t)0x00000020)
#define FMC_InternalBank_Number_2 ((uint32_t)0x00000000)
#define FMC_InternalBank_Number_4 ((uint32_t)0x00000040)
#define FMC_CAS_Latency_1 ((uint32_t)0x00000080)
#define FMC_CAS_Latency_2 ((uint32_t)0x00000100)
#define FMC_CAS_Latency_3 ((uint32_t)0x00000180)
#define FMC_Write_Protection_Disable ((uint32_t)0x00000000)
#define FMC_Write_Protection_Enable ((uint32_t)0x00000200)
#define FMC_SDClock_Disable ((uint32_t)0x00000000)
#define FMC_SDClock_Period_2 ((uint32_t)0x00000800)
#define FMC_SDClock_Period_3 ((uint32_t)0x00000C00)
#define FMC_Read_Burst_Disable ((uint32_t)0x00000000)
#define FMC_Read_Burst_Enable ((uint32_t)0x00001000)
#define FMC_ReadPipe_Delay_0 ((uint32_t)0x00000000)
#define FMC_ReadPipe_Delay_1 ((uint32_t)0x00002000)
#define FMC_ReadPipe_Delay_2 ((uint32_t)0x00004000)
// Комманды контроллера
#define FMC_Command_Mode_normal ((uint32_t)0x00000000)
#define FMC_Command_Mode_CLK_Enabled ((uint32_t)0x00000001)
#define FMC_Command_Mode_PALL ((uint32_t)0x00000002)
#define FMC_Command_Mode_AutoRefresh ((uint32_t)0x00000003)
#define FMC_Command_Mode_LoadMode ((uint32_t)0x00000004)
#define FMC_Command_Mode_Selfrefresh ((uint32_t)0x00000005)
#define FMC_Command_Mode_PowerDown ((uint32_t)0x00000006)
#define FMC_Command_Target_bank2 ((uint32_t)0x00000008)
#define FMC_Command_Target_bank1 ((uint32_t)0x00000010)
#define FMC_Command_Target_bank1_2 ((uint32_t)0x00000018)
// управление памятью
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAM ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
// Инициализация ОЗУ на плате.
void draminit(void)
{
uint32_t tmp = 0;
uint32_t timeout = SDRAM_TIMEOUT;
// Инициализация пинов памяти
PINSDRAM_INIT;
// FMC SDRAM последовательность инициализации устройства
// Шаг 1
// Строки: [9:0]
tmp |= FMC_ColumnBits_Number_9b;
// Столбцы: [13:0]
tmp |= FMC_RowBits_Number_13b;
tmp |= FMC_NORSRAM_MemoryDataWidth_16b;
tmp |= FMC_InternalBank_Number_4;
// CL: Cas Latency = 3 цикла
tmp |= FMC_CAS_Latency_3;
tmp |= FMC_Write_Protection_Disable;
tmp |= FMC_SDClock_Period_2;
tmp |= FMC_Read_Burst_Enable;
tmp |= FMC_ReadPipe_Delay_1;
// FMC SDRAM bank initialization
// FMC SDRAM control configuration. Банк 1.
FMC_Bank5_6->SDCR[0] = tmp;
// Шаг 2
// Тайминги для 90 Mhz на SD. Частота (180Mhz/2)
// TMRD: 2 цикла ожидания
tmp = 2-1;
// TXSR: min=70ns (7x11.11ns)
tmp |= (7-1)<<4;
// TRAS: min=42ns (4x11.11ns) max=120k (ns)
tmp |= (4-1)<<8;
// TRC: min=70 (7x11.11ns)
tmp |= (7-1)<<12;
// TWR: min=1+ 7ns (1+1x11.11ns)
tmp |= (2-1)<<16;
// TRP: 20ns => 2x11.11ns
tmp |= (2-1)<<20;
// TRCD: 20ns => 2x11.11ns
tmp |= (2-1)<<24;
// FMC SDRAM тайминги. Банк 1.
FMC_Bank5_6->SDTR[0] = tmp;
// Шаг 3
// Разрешение команд
tmp = FMC_Command_Mode_CLK_Enabled;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (1-1)<<5;
// FMC_ModeRegisterDefinition
tmp |= 0<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;
// Шаг 4
// Задержка 100мс
hDelay(100);
// Шаг 5
// Сконфигурировать PALL (precharge all)
tmp = FMC_Command_Mode_PALL;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (1-1)<<5;
// FMC_ModeRegisterDefinition
tmp |= 0<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;
// Шаг 6
// Сконфигурировать Auto-Refresh
tmp = FMC_Command_Mode_AutoRefresh;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (8-1)<<5;
// FMC_ModeRegisterDefinition
tmp |= 0<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;
// Шаг 7
// Сконфигурировать load Mode регистр
tmp = FMC_Command_Mode_LoadMode;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (8-1)<<5;
// FMC_ModeRegisterDefinition
// Запрограммировать mode register внешней памяти
tmp |= ((uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_3 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE)<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;
// Шаг 8
// Установить счётчик регенерации памяти
// (7.81 us x Freq) - 20
FMC_Bank5_6->SDRTR |= (683<<1);
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
}
/************************************************************************
* LTCD + DMA2D *
************************************************************************/
// Alias word address of PLLSAION bit
#define RCC_OFFSET (RCC_BASE - PERIPH_BASE)
#define CR_OFFSET (RCC_OFFSET + 0x00)
#define PLLSAION_BITNUMBER 0x1C
//#define CR_PLLSAION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLSAION_BITNUMBER * 4))
#define RCC_FLAG_PLLSAIRDY 0x1D
#define GCR_MASK ((uint32_t)0x0FFE888F) // LTDC GCR Mask
#define LTDC_HSPOLARITY_AL ((uint32_t)0x00000000) // Horizontal Synchronization is active low.
#define LTDC_HSPOLARITY_AH LTDC_GCR_HSPOL // Horizontal Synchronization is active high.
#define LTDC_VSPOLARITY_AL ((uint32_t)0x00000000) // Vertical Synchronization is active low.
#define LTDC_VSPOLARITY_AH LTDC_GCR_VSPOL // Vertical Synchronization is active high.
#define LTDC_DEPOLARITY_AL ((uint32_t)0x00000000) // Data Enable, is active low.
#define LTDC_DEPOLARITY_AH LTDC_GCR_DEPOL // Data Enable, is active high.
#define LTDC_PCPOLARITY_IPC ((uint32_t)0x00000000) // input pixel clock.
#define LTDC_PCPOLARITY_IIPC LTDC_GCR_PCPOL // inverted input pixel clock.
#define LTDC_PIXELFORMAT_RGB565 ((uint32_t)0x00000002)
#define LTDC_BLENDINGFACTOR1_CA ((uint32_t)0x00000400)
#define LTDC_BLENDINGFACTOR1_PAXCA ((uint32_t)0x00000600)
#define LTDC_BLENDINGFACTOR2_CA ((uint32_t)0x00000005)
#define LTDC_BLENDINGFACTOR2_PAXCA ((uint32_t)0x00000007)
#define LTDC_IMRELOAD LTDC_SRCR_IMR // Immediately Reload.
#define LTDC_VBRELOAD LTDC_SRCR_VBR // Vertical Blanking Reload.
// ChromART
// @defgroup DMA2D_Input_Color_Mode DMA2D Input Color Mode
#define CM_ARGB8888 ((uint32_t)0x00000000U) // ARGB8888 color mode
#define CM_RGB888 ((uint32_t)0x00000001U) // RGB888 color mode
#define CM_RGB565 ((uint32_t)0x00000002U) // RGB565 color mode
#define CM_ARGB1555 ((uint32_t)0x00000003U) // ARGB1555 color mode
#define CM_ARGB4444 ((uint32_t)0x00000004U) // ARGB4444 color mode
#define CM_L8 ((uint32_t)0x00000005U) // L8 color mode
#define CM_AL44 ((uint32_t)0x00000006U) // AL44 color mode
#define CM_AL88 ((uint32_t)0x00000007U) // AL88 color mode
#define CM_L4 ((uint32_t)0x00000008U) // L4 color mode
#define CM_A8 ((uint32_t)0x00000009U) // A8 color mode
#define CM_A4 ((uint32_t)0x0000000AU) // A4 color mode
#define DMA2D_ARGB8888 ((uint32_t)0x00000000U) // ARGB8888 DMA2D color mode
#define DMA2D_RGB888 ((uint32_t)0x00000001U) // RGB888 DMA2D color mode
#define DMA2D_RGB565 ((uint32_t)0x00000002U) // RGB565 DMA2D color mode
#define DMA2D_ARGB1555 ((uint32_t)0x00000003U) // ARGB1555 DMA2D color mode
#define DMA2D_ARGB4444 ((uint32_t)0x00000004U) // ARGB4444 DMA2D color mode
// Инициализация LCD
void drvTFTinit(void)
{
uint32_t tmpreg;
// 480X272
// Разрешить Pixel Clock
// Конфигурируем PLLSAI предделитель для LCD
// PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz
// PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAI_N = 192 Mhz
// PLLLCDCLK = PLLSAI_VCO Output/PLLSAI_R = 192/3 = 64 Mhz
RCC->PLLSAICFGR = (192 << 6) | (7 << 24) | (3 << 28);
// LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = 64/8 = 8 Mhz
tmpreg = RCC->DCKCFGR;
tmpreg &= ~RCC_DCKCFGR_PLLSAIDIVR; // Очистить биты PLLSAIDIVR[2:0]
tmpreg |= RCC_DCKCFGR_SAI1ASRC_1; // Установить значение PLLSAIDIVR 2 (поделить на 8)
RCC->DCKCFGR = tmpreg; // Сохранить
*(__IO uint32_t *) CR_PLLSAION_BB = (uint32_t)1; // Разрешить PLLSAI тактирование
// Ждать запуска PLLSAI
while((RCC->CR & (1<<RCC_FLAG_PLLSAIRDY)) == 0)
{
}
// Включить тактирование LTDC
__LTDC_CLK_ENABLE();
// Настроить пины LCD
PINLCD_INIT;
// ***** Инициализация LTDC *****
// *** Тайминги ***
// горизонтальная синхронизация ширина = Hsync - 1 (41)
LTDC->SSCR &= ~(LTDC_SSCR_VSH | LTDC_SSCR_HSW);
tmpreg = (40 << 16);
// вертикальная синхронизация высота = Vsync - 1 (10)
LTDC->SSCR |= (tmpreg | 9);
// горизонтальная ширина с полочкой = Hsync + HBP - 1
LTDC->BPCR &= ~(LTDC_BPCR_AVBP | LTDC_BPCR_AHBP);
tmpreg = (42 << 16);
// вертикальная высота с полочкой = Vsync + HBP - 1
LTDC->BPCR |= (tmpreg | 11);
// активная ширина = Hsync + HBP + Active Width - 1
LTDC->AWCR &= ~(LTDC_AWCR_AAH | LTDC_AWCR_AAW);
tmpreg = (522 << 16);
// активная высота = Vsync + VBP + Active Heigh - 1
LTDC->AWCR |= (tmpreg | 283);
// полная ширина = Hsync + HBP + Active Width + HFP - 1
LTDC->TWCR &= ~(LTDC_TWCR_TOTALH | LTDC_TWCR_TOTALW);
tmpreg = (524 << 16);
// полная высота = Vsync + VBP + Active Heigh + VFP - 1
LTDC->TWCR |= (tmpreg | 285);
// *** Полярность ***
// Полярность горизонтальной синхронизации = активный 0
// Полярность вертикальной синхронизации = активный 0
// Полярность "data enable" = активный 0
// Полярность "pixel clock" без инверсии
LTDC->GCR &= (uint32_t)GCR_MASK;
LTDC->GCR |= (uint32_t)(LTDC_HSPOLARITY_AL | LTDC_VSPOLARITY_AL | LTDC_DEPOLARITY_AL | LTDC_PCPOLARITY_IPC);
// R,G,B фона
//LTDC->BCCR &= ~(LTDC_BCCR_BCBLUE | LTDC_BCCR_BCGREEN | LTDC_BCCR_BCRED);
//LTDC->BCCR |= BACKGROUNDCOLOR;
LTDC->BCCR = BACKGROUNDCOLOR;
// *** Завершение инициализации LTDC ***
// *** инициализация слоя 1 ***
// Если вся область активного дисплея используется для отображения изображения, то:
// Horizontal start = horizontal synchronization + Horizontal back porch = 43
// Vertical start = vertical synchronization + vertical back porch = 12
// Horizontal stop = Horizontal start + window width -1 = 43 + 480 -1
// Vertical stop = Vertical start + window height -1 = 12 + 272 -1
//LTDC_Layer1->WHPCR &= ~(LTDC_LxWHPCR_WHSTPOS | LTDC_LxWHPCR_WHSPPOS);
tmpreg = (480 + 43 - 1) << 16; // Horizontal stop
LTDC_Layer1->WHPCR = (43 | tmpreg); // Horizontal start
//LTDC_Layer1->WVPCR &= ~(LTDC_LxWVPCR_WVSTPOS | LTDC_LxWVPCR_WVSPPOS);
tmpreg = (272 + 12 - 1) << 16; // Vertical stop
LTDC_Layer1->WVPCR = (12 | tmpreg); // Vertical start
// Формат пикселя
//LTDC_Layer1->PFCR &= ~(LTDC_LxPFCR_PF);
LTDC_Layer1->PFCR = LTDC_PIXELFORMAT_RGB565;
// Alpha constant (255 totally opaque)
//LTDC_Layer1->CACR &= ~(LTDC_LxCACR_CONSTA);
LTDC_Layer1->CACR = 255;
// Цвет по умолчанию
LTDC_Layer1->DCCR = 0;
// Блэндинг факторы
LTDC_Layer1->BFCR = (LTDC_BLENDINGFACTOR1_CA | LTDC_BLENDINGFACTOR2_CA);
// Стартовый адресс
LTDC_Layer1->CFBAR = VIDEOBUF_L1ADR;
// Длина одной строки пикселей в байтах + 3:
// Длина строки = Ширина x число байт на пиксель + 3
// Ширина = 480
// число байт на пиксель = 2 (формат пикселя : RGB565)
tmpreg = ((480 * 2) + 3);
// Смещение между 2 строками
LTDC_Layer1->CFBLR = ((480 * 2)<<16) | tmpreg;
// Число строк
LTDC_Layer1->CFBLNR = 272;
// Разрешить работу слоя 1
LTDC_Layer1->CR |= (uint32_t)LTDC_LxCR_LEN;
// Перегрузить конфигурацию слоя 1
LTDC->SRCR = (uint32_t)LTDC_IMRELOAD;
// Запустить LCD
LTDC->GCR |= (uint32_t)LTDC_GCR_LTDCEN;
// Запустить ChromART
__DMA2D_CLK_ENABLE();
}
// Распаковать картинку A4 на экран
void copyA4toTFT(void *pSrc, void *pDst, uint16_t xSize, uint16_t ySize)
{
DMA2D->CR = 0x00010000UL | (1 << 9); // Control Register (Memory to memory with pixel format conversion and TCIE)
// Указатели
DMA2D->FGMAR = (uint32_t)pSrc; // Foreground Memory Address Register (Source address)
DMA2D->OMAR = (uint32_t)pDst; // Output Memory Address Register (Destination address)
// Смещения
DMA2D->FGOR = xSize; // Foreground Offset Register (Source line offset)
DMA2D->OOR = _layerX-1; // Output Offset Register (Destination line offset)
// Входной и выходной Форматы пикселя
DMA2D->FGPFCCR = CM_A4; // Foreground PFC Control Register (Defines the input pixel format)
DMA2D->OPFCCR = DMA2D_RGB565; // Output PFC Control Register (Defines the output pixel format)
// Установить цвет
DMA2D->FGCOLR = _fcolor; // Foreground PFC Control Register (Defines the input pixel format)
// Установить размер
DMA2D->NLR = (uint32_t)(xSize << 16) | ySize; // Number of Line Register (Size configuration of area to be transfered)
// Выполнить
DMA2D->CR |= DMA2D_CR_START;
while (DMA2D->CR & DMA2D_CR_START)
{
}
}
// Скопировать картинку С16 на экран
void copyC16(void *pSrc, void *pDst, uint16_t xSize, uint16_t ySize, uint16_t xSizeSrc, uint16_t xSizeDst)
{
DMA2D->CR = (1 << 9); // без модификации
// Указатели
DMA2D->FGMAR = (uint32_t)pSrc; // Foreground Memory Address Register (Source address)
DMA2D->OMAR = (uint32_t)pDst; // Output Memory Address Register (Destination address)
// Смещения
DMA2D->FGOR = xSizeSrc; // Foreground Offset Register (Source line offset)
DMA2D->OOR = xSizeDst; // Output Offset Register (Destination line offset)
// Входной и выходной Форматы пикселя
DMA2D->FGPFCCR = CM_RGB565; // Foreground PFC Control Register (Defines the input pixel format)
DMA2D->OPFCCR = DMA2D_RGB565; // Output PFC Control Register (Defines the output pixel format)
// Установить размер
DMA2D->NLR = (uint32_t)(xSize << 16) | ySize; // Number of Line Register (Size configuration of area to be transfered)
// Выполнить
DMA2D->CR |= DMA2D_CR_START;
while (DMA2D->CR & DMA2D_CR_START)
{
}
}
// Залить прямоугольник на экране
void FillRectTFT(void *pSrc, uint16_t xSize, uint16_t ySize)
{
// Set up mode
DMA2D->CR = 0x00030000UL | (1 << 9);
DMA2D->OCOLR = _color;
// Set up pointers
DMA2D->OMAR = (uint32_t)pSrc;
// Set up offsets
DMA2D->OOR = _layerX-1;
// Set up pixel format
DMA2D->OPFCCR = DMA2D_RGB565;
// Set up size
DMA2D->NLR = (uint32_t)(xSize << 16) | (uint16_t)ySize;
DMA2D->CR |= DMA2D_CR_START;
// Wait until transfer is done
while (DMA2D->CR & DMA2D_CR_START)
{
}
}
// *** Биты контроллера FMC ***
// Программирование контроллера
#define FMC_ColumnBits_Number_8b ((uint32_t)0x00000000)
#define FMC_ColumnBits_Number_9b ((uint32_t)0x00000001)
#define FMC_ColumnBits_Number_10b ((uint32_t)0x00000002)
#define FMC_ColumnBits_Number_11b ((uint32_t)0x00000003)
#define FMC_RowBits_Number_11b ((uint32_t)0x00000000)
#define FMC_RowBits_Number_12b ((uint32_t)0x00000004)
#define FMC_RowBits_Number_13b ((uint32_t)0x00000008)
#define FMC_NORSRAM_MemoryDataWidth_8b ((uint32_t)0x00000000)
#define FMC_NORSRAM_MemoryDataWidth_16b ((uint32_t)0x00000010)
#define FMC_NORSRAM_MemoryDataWidth_32b ((uint32_t)0x00000020)
#define FMC_InternalBank_Number_2 ((uint32_t)0x00000000)
#define FMC_InternalBank_Number_4 ((uint32_t)0x00000040)
#define FMC_CAS_Latency_1 ((uint32_t)0x00000080)
#define FMC_CAS_Latency_2 ((uint32_t)0x00000100)
#define FMC_CAS_Latency_3 ((uint32_t)0x00000180)
#define FMC_Write_Protection_Disable ((uint32_t)0x00000000)
#define FMC_Write_Protection_Enable ((uint32_t)0x00000200)
#define FMC_SDClock_Disable ((uint32_t)0x00000000)
#define FMC_SDClock_Period_2 ((uint32_t)0x00000800)
#define FMC_SDClock_Period_3 ((uint32_t)0x00000C00)
#define FMC_Read_Burst_Disable ((uint32_t)0x00000000)
#define FMC_Read_Burst_Enable ((uint32_t)0x00001000)
#define FMC_ReadPipe_Delay_0 ((uint32_t)0x00000000)
#define FMC_ReadPipe_Delay_1 ((uint32_t)0x00002000)
#define FMC_ReadPipe_Delay_2 ((uint32_t)0x00004000)
// Комманды контроллера
#define FMC_Command_Mode_normal ((uint32_t)0x00000000)
#define FMC_Command_Mode_CLK_Enabled ((uint32_t)0x00000001)
#define FMC_Command_Mode_PALL ((uint32_t)0x00000002)
#define FMC_Command_Mode_AutoRefresh ((uint32_t)0x00000003)
#define FMC_Command_Mode_LoadMode ((uint32_t)0x00000004)
#define FMC_Command_Mode_Selfrefresh ((uint32_t)0x00000005)
#define FMC_Command_Mode_PowerDown ((uint32_t)0x00000006)
#define FMC_Command_Target_bank2 ((uint32_t)0x00000008)
#define FMC_Command_Target_bank1 ((uint32_t)0x00000010)
#define FMC_Command_Target_bank1_2 ((uint32_t)0x00000018)
// управление памятью
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAM ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
// Инициализация ОЗУ на плате.
void draminit(void)
{
uint32_t tmp = 0;
uint32_t timeout = SDRAM_TIMEOUT;
// Инициализация пинов памяти
PINSDRAM_INIT;
// FMC SDRAM последовательность инициализации устройства
// Шаг 1
// Строки: [9:0]
tmp |= FMC_ColumnBits_Number_9b;
// Столбцы: [13:0]
tmp |= FMC_RowBits_Number_13b;
tmp |= FMC_NORSRAM_MemoryDataWidth_16b;
tmp |= FMC_InternalBank_Number_4;
// CL: Cas Latency = 3 цикла
tmp |= FMC_CAS_Latency_3;
tmp |= FMC_Write_Protection_Disable;
tmp |= FMC_SDClock_Period_2;
tmp |= FMC_Read_Burst_Enable;
tmp |= FMC_ReadPipe_Delay_1;
// FMC SDRAM bank initialization
// FMC SDRAM control configuration. Банк 1.
FMC_Bank5_6->SDCR[0] = tmp;
// Шаг 2
// Тайминги для 90 Mhz на SD. Частота (180Mhz/2)
// TMRD: 2 цикла ожидания
tmp = 2-1;
// TXSR: min=70ns (7x11.11ns)
tmp |= (7-1)<<4;
// TRAS: min=42ns (4x11.11ns) max=120k (ns)
tmp |= (4-1)<<8;
// TRC: min=70 (7x11.11ns)
tmp |= (7-1)<<12;
// TWR: min=1+ 7ns (1+1x11.11ns)
tmp |= (2-1)<<16;
// TRP: 20ns => 2x11.11ns
tmp |= (2-1)<<20;
// TRCD: 20ns => 2x11.11ns
tmp |= (2-1)<<24;
// FMC SDRAM тайминги. Банк 1.
FMC_Bank5_6->SDTR[0] = tmp;
// Шаг 3
// Разрешение команд
tmp = FMC_Command_Mode_CLK_Enabled;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (1-1)<<5;
// FMC_ModeRegisterDefinition
tmp |= 0<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;
// Шаг 4
// Задержка 100мс
hDelay(100);
// Шаг 5
// Сконфигурировать PALL (precharge all)
tmp = FMC_Command_Mode_PALL;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (1-1)<<5;
// FMC_ModeRegisterDefinition
tmp |= 0<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;
// Шаг 6
// Сконфигурировать Auto-Refresh
tmp = FMC_Command_Mode_AutoRefresh;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (8-1)<<5;
// FMC_ModeRegisterDefinition
tmp |= 0<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;
// Шаг 7
// Сконфигурировать load Mode регистр
tmp = FMC_Command_Mode_LoadMode;
tmp |= FMC_Command_Target_bank1;
// FMC_AutoRefreshNumber
tmp |= (8-1)<<5;
// FMC_ModeRegisterDefinition
// Запрограммировать mode register внешней памяти
tmp |= ((uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_3 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE)<<9;
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
// Послать комманду
FMC_Bank5_6->SDCMR = tmp;
// Шаг 8
// Установить счётчик регенерации памяти
// (7.81 us x Freq) - 20
FMC_Bank5_6->SDRTR |= (683<<1);
// ждать пока SDRAM контроллер будет готов
timeout = SDRAM_TIMEOUT;
while((FMC_Bank5_6->SDSR & FMC_SDSR_BUSY) && (timeout > 0))
{
timeout--;
}
}
/************************************************************************
* LTCD + DMA2D *
************************************************************************/
// Alias word address of PLLSAION bit
#define RCC_OFFSET (RCC_BASE - PERIPH_BASE)
#define CR_OFFSET (RCC_OFFSET + 0x00)
#define PLLSAION_BITNUMBER 0x1C
//#define CR_PLLSAION_BB (PERIPH_BB_BASE + (CR_OFFSET * 32) + (PLLSAION_BITNUMBER * 4))
#define RCC_FLAG_PLLSAIRDY 0x1D
#define GCR_MASK ((uint32_t)0x0FFE888F) // LTDC GCR Mask
#define LTDC_HSPOLARITY_AL ((uint32_t)0x00000000) // Horizontal Synchronization is active low.
#define LTDC_HSPOLARITY_AH LTDC_GCR_HSPOL // Horizontal Synchronization is active high.
#define LTDC_VSPOLARITY_AL ((uint32_t)0x00000000) // Vertical Synchronization is active low.
#define LTDC_VSPOLARITY_AH LTDC_GCR_VSPOL // Vertical Synchronization is active high.
#define LTDC_DEPOLARITY_AL ((uint32_t)0x00000000) // Data Enable, is active low.
#define LTDC_DEPOLARITY_AH LTDC_GCR_DEPOL // Data Enable, is active high.
#define LTDC_PCPOLARITY_IPC ((uint32_t)0x00000000) // input pixel clock.
#define LTDC_PCPOLARITY_IIPC LTDC_GCR_PCPOL // inverted input pixel clock.
#define LTDC_PIXELFORMAT_RGB565 ((uint32_t)0x00000002)
#define LTDC_BLENDINGFACTOR1_CA ((uint32_t)0x00000400)
#define LTDC_BLENDINGFACTOR1_PAXCA ((uint32_t)0x00000600)
#define LTDC_BLENDINGFACTOR2_CA ((uint32_t)0x00000005)
#define LTDC_BLENDINGFACTOR2_PAXCA ((uint32_t)0x00000007)
#define LTDC_IMRELOAD LTDC_SRCR_IMR // Immediately Reload.
#define LTDC_VBRELOAD LTDC_SRCR_VBR // Vertical Blanking Reload.
// ChromART
// @defgroup DMA2D_Input_Color_Mode DMA2D Input Color Mode
#define CM_ARGB8888 ((uint32_t)0x00000000U) // ARGB8888 color mode
#define CM_RGB888 ((uint32_t)0x00000001U) // RGB888 color mode
#define CM_RGB565 ((uint32_t)0x00000002U) // RGB565 color mode
#define CM_ARGB1555 ((uint32_t)0x00000003U) // ARGB1555 color mode
#define CM_ARGB4444 ((uint32_t)0x00000004U) // ARGB4444 color mode
#define CM_L8 ((uint32_t)0x00000005U) // L8 color mode
#define CM_AL44 ((uint32_t)0x00000006U) // AL44 color mode
#define CM_AL88 ((uint32_t)0x00000007U) // AL88 color mode
#define CM_L4 ((uint32_t)0x00000008U) // L4 color mode
#define CM_A8 ((uint32_t)0x00000009U) // A8 color mode
#define CM_A4 ((uint32_t)0x0000000AU) // A4 color mode
#define DMA2D_ARGB8888 ((uint32_t)0x00000000U) // ARGB8888 DMA2D color mode
#define DMA2D_RGB888 ((uint32_t)0x00000001U) // RGB888 DMA2D color mode
#define DMA2D_RGB565 ((uint32_t)0x00000002U) // RGB565 DMA2D color mode
#define DMA2D_ARGB1555 ((uint32_t)0x00000003U) // ARGB1555 DMA2D color mode
#define DMA2D_ARGB4444 ((uint32_t)0x00000004U) // ARGB4444 DMA2D color mode
// Инициализация LCD
void drvTFTinit(void)
{
uint32_t tmpreg;
// 480X272
// Разрешить Pixel Clock
// Конфигурируем PLLSAI предделитель для LCD
// PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz
// PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAI_N = 192 Mhz
// PLLLCDCLK = PLLSAI_VCO Output/PLLSAI_R = 192/3 = 64 Mhz
RCC->PLLSAICFGR = (192 << 6) | (7 << 24) | (3 << 28);
// LTDC clock frequency = PLLLCDCLK / RCC_PLLSAIDivR = 64/8 = 8 Mhz
tmpreg = RCC->DCKCFGR;
tmpreg &= ~RCC_DCKCFGR_PLLSAIDIVR; // Очистить биты PLLSAIDIVR[2:0]
tmpreg |= RCC_DCKCFGR_SAI1ASRC_1; // Установить значение PLLSAIDIVR 2 (поделить на 8)
RCC->DCKCFGR = tmpreg; // Сохранить
*(__IO uint32_t *) CR_PLLSAION_BB = (uint32_t)1; // Разрешить PLLSAI тактирование
// Ждать запуска PLLSAI
while((RCC->CR & (1<<RCC_FLAG_PLLSAIRDY)) == 0)
{
}
// Включить тактирование LTDC
__LTDC_CLK_ENABLE();
// Настроить пины LCD
PINLCD_INIT;
// ***** Инициализация LTDC *****
// *** Тайминги ***
// горизонтальная синхронизация ширина = Hsync - 1 (41)
LTDC->SSCR &= ~(LTDC_SSCR_VSH | LTDC_SSCR_HSW);
tmpreg = (40 << 16);
// вертикальная синхронизация высота = Vsync - 1 (10)
LTDC->SSCR |= (tmpreg | 9);
// горизонтальная ширина с полочкой = Hsync + HBP - 1
LTDC->BPCR &= ~(LTDC_BPCR_AVBP | LTDC_BPCR_AHBP);
tmpreg = (42 << 16);
// вертикальная высота с полочкой = Vsync + HBP - 1
LTDC->BPCR |= (tmpreg | 11);
// активная ширина = Hsync + HBP + Active Width - 1
LTDC->AWCR &= ~(LTDC_AWCR_AAH | LTDC_AWCR_AAW);
tmpreg = (522 << 16);
// активная высота = Vsync + VBP + Active Heigh - 1
LTDC->AWCR |= (tmpreg | 283);
// полная ширина = Hsync + HBP + Active Width + HFP - 1
LTDC->TWCR &= ~(LTDC_TWCR_TOTALH | LTDC_TWCR_TOTALW);
tmpreg = (524 << 16);
// полная высота = Vsync + VBP + Active Heigh + VFP - 1
LTDC->TWCR |= (tmpreg | 285);
// *** Полярность ***
// Полярность горизонтальной синхронизации = активный 0
// Полярность вертикальной синхронизации = активный 0
// Полярность "data enable" = активный 0
// Полярность "pixel clock" без инверсии
LTDC->GCR &= (uint32_t)GCR_MASK;
LTDC->GCR |= (uint32_t)(LTDC_HSPOLARITY_AL | LTDC_VSPOLARITY_AL | LTDC_DEPOLARITY_AL | LTDC_PCPOLARITY_IPC);
// R,G,B фона
//LTDC->BCCR &= ~(LTDC_BCCR_BCBLUE | LTDC_BCCR_BCGREEN | LTDC_BCCR_BCRED);
//LTDC->BCCR |= BACKGROUNDCOLOR;
LTDC->BCCR = BACKGROUNDCOLOR;
// *** Завершение инициализации LTDC ***
// *** инициализация слоя 1 ***
// Если вся область активного дисплея используется для отображения изображения, то:
// Horizontal start = horizontal synchronization + Horizontal back porch = 43
// Vertical start = vertical synchronization + vertical back porch = 12
// Horizontal stop = Horizontal start + window width -1 = 43 + 480 -1
// Vertical stop = Vertical start + window height -1 = 12 + 272 -1
//LTDC_Layer1->WHPCR &= ~(LTDC_LxWHPCR_WHSTPOS | LTDC_LxWHPCR_WHSPPOS);
tmpreg = (480 + 43 - 1) << 16; // Horizontal stop
LTDC_Layer1->WHPCR = (43 | tmpreg); // Horizontal start
//LTDC_Layer1->WVPCR &= ~(LTDC_LxWVPCR_WVSTPOS | LTDC_LxWVPCR_WVSPPOS);
tmpreg = (272 + 12 - 1) << 16; // Vertical stop
LTDC_Layer1->WVPCR = (12 | tmpreg); // Vertical start
// Формат пикселя
//LTDC_Layer1->PFCR &= ~(LTDC_LxPFCR_PF);
LTDC_Layer1->PFCR = LTDC_PIXELFORMAT_RGB565;
// Alpha constant (255 totally opaque)
//LTDC_Layer1->CACR &= ~(LTDC_LxCACR_CONSTA);
LTDC_Layer1->CACR = 255;
// Цвет по умолчанию
LTDC_Layer1->DCCR = 0;
// Блэндинг факторы
LTDC_Layer1->BFCR = (LTDC_BLENDINGFACTOR1_CA | LTDC_BLENDINGFACTOR2_CA);
// Стартовый адресс
LTDC_Layer1->CFBAR = VIDEOBUF_L1ADR;
// Длина одной строки пикселей в байтах + 3:
// Длина строки = Ширина x число байт на пиксель + 3
// Ширина = 480
// число байт на пиксель = 2 (формат пикселя : RGB565)
tmpreg = ((480 * 2) + 3);
// Смещение между 2 строками
LTDC_Layer1->CFBLR = ((480 * 2)<<16) | tmpreg;
// Число строк
LTDC_Layer1->CFBLNR = 272;
// Разрешить работу слоя 1
LTDC_Layer1->CR |= (uint32_t)LTDC_LxCR_LEN;
// Перегрузить конфигурацию слоя 1
LTDC->SRCR = (uint32_t)LTDC_IMRELOAD;
// Запустить LCD
LTDC->GCR |= (uint32_t)LTDC_GCR_LTDCEN;
// Запустить ChromART
__DMA2D_CLK_ENABLE();
}
// Распаковать картинку A4 на экран
void copyA4toTFT(void *pSrc, void *pDst, uint16_t xSize, uint16_t ySize)
{
DMA2D->CR = 0x00010000UL | (1 << 9); // Control Register (Memory to memory with pixel format conversion and TCIE)
// Указатели
DMA2D->FGMAR = (uint32_t)pSrc; // Foreground Memory Address Register (Source address)
DMA2D->OMAR = (uint32_t)pDst; // Output Memory Address Register (Destination address)
// Смещения
DMA2D->FGOR = xSize; // Foreground Offset Register (Source line offset)
DMA2D->OOR = _layerX-1; // Output Offset Register (Destination line offset)
// Входной и выходной Форматы пикселя
DMA2D->FGPFCCR = CM_A4; // Foreground PFC Control Register (Defines the input pixel format)
DMA2D->OPFCCR = DMA2D_RGB565; // Output PFC Control Register (Defines the output pixel format)
// Установить цвет
DMA2D->FGCOLR = _fcolor; // Foreground PFC Control Register (Defines the input pixel format)
// Установить размер
DMA2D->NLR = (uint32_t)(xSize << 16) | ySize; // Number of Line Register (Size configuration of area to be transfered)
// Выполнить
DMA2D->CR |= DMA2D_CR_START;
while (DMA2D->CR & DMA2D_CR_START)
{
}
}
// Скопировать картинку С16 на экран
void copyC16(void *pSrc, void *pDst, uint16_t xSize, uint16_t ySize, uint16_t xSizeSrc, uint16_t xSizeDst)
{
DMA2D->CR = (1 << 9); // без модификации
// Указатели
DMA2D->FGMAR = (uint32_t)pSrc; // Foreground Memory Address Register (Source address)
DMA2D->OMAR = (uint32_t)pDst; // Output Memory Address Register (Destination address)
// Смещения
DMA2D->FGOR = xSizeSrc; // Foreground Offset Register (Source line offset)
DMA2D->OOR = xSizeDst; // Output Offset Register (Destination line offset)
// Входной и выходной Форматы пикселя
DMA2D->FGPFCCR = CM_RGB565; // Foreground PFC Control Register (Defines the input pixel format)
DMA2D->OPFCCR = DMA2D_RGB565; // Output PFC Control Register (Defines the output pixel format)
// Установить размер
DMA2D->NLR = (uint32_t)(xSize << 16) | ySize; // Number of Line Register (Size configuration of area to be transfered)
// Выполнить
DMA2D->CR |= DMA2D_CR_START;
while (DMA2D->CR & DMA2D_CR_START)
{
}
}
// Залить прямоугольник на экране
void FillRectTFT(void *pSrc, uint16_t xSize, uint16_t ySize)
{
// Set up mode
DMA2D->CR = 0x00030000UL | (1 << 9);
DMA2D->OCOLR = _color;
// Set up pointers
DMA2D->OMAR = (uint32_t)pSrc;
// Set up offsets
DMA2D->OOR = _layerX-1;
// Set up pixel format
DMA2D->OPFCCR = DMA2D_RGB565;
// Set up size
DMA2D->NLR = (uint32_t)(xSize << 16) | (uint16_t)ySize;
DMA2D->CR |= DMA2D_CR_START;
// Wait until transfer is done
while (DMA2D->CR & DMA2D_CR_START)
{
}
}
Комментариев нет:
Отправить комментарий