It seems that Processor Expert's AsynchroSerial generates incorrect code when interrupts are disabled. I am experimenting with a K22F board and implementing a basic serial echo program. The complete project is attached.
With interrupts disabled, AS1_RecvChar always returns ERR_RXEMPTY.
Digging into the code, it seems that the issue lies with the InterruptRx function in ASerialLdd1.c. The code reads:
static void InterruptRx(ASerialLdd1_TDeviceDataPtr DeviceDataPrv)
{
register uint16_t Data; /* Temporary variable for data */
Data = (uint16_t)UART_PDD_GetChar8(UART1_BASE_PTR); /* Read an 8-bit character from the receiver */
if (DeviceDataPrv->InpDataNumReq != 0x00U) { /* Is the receive block operation pending? */
*(DeviceDataPrv->InpDataPtr++) = (uint8_t)Data; /* Put an 8-bit character to the receive buffer */
DeviceDataPrv->InpRecvDataNum++; /* Increment received char. counter */
if (DeviceDataPrv->InpRecvDataNum == DeviceDataPrv->InpDataNumReq) { /* Is the requested number of characters received? */
DeviceDataPrv->InpDataNumReq = 0x00U; /* If yes then clear number of requested characters to be received. */
}
}
}The issue is that DeviceDataPrv->InpDataNumReq is always zero! Therefore the main code is skipped. InpDataNumReq is set by ASerialLdd1_ReceiveBlock() ... but that function is not run by AS1_RecvChar until a character has already been received (see below). The return ERR_RXEMPTY happens before ASerialLdd1_ReceiveBlock. The crucial setting DeviceDataPrv->InpDataNumReq is never modified.
byte AS1_RecvChar(AS1_TComData *Chr)
{
byte Result = ERR_OK; /* Return error code */
LDD_SERIAL_TError SerialErrorMask; /* Serial error mask variable */
if (!EnMode) { /* Is the device disabled in the actual speed CPU mode? */
return ERR_SPEED; /* If yes then error */
}
ASerialLdd1_Main(ASerialLdd1_DeviceDataPtr);
if (ASerialLdd1_GetError(ASerialLdd1_DeviceDataPtr, &SerialErrorMask) == ERR_OK) { /* Get error state */
if (SerialErrorMask != 0U) {
Result = ERR_COMMON; /* If yes then set common error value */
} else {
if (ASerialLdd1_GetReceivedDataNum(ASerialLdd1_DeviceDataPtr) == 0U) { /* Is not received char? */
return ERR_RXEMPTY; /* If yes then error is returned */
}
}
}
*Chr = BufferRead; /* Read the char */
(void)ASerialLdd1_ReceiveBlock(ASerialLdd1_DeviceDataPtr, &BufferRead, 1U); /* Receive one data byte */
ASerialLdd1_Main(ASerialLdd1_DeviceDataPtr);
return Result; /* Return error code */
}
I can work around this by enabling interrupts, but it's confusing to new users when a certain check box in Processor Expert silently breaks the code!
Original Attachment has been moved to: AsynchroSerial_Bug_K22F.zip