📄 picture_demo.c
字号:
/***********************************************************************
* $Workfile: picture_demo.c $
* $Revision: 1.2 $
* $Author: WellsK $
* $Date: Dec 03 2003 14:23:44 $
*
* Project: SDK7A400 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/lh7a400/bsps/sdk7a400/demos/filex/picture_demo.c-arc $
*
* Rev 1.2 Dec 03 2003 14:23:44 WellsK
* Changed frame buffer addresses to virtual address to better
* support future LOLO mappings.
*
* Rev 1.1 Oct 28 2003 15:30:48 WellsK
* Updated to use common LCD parameters.
*
* Rev 1.0 Oct 02 2003 11:56:54 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 "lh7a400_clcdc_driver.h"
#include "lh7a400_gpio_driver.h"
#include "lh7a400_timer_driver.h"
#include "lh7a400_int_driver.h"
#include "sdk7a400_cpld_driver.h"
#include "sdk7a400_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 logical addresses - be careful that the ThreadX byte pool
doesn't get too big, as it will collide with the frame buffer,
ThreadX stacks, etc. Ideally, we would like to use the ThreadX
functions to allocate a byte pool for the frame buffer and then
convert the logical address to a physical address for the LCD
hardware. Next build maybe. */
#define FBLOG1 0xC1C00000 /* Logical address frame buffer 1 */
#define FBLOG2 0xC1E00000 /* Logical address frame buffer 2 */
/* Physical 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 */
int_initialize(0xC0000000);
/* Attach the ThreadX interrupt handler to the IRQ vector */
int_install_handler(IRQ_VEC, (PFV) __tx_irq_handler);
/* Setup LCD muxing for all 16 data bits */
gpio_lcd_signal_select(GPIO_LCDV_0_15);
/* Setup LCD paramaters in the LCD controller */
lcddev = abl_open((INT_32) CLCDC, (INT_32) &LCDPANEL);
/* Get physical address of frame buffers */
fbphy[0] = (UNS_32 *) cp15_map_virtual_to_physical(fblog[0]);
fbphy[1] = (UNS_32 *) cp15_map_virtual_to_physical(fblog[1]);
/* Set frame buffer address */
abl_ioctl(lcddev, LCD_SET_UP_FB, (INT_32) fbphy[0]);
/* Make sure shared JTAG signal on PA2 is not active */
gpio_set_data_dir(GPIO_PORT_A, 0x04, GPIO_OUTPUT);
gpio_data_write(GPIO_PORT_A, 0x04);
/* Turn on the LCD backlight */
cpld_enable_lcd_veeen(TRUE);
/* 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);
}
/* Enable LCD controller and power signals */
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 */
/*
int_install_handler(INT_TC1UINTR, **some_timer_isr**);
*/
/* Enable timer interrupt in the interrupt controller */
int_enable(INT_TC1UINTR);
/* 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 + -