#include <windows.h> #include <stdlib.h> // DirectDSP® software package include files #include "enmgr.h" // Engine Manager #include "hwmgr.h" // Hardware Manager #include "hwlib.h" // Hardware Library // some global variables ...note: many variable and type declarations omitted for brevity... HANDLE FAR hEngine = NULL; // declare at least one variable FAR to limit this to a single-instance program HANDLE hBoard = NULL; BOOL fBoardInitialized = FALSE; char szBoard[30]; UINT uMemArch; int wBuflen = 1024; DWORD dwMemSize,dwBufferBaseAddr; HWND hwndScope = NULL; WORD wBoardClass; float FsDesired = 22050.0; float FsActual; DWORD dwFsMode; short int ChanList = 0; int PASCAL WinMain (HANDLE hInstance, HANDLE hPrevInst, LPSTR lpszCmdParam, int nCmdShow) { // comment this call if status messages from HwLib should not be visible DSShowEngMgrStatusWindow(); // turn on debug status window in Engine Manager // show hardware selector dialog (Hardware Manager); returns board designator string // note: if hardware choice is fixed, then skip this call and use correct board designator string // in DSAssignBoard call below if (DSShowHardwareSelectorDlg(NULL, szBoard) == IDCANCEL) goto cleanup; // open engine hEngine = DSEngineOpen(DS_EO_HSM, NULL); // first try to open Hypersignal-Macro or // Hypersignal-Macro EX as engine if (!hEngine) { hEngine = DSEngineOpen(DS_EO_HSA, NULL); // if that doesn't work, try // Hypersignal-Acoustic if (!hEngine) { itoa(DSGetHWLibErrorStatus(), tmpstr, 10); lstrcat(tmpstr, " is error code; DSEngineOpen failed"); MessageBox(GetActiveWindow(), tmpstr, "Dscope Test Prog", MB_OK); goto cleanup; } } // assign a board handle: engine handle, board designator, bus type, IO base addr, Mem base addr hBoard = DSAssignBoard(hEngine, szBoard, NULL, NULL, NULL); // initialize the board; make sure it's installed, reset all processors fBoardInitialized = DSInitBoard(hBoard); if (!fBoardInitialized) { itoa(DSGetEngineErrorStatus(hEngine), tmpstr, 10); lstrcat(tmpstr, " is error code; DSInitBoard failed"); MessageBox(GetActiveWindow(), tmpstr, "Dscope Test Prog", MB_OK); goto cleanup; } // interrogate engine for board type values wBoardClass = DSGetBoardClass(hBoard); // get memory architecture uMemArch = DSGetMemArch(hBoard); if (uMemArch == NULL) { MessageBox(GetActiveWindow(), "DSGetMemArch failed","Dscope Test Prog", MB_OK); goto cleanup; } // determine sampling rate ctrl. reg. value, and actual rate (closest rate possible to desired); // CalcSampFreq returns ctrl. reg. value directly, uses ptr to return actual sampling frequency (in Hz) dwFsMode = DSCalcSampFreq(hBoard, FsDesired, 1, &ChanList, &FsActual); // demo assumes 1 channel, initial value 22.05 kHz // load executable DSP code file (usually a COFF file produced by DSP manufacturer's linker) if (!DSLoadFileProcessor(hBoard, NULL, 1)) { // load default file for the board type (processor 0 only) MessageBox(GetActiveWindow(), "DSLoadFileBoard: problem loading file", "Dscope Test Prog", MB_OK); goto cleanup; } // get the memory size, (note that this currently has to be done after LoadFile) dwMemSize = DSGetMemSize(hBoard, 0x01); // processor 0 only // reset the DSP board (should already be in reset state; processor 0 only) DSResetProcessor(hBoard, 0x01); // send down some important variables (needed if a default Hypersignal DSP file is being used) DSPutDSPProperty(hBoard, DSP_BOARDCLASS, wBoardClass & 0x0ff); // main type in low byte DSPutDSPProperty(hBoard, DSP_BOARDSUBCLASS, wBoardClass >> 8); // subtype in high byte DSPutDSPProperty(hBoard, DSP_OPMODE, 2); // Dig. Scope is mode 2 DSPutDSPProperty(hBoard, DSP_FILTTYPE1, 0); // disable trace 1 real-time filter DSPutDSPProperty(hBoard, DSP_FILTTYPE2, 0); // disable trace 2 real-time filter DSPutDSPProperty(hBoard, DSP_TRIGLEVEL, 0); // free-run triggering DSPutDSPProperty(hBoard, DSP_TRIGCHANLIST, 0); DSPutDSPProperty(hBoard, DSP_BUFLEN, wBuflen); // buffer size DSPutDSPProperty(hBoard, DSP_HOSTBUFNUM, 0); DSPutDSPProperty(hBoard, DSP_BUFNUM, 0); DSPutDSPProperty(hBoard, DSP_CHANLIST, 0); // starting channel DSPutDSPProperty(hBoard, DSP_NUMCHAN, 1); // number of channels DSPutDSPProperty(hBoard, DSP_GAINLIST, 0); // gain list DSPutDSPProperty(hBoard, DSP_FSMODE, dwFsMode); // sampling rate control register (mode value) DSPutDSPProperty(hBoard, DSP_FSVALUE, *((long*)&FsActual)); // actual sampling rate (in Hz) // get address of input time domain data dwBufferBaseAddr = DSGetDSPProperty(hBoard, DSP_TIMDATAADDR); if (!hPrevInst) { ...note: window class registration and CreateWindow code omitted for brevity... hwndScope = CreateWindow(... ShowWindow(hwndScope, nCmdShow); UpdateWindow(hwndScope); } // scope window is born; turn the board loose... (processor 0 only) DSRunProcessor(hBoard, 0x01); // tell engine to wait for a buffer, and then send a BUFRDY message to our window when one is ready DSRegisterEngineMsgWnd(hEngine, DS_REMW_SETDSPDATARDYMSG, hwndScope); // register callback window for buffer ready messages DSWaitForBuffer(hBoard, 0, NULL, DS_WFB_POLLED); // time to give up and become a Windows animal while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage (&msg); DispatchMessage (&msg); } cleanup: if (fBoardInitialized) DSDisableBoard(hBoard); // disable board (all processors) if (hBoard != NULL) DSFreeBoard(hBoard); if (hEngine != NULL) DSEngineClose(hEngine); return msg.wParam; } long WINAPI _export WndProc(HWND hwnd, WORD wMsg, WORD wParam, LONG lParam) { ...note: most variable declarations omitted for brevity... static HGLOBAL hBuf = NULL; static int far* buf; static short int nCurBuf = 0; switch (wMsg) { ...note: other message-processing code omitted for brevity... case WM_CREATE: // allocate some memory to hold board buffers hBuf = GlobalAlloc(GMEM_ZEROINIT | GMEM_MOVEABLE | GMEM_DISCARDABLE, MAX_BUF_LEN*sizeof(int)); break; case WM_DSPENGINE_BUFRDY: // message sent by DSP engine when data buffer is ready buf = (int far*)GlobalLock(hBuf); // transfer below illustrates two common type of DSP memory architectures if (uMemArch == DS_GMA_VECTOR) { // vector data memory if (nCurBuf == 0) uStatus = DSGetMem(hBoard, DS_GM_VECTOR_DATA_X, dwBufferBaseAddr, DS_GM_SIZE16, buf, wBuflen); else uStatus = DSGetMem(hBoard, DS_GM_VECTOR_DATA_Y, dwBufferBaseAddr, DS_GM_SIZE16, buf, wBuflen); } else { // linear data/prog memory, or modified harvard arch. with linear data memory uStatus = DSGetMem(hBoard, DS_GM_LINEAR_DATA_RT, dwBufferBaseAddr+nCurBuf*wBuflen, DS_GM_SIZE16, buf, wBuflen); } GlobalUnlock(hBuf); if (!uStatus) MessageBox(hwnd, "DSGetMem: problem with point transfer", "Dscope Test Prog", MB_OK); else FirstBufferRcvd = TRUE; nCurBuf ^= 1; // switch buffers DSPutDSPProperty(hBoard, DSP_HOSTBUFNUM, nCurBuf); // write the new buffer # if (!IsIconic(hwnd)) DSWaitForBuffer(hBoard, nCurBuf, NULL, DS_WFB_POLLED); break; } return 0L; }