📄 picture_demo.c
字号:
/***********************************************************************
* $Workfile: picture_demo.c $
* $Revision: 1.4 $
* $Author: WellsK $
* $Date: Dec 08 2003 14:12:04 $
*
* Project: SDK7A404 simple threadx/filex picture example
*
* Description:
* This file contains a simple threadx demo that will initialize
* the SDK7A404 board and then jump to c_entry(), which will
* initialize ThreadX and start the ThreadX tasks.
*
* Revision History:
* $Log: //smaicnt2/pvcs/VM/sharpmcu/archives/sharpmcu/software/csps/lh7a404/bsps/sdk7a404/demos/filex/picture_demo.c-arc $
*
* Rev 1.4 Dec 08 2003 14:12:04 WellsK
* Made some updates to the way frame buffers are mapped to
* improve future support with LOLO.
*
* Rev 1.3 Oct 28 2003 14:54:36 WellsK
* Corrected ioctl functions. SHould be abl_ioctl instead of
* lcd_ioctl.
*
* Rev 1.2 Oct 28 2003 11:16:58 WellsK
* Updated to use common LCD driver format.
*
* Rev 1.1 Oct 01 2003 12:04:18 WellsK
* Added logic to get TTB address from register CP15 TTB.
*
* Rev 1.0 Sep 18 2003 11:53:26 WellsK
* Initial revision.
*
*
***********************************************************************
* SHARP MICROELECTRONICS OF THE AMERICAS MAKES NO REPRESENTATION
* OR WARRANTIES WITH RESPECT TO THE PERFORMANCE OF THIS SOFTWARE,
* AND SPECIFICALLY DISCLAIMS ANY RESPONSIBILITY FOR ANY DAMAGES,
* SPECIAL OR CONSEQUENTIAL, CONNECTED WITH THE USE OF THIS SOFTWARE.
*
* SHARP MICROELECTRONICS OF THE AMERICAS PROVIDES THIS SOFTWARE SOLELY
* FOR THE PURPOSE OF SOFTWARE DEVELOPMENT INCORPORATING THE USE OF A
* SHARP MICROCONTROLLER OR SYSTEM-ON-CHIP PRODUCT. USE OF THIS SOURCE
* FILE IMPLIES ACCEPTANCE OF THESE CONDITIONS.
*
* COPYRIGHT (C) 2001 SHARP MICROELECTRONICS OF THE AMERICAS, INC.
* CAMAS, WA
**********************************************************************/
#include "abl_bmp.h"
#include "abl_heap.h"
#include "abl_swim.h"
#include "abl_swim_font.h"
#include "abl_swim_image.h"
#include "abl_arm922t_cp15_driver.h"
#include "lh7a404_clcdc_driver.h"
#include "lh7a404_gpio_driver.h"
#include "lh7a404_timer_driver.h"
#include "lh7a404_vic_driver.h"
#include "sdk7a404_cpld_driver.h"
#include "sdk7a404_fx_cf_driver.h"
#include "abl_api.h"
#include "tx_api.h"
/* Pick only 1 panel from the following list of defines */
#define LCDPANEL sharp_lq035
//#define LCDPANEL sharp_lq039
//#define LCDPANEL sharp_lq057
//#define LCDPANEL sharp_lq064
//#define LCDPANEL sharp_lq104
//#define LCDPANEL sharp_lq121
#define DEMO_STACK_SIZE 0x1000 /* Thread stack sizes */
#define DEMO_STACK_POOL_SIZE 0x8000 /* Byte pool size */
/* ThreadX thread object control blocks */
TX_THREAD thread_0;
/* ThreadX byte pool */
TX_BYTE_POOL byte_pool_0;
/* Timer ThreadX interrupt handler (from tx_ill.s) */
extern void __tx_irq_handler(void);
FX_MEDIA cf_card;
FX_FILE cf_file;
unsigned char cf_buffer[2048];
/* Device handle for LCD driver */
INT_32 lcddev;
/* Device handle for timer driver */
INT_32 timer1dev;
/* Window sizes */
INT_32 xsz, ysz;
/* Frame buffer logical addresses */
#define FBLOG1 0xC1C00000
#define FBLOG2 0xC1E00000
/* Virtual frame buffer addresses */
COLOR_T *fblog[2] = {(COLOR_T *) FBLOG1, (COLOR_T *) FBLOG2};
/* Physical frame buffer addresses */
UNS_32 fbphy[2];
/* Names of .bmp files */
CHAR bmpfiles[64][16];
/* BMP structure */
BMP_T *bmp;
/* Temporary frame buffer */
COLOR_T *fbt;
/***********************************************************************
*
* Function: thread_0_entry
*
* Purpose: Thread 1
*
* Processing:
* Picture management file and display thread
*
* Parameters:
* thread_input: Thread input data value, not used
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void thread_0_entry(ULONG thread_input)
{
SWIM_WINDOW_T pwin[2];
static UINT status;
ULONG actual, image, tmp;
INT_16 xsize, ysize;
INT_32 fbindex = 0;
/* Picture windows, 2 of them are used with only 1 visible, so
one will be rendered while the other is displayed */
swim_window_open(&pwin[0], xsz, ysz, fblog[0], 0, 0,
(xsz- 1) , (ysz - 1), 0, WHITE, BLACK, DARKGRAY);
swim_window_open(&pwin[1], xsz, ysz, fblog[1], 0, 0,
(xsz- 1) , (ysz - 1), 0, WHITE, BLACK, DARKGRAY);
/* Open the CF device */
status = fx_media_open(&cf_card, "CF CARD", _fx_cf_driver, 0,
&cf_buffer[0], 1024);
/* Start in root directory at start of directory */
fx_directory_default_set(&cf_card, FX_NULL);
/* Generate a list of up to 64 BMP files */
swim_put_text(&pwin[0], "Getting BMP file list from the CF card's "
"root directory\n");
actual = 0;
status = fx_directory_first_entry_find(&cf_card,
&bmpfiles[actual][0]);
while (status == FX_SUCCESS)
{
swim_put_text(&pwin[0], "File found: ");
swim_put_text(&pwin[0], &bmpfiles[actual][0]);
if (((bmpfiles[actual][9] == 'B') ||
(bmpfiles[actual][9] == 'b')) &&
((bmpfiles[actual][10] == 'M') ||
(bmpfiles[actual][10] == 'm')) &&
((bmpfiles[actual][11] == 'P') ||
(bmpfiles[actual][11] == 'p')))
{
swim_put_text(&pwin[0], " :Added\n");
actual++;
}
else
{
swim_put_text(&pwin[0], " :Skipping\n");
}
status = fx_directory_next_entry_find(&cf_card,
&bmpfiles[actual][0]);
}
/* Small (4s) delay to peruse file list */
swim_put_text(&pwin[0], "Image processing started...\n");
tx_thread_sleep(1000);
while(1)
{
image = 0;
while (image < actual)
{
/* Load file into image structure */
status = fx_file_open(&cf_card, &cf_file,
&bmpfiles[image][0], FX_OPEN_FOR_READ);
/* Read BMP file fields into BMP structure */
fx_file_read(&cf_file, &bmp->bftype,
sizeof(bmp->bftype), &tmp);
fx_file_read(&cf_file, &bmp->bfsize,
sizeof(bmp->bfsize), &tmp);
fx_file_read(&cf_file, &bmp->rsv1,
sizeof(bmp->rsv1), &tmp);
fx_file_read(&cf_file, &bmp->dataoffset,
sizeof(bmp->dataoffset), &tmp);
fx_file_read(&cf_file, &bmp->bisize,
sizeof(bmp->bisize), &tmp);
fx_file_read(&cf_file, &bmp->biwidth,
sizeof(bmp->biwidth), &tmp);
fx_file_read(&cf_file, &bmp->biheight,
sizeof(bmp->biheight), &tmp);
fx_file_read(&cf_file, &bmp->biplanes,
sizeof(bmp->biplanes), &tmp);
fx_file_read(&cf_file, &bmp->bibitcount,
sizeof(bmp->bibitcount), &tmp);
fx_file_read(&cf_file, &bmp->bicompressn,
sizeof(bmp->bicompressn), &tmp);
fx_file_read(&cf_file, &bmp->bisizeimage,
sizeof(bmp->bisizeimage), &tmp);
fx_file_read(&cf_file, &bmp->rsv3,
sizeof(bmp->rsv3), &tmp);
fx_file_read(&cf_file, &bmp->rsv4,
sizeof(bmp->rsv4), &tmp);
fx_file_read(&cf_file, &bmp->buclrused,
sizeof(bmp->buclrused), &tmp);
fx_file_read(&cf_file, &bmp->biclrimp,
sizeof(bmp->biclrimp), &tmp);
/* Read rest of image until processing is complete */
fx_file_read(&cf_file, (UNS_32 *) bmp->ct_data,
((800 * 600 * 4) + (256 * 4)), &tmp);
/* Convert image to frame buffer depth */
bmp_convert_image(bmp, &xsize, &ysize, fbt);
/* Display image in active frame buffer */
swim_put_scale_image(&pwin[fbindex], fbt, (INT_32) xsize,
(INT_32) ysize);
abl_ioctl(lcddev, LCD_SET_UP_FB, (INT_32) fbphy[fbindex]);
/* Switch to inactive frame buffer for next image render */
fbindex = 1 - fbindex;
/* Small wait of 15 seconds */
tx_thread_sleep((15 * 1000));
image++;
/* Close the file */
status = fx_file_close(&cf_file);
}
}
}
/***********************************************************************
*
* Function: c_entry
*
* Purpose: Main entry point for image - transfers from startup code
*
* Processing:
* See function.
*
* Parameters: None
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void c_entry()
{
INT_32 regionsize;
/* Initialize the IO system */
abl_api_init((UNS_32 *) NULL);
/* Register LCD, timer, and UART drivers in API - instead of
registering, the direct driver functions can also be called
directly. */
abl_api_register((INT_32) CLCDC, (void *) lcd_open,
(void *) lcd_close, (void *) lcd_read,
(void *) lcd_write, (void *) lcd_ioctl);
abl_api_register((INT_32) TIMER1, (void *) timer_open,
(void *) timer_close, (void *) timer_read,
(void *) timer_write, (void *) timer_ioctl);
/* Initialize the CPLD interface driver */
cpld_init();
/* Set virtual address of MMU table (needed for VIC driver
functions) */
cp15_set_vmmu_addr((UNS_32 *) cp15_get_ttb());
/* Initialize the interrupt system */
vic_initialize(0xC0000000);
/* Attach the ThreadX interrupt handler to the IRQ vector */
vic_install_arm_handler(IRQ_VEC, (PFV) __tx_irq_handler);
/* Install VIC1 and VIC2 handlers (used in IRQ) */
vic_install_arm_handler(VIC1_IRQ_VEC, (PFV) vic1_irq_dispatcher);
vic_install_arm_handler(VIC2_IRQ_VEC, (PFV) vic2_irq_dispatcher);
/* Enable GPIO signals PE4..7 and PD0..7 as LCD signals */
gpio_lcd_signal_select(GPIO_LCDV_0_15);
/* Open LCD display */
lcddev = abl_open((INT_32) CLCDC, (INT_32) &LCDPANEL);
/* Get physical addresses of frame buffers */
fbphy[0] = cp15_map_virtual_to_physical(fblog[0]);
fbphy[1] = cp15_map_virtual_to_physical(fblog[1]);
/* Set frame buffer */
abl_ioctl(lcddev, LCD_SET_UP_FB, (INT_32) fbphy[0]);
/* Also make sure that the CPLD_JTAG_OE signal is in the
correct state */
gpio_set_data_dir(GPIO_PORT_A, 0x04, GPIO_OUTPUT);
gpio_data_write(GPIO_PORT_A, 0x04);
/* Set color depth to 16 bits per pixel */
abl_ioctl(lcddev, LCD_SET_BPP, 16);
/* For displays that require more bandwidth, set DMA to request
a transfer on 4 words empty instead of the default 8. This may
help prevent 'display tearing' due to a starved LCD controller */
regionsize = abl_ioctl(lcddev, LCD_GET_STATUS, LCD_XSIZE) *
abl_ioctl(lcddev, LCD_GET_STATUS, LCD_YSIZE) *
sizeof (COLOR_T);
if (regionsize >= (800 * 600 * 2))
{
/* Displays of 800x600 pixels and 16-bits of color (or larger)
will use faster DMA requests */
abl_ioctl(lcddev, LCD_DMA_ON_4MT, 1);
}
/* HRTFT/TFT panel board initialization only */
if ((abl_ioctl(lcddev, LCD_GET_STATUS, LCD_PANEL_TYPE) == HRTFT) ||
(abl_ioctl(lcddev, LCD_GET_STATUS, LCD_PANEL_TYPE) == ADTFT) ||
(abl_ioctl(lcddev, LCD_GET_STATUS, LCD_PANEL_TYPE) == TFT))
{
/* Enable power to the LCD panel (sets VDDEN on PC3) */
gpio_set_data_dir(GPIO_PORT_C, 0x08, GPIO_OUTPUT);
gpio_data_write(GPIO_PORT_C, 0x08);
}
else
{
/* Other displays - do nothing (yet) */
;
}
/* Enable display */
abl_ioctl(lcddev, LCD_PWENABLE, 1);
/* Save display size */
xsz = abl_ioctl(lcddev, LCD_GET_STATUS, LCD_XSIZE);
ysz = abl_ioctl(lcddev, LCD_GET_STATUS, LCD_YSIZE);
/* Setup timer 1 for a 1000Hz (1mS) interrupt */
timer1dev = abl_open((INT_32) TIMER1, 0);
abl_ioctl(timer1dev, TIMER_SET_USECS, (1 * TIMER_MSEC));
/* Normally, we would put the address of the timer interrupt in
the IRQ dispatcher, but the ThreadX interrupt handler in the
tx_ill.s file directly handles the timer 1 interrupt so the
following statement is not needed */
/*
vic_install_handler(VIC_TC1UINTR, VIC_VECTORED, **some_timer_isr**);
*/
/* Enable timer interrupt in the interrupt controller */
vic_int_enable(VIC_TC1UINTR, TRUE);
/* Start timer 1 */
abl_ioctl(timer1dev, TIMER_ENABLE, 1);
/* Initialize heap memory */
abl_heap_init((UNS_32 *) 0xC0100000, 0xC1000000);
/* Allocate BMP data */
bmp = (BMP_T *) abl_new(sizeof (BMP_T));
bmp->ct_data = (INT_32) abl_new((800 * 600 * 4) + (256 * 4));
fbt = (COLOR_T *) abl_new((800 * 600 * sizeof (COLOR_T)) + 16);
/* Enter the ThreadX kernel. */
tx_kernel_enter();
}
/***********************************************************************
*
* Function: tx_application_define
*
* Purpose: Setup ThreadX tasks
*
* Processing:
* See function.
*
* Parameters:
* first_unused_memory: First address of unused memory
*
* Outputs: None
*
* Returns: Nothing
*
* Notes: None
*
**********************************************************************/
void tx_application_define(void *first_unused_memory)
{
CHAR *pointer;
/* Create a byte memory pool from which to allocate the thread stacks. */
tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory,
DEMO_STACK_POOL_SIZE);
/* Allocate the stack for thread 0 */
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE,
TX_NO_WAIT);
/* Create thread 0 */
tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,
pointer, DEMO_STACK_SIZE, 16, 16, 1, TX_AUTO_START);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -