Initial commit.

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2023-11-03 09:36:07 +08:00
parent bf1a3b180c
commit bb2190586f
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
8 changed files with 1036 additions and 0 deletions

2
src/Xilinx.spec Normal file
View File

@ -0,0 +1,2 @@
*startfile:
crti%O%s crtbegin%O%s

226
src/gpio_lp.c Normal file
View File

@ -0,0 +1,226 @@
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "platform.h"
#include "xil_printf.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xgpio.h"
#include "xgpio_l.h"
#define GPIO_ENABLE_MASK 0x80 // BIT7
#define GPIO_LP_L0P_MASK 0x01 // BIT0
#define GPIO_LP_L1P_MASK 0x02 // BIT1
#define GPIO_LP_L0N_MASK 0x04 // BIT2
#define GPIO_LP_L1N_MASK 0x08 // BIT3
#define GPIO_LP_CKP_MASK 0x10 // BIT4
#define GPIO_LP_CKN_MASK 0x20 // BIT5
#define GPIO_LP_RST_MASK 0x40 // BIT6
#define GPIO_WRITE(val) XGpio_WriteReg(lp_ctrl_gpio.BaseAddress, XGPIO_DATA_OFFSET, val)
#define GPIO_READ() XGpio_ReadReg(lp_ctrl_gpio.BaseAddress, XGPIO_DATA_OFFSET)
// CK+- 11 D1+- 11 D0+- 11
#define GPIO_LP_11() GPIO_WRITE(GPIO_ENABLE_MASK | GPIO_LP_RST_MASK | \
GPIO_LP_CKP_MASK | GPIO_LP_CKN_MASK | \
GPIO_LP_L0P_MASK | GPIO_LP_L0N_MASK | \
GPIO_LP_L1P_MASK | GPIO_LP_L1N_MASK)
// CK+- 11 D1+- 11 D0+- 10
#define GPIO_LP_10() GPIO_WRITE(GPIO_ENABLE_MASK | GPIO_LP_RST_MASK | \
GPIO_LP_CKP_MASK | GPIO_LP_CKN_MASK | \
GPIO_LP_L0P_MASK | \
GPIO_LP_L1P_MASK | GPIO_LP_L1N_MASK)
// CK+- 11 D1+- 11 D0+- 01
#define GPIO_LP_01() GPIO_WRITE(GPIO_ENABLE_MASK | GPIO_LP_RST_MASK | \
GPIO_LP_CKP_MASK | GPIO_LP_CKN_MASK | \
GPIO_LP_L0N_MASK | \
GPIO_LP_L1P_MASK | GPIO_LP_L1N_MASK)
// CK+- 11 D1+- 11 D0+- 00
#define GPIO_LP_00() GPIO_WRITE(GPIO_ENABLE_MASK | GPIO_LP_RST_MASK | \
GPIO_LP_CKP_MASK | GPIO_LP_CKN_MASK | \
GPIO_LP_L1P_MASK | GPIO_LP_L1N_MASK)
#define DELAY_TXS()
// Escape mode command list
#define MIPI_LP_ESC_LPDT 0x87
#define MIPI_CRC_POLY
static XGpio lp_ctrl_gpio;
static uint32_t MIPI_ECC_TABLE[] = {
0b111100010010110010110111,
0b111100100101010101011011,
0b011101001001101001101101,
0b101110001110001110001110,
0b110111110000001111110000,
0b111011111111110000000000
};
int gpio_lp_init(void) {
return XGpio_Initialize(&lp_ctrl_gpio, XPAR_VIDEO_ROUTINE_AXI_GPIO_0_DEVICE_ID);
}
int gpio_lp_release(void) {
GPIO_WRITE(GPIO_LP_RST_MASK);
return XST_SUCCESS;
}
void gpio_lp_setup(void) {
GPIO_LP_11();
DELAY_TXS();
}
void gpio_lp_lcd_reset(void) {
GPIO_WRITE(GPIO_READ() & ~(GPIO_LP_RST_MASK));
usleep(50);
GPIO_WRITE(GPIO_READ() | GPIO_LP_RST_MASK);
usleep(5 * 1000);
}
// Send EME sequence
static inline void gpio_lp_enter_escape(void) {
GPIO_LP_10();
DELAY_TXS();
GPIO_LP_00();
DELAY_TXS();
GPIO_LP_01();
DELAY_TXS();
GPIO_LP_00();
DELAY_TXS();
}
// Send Mark-1 sequence
static inline void gpio_lp_exit_escape(void) {
GPIO_LP_00();
DELAY_TXS();
GPIO_LP_10();
DELAY_TXS();
GPIO_LP_11();
DELAY_TXS();
}
// Shift 1 byte from LSB
static inline void gpio_lp_shift_byte(uint8_t byte) {
for(uint8_t i = 0; i < 8; i++) {
if(byte & (1U << i)) {
// Shift '1'
GPIO_LP_10();
DELAY_TXS();
GPIO_LP_00();
DELAY_TXS();
}
else {
// Shift '0'
GPIO_LP_01();
DELAY_TXS();
GPIO_LP_00();
DELAY_TXS();
}
}
}
static void gpio_lpdt(uint8_t *payload, uint16_t length) {
gpio_lp_enter_escape();
gpio_lp_shift_byte(MIPI_LP_ESC_LPDT);
for(uint16_t i = 0; i < length; i++) {
gpio_lp_shift_byte(payload[i]);
}
gpio_lp_exit_escape();
}
static void gpio_lpdt_compute_ecc(uint8_t *ph) {
uint32_t ph_val = ph[0] | ph[1] << 8U | ph[2] << 16U;
uint8_t ecc_byte = 0;
for(uint8_t i = 0; i < 6; i++) { // Each bit in table
uint32_t field = ph_val & MIPI_ECC_TABLE[i];
uint8_t parity = 0;
// Calculate parity
for(uint8_t j = 0; j < 24; j++) {
parity ^= field;
field >>= 1;
}
if(parity & 1) {
ecc_byte |= 1 << i;
}
}
ph[3] = ecc_byte;
}
static uint16_t gpio_lpdt_compute_crc(uint8_t *pkt_pd, uint16_t len) {
uint16_t poly = 0x8408;
int byte_counter;
int bit_counter;
uint8_t current_data;
uint16_t result = 0xffff;
for (byte_counter = 0; byte_counter < len; byte_counter++) {
current_data = pkt_pd[byte_counter];
for (bit_counter = 0; bit_counter < 8; bit_counter++)
{
if (((result & 0x0001) ^ ((current_data) & 0x0001)))
result = ((result >> 1) & 0x7fff) ^ poly;
else
result = ((result >> 1) & 0x7fff);
current_data = (current_data >> 1); // & 0x7F;
}
}
return result;
}
int gpio_lp_write_dcs(uint8_t command, uint8_t *param, uint16_t param_length) {
if(param_length > 1) {
// Compose a long write
uint16_t packet_length = param_length + 7; // DI + WC0 + WC1 + ECC + CMD + CRC0 + CRC1
uint8_t *packet_buffer = malloc(packet_length);
if(!packet_buffer) return XST_FAILURE;
packet_buffer[0] = 0x39; // DCS long write command
packet_buffer[1] = (param_length + 1) & 0xFFU; // WC0
packet_buffer[2] = (param_length + 1) >> 8U; // WC1
// Fill in ECC byte.
gpio_lpdt_compute_ecc(packet_buffer);
packet_buffer[4] = command;
memcpy(&packet_buffer[5], param, param_length);
// Compute CRC for LPa
uint16_t crc = gpio_lpdt_compute_crc(&packet_buffer[4], param_length + 1);
packet_buffer[packet_length - 2] = crc & 0xFF;
packet_buffer[packet_length - 1] = crc >> 8U;
gpio_lpdt(packet_buffer, packet_length);
free(packet_buffer);
}
else if(param_length > 0) {
// Compose a short write with 1 parameter
uint8_t packet_buffer[4] = { 0x15, command, param[0], 0x00 };
gpio_lpdt_compute_ecc(packet_buffer);
// Shift the packet out.
gpio_lpdt(packet_buffer, 0x04);
} else {
// Compose a short write without parameters
uint8_t packet_buffer[4] = { 0x05, command, 0x00, 0x00 };
gpio_lpdt_compute_ecc(packet_buffer); // Fill in ECC byte
// Shift the packet out.
gpio_lpdt(packet_buffer, 0x04);
}
return XST_SUCCESS;
}

11
src/gpio_lp.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef GPIO_LP_H
#define GPIO_LP_H
int gpio_lp_init(void);
void gpio_lp_setup(void);
void gpio_lp_lcd_reset(void);
int gpio_lp_release(void);
int gpio_lp_write_dcs(uint8_t command, uint8_t *param, uint16_t param_length);
#endif

348
src/lcd_test.c Normal file
View File

@ -0,0 +1,348 @@
/******************************************************************************
*
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*
* helloworld.c: simple test application
*
* This application configures UART 16550 to baud rate 9600.
* PS7 UART (Zynq) is not initialized by this application, since
* bootrom/bsp configures it to baud rate 115200
*
* ------------------------------------------------
* | UART TYPE BAUD RATE |
* ------------------------------------------------
* uartns550 9600
* uartlite Configurable only in HW design
* ps7_uart 115200 (configured by bootrom/bsp)
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include "platform.h"
#include "xil_printf.h"
#include "xil_cache.h"
#include "xparameters.h"
#include "xv_frmbufrd.h"
#include "xscugic.h"
#include "xdsitxss.h"
#include "gpio_lp.h"
#define IMAGE_WIDTH 540
#define IMAGE_HEIGHT 960
#define IMAGE_PIXEL_SIZE 4
#define BITBANG_COMMAND 1
#define ENABLE_VIDEO 1
static uint8_t __aligned(64) s_image_buffer[IMAGE_WIDTH * IMAGE_HEIGHT * IMAGE_PIXEL_SIZE];
static XV_frmbufrd s_frmbufrd;
static XDsiTxSs s_dsi_txss;
static uint8_t s_lcd_init_seq[] = {
0xFF, 4, 0xAA, 0x55, 0x25, 0x01,
0xF0, 5, 0x55, 0xAA, 0x52, 0x08, 0x00,
0xB1, 3, 0xFC, 0x00, 0x00,
0xB8, 4, 0x01, 0x02, 0x02, 0x02,
0xBC, 3, 0x05, 0x05, 0x05,
0xB7, 2, 0x00, 0x00,
0xC8, 18, 0x01, 0x00, 0x46, 0x1E, 0x46, 0x1E, 0x46, 0x1E, 0x46, 0x1E, 0x64, 0x3C, 0x3C, 0x64, 0x64, 0x3C, 0x3C, 0x64,
0xF0, 5, 0x55, 0xAA, 0x52, 0x08, 0x01,
0xB0, 3, 0x05, 0x05, 0x05,
0xB6, 3, 0x44, 0x44, 0x44,
0xB1, 3, 0x05, 0x05, 0x05,
0xB7, 3, 0x34, 0x34, 0x34,
0xB3, 3, 0x16, 0x16, 0x16,
0xB4, 3, 0x0A, 0x0A, 0x0A,
0xBC, 3, 0x00, 0x90, 0x11,
0xBD, 3, 0x00, 0x90, 0x11,
0xBE, 1, 0x51,
0xD1, 16, 0x00, 0x17, 0x00, 0x24, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x66, 0x00, 0x86, 0x00, 0xA0, 0x00, 0xCC,
0xD2, 16, 0x00, 0xF1, 0x01, 0x26, 0x01, 0x4E, 0x01, 0x8C, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xE7, 0x02, 0x0E,
0xD3, 16, 0x02, 0x22, 0x02, 0x3C, 0x02, 0x4F, 0x02, 0x71, 0x02, 0x90, 0x02, 0xC6, 0x02, 0xF1, 0x03, 0x3A,
0xD4, 4, 0x03, 0xB5, 0x03, 0xC1,
0xD5, 16, 0x00, 0x17, 0x00, 0x24, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x66, 0x00, 0x86, 0x00, 0xA0, 0x00, 0xCC,
0xD6, 16, 0x00, 0xF1, 0x01, 0x26, 0x01, 0x4E, 0x01, 0x8C, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xE7, 0x02, 0x0E,
0xD7, 16, 0x02, 0x22, 0x02, 0x3C, 0x02, 0x4F, 0x02, 0x71, 0x02, 0x90, 0x02, 0xC6, 0x02, 0xF1, 0x03, 0x3A,
0xD8, 4, 0x03, 0xB5, 0x03, 0xC1,
0xD9, 16, 0x00, 0x17, 0x00, 0x24, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x66, 0x00, 0x86, 0x00, 0xA0, 0x00, 0xCC,
0xDD, 16, 0x00, 0xF1, 0x01, 0x26, 0x01, 0x4E, 0x01, 0x8C, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xE7, 0x02, 0x0E,
0xDE, 16, 0x02, 0x22, 0x02, 0x3C, 0x02, 0x4F, 0x02, 0x71, 0x02, 0x90, 0x02, 0xC6, 0x02, 0xF1, 0x03, 0x3A,
0xDF, 4, 0x03, 0xB5, 0x03, 0xC1,
0xE0, 16, 0x00, 0x17, 0x00, 0x24, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x66, 0x00, 0x86, 0x00, 0xA0, 0x00, 0xCC,
0xE1, 16, 0x00, 0xF1, 0x01, 0x26, 0x01, 0x4E, 0x01, 0x8C, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xE7, 0x02, 0x0E,
0xE2, 16, 0x02, 0x22, 0x02, 0x3C, 0x02, 0x4F, 0x02, 0x71, 0x02, 0x90, 0x02, 0xC6, 0x02, 0xF1, 0x03, 0x3A,
0xE3, 4, 0x03, 0xB5, 0x03, 0xC1,
0xE4, 16, 0x00, 0x17, 0x00, 0x24, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x66, 0x00, 0x86, 0x00, 0xA0, 0x00, 0xCC,
0xE5, 16, 0x00, 0xF1, 0x01, 0x26, 0x01, 0x4E, 0x01, 0x8C, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xE7, 0x02, 0x0E,
0xE6, 16, 0x02, 0x22, 0x02, 0x3C, 0x02, 0x4F, 0x02, 0x71, 0x02, 0x90, 0x02, 0xC6, 0x02, 0xF1, 0x03, 0x3A,
0xE7, 4, 0x03, 0xB5, 0x03, 0xC1,
0xE8, 16, 0x00, 0x17, 0x00, 0x24, 0x00, 0x3D, 0x00, 0x52, 0x00, 0x66, 0x00, 0x86, 0x00, 0xA0, 0x00, 0xCC,
0xE9, 16, 0x00, 0xF1, 0x01, 0x26, 0x01, 0x4E, 0x01, 0x8C, 0x01, 0xBC, 0x01, 0xBE, 0x01, 0xE7, 0x02, 0x0E,
0xEA, 16, 0x02, 0x22, 0x02, 0x3C, 0x02, 0x4F, 0x02, 0x71, 0x02, 0x90, 0x02, 0xC6, 0x02, 0xF1, 0x03, 0x3A,
0xEB, 4, 0x03, 0xB5, 0x03, 0xC1,
0x35, 1, 0x00,
0x11, 0
};
static int init_drivers(void) {
XV_frmbufrd_Config *frmbufrd_config = XV_frmbufrd_LookupConfig(XPAR_VIDEO_ROUTINE_V_FRMBUF_RD_0_DEVICE_ID);
int status = XV_frmbufrd_Initialize(&s_frmbufrd, frmbufrd_config->BaseAddress);
if(status != XST_SUCCESS) {
printf("FramebufRd initialization failed.\r\n");
return XST_FAILURE;
}
return XST_SUCCESS;
}
static void config_frmbuf(void) {
XV_frmbufrd_Set_HwReg_width(&s_frmbufrd, IMAGE_WIDTH);
XV_frmbufrd_Set_HwReg_height(&s_frmbufrd, IMAGE_HEIGHT);
XV_frmbufrd_Set_HwReg_stride(&s_frmbufrd, IMAGE_WIDTH * IMAGE_PIXEL_SIZE);
XV_frmbufrd_Set_HwReg_video_format(&s_frmbufrd, 27); // BGRX8
XV_frmbufrd_Set_HwReg_frm_buffer_V(&s_frmbufrd, (u32)s_image_buffer);
XV_frmbufrd_EnableAutoRestart(&s_frmbufrd);
XV_frmbufrd_Start(&s_frmbufrd);
printf("Frame buffer read configured.\r\n");
}
#if BITBANG_COMMAND
#else
static int dsi_sendcommand(XDsiTxSs *txss, uint8_t command, uint8_t *param, uint8_t param_length) {
if(param_length > 1) {
txss->CmdPkt.CmdPkt = XDSI_CMD_MODE_LONG_PKT;
txss->CmdPkt.SpktData.DataType = 0x39; // DCS long write
txss->CmdPkt.SpktData.Data0 = param_length + 1; // word count.
txss->CmdPkt.SpktData.VcId = 0;
uint8_t *pkt_buffer = (uint8_t *)txss->CmdPkt.LongPktData;
memset(pkt_buffer, 0x00, 256);
pkt_buffer[0] = command;
memcpy(&pkt_buffer[1], param, param_length);
}
else if(param_length > 0) {
txss->CmdPkt.CmdPkt = XDSI_CMD_MODE_SHORT_PKT;
txss->CmdPkt.SpktData.DataType = 0x15; // DCS write, 1 parameter
txss->CmdPkt.SpktData.Data0 = command;
txss->CmdPkt.SpktData.Data1 = param[0];
txss->CmdPkt.SpktData.VcId = 0;
}
else {
txss->CmdPkt.CmdPkt = XDSI_CMD_MODE_SHORT_PKT;
txss->CmdPkt.SpktData.DataType = 0x05; // DCS write, no parameter
txss->CmdPkt.SpktData.Data0 = command;
txss->CmdPkt.SpktData.Data1 = 0x00;
txss->CmdPkt.SpktData.VcId = 0;
}
return XDsiTxSs_SendCmdModePacket(txss);
}
#endif
static int dsi_initseq(XDsiTxSs *txss) {
#if BITBANG_COMMAND
int status = gpio_lp_write_dcs(0x01, NULL, 0x00);
#else
int status = dsi_sendcommand(txss, 0x01, NULL, 0x00);
#endif
if(status != XST_SUCCESS) {
printf("Reset command send failed.\r\n");
return status;
}
usleep(200 * 1000);
uint32_t i = 0;
while(i < sizeof(s_lcd_init_seq)) {
#if BITBANG_COMMAND
status = gpio_lp_write_dcs(s_lcd_init_seq[i], &s_lcd_init_seq[i + 2], s_lcd_init_seq[i + 1]);
#else
status = dsi_sendcommand(txss, s_lcd_init_seq[i], &s_lcd_init_seq[i + 2], s_lcd_init_seq[i + 1]);
#endif
if(status != XST_SUCCESS) {
printf("Send initialization command failed at %ld", i);
return status;
}
i += s_lcd_init_seq[i + 1] + 2; // Next seq
}
usleep(200 * 1000);
#if BITBANG_COMMAND
status = gpio_lp_write_dcs(0x29, NULL, 0x00);
#else
status = dsi_sendcommand(txss, 0x29, NULL, 0x00);
#endif
return status;
}
static int config_dsi(void) {
XDsiTxSs_Config *config = XDsiTxSs_LookupConfig(XPAR_VIDEO_ROUTINE_MIPI_DSI_TX_SUBSYSTEM_0_DEVICE_ID);
if(!config) return XST_FAILURE;
int status = XDsiTxSs_CfgInitialize(&s_dsi_txss, config, config->BaseAddr);
if(status != XST_SUCCESS) {
printf("DSI TX subsystem initialization failed.\r\n");
return status;
}
status = XDsiTxSs_SelfTest(&s_dsi_txss);
if(status != XST_SUCCESS) {
printf("DSI TX subsystem self test failed.\r\n");
return status;
}
else {
printf("DSI TX subsystem self test succeeded.\r\n");
}
XDsiTxSs_Reset(&s_dsi_txss);
#if BITBANG_COMMAND
gpio_lp_init();
gpio_lp_setup();
gpio_lp_lcd_reset();
// Return all lanes to LP-11 state
usleep(200 * 1000);
#else
status = XDsiTxSs_SetDSIMode(&s_dsi_txss, XDSI_COMMAND_MODE);
if(status != XST_SUCCESS) {
printf("Set DSI mode failed.\r\n");
}
usleep(20 * 1000);
status = XDsiTxSs_Activate(&s_dsi_txss, XDSITXSS_PHY, XDSITXSS_ENABLE);
if(status != XST_SUCCESS) {
printf("D-PHY enable failed.\r\n");
}
status = XDsiTxSs_Activate(&s_dsi_txss, XDSITXSS_DSI, XDSITXSS_ENABLE);
if(status != XST_SUCCESS) {
printf("DSI controller enable failed.\r\n");
}
#endif
usleep(200 * 1000);
dsi_initseq(&s_dsi_txss);
#if BITBANG_COMMAND
gpio_lp_release();
#else
status = XDsiTxSs_Activate(&s_dsi_txss, XDSITXSS_DSI, XDSITXSS_DISABLE);
#endif
#if ENABLE_VIDEO
XDsiTxSs_Reset(&s_dsi_txss);
XDsi_VideoTiming timing = {
.HActive = 540 * 3,
.HFrontPorch = 83,
.HBackPorch = 360,
.HSyncWidth = 7,
.VActive = 960,
.VFrontPorch = 15,
.VBackPorch = 15,
.VSyncWidth = 10,
.BLLPBurst = 0,
};
XDsiTxSs_SetCustomVideoInterfaceTiming(&s_dsi_txss, XDSI_VM_NON_BURST_SYNC_EVENT, &timing);
status = XDsiTxSs_Activate(&s_dsi_txss, XDSITXSS_PHY, XDSITXSS_ENABLE);
if(status != XST_SUCCESS) {
printf("D-PHY enable failed.\r\n");
}
status = XDsiTxSs_Activate(&s_dsi_txss, XDSITXSS_DSI, XDSITXSS_ENABLE);
if(status != XST_SUCCESS) {
printf("DSI enable failed.\r\n");
}
s_dsi_txss.SpktData.Data0 = 0x00;
s_dsi_txss.SpktData.Data1 = 0x00;
s_dsi_txss.SpktData.DataType = 0x32;
s_dsi_txss.SpktData.VcId = 0;
XDsiTxSs_SendShortPacket(&s_dsi_txss);
#endif
return status;
}
int main()
{
init_platform();
if(init_drivers() != XST_SUCCESS) {
printf("Driver initialization failed.\r\n");
for(;;) {
//
}
}
config_frmbuf();
if(config_dsi() != XST_SUCCESS) {
printf("DSI TXSS initialization failed.\r\n");
for(;;) {
//
}
}
memset(s_image_buffer, 0xFF, IMAGE_WIDTH * IMAGE_HEIGHT * IMAGE_PIXEL_SIZE);
Xil_DCacheFlushRange((UINTPTR)s_image_buffer, IMAGE_WIDTH * IMAGE_HEIGHT * IMAGE_PIXEL_SIZE);
for(;;) {
sleep(1);
}
print("Hello World\r\n");
print("Successfully ran Hello World application\r\n");
cleanup_platform();
return 0;
}

291
src/lscript.ld Normal file
View File

@ -0,0 +1,291 @@
/*******************************************************************/
/* */
/* This file is automatically generated by linker script generator.*/
/* */
/* Version: 2018.3 */
/* */
/* Copyright (c) 2010-2019 Xilinx, Inc. All rights reserved. */
/* */
/* Description : Cortex-A9 Linker Script */
/* */
/*******************************************************************/
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x2000;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 0x2000;
_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024;
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
/* Define Memories in the system */
MEMORY
{
ps7_ddr_0 : ORIGIN = 0x100000, LENGTH = 0x1FF00000
ps7_ram_0 : ORIGIN = 0x0, LENGTH = 0x30000
ps7_ram_1 : ORIGIN = 0xFFFF0000, LENGTH = 0xFE00
}
/* Specify the default entry point to the program */
ENTRY(_vector_table)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
.text : {
KEEP (*(.vectors))
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > ps7_ddr_0
.init : {
KEEP (*(.init))
} > ps7_ddr_0
.fini : {
KEEP (*(.fini))
} > ps7_ddr_0
.rodata : {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > ps7_ddr_0
.rodata1 : {
__rodata1_start = .;
*(.rodata1)
*(.rodata1.*)
__rodata1_end = .;
} > ps7_ddr_0
.sdata2 : {
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
__sdata2_end = .;
} > ps7_ddr_0
.sbss2 : {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > ps7_ddr_0
.data : {
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.jcr)
*(.got)
*(.got.plt)
__data_end = .;
} > ps7_ddr_0
.data1 : {
__data1_start = .;
*(.data1)
*(.data1.*)
__data1_end = .;
} > ps7_ddr_0
.got : {
*(.got)
} > ps7_ddr_0
.note.gnu.build-id : {
KEEP (*(.note.gnu.build-id))
} > ps7_ddr_0
.ctors : {
__CTOR_LIST__ = .;
___CTORS_LIST___ = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
___CTORS_END___ = .;
} > ps7_ddr_0
.dtors : {
__DTOR_LIST__ = .;
___DTORS_LIST___ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
___DTORS_END___ = .;
} > ps7_ddr_0
.fixup : {
__fixup_start = .;
*(.fixup)
__fixup_end = .;
} > ps7_ddr_0
.eh_frame : {
*(.eh_frame)
} > ps7_ddr_0
.eh_framehdr : {
__eh_framehdr_start = .;
*(.eh_framehdr)
__eh_framehdr_end = .;
} > ps7_ddr_0
.gcc_except_table : {
*(.gcc_except_table)
} > ps7_ddr_0
.mmu_tbl (ALIGN(16384)) : {
__mmu_tbl_start = .;
*(.mmu_tbl)
__mmu_tbl_end = .;
} > ps7_ddr_0
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidix.*.*)
__exidx_end = .;
} > ps7_ddr_0
.preinit_array : {
__preinit_array_start = .;
KEEP (*(SORT(.preinit_array.*)))
KEEP (*(.preinit_array))
__preinit_array_end = .;
} > ps7_ddr_0
.init_array : {
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > ps7_ddr_0
.fini_array : {
__fini_array_start = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
} > ps7_ddr_0
.ARM.attributes : {
__ARM.attributes_start = .;
*(.ARM.attributes)
__ARM.attributes_end = .;
} > ps7_ddr_0
.sdata : {
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > ps7_ddr_0
.sbss (NOLOAD) : {
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
__sbss_end = .;
} > ps7_ddr_0
.tdata : {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > ps7_ddr_0
.tbss : {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > ps7_ddr_0
.bss (NOLOAD) : {
__bss_start = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
__bss_end = .;
} > ps7_ddr_0
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
/* Generate Stack and Heap definitions */
.heap (NOLOAD) : {
. = ALIGN(16);
_heap = .;
HeapBase = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
HeapLimit = .;
} > ps7_ddr_0
.stack (NOLOAD) : {
. = ALIGN(16);
_stack_end = .;
. += _STACK_SIZE;
. = ALIGN(16);
_stack = .;
__stack = _stack;
. = ALIGN(16);
_irq_stack_end = .;
. += _IRQ_STACK_SIZE;
. = ALIGN(16);
__irq_stack = .;
_supervisor_stack_end = .;
. += _SUPERVISOR_STACK_SIZE;
. = ALIGN(16);
__supervisor_stack = .;
_abort_stack_end = .;
. += _ABORT_STACK_SIZE;
. = ALIGN(16);
__abort_stack = .;
_fiq_stack_end = .;
. += _FIQ_STACK_SIZE;
. = ALIGN(16);
__fiq_stack = .;
_undef_stack_end = .;
. += _UNDEF_STACK_SIZE;
. = ALIGN(16);
__undef_stack = .;
} > ps7_ddr_0
_end = .;
}

111
src/platform.c Normal file
View File

@ -0,0 +1,111 @@
/******************************************************************************
*
* Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#include "xparameters.h"
#include "xil_cache.h"
#include "platform_config.h"
/*
* Uncomment one of the following two lines, depending on the target,
* if ps7/psu init source files are added in the source directory for
* compiling example outside of SDK.
*/
/*#include "ps7_init.h"*/
/*#include "psu_init.h"*/
#ifdef STDOUT_IS_16550
#include "xuartns550_l.h"
#define UART_BAUD 9600
#endif
void
enable_caches()
{
#ifdef __PPC__
Xil_ICacheEnableRegion(CACHEABLE_REGION_MASK);
Xil_DCacheEnableRegion(CACHEABLE_REGION_MASK);
#elif __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_ICACHE
Xil_ICacheEnable();
#endif
#ifdef XPAR_MICROBLAZE_USE_DCACHE
Xil_DCacheEnable();
#endif
#endif
}
void
disable_caches()
{
#ifdef __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_DCACHE
Xil_DCacheDisable();
#endif
#ifdef XPAR_MICROBLAZE_USE_ICACHE
Xil_ICacheDisable();
#endif
#endif
}
void
init_uart()
{
#ifdef STDOUT_IS_16550
XUartNs550_SetBaud(STDOUT_BASEADDR, XPAR_XUARTNS550_CLOCK_HZ, UART_BAUD);
XUartNs550_SetLineControlReg(STDOUT_BASEADDR, XUN_LCR_8_DATA_BITS);
#endif
/* Bootrom/BSP configures PS7/PSU UART to 115200 bps */
}
void
init_platform()
{
/*
* If you want to run this example outside of SDK,
* uncomment one of the following two lines and also #include "ps7_init.h"
* or #include "ps7_init.h" at the top, depending on the target.
* Make sure that the ps7/psu_init.c and ps7/psu_init.h files are included
* along with this example source files for compilation.
*/
/* ps7_init();*/
/* psu_init();*/
enable_caches();
init_uart();
}
void
cleanup_platform()
{
disable_caches();
}

41
src/platform.h Normal file
View File

@ -0,0 +1,41 @@
/******************************************************************************
*
* Copyright (C) 2008 - 2014 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
#ifndef __PLATFORM_H_
#define __PLATFORM_H_
#include "platform_config.h"
void init_platform();
void cleanup_platform();
#endif

6
src/platform_config.h Normal file
View File

@ -0,0 +1,6 @@
#ifndef __PLATFORM_CONFIG_H_
#define __PLATFORM_CONFIG_H_
#define STDOUT_IS_PS7_UART
#define UART_DEVICE_ID 0
#endif