(MSDN)Make time-consuming for loop go background (ReadFile, WriteFile, Overlapped structure) - readfile

My goal is to read dataBuffer from A and write the data to device B repeatedly using MSDN APIs. I am using ReadFileEx and WriteFileEx to request overlapped I/O reading and writing, so that the original time-consuming for-loop using ReadFile and WriteFile can now go background and the UI main thread can be responsive all the time.
I first create structure MY_OVERLAPPED which inherits from OVERLAPPED and two more elements are added, event is a pointer to MyClass which can help access the variables in that class, handles, dataBuffer, etc., and count is for resetting Offset value each time before ReadFileEx is called. The reading position is count*524288, since I read 524288 bytes each time and store in dataBuffer.
My question is:
1.how do I not use the inherited OVERLAPPED structure's Offset element to change reading position, such as using reference count?
2.The following code does not work the way I think. The ReadCompletionRoutine can only run one time and end up with receiving extremely long offset number. For now I presume that's the issue and focus on it first, so please feel free to correct any of my code structure.
My code flow is:
1. set reading point to 0
2. call overlapped ReadFileEx
3. ReadCompletion will be called, the data read will be written using overlapped WriteFileEx
4. WriteCompletion will be called, set pointer to next 524288 bytes and read
5.(and so on) two completion routines will call each other till all data is transfered
MyClass.h
struct MY_OVERLAPPED: OVERLAPPED {
MyClass *event;
unsigned long long count;
};
MyClass.cpp - main
MY_OVERLAPPED overlap;
memset(&overlap, 0,sizeof(overlap));
//point to this class (MyClass), so all variables can later be accessed
overlap.event = this;
//set read position******how do I not use Offset??
overlap.Offset = 0;
overlap.OffsetHigh = 0;
overlap.count = 0;
//start the first read io request, read 524288 bytes, which 524288 bytes will be written in ReadCompletionRoutine
ReadFileEx(overlap.event->hSource, overlap.event->data, 524288, &overlap, ReadCompletionRoutine);
SleepEx(0,TRUE);
MyClass.cpp - CALLBACKs
void CALLBACK ReadCompletionRoutine(DWORD errorCode, DWORD bytestransfered, LPOVERLAPPED lpOverlapped)
{
//type cast to MY_OVERLAPPED
MY_OVERLAPPED *overlap = static_cast<MY_OVERLAPPED*>(lpOverlapped);
//write 524288 bytes and continue to read next 524288 bytes in WriteCompletionRoutine
WriteFileEx(overlap->event->hDevice, overlap->event->data, 524288, overlap, WriteCompletionRoutine);
}
void CALLBACK WriteCompletionRoutine(DWORD errorCode, DWORD bytestransfered, LPOVERLAPPED lpOverlapped)
{
MY_OVERLAPPED *overlap = static_cast<MY_OVERLAPPED*>(lpOverlapped);
//set new offset to 524288*i, i = overlap->count for next block reading
overlap->count = (overlap->count)+1;
LARGE_INTEGER location;
location.QuadPart = 524288*(overlap->count);
overlap->Offset = location.LowPart;
overlap->OffsetHigh = location.HighPart;
ReadFileEx(overlap->event->hSource, overlap->event->data, 524288, overlap, ReadCompletionRoutine);
}

Related

Direct data into non existing array

I want to find the number of running processes using EnumProcesses function from psapi library. The function requieres an array that will receive the list of process identifiers. It also writes the total number of bytes of found data into a given variable. I didn't want the process list, just their number. I did the following.
DWORD listSize;
DWORD a;
EnumProcesses( &a, 1000*sizeof(DWORD), &listSize ) ;
listSize/=sizeof(DWORD);
printf("%d",listSize);
This writes the real number of processes into listSize however the program stops working after that. I was wondering if there is a way to immediately send the retrieved data into oblivion and just get the number of it.
Not possible. However providing a big enough array isn't really much of an issue on modern systems.
I recommend writing a helper function that wraps this all away for you with a dynamically sized container, so you can handle cases where more processes exist than your original array can hold:
DWORD GetNumberOfProcesses()
{
std::vector<DWORD> processes;
DWORD size = 0;
DWORD bytesReturned = 0;
while (bytesReturned == size)
{
size += 1024 * sizeof(DWORD);
processes.resize(size / sizeof(DWORD));
if (!EnumProcesses(processes.data(), size, &bytesReturned))
{
return -1;
}
}
return bytesReturned / sizeof(DWORD);
}

Arduino Void loop() does not loop

I am new to Arduino. I'm looking at Makecourse tutorial on RC522 RFID reader/writer
I pasted the script below. Basically, it detects a card then writes some data into block 2.
After compiling and uploading the code, I put up one card to the RFID reader, it works - but just once. When i put up a second card, nothing happens. Why?
I've compared this script with other example scripts from the mfrc522 library, they are pretty similar - in the void loop() section, it checks if NewCardPresent... ReadCardSerial... then proceeds to run the intended action. I've tried those example scripts and I can keep presenting a new card to the reader and the script will run again.
However this sketch, the loops only ran once. Is it the structure? How can i edit it to make it run continuously? I apologise if the answer is very simple :/
#include <SPI.h>//include the SPI bus library
#include <MFRC522.h>//include the RFID reader library
#define SS_PIN 10 //slave select pin
#define RST_PIN 5 //reset pin
MFRC522 mfrc522(SS_PIN, RST_PIN); // instatiate a MFRC522 reader object.
MFRC522::MIFARE_Key key;//create a MIFARE_Key struct named 'key', which will hold the card information
void setup() {
Serial.begin(9600); // Initialize serial communications with the PC
SPI.begin(); // Init SPI bus
mfrc522.PCD_Init(); // Init MFRC522 card (in case you wonder what PCD means: proximity coupling device)
Serial.println("Scan a MIFARE Classic card");
// Prepare the security key for the read and write functions - all six key bytes are set to 0xFF at chip delivery from the factory.
// Since the cards in the kit are new and the keys were never defined, they are 0xFF
// if we had a card that was programmed by someone else, we would need to know the key to be able to access it. This key would then need to be stored in 'key' instead.
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;//keyByte is defined in the "MIFARE_Key" 'struct' definition in the .h file of the library
}
}
int block=2;//this is the block number we will write into and then read. Do not write into 'sector trailer' block, since this can make the block unusable.
byte blockcontent[16] = {"makecourse_____"};//an array with 16 bytes to be written into one of the 64 card blocks is defined
//byte blockcontent[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};//all zeros. This can be used to delete a block.
byte readbackblock[18];//This array is used for reading out a block. The MIFARE_Read method requires a buffer that is at least 18 bytes to hold the 16 bytes of a block.
void loop()
{
/*****************************************establishing contact with a tag/card**********************************************************************/
// Look for new cards (in case you wonder what PICC means: proximity integrated circuit card)
if ( ! mfrc522.PICC_IsNewCardPresent()) {//if PICC_IsNewCardPresent returns 1, a new card has been found and we continue
return;//if it did not find a new card is returns a '0' and we return to the start of the loop
}
// Select one of the cards
if ( ! mfrc522.PICC_ReadCardSerial()) {//if PICC_ReadCardSerial returns 1, the "uid" struct (see MFRC522.h lines 238-45)) contains the ID of the read card.
return;//if it returns a '0' something went wrong and we return to the start of the loop
}
// Among other things, the PICC_ReadCardSerial() method reads the UID and the SAK (Select acknowledge) into the mfrc522.uid struct, which is also instantiated
// during this process.
// The UID is needed during the authentication process
//The Uid struct:
//typedef struct {
//byte size; // Number of bytes in the UID. 4, 7 or 10.
//byte uidByte[10]; //the user ID in 10 bytes.
//byte sak; // The SAK (Select acknowledge) byte returned from the PICC after successful selection.
//} Uid;
Serial.println("card selected");
/*****************************************writing and reading a block on the card**********************************************************************/
writeBlock(block, blockcontent);//the blockcontent array is written into the card block
//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
//The 'PICC_DumpToSerial' method 'dumps' the entire MIFARE data block into the serial monitor. Very useful while programming a sketch with the RFID reader...
//Notes:
//(1) MIFARE cards conceal key A in all trailer blocks, and shows 0x00 instead of 0xFF. This is a secutiry feature. Key B appears to be public by default.
//(2) The card needs to be on the reader for the entire duration of the dump. If it is removed prematurely, the dump interrupts and an error message will appear.
//(3) The dump takes longer than the time alloted for interaction per pairing between reader and card, i.e. the readBlock function below will produce a timeout if
// the dump is used.
//mfrc522.PICC_DumpToSerial(&(mfrc522.uid));//uncomment this if you want to see the entire 1k memory with the block written into it.
readBlock(block, readbackblock);//read the block back
Serial.print("read block: ");
for (int j=0 ; j<16 ; j++)//print the block contents
{
Serial.write (readbackblock[j]);//Serial.write() transmits the ASCII numbers as human readable characters to serial monitor
}
Serial.println("");
}
and this is the function that came along with the sketch:
int writeBlock(int blockNumber, byte arrayAddress[])
{
//this makes sure that we only write into data blocks. Every 4th block is a trailer block for the access/security info.
int largestModulo4Number=blockNumber/4*4;
int trailerBlock=largestModulo4Number+3;//determine trailer block for the sector
if (blockNumber > 2 && (blockNumber+1)%4 == 0){Serial.print(blockNumber);Serial.println(" is a trailer block:");return 2;}//block number is a trailer block (modulo 4); quit and send error code 2
Serial.print(blockNumber);
Serial.println(" is a data block:");
/*****************************************authentication of the desired block for access***********************************************************/
byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
//byte PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);
//this method is used to authenticate a certain block for writing or reading
//command: See enumerations above -> PICC_CMD_MF_AUTH_KEY_A = 0x60 (=1100000), // this command performs authentication with Key A
//blockAddr is the number of the block from 0 to 15.
//MIFARE_Key *key is a pointer to the MIFARE_Key struct defined above, this struct needs to be defined for each block. New cards have all A/B= FF FF FF FF FF FF
//Uid *uid is a pointer to the UID struct that contains the user ID of the card.
if (status != MFRC522::STATUS_OK) {
Serial.print("PCD_Authenticate() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 3;//return "3" as error message
}
//it appears the authentication needs to be made before every block read/write within a specific sector.
//If a different sector is being authenticated access to the previous one is lost.
/*****************************************writing the block***********************************************************/
status = mfrc522.MIFARE_Write(blockNumber, arrayAddress, 16);//valueBlockA is the block number, MIFARE_Write(block number (0-15), byte array containing 16 values, number of bytes in block (=16))
//status = mfrc522.MIFARE_Write(9, value1Block, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print("MIFARE_Write() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 4;//return "4" as error message
}
Serial.println("block was written");
}
int readBlock(int blockNumber, byte arrayAddress[])
{
int largestModulo4Number=blockNumber/4*4;
int trailerBlock=largestModulo4Number+3;//determine trailer block for the sector
/*****************************************authentication of the desired block for access***********************************************************/
byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
//byte PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);
//this method is used to authenticate a certain block for writing or reading
//command: See enumerations above -> PICC_CMD_MF_AUTH_KEY_A = 0x60 (=1100000), // this command performs authentication with Key A
//blockAddr is the number of the block from 0 to 15.
//MIFARE_Key *key is a pointer to the MIFARE_Key struct defined above, this struct needs to be defined for each block. New cards have all A/B= FF FF FF FF FF FF
//Uid *uid is a pointer to the UID struct that contains the user ID of the card.
if (status != MFRC522::STATUS_OK) {
Serial.print("PCD_Authenticate() failed (read): ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 3;//return "3" as error message
}
//it appears the authentication needs to be made before every block read/write within a specific sector.
//If a different sector is being authenticated access to the previous one is lost.
/*****************************************reading a block***********************************************************/
byte buffersize = 18;//we need to define a variable with the read buffer size, since the MIFARE_Read method below needs a pointer to the variable that contains the size...
status = mfrc522.MIFARE_Read(blockNumber, arrayAddress, &buffersize);//&buffersize is a pointer to the buffersize variable; MIFARE_Read requires a pointer instead of just a number
if (status != MFRC522::STATUS_OK) {
Serial.print("MIFARE_read() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 4;//return "4" as error message
}
Serial.println("block was read");
}
Arduino Loop() is supposed to be called infinitely unlike you observed.
Therefore you need to check two possibilities as below.
1) any return is happening at the beginning of the loop(). I saw two return statements. You'd better insert debug messages among them so that you could know how far reached before returning this function.
2) any blocking is happing in the loop(). I don't know but you'd better check this as well.
Turns out adding this few lines at the end of the script resolved the issue:
delay(1000);
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
:)
I think the problem is not with the loop. It is ruining continuously. You can check it by using some serial print in the beginning of the loop. Problem is after a card is detected the first time this program doesn't identify a card the second time.So focus on that. The loop is fine.

Sending buffer over message queue

I am trying to send (ideally) a 2d buffer from one process to another, over a Message Queue, but i am attempting to do it first with a 1d buffer.
The functions called to initialization the queue are the following:
HANDLE MsgQueueCommunicator::InitMessageQueue_data(bool IsRead,wchar16_t* wQueueName)
{
MSGQUEUEOPTIONS msgopts;
msgopts.dwSize = sizeof(MSGQUEUEOPTIONS);
msgopts.dwFlags = MSGQUEUE_ALLOW_BROKEN;//0;
msgopts.dwMaxMessages = 0;
msgopts.cbMaxMessage = sizeof(data[20]);
msgopts.bReadAccess = IsRead;
HANDLE hq = CreateMsgQueue(wQueueName, &msgopts);
if ( hq == NULL )
{
return NULL;
}
return hq;
}
Queue initialization in process 1:
HANDLE hMsgQueueR = MsgQueueCommunicator::getInstance()->InitMessageQueue_data(true, L"CommDataStreaming");
Queue initialization in process 2:
HANDLE s_hMsgQueue_Communication = MsgQueueCommunicator::getInstance()->InitMessageQueue_data(false,L"CommDataStreaming");
To write to the queue, i call the following functions:
BOOL MsgQueueCommunicator::Write_Array_To_Queue(HANDLE hq,double data[20])
{
return WriteMsgQueue(hq,(LPVOID)&data, sizeof(data),INFINITE,0);
}
MsgQueueCommunicator::getInstance()->Write_Array_To_Queue(s_hMsgQueue_Communication, usb_data);
Where usb_data is a 1d double array.
To read from the queue, i call the following functions:
BOOL MsgQueueCommunicator::Read_Array_From_Msg_Queue(HANDLE hq,double data[20])
{
DWORD dwBytesRead;
DWORD dwFlags;
return ReadMsgQueue(hq, (LPVOID)&data, sizeof(data), &dwBytesRead, INFINITE, &dwFlags);
}
MsgQueueCommunicator::getInstance()->Read_Array_From_Msg_Queue(hMsgQueueR, usb_data);
Where usb_data is again a 1d double array.
Now, when i check the values that are placed into usb_data[20] before it is written to the queue, i can see that they are non-zero integers. However, when i read the array from the queue and check its values, they are zero. Im not sure what is causing this issue. I've used message queues to send single values, strings, and structs, so i figured i would be able to follow the same procedure to send over an array, but this does not seem to be the case, unless i am overlooking something.
My question is, can i send arrays/buffers over a message queue, and if yes, have I set it up properly?
Note:This is being developed in a windows embedded compact 7 environment and VS2008.
There are several problems with the code provided.
1) Wrong parameter values - you do not need to take an address of the data buffer since the variable is already a pointer to the beginning of the memory that contains the elements. So change (LPVOID)&data to (LPVOID)data.
2) Wrong size - the sizeof operator will return 4 since that is the size of the pointer. In your case you would need to pass 160 as the size (20 * sizeof(double)).
As for variable size writes - this gets a bit more complicated since you need to know how much data to read at the other end. What you can do is use lets say first/first two/first four bytes of the buffer to contain size and then proceed with the data. Then you can have a function that accepts a double array of variable length and writes it. For example:
BOOL Write_Array_To_Queue(HANDLE hq,double data[], unsigned int count)
{
size_t buffer_size = sizeof(count) + count * sizeof(double);
BYTE* buffer = new BYTE[buffer_size];
memcpy(buffer, &count, sizeof(count));
memcpy(buffer + sizeof(count), &data, sizeof(double) * count);
return WriteMsgQueue(hq,(LPVOID)buffer, buffer_size,INFINITE,0);
}
or
BOOL Write_Array_To_Queue(HANDLE hq,double data[], unsigned int count)
{
return WriteMsgQueue(hq,(LPVOID)&count, sizeof(count),INFINITE,0) && WriteMsgQueue(hq,(LPVOID)data, sizeof(double) * count,INFINITE,0);
}
and then in the receiving side you would first read out an unsigned int and then read as much data as denoted by the read value.

Serial communication read not working at all time

I am writing a c++ application for half duplex communication to download data from a device. Following is the class i am using for serial communication.
class CSerialCommHelper
{
HANDLE m_pPortHandle; //Handle to the COM port
HANDLE m_hReadThread; //Handle to the Read thread
HANDLE m_hPortMutex; //Handle to Port Mutex
std::wstring m_strPortName; //Portname
COMMTIMEOUTS m_CommTimeouts; //Communication Timeout Structure
_DCB dcb; //Device Control Block
DWORD m_dwThreadID; //Thread ID
string m_strBuffer;
public:
CSerialCommHelper();
HRESULT Open();
HRESULT ConfigPort();
static void * ReadThread(void *);
HRESULT Write(const unsigned char *,DWORD);
string GetFrameFromBuffer();
HRESULT Close();
~CSerialCommHelper(void);
};
ReadThread and Write function is as follows :
void * CSerialCommHelper::ReadThread(void * pObj)
{
CSerialCommHelper *pCSerialCommHelper =(CSerialCommHelper *)pObj;
DWORD dwBytesTransferred =0;
DWORD byte=0;;
while (pCSerialCommHelper->m_pPortHandle != INVALID_HANDLE_VALUE)
{
pCSerialCommHelper->m_strBuffer.clear();
pCSerialCommHelper->m_usBufSize=0;
WaitForSingleObject(pCSerialCommHelper->m_hPortMutex,INFINITE);
do
{
dwBytesTransferred = 0;
ReadFile (pCSerialCommHelper->m_pPortHandle,&byte,1,&dwBytesTransferred,NULL);
if (dwBytesTransferred == 1)
{
pCSerialCommHelper->m_strBuffer.push_back((char)byte);
pCSerialCommHelper->m_usBufSize++;
continue;
}
}
while ((dwBytesTransferred == 1) && (pCSerialCommHelper->m_pPortHandle != INVALID_HANDLE_VALUE));
ReleaseMutex(pCSerialCommHelper->m_hPortMutex);
Sleep(2);
}
ExitThread(0);
return 0;
}
Write function waits for readthread to release mutex and writes to data to port .
GetFrameFromBuffer will be called from application which uses the SerialCommhelper
and it returns the m_strBuffer string .
My problem is whenever i am trying to download huge amount of data.
I am losing some data frames .
I am getting response from device in between .0468 to .1716 secs.
After analysing different error scenarios i came to know that is not problem with time as other frames are getting downloaded at the same time interval.
Function which is calling getframebuffer is continuosly calling it until is gets a filled string.
It seems like these two statements should not be in your outer while loop:
pCSerialCommHelper->m_strBuffer.clear();
pCSerialCommHelper->m_usBufSize=0;
Your inner while loop reads bytes as long as they're immediately available, and the outer loop does a Sleep(2) the moment the inner loop doesn't give you a byte.
If you're waiting until an entire packet is available, it seems like you should keep looping until you get all the bytes, without clearing partway through the process.
I don't really know the ReadFile API, but I'm guessing that ReadFile might return 0 if there's no bytes immediately available, or at least available by whatever timeout you specified when opening the serial device.
ReleaseMutex(pCSerialCommHelper->m_hPortMutex);
Sleep(2);
That Sleep() call is hiding the real problem. It is never correct in threaded code, always a band-aid for a timing bug.
You certainly seem to have one, that m_hPortMutex spells doom as well. If you do in fact have multiple threads trying to read from the serial port then they are going to start fighting over that mutex. The outcome will be very poor, each thread will get a handful of bytes from the port. But clearly you want to read a frame of data. There is zero hope that you can glue the handfuls of bytes that each thread gets back together into a frame, you've lost their sequence. So sleeping for a while seemed like a workaround, it inject delays that can give you a better shot at reading a frame. Usually, not always. You also wrote it in the wrong place.
This code is just broken. Delete the Sleep(). Do not exit the loop until you've read the entire frame.

FT_Read fails, UNLESS reading byte-by-byte where every FT_Read is followed by FT_Purge

PROBLEM:
Micro-controller is transmitting 10 bytes(ASCII A,B,C,D,E,F,G,H,I,J) in for-loop under debugger control.
Windows application (C++/CLI Code abstracted below) is supposed to receive these bytes.
Refer the two different FT_Read attempts, first in while-loop and second in for-loop
Case #1: Executing micro-controller-for-loop in one-go, the While loop exits with RxMessage array holding first byte correctly as 'A' and rest nine bytes as junk. where fsuccess returned as FT_OK and TotalRxBytes=10
Case #2: Stepping in micro-controller-for-loop to transmit byte by byte, the While loop exits with RxMessage array holding 'A',0xFF,'B',0xFF,'C',0xFF,'D',0xFF,'E',0xFF. while fsuccess returned as FT_OK and TotalRxBytes=10
Case #3: Stepping in micro-controller-for-loop to transmit byte by byte. Executing Windows-app For-loop in one go. The Windows-app For-loop exits with RxMessage holding all 10 bytes correctly as 'A','B','C','D','E','F','G','H','I','J'.
Note: In case 1 & 2 above, the micro-controller-for-loop takes 5 iterations for Windows-app For-loop to exit as if '?' and 0xFF transmitted in every micro-controller-for-loop iteration. Whereas in Case #3, micro-controller-for-loop takes exactly 10 iterations to Windows-app For-loop to exit, as if FT_Read + FT_Purge removes undesired 0xFF chunk
private:
/// Required designer variable.
PVOID fth;
BOOL fSuccess, fthsuccess;
array<wchar_t> ^ TxMessage;
array<unsigned char> ^ RxMessage;
Form1(void) //Constructor
{
fthsuccess = false;
InitializeComponent();
TxMessage = gcnew array<wchar_t> (12);
RxMessage = gcnew array<unsigned char> (12);
}
/*PS. All the FT_xxxx calls below are tested for fsuccess before proceeding ahead */
FT_Open(0, ppfthandle);
FT_SetBaudRate(*ppfthandle, 9600);
unsigned char LatencyTimer;
FT_SetLatencyTimer(*ppfthandle, 2);
FT_GetLatencyTimer(*ppfthandle, &LatencyTimer);
FT_SetDataCharacteristics(*ppfthandle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE);
FT_SetTimeouts(*ppfthandle, 10000/*read*/, 1000/*write*/);
if(fthsuccess == true)
{
pin_ptr<FT_HANDLE> ppfthandle = &fth;
pin_ptr<wchar_t> ppTx = &TxMessage[0];
fSuccess = FT_Write(*ppfthandle,&ppTx[0],4,&dwhandled);
/*in absence of Purge below, Tx chars echo as part of Rx chars
ultimately workaround would be needed to avoid Purging of
real time RxData at runtime
*/
FT_Purge(*ppfthandle, FT_PURGE_RX | FT_PURGE_TX);
pin_ptr<unsigned char> ppRx = &RxMessage[0];
DWORD RxBytes,TotalRxBytes;
RxBytes=TotalRxBytes=0;
while(TotalRxBytes<10){
FT_GetQueueStatus(*ppfthandle,&RxBytes);
fSuccess = FT_Read(*ppfthandle,ppRx,RxBytes,&dwhandled);//reading 10 bytes in one go
if(fSuccess != FT_OK){
break;
}
TotalRxBytes += dwhandled;
ppRx = &RxMessage[TotalRxBytes];
}
fSuccess = FT_Purge(*ppfthandle, FT_PURGE_RX | FT_PURGE_TX);
ppRx = &RxMessage[0];//reset ppRx and attempt read in for-loop, the same bytes from micro-controller
for(int i=0;i<10;i++)//reading byte-by-byte in debug steps
{
fSuccess = FT_Read(*ppfthandle,&ppRx[i],1,&dwhandled);
/*in absence of Purge below, alternate characters are read as 0xFF
ultimately workaround would be needed to avoid Purging of
real time RxData at runtime
*/
FT_Purge(*ppfthandle, FT_PURGE_RX | FT_PURGE_TX);
}
}// if (!fthsuccess)
Code snippet from microcontroller below:
uint8_t Series[10]={'A','B','C','D','E','F','G','H','I','J'};
for(loopcount=0;loopcount<10;loopcount++)
{
UART1Send(Series+loopcount,1);
}
Double check FT_SetDataCharacteristics(*ppfthandle, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE) is correct. Any mismatch between the two devices will result in problems.