/*---------------------------------------------------------------------- File: dcthost.c Description: A p.c. program to work with dctdma. Perform a DCT IDCT on a picture using DSP. Blocks are sent and received in 64-word (32-bit) blocks via PCI-DMA. It loads the dsp program in DCTDMA.OUT before running. * Note requires Microsoft(TM) Visual C++ 5.0 to run. * Also requires to link with evm6x.lib. * Make sure evm6x.dll is available. ** If there is error reading, increase the timeout value in the evm6x_set_timeout (time_out_ms) function. -----------------------------------------------------------------------*/ #include #include #include #include #include "scenary.h" #include "evm6xdll.h" /******************************************************** Display Routines. *********************************************************/ HWND hwnd1, hwnd2; HBITMAP hbitmap1, hbitmap2; HDC memdc1, memdc2; volatile BOOL bInit; LRESULT CALLBACK DisplayWndProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAINTSTRUCT ps; HDC hdc; switch (uMsg) { case WM_PAINT: BeginPaint (hwnd, &ps); hdc = GetDC (hwnd); BitBlt (hdc, 0, 0, 256, 256, (hwnd==hwnd1)?memdc1:memdc2, 0, 0, SRCCOPY); ReleaseDC (hwnd, hdc); EndPaint (hwnd, &ps); break; default: return DefWindowProc (hwnd, uMsg, wParam, lParam); } return 0; } DWORD WINAPI DisplayThread (void *dummy) { MSG msg; WNDCLASS wndClass; char lpClassName[] = "DISPLAY_TEST_DCT"; RECT rect; HDC hdc; memset(&wndClass, 0, sizeof(wndClass)); wndClass.style = CS_HREDRAW | CS_VREDRAW; wndClass.hInstance = 0; wndClass.hIcon = NULL; wndClass.hCursor = LoadCursor (NULL, IDC_ARROW); wndClass.hbrBackground = GetStockObject (BLACK_BRUSH); wndClass.lpszMenuName = NULL; wndClass.lpfnWndProc = DisplayWndProc; wndClass.lpszClassName = lpClassName; RegisterClass(&wndClass); rect.top = rect.left = 0; rect.right = rect.bottom = 256; AdjustWindowRect (&rect, WS_CAPTION, FALSE); hwnd1 = CreateWindow (lpClassName, "Raw Image Display", WS_POPUP|WS_CAPTION|WS_VISIBLE, 0, 0, rect.right-rect.left, rect.bottom-rect.top, NULL, NULL, NULL, NULL); hwnd2 = CreateWindow (lpClassName, "Reconstructed Image Display", WS_POPUP|WS_CAPTION|WS_VISIBLE, rect.right-rect.left, 0, rect.right-rect.left, rect.bottom-rect.top, NULL, NULL, NULL, NULL); hdc = GetDC (hwnd1); memdc1 = CreateCompatibleDC (hdc); hbitmap1 = CreateCompatibleBitmap (hdc, 256, 256); SelectObject (memdc1, hbitmap1); SelectObject (memdc1, GetStockObject (BLACK_BRUSH)); SelectObject (memdc1, GetStockObject (BLACK_PEN)); Rectangle (memdc1, 0, 0, 256, 256); ReleaseDC (hwnd1, hdc); hdc = GetDC (hwnd2); memdc2 = CreateCompatibleDC (hdc); hbitmap2 = CreateCompatibleBitmap (hdc, 256, 256); SelectObject (memdc2, hbitmap2); SelectObject (memdc2, GetStockObject (WHITE_BRUSH)); SelectObject (memdc2, GetStockObject (WHITE_PEN)); Rectangle (memdc2, 0, 0, 256, 256); ReleaseDC (hwnd2, hdc); bInit = TRUE; while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage(&msg); } return msg.wParam; } void DisplayInit (void) { DWORD dwId; bInit = FALSE; CreateThread (NULL, 0, DisplayThread, NULL, 0, &dwId); while (!bInit); return; } void DisplayBlock (int display, int row, int col, int *pRawBlock) { int x, y; RECT rect; int int_pixel; unsigned char char_pixel; HWND hwnd; HDC memdc, hdc; int pBlock [64]; int *ptr; memcpy (pBlock, pRawBlock, 64*sizeof (int)); ptr = pBlock; if (display == 1) { hwnd = hwnd1; memdc = memdc1; } else { hwnd = hwnd2; memdc = memdc2; } for (y=0;y<8;y++) { for (x=0;x<8;x++) { int_pixel = *ptr++; if (int_pixel<0) char_pixel = 0; else if (int_pixel>255) char_pixel = 255; else char_pixel = (char) int_pixel; SetPixel (memdc, col*8+x, row*8+y, RGB (char_pixel, char_pixel, char_pixel)); } } rect.left = col*8; rect.right=rect.left+7; rect.top = row*8; rect.bottom=rect.top+7; hdc = GetDC (hwnd); SendMessage (hwnd, WM_PAINT, (WPARAM) hdc, 0); ReleaseDC (hwnd, hdc); return; } /******************************************************** DSP Routines. *********************************************************/ #define LOAD_DSP_CODE HANDLE hBoard; HANDLE hEvent; #define DSP_OTHERS -1 #define DSP_DIRECT 0x00 #define DSP_DCT 0x01 #define DSP_IDCT 0x02 #define DSP_DCT_QUANTIZE 0x03 #define DSP_IDCT_UNQUANTIZE 0x04 BOOL DspBoardInit (void) { int dummy; int i; #ifdef LOAD_DSP_CODE evm6x_reset_board(hBoard); for (i=0; i<5; i++) { Sleep(100); printf ("\rReseting the DSP, please wait \\"); Sleep(100); printf ("\rReseting the DSP, please wait |"); Sleep(100); printf ("\rReseting the DSP, please wait /"); Sleep(100); printf ("\rReseting the DSP, please wait -"); } evm6x_reset_dsp (hBoard, HPI_BOOT); evm6x_init_emif (hBoard, NULL); if (!evm6x_coff_load (hBoard, NULL, "DCTDMA.OUT", FALSE, FALSE, FALSE)) { //evm6x_unreset_dsp (hBoard); return FALSE; } evm6x_unreset_dsp (hBoard); #endif evm6x_retrieve_message (hBoard, &dummy); // Clear previous mail-box message. return TRUE; } BOOL DspDriverInit (void) { char str[80]; hBoard = evm6x_open (0, TRUE); if (hBoard == INVALID_HANDLE_VALUE) return FALSE; evm6x_set_timeout (hBoard, 1000); evm6x_abort_write (hBoard); evm6x_clear_message_event (hBoard); sprintf (str, "%s%d", EVM6X_GLOBAL_MESSAGE_EVENT_BASE_NAME, 0); hEvent = OpenEvent (SYNCHRONIZE, FALSE, str); if (hEvent==NULL) { evm6x_close (hBoard); return FALSE; } return TRUE; } void DspDriverClose (void) { CloseHandle (hEvent); evm6x_close (hBoard); return; } int DspCommand (int *input, int *output, int command) { EVM6XDLL_MESSAGE msg; int count; int wait_ms = 3000; // Time out for dsp to process a block. //===== Send command to dsp via mailbox ===== msg = command; if (!evm6x_send_message (hBoard, &msg)) return 1; //===== Send 64-word block via PCI-DMA to DSP for processing ===== count = 256; if (!evm6x_write (hBoard, (unsigned long *) input, &count)) return 2; if (count!=256) return 3; //===== Wait for mailbox message from DSP ===== while (!WaitForSingleObject (hEvent, 1)) { wait_ms-=1; if (wait_ms == 0) return 4; } evm6x_retrieve_message (hBoard, &msg); //===== Read processed 64-word block via PCI-DMA from DSP ===== count = 256; if (!evm6x_read (hBoard, (unsigned long *) output, &count)) return 5; if (count!=256) return 6; return 0; } /******************************************************** Main Routines. *********************************************************/ int main (int argc, char *argv[]) { int row, col; int x, y; int pRawBlock[64]; int pDctBlock[64]; int pReconBlock[64]; int *pTmp; int nReturn; //===== Initialize the DSP driver, DSP board and display ===== if (!DspDriverInit ()) { printf ("Error Initialising Evm6x driver!\n"); return -1; } if (!DspBoardInit ()) { printf ("Error Initialising Evm6x board!\n"); DspDriverClose (); return -1; } DisplayInit (); //===== Perform DSP communications (each transaction involves 64 32-bit words ===== row = 0; col = 0; while (1) { /* User quits before program finishes */ if (kbhit()) { getch(); break; } /* Collect 64-pixel block and arrange into contiguous block and display it. */ pTmp = pRawBlock; for (y=0;y<8;y++) for (x=0;x<8;x++) *pTmp++ = (int) image_in[(col*8+x)+(row*8+y)*256]; DisplayBlock (1, row, col, pRawBlock); /* Send a DSP command: DCT */ if ((nReturn=DspCommand (pRawBlock, pDctBlock, DSP_DCT))!=0) { switch (nReturn) { case 1: printf ("Error in Mailbox Message (row %d, col %d)!\n", row, col); break; case 2: printf ("Error in DmaWrite (row %d, col %d)!\n", row, col); break; case 3: printf ("Cannot complete DmaWrite (row %d, col %d)!\n", row, col); break; case 4: printf ("DSP process takes too long (row %d, col %d)!\n", row, col); break; case 5: printf ("Error in DmaRead (row %d, col %d)!\n", row, col); break; case 6: printf ("Cannot complete DmaRead (row %d, col %d)!\n", row, col); break; } break; } /* Send a DSP command: IDCT */ if ((nReturn=DspCommand (pDctBlock, pReconBlock, DSP_IDCT))!=0) { switch (nReturn) { case 1: printf ("Error in Mailbox Message (row %d, col %d)!\n", row, col); break; case 2: printf ("Error in DmaWrite (row %d, col %d)!\n", row, col); break; case 3: printf ("Cannot complete DmaWrite (row %d, col %d)!\n", row, col); break; case 4: printf ("DSP process takes too long (row %d, col %d)!\n", row, col); break; case 5: printf ("Error in DmaRead (row %d, col %d)!\n", row, col); break; case 6: printf ("Cannot complete DmaRead (row %d, col %d)!\n", row, col); break; } break; } /* Display processed block */ DisplayBlock (2, row, col, pReconBlock); /* Next block */ if (++col == 32) { col = 0; if (++row == 32) { DspDriverClose (); printf ("Done!. Press any key to quit\n"); getch (); return 0; } } } //===== Close the connection with the DSP driver ===== DspDriverClose (); return 0; }