// DIFastDlg.cpp : implementation file // #include "stdafx.h" #include "AIOUSB.h" #include "DIFast.h" #include "DetectDialog.h" #include "DIFastDlg.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif unsigned long DeviceIndex = diOnly; ///////////////////////////////////////////////////////////////////////////// // CDIFastDlg dialog CDIFastDlg::CDIFastDlg(CWnd* pParent /*=NULL*/) : CDialog(CDIFastDlg::IDD, pParent) { //{{AFX_DATA_INIT(CDIFastDlg) m_BlurbText = _T("This sample receives files sent by the DOFast sample, or equivalent. The protocol is simple:" "\r\n" "\r\n• 2 words: BodyLen, Intel DWord = length of file contents, in bytes." "\r\n• 1 word: NameLen = length of filename, in bytes." "\r\n• 253 words: Filename, in Windows ANSI, as words in Intel byte order." "\r\n• [BodyLen/2, round up to multiple of 256] words: File contents, as words in Intel byte order." "\r\n" "\r\nThis protocol uses the high-speed USB packet size of 512 bytes."); //}}AFX_DATA_INIT m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void CDIFastDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDIFastDlg) DDX_Control(pDX, IDC_LOGLIST, m_LogList); DDX_Text(pDX, IDC_BLURBEDIT, m_BlurbText); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CDIFastDlg, CDialog) //{{AFX_MSG_MAP(CDIFastDlg) ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDSTART, OnStart) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CDIFastDlg message handlers void CDIFastDlg::Log(LPCTSTR Str) { m_LogList.SetCurSel(m_LogList.AddString(Str)); } BOOL CDIFastDlg::OnInitDialog() { CDialog::OnInitDialog(); SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon unsigned long PID; unsigned long Status = QueryDeviceInfo(DeviceIndex, &PID, NULL, NULL, NULL, NULL); if ( Status != ERROR_SUCCESS ) PID = 0; switch ( PID ) { case 0x8008: //Input-only board //case 0x8009: //Output-only board case 0x800A: //Input-only board case 0x800B: case 0x800C: case 0x800D: //Input-only board //case 0x800E: //Output-only board case 0x800F: break; default: DetectDialog MyDetectDialog; if (MyDetectDialog.DoModal() == IDOK) DeviceIndex = MyDetectDialog.index; else exit(1) ; break; } double ReadClockHz = 0; //External or "off" double WriteClockHz = 0; //External or "off" DIO_StreamSetClocks(DeviceIndex, &ReadClockHz, &WriteClockHz); DIO_StreamOpen(DeviceIndex, true); DIO_StreamClose(DeviceIndex); unsigned char OutMask = 0x08; //A, B, and C input; D is opposite C, so it's output. unsigned long DIOData = 0xFFFFFFFF; unsigned char TristateMask = 0x00; DIO_ConfigureEx(DeviceIndex, &OutMask, &DIOData, &TristateMask); UpdateData(false); return TRUE; // return TRUE unless you set the focus to a control } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CDIFastDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CDIFastDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } //This is the function that actually reads chunks of data(frames). This // sample receives files, not realtime data, so this function just reads // chunks until it gets the whole file or there's an error. unsigned long DoTransferData(unsigned long TransferPackets, const void *Buffer) { unsigned long BytesTransferred = 0, WordsLeft = TransferPackets * 256, Status; PUSHORT NextPt = PUSHORT(Buffer); do { Status = DIO_StreamFrame(DeviceIndex, WordsLeft, NextPt, &BytesTransferred); if ( Status != ERROR_SUCCESS ) break; //BytesTransferred will always be integral words. unsigned long WordsTransferred = BytesTransferred / 2; WordsLeft -= WordsTransferred; NextPt += WordsTransferred; } while ( WordsLeft > 0 ); return Status; } typedef struct { unsigned long BodyLen; unsigned short NameLen; char FileName[506]; } THeader; void CDIFastDlg::OnStart() { unsigned short *Buf; THeader HeaderBuf; unsigned long Status, ContentPackets; CString FileName; Log("Listening for a file..."); DIO_StreamOpen(DeviceIndex, true); //Get header. Status = DoTransferData(1, &HeaderBuf); if ( Status != ERROR_SUCCESS ) { CString ErrorStr; ErrorStr.Format("Error %ld reading file header, aborting.", Status); Log(ErrorStr); } else { HeaderBuf.FileName[HeaderBuf.NameLen] = '\0'; FileName = HeaderBuf.FileName; //Get file body. ContentPackets = HeaderBuf.BodyLen; if ( ContentPackets & 0x1FF ) ContentPackets += 0x200; //Round up to integral packets. ContentPackets /= 0x200; Buf = PUSHORT(malloc(ContentPackets * 2 * 512)); Status = DoTransferData(ContentPackets, Buf); if ( Status != ERROR_SUCCESS ) { free(Buf); CString ErrorStr; ErrorStr.Format("Error %ld reading file body, aborting.", Status); Log(ErrorStr); } else { CFile NewFile(FileName, CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone); NewFile.Write(Buf, HeaderBuf.BodyLen); NewFile.Close(); free(Buf); Log("Saved file " + FileName + "."); } } DIO_StreamClose(DeviceIndex); Log("Done."); }