MPU
int Mpu_Init(void)
{
///// SDIO
MPU_Region_InitTypeDef MPU_InitStructSDIO;
/// Disable the MPU
HAL_MPU_Disable();
/// Enable the MPU
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
MPU_Region_InitTypeDef MPU_InitStruct;
HAL_MPU_Disable();
MPU_InitStruct.Enable=MPU_REGION_ENABLE;
MPU_InitStruct.BaseAddress = 0x60000000;
MPU_InitStruct.Size = MPU_REGION_SIZE_1MB;
MPU_InitStruct.AccessPermission=MPU_REGION_FULL_ACCESS;
MPU_InitStruct.TypeExtField=MPU_TEX_LEVEL0;
MPU_InitStruct.IsCacheable=MPU_ACCESS_NOT_CACHEABLE;
MPU_InitStruct.IsBufferable=MPU_ACCESS_BUFFERABLE;
MPU_InitStruct.IsShareable=MPU_ACCESS_SHAREABLE;
MPU_InitStruct.Number=MPU_REGION_NUMBER0;
MPU_InitStruct.SubRegionDisable=0x00;
MPU_InitStruct.DisableExec=MPU_INSTRUCTION_ACCESS_ENABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
/// board_H..
#ifndef _GDISP_LLD_BOARD_H
#define _GDISP_LLD_BOARD_H
#define LCD_PIN_PWM GPIO_PIN_13
#define LCD_PORT_PWM GPIOD
#define LCD_PIN_RESET GPIO_PIN_11
#define LCD_PORT_RESET GPIOD
#define SSD1963_DELAY(ms) gfxSleepMilliseconds(ms)
#define SSD1963_RESET_PIN_SET HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11,GPIO_PIN_SET);
#define SSD1963_RESET_PIN_RESET HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11,GPIO_PIN_RESET);
#define SSD1963_REG (*((volatile unsigned short *) 0x60000000))
#define SSD1963_RAM (*((volatile unsigned short *) 0x60040000))
#define SSD1963_WRITE_CMD(cmd) SSD1963_REG=((unsigned short)cmd)
#define SSD1963_WRITE_DATA(data) SSD1963_RAM=((unsigned short)data)
#define SSD1963_READ_DATA() SSD1963_RAM
/*
static const LCD_Parameters DisplayTimings[] = {
// You need one of these array elements per display
{
800, 480, // Panel width and height
0, 0, 48, // Horizontal Timings (back porch, front porch, pulse)
CALC_PERIOD(800,0,0,48), // Total Horizontal Period (calculated from above line)
2, 2, 10, // Vertical Timings (back porch, front porch, pulse)
CALC_PERIOD(480,2,2,10), // Total Vertical Period (calculated from above line)
CALC_FPR(800,480,2,2,48,2,2,10,60ULL), // FPR - the 60ULL is the frames per second. Note the ULL!
gFalse, // Flip horizontally
gFalse // Flip vertically
},
};*/
#define PANEL_WIDTH 800
#define PANEL_HEIGHT 480
#define HORIZONTAL_BACK_PORCH 46
#define HORIZONTAL_FRONT_PORCH 210
#define HORIZONTAL_PULSE_WIDTH 1
#define HORIZONTAL_TOTAL 1056
#define VERTICAL_BACK_PORCH 23
#define VERTICAL_FRONT_PORCH 22
#define VERTICAL_PULSE_WIDTH 1
#define VERTICAL_TOTAL 525
static const LCD_Parameters DisplayTimings[] = {
// You need one of these array elements per display
{
PANEL_WIDTH, PANEL_HEIGHT,
HORIZONTAL_BACK_PORCH, HORIZONTAL_FRONT_PORCH, HORIZONTAL_PULSE_WIDTH,
CALC_PERIOD(PANEL_WIDTH,HORIZONTAL_BACK_PORCH, HORIZONTAL_FRONT_PORCH,HORIZONTAL_BACK_PORCH), /// HORIZONTAL_TOTAL
VERTICAL_BACK_PORCH, VERTICAL_FRONT_PORCH, VERTICAL_PULSE_WIDTH,
CALC_PERIOD(PANEL_HEIGHT, VERTICAL_BACK_PORCH, VERTICAL_FRONT_PORCH,HORIZONTAL_BACK_PORCH),
//CALC_FPR(PANEL_WIDTH,480,2,2,48,2,2,10,60ULL)
HORIZONTAL_TOTAL * VERTICAL_TOTAL * 60ULL * 1048576 / 100000000,
gFalse, // Flip horizontally
gTrue // Flip vertically
},
};
static GFXINLINE void init_board(GDisplay *g)
{
(void) g;
GPIO_InitTypeDef gpio = {0};
SRAM_HandleTypeDef hsram1 = {0};
FMC_NORSRAM_TimingTypeDef Timing = {0};
FMC_NORSRAM_TimingTypeDef ExtTiming = {0};
/// Pwm
gpio.Pin = LCD_PIN_PWM;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LCD_PORT_PWM, &gpio);
/// Reset
gpio.Pin = LCD_PIN_RESET;
gpio.Mode = GPIO_MODE_OUTPUT_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(LCD_PORT_RESET, &gpio);
__HAL_RCC_FMC_CLK_ENABLE();
/// FMC GPIO Configuration
/// PE7 ------> FMC_D4
/// PE8 ------> FMC_D5
/// PE9 ------> FMC_D6
/// PE10 ------> FMC_D7
/// PE11 ------> FMC_D8
/// PE12 ------> FMC_D9
/// PE13 ------> FMC_D10
/// PE14 ------> FMC_D11
/// PE15 ------> FMC_D12
/// PD8 ------> FMC_D13
/// PD9 ------> FMC_D14
/// PD10 ------> FMC_D15
/// PD12 ------> FMC_A17
/// PD14 ------> FMC_D0
/// PD15 ------> FMC_D1
/// PD0 ------> FMC_D2
/// PD1 ------> FMC_D3
/// PD4 ------> FMC_NOE
/// PD5 ------> FMC_NWE
/// PD7 ------> FMC_NE1
gpio.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|GPIO_PIN_15;
gpio.Mode = GPIO_MODE_AF_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOE, &gpio);
gpio.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_12
|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;
gpio.Mode = GPIO_MODE_AF_PP;
gpio.Pull = GPIO_NOPULL;
gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
gpio.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOD, &gpio);
/// USER CODE BEGIN FMC_MspInit 1
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_11,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_5, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOD, GPIO_PIN_7, GPIO_PIN_SET);
/// Perform the SRAM1 memory initialization sequence
hsram1.Instance = FMC_NORSRAM_DEVICE;
hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
/// hsram1.Init
hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE;
hsram1.Init.MemoryType = FMC_MEMORY_TYPE_SRAM;
hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;
hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE;
hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_ENABLE;
hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;
hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;
hsram1.Init.WriteFifo = FMC_WRITE_FIFO_ENABLE;
hsram1.Init.PageSize = FMC_PAGE_SIZE_NONE;
/// Timing
Timing.AddressSetupTime = 3;
Timing.AddressHoldTime = 15;
Timing.DataSetupTime = 14;
Timing.BusTurnAroundDuration = 0;
Timing.CLKDivision = 16;
Timing.DataLatency = 17;
Timing.AccessMode = FMC_ACCESS_MODE_A;
/// ExtTiming
ExtTiming.AddressSetupTime = 1;
ExtTiming.AddressHoldTime = 15;
ExtTiming.DataSetupTime = 2;
ExtTiming.BusTurnAroundDuration = 0;
ExtTiming.CLKDivision = 16;
ExtTiming.DataLatency = 17;
ExtTiming.AccessMode = FMC_ACCESS_MODE_A;
if (HAL_SRAM_Init(&hsram1, &Timing, &ExtTiming) != HAL_OK)
{
Error_Handler( );
}
}
static GFXINLINE void post_init_board(GDisplay *g)
{
(void) g;
}
static GFXINLINE void setpin_reset(GDisplay *g, gBool state) {
(void) g;
(void) state;
if(state==gFalse)
{
printf("SSD1963_RESET_PIN_SET\n\r");
SSD1963_RESET_PIN_SET;
}
else
{
printf("SSD1963_RESET_PIN_RESET\n\r");
SSD1963_RESET_PIN_RESET;
}
}
static GFXINLINE void acquire_bus(GDisplay *g) {
(void) g;
}
static GFXINLINE void release_bus(GDisplay *g) {
(void) g;
}
static GFXINLINE void write_index(GDisplay *g, gU16 index) {
(void) g;
(void) index;
SSD1963_WRITE_CMD(index);
}
static GFXINLINE void write_data(GDisplay *g, gU16 data) {
(void) g;
(void) data;
SSD1963_WRITE_DATA(data);
}
#endif /* _GDISP_LLD_BOARD_H */
/// gdisp_lld_ssd1963
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g)
{
unsigned short color_bus;
acquire_bus(g);
set_viewport(g);
write_index(g, SSD1963_READ_MEMORY_START);
color_bus = SSD1963_READ_DATA();
release_bus(g);
return (color_t)color_bus ;
}
LLDSPEC gBool gdisp_lld_init(GDisplay *g)
{
LCD_Parameters * lcdp;
/// Some displays (e.g. Displaytech) have an on-board setup process which just requires that we don't touch anything for a time after power up.
/// For this type of display define GDISP_SSD1963_NO_INIT as TRUE, and implement an appropriate delay in the board file.
/// With such displays we can skip most of the initialisation. We also skip pulsing the reset pin, since it
/// will introduce an extra second or so of display to the startup time.
// The private area for this controller is the LCD timings
lcdp = (void *)&DisplayTimings[g->controllerdisplay];
g->priv = lcdp;
// Initialise the board interface
init_board(g);
/// Some displays (e.g. Displaytech) have an on-board setup process which just requires that we don't touch anything for a time after power up.
/// For this type of display define GDISP_SSD1963_NO_INIT as GFXON, and implement an appropriate delay in the board file.
/// With such displays we can skip most of the initialisation. We also skip pulsing the reset pin, since it
/// will introduce an extra second or so of display to the startup time.
// The private area for this controller is the LCD timings
lcdp = (void *)&DisplayTimings[g->controllerdisplay];
g->priv = lcdp;
// Initialise the board interface
//init_board(g);
#if !GDISP_SSD1963_NO_INIT
// Hardware reset
setpin_reset(g, gTrue);
gfxSleepMilliseconds(5);
setpin_reset(g, gFalse);
gfxSleepMilliseconds(5);
#endif
// Get the bus for the following initialisation commands
acquire_bus(g);
#if !GDISP_SSD1963_NO_INIT
write_index(g, SSD1963_SOFT_RESET); // Software reset - clears almost everything (apart from PLL)
write_index(g, SSD1963_SOFT_RESET); // Software reset - clears almost everything (apart from PLL)
write_index(g, SSD1963_SOFT_RESET); // Software reset - clears almost everything (apart from PLL)
gfxSleepMilliseconds(5);
/// Driver PLL config
write_index(g, SSD1963_SET_PLL_MN);
write_data(g, 35); // PLLclk = REFclk (10Mhz) * 36 (360Mhz)
write_data(g, 2); // SYSclk = PLLclk / 3 (120MHz)
write_data(g, 54); // Apply calculation bit, else it is ignored
write_reg(g, SSD1963_SET_PLL, 0x01); // Enable PLL
gfxSleepMilliseconds(5);
/*write_reg(g, SSD1963_SET_PLL, 0x03); // Use PLL
*/
write_index(g, SSD1963_SET_PLL);
gfxSleepMilliseconds(1); /// !!!!
write_data(g, 0x03);
gfxSleepMilliseconds(1); /// !!!!
//SSD1963_WRITE_CMD(0x00E6); /// PLL setting for PCLK, depends on resolution
//SSD1963_WRITE_DATA(0x0003);
//SSD1963_WRITE_DATA(0x00FF);
//SSD1963_WRITE_DATA(0x00FF);
/// LCD panel parameters
write_index(g, SSD1963_SET_LCD_MODE);
write_data(g, lcdp->mode & 0xFF);
write_data(g, (lcdp->mode >> 8) & 0xFF);
/// write_data(g, 0x18); //Enabled dithering
/// write_data(g, 0x00);
write_data16(g, lcdp->width-1);
write_data16(g, lcdp->height-1);
write_data(g, 0x00); // RGB - line sequences for serial TFT
#endif
/// Display flipping
if (lcdp->flipHorz)
{
write_reg(g, SSD1963_SET_ADDRESS_MODE, SSD1963_ADDR_MODE_FLIP_HORZ);
} else if (lcdp->flipVert)
{
write_reg(g, SSD1963_SET_ADDRESS_MODE, SSD1963_ADDR_MODE_FLIP_VERT);
} else if (lcdp->flipHorz && lcdp->flipVert)
{
write_reg(g, SSD1963_SET_ADDRESS_MODE, SSD1963_ADDR_MODE_FLIP_VERT | SSD1963_ADDR_MODE_FLIP_HORZ);
}
else
{
write_reg(g, SSD1963_SET_ADDRESS_MODE, 0x00);
}
write_reg(g, SSD1963_SET_PIXEL_DATA_INTERFACE, SSD1963_PDI_16BIT565);
write_reg(g, SSD1963_SET_PIXEL_FORMAT, 0x50);
#if !GDISP_SSD1963_NO_INIT
/// LCD Clock specs
write_index(g, SSD1963_SET_LSHIFT_FREQ);
write_data(g, (lcdp->fpr >> 16) & 0xFF);
write_data(g, (lcdp->fpr >> 8) & 0xFF);
write_data(g, lcdp->fpr & 0xFF);
write_index(g, SSD1963_SET_HORI_PERIOD);
write_data16(g, lcdp->hperiod);
write_data16(g, lcdp->hpulse + lcdp->hbporch);
write_data(g, lcdp->hpulse - 1);
write_data(g, 0x00);
write_data(g, 0x00);
write_data(g, 0x00);
write_index(g, SSD1963_SET_VERT_PERIOD);
write_data16(g, lcdp->vperiod);
write_data16(g, lcdp->vpulse + lcdp->vbporch);
write_data(g, lcdp->vpulse - 1);
write_data(g, 0x00);
write_data(g, 0x00);
#if 0
/// Enable DBC to control Backlight
write_index(g, SSD1963_SET_DBC_CONF);
write_data(g, 0x2F);
#endif
#endif
/*
#if 0
/// Tear effect indicator ON. This is used to tell the host MCU when the driver is not refreshing the panel (during front/back porch)
write_reg(g, SSD1963_SET_TEAR_ON, 0x00);
#endif
*/
/// Turn on
write_index(g, SSD1963_SET_DISPLAY_ON);
/// Turn on the back-light
set_backlight(g, GDISP_INITIAL_BACKLIGHT);
// Finish Init
post_init_board(g);
// Release the bus
release_bus(g);
/// Initialise the GDISP structure
g->g.Width = lcdp->width;
g->g.Height = lcdp->height;
g->g.Orientation = gOrientation0;
g->g.Powermode = gPowerOn;
g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
g->g.Contrast = GDISP_INITIAL_CONTRAST;
HAL_GPIO_WritePin(LCD_PORT_PWM, LCD_PIN_PWM, GPIO_PIN_SET);
return gTrue;
}