Other Parts Discussed in Thread: C2000WARE, MOTORWARE
I’m working on the serial comm for a motor control board (MCB). I'm using InstaSpin Lab 05b as a model. I had serial communications working pretty flawlessly as a stand-alone application, using examples in C2000Ware as a starting point. When I tried integrating the MotorWare code for InstaSpin Lab 05b with this code, however, everything ground to a halt. A colleague suggested using serial communications code native to MotorWare - that way the risk of any definitions contained in header files, etc... would be in less danger of stepping on each other. This board must be able to communicate with, and take direction from an LCD module. The LCD module sends out requests for data, using the SLIP protocol, every 500 ms. It also sends commands whenever the user changes parameters via the LCD. The MCB must be able to collect the entire message from the LCD, respond to requests for data (using the SLIP protocol), and carry out any changes (to speed, torque limit, etc...) requested by the LCD module.
I can see data in the SCIRXBUF register, and the RXFFST bits of the SCIFFRX register indicate that there is data in the FIFO.
I was hoping that I could examine the SCIFFRX register’s FIFO status bits, and if their value matched that of the RXFFIL, I could consider the FIFO contents good data, and I could grab the data from the SCIRXBUF a number of times corresponding to the FIFO depth (RXFFIL). I started off just setting the FIFO depth to 1, just to see if I could grab a byte at a time. No luck there. I attributed the failure to the fact that the FIFO depth that I’d set didn’t match the number in the FIFO Status bits. I was probably wrong about that. I still don’t know why I couldn’t grab the buffer contents under those conditions. Anyway, I tried a somewhat different tack.
Using “SCI_getDataNonBlocking" (a comm function native to MotorWare) in the main loop, which calls “SCI_rxDataReady” written as follows:
static inline bool SCI_rxDataReady(SCI_Handle sciHandle)
{
SCI_Obj *sci = (SCI_Obj *)sciHandle;
bool status;
// status = (sci->SCIRXST & SCI_SCIRXST_RXRDY_BITS) >> 6;
status = (sci->SCIFFRX & SCI_SCIFFRX_FIFO_ST4_BIT) >> 10;
return((bool)status);
} // end of SCI_rxDataReady() function
I defined SCI_SCIFFRX_FIFO_ST4_BIT as follows in sci.h (where a lot of similar defines occur):
#define SCI_SCIFFRX_FIFO_ST4_BIT (1 << 10)
RXRDY is commented out and can’t be used because I’m employing the FIFO. I picked a depth of 4, because that’s where the RXFFST bits always seem to land. I’m not sure why, but the FIFO depth listed by the FIFO status bits is always 4. Whatever… I figured I could work with that. For some reason, though, ‘status’ always ends up zero. There is data in the buffer and the bit of interest (bit 11 of the SCIFFRX register) is set when I look at the registers, so I don’t see how this could be.
It’s my understanding (or perhaps misunderstanding) that when the value of the FIFO Status bits exceeds the value specified by the RXFFIL bits, then an interrupt flag (RXFFINT) is set. So, I figured I could use this flag to determine whether there were the requisite number of bytes in the FIFO, even if I’m not explicitly using the interrupt. So, SCI_rxDataReady is rewritten as:
//! \return The receive data status
static inline bool SCI_rxDataReady(SCI_Handle sciHandle)
{
SCI_Obj *sci = (SCI_Obj *)sciHandle;
bool status;
// status = (sci->SCIRXST & SCI_SCIRXST_RXRDY_BITS) >> 6;
// status = (sci->SCIFFRX & SCI_SCIFFRX_FIFO_ST4_BIT) >> 10;
status = (sci->SCIFFRX & SCI_SCIFFRX_INT_BITS) >> 7;
return((bool)status);
} // end of SCI_rxDataReady() function
Where SCI_SCIFFRX_INT_BITS is defined (in sci.h) as:
#define SCI_SCIFFRX_INT_BITS ( 1 << 7)
Status still comes up zero, even though I can see that the RXFFINT bit is a 1 in the register.
All I can think of is that I still must be missing something in setup, something specific to the FIFO, but I haven’t been able to determine what.
Here are the relevant subroutines for setting up the FIFO, and the serial comm in general.
void SCI_enableRxFifo(SCI_Handle sciHandle)
{
SCI_Obj *sci = (SCI_Obj *)sciHandle;
// Clear the appropriate RXFFIL bits.
sci->SCIFFRX &= SCI_SCIFFRX_FIFO_RXFFIL_CLR_BITS;
// Set the RXFFIL LSB to indicate a reset should be generated when there is 1 byte in FIFO.
sci->SCIFFRX |= SCI_SCIFFRX_FIFO_RXFFIL_SET_BITS;
// Set the FIFO Reset bit.
sci->SCIFFRX |= SCI_SCIFFRX_FIFO_RESET_BITS;
return;
} // end of SCI_enableRxFifo() function
Where the clear and set constants listed above are defined as follows:
#define SCI_SCIFFRX_FIFO_RXFFIL_CLR_BITS 0xffe4
#define SCI_SCIFFRX_FIFO_RXFFIL_SET_BITS 0x0004
The comments associated with the above code were originally written when I was trying to detect one byte. The FIFO status bits, however, always seem to indicate that 4 bytes had been collected, so I figured I’d just roll with that. (Didn’t think it was worth changing the comments, until I’ve settled on an actual FIFO level.)
void HAL_setupSciB(HAL_Handle handle)
{
HAL_Obj *obj = (HAL_Obj *)handle;
SCI_reset(obj->sciBHandle); // *
SCI_enableTx(obj->sciBHandle); // *
SCI_enableTxFifoEnh(obj->sciBHandle); //*
SCI_enableTxFifo(obj->sciBHandle); // *
SCI_clearTxFifoInt(obj->sciBHandle); // *
//SCI_setTxDelay(obj->sciBHandle,0x0018);
SCI_enableRx(obj->sciBHandle); // *
SCI_resetRxFifo(obj->sciBHandle); // Empty Rx FIFO
SCI_enableRxFifo(obj->sciBHandle); // *
SCI_clearRxFifoInt(obj->sciBHandle); // *
SCI_setBaudRate(obj->sciBHandle,SCI_BaudRate_115_2_kBaud); // *
SCI_setCharLength(obj->sciBHandle,SCI_CharLength_8_Bits); // *
SCI_enable(obj->sciBHandle); // *
/* All of these were echoed in scib_loop_init & scib_fifo_init, though not in the same order.
There are additional setup routines in scib_loop_init & scib_fifo_init:
SCI_resetTxFifo(sci_Reg_Handle); // Empty Tx FIFO
SCI_resetRxFifo(sci_Reg_Handle); // Empty Rx FIFO
SCI_clearAutoBaudDetect(sci_Reg_Handle);
SCI_disableAutoBaudAlign(sci_Reg_Handle);
SCI_enableTxInt(sci_Reg_Handle);// Enable RXRDY/BRKDT & Enable TXRDY interrupts.
SCI_enableRxInt(sci_Reg_Handle);
SCI_disableTxInt(sci_Reg_Handle);
SCI_disableRxBreakInt(sci_Reg_Handle);//Disable Receiver-buffer break
SCI_disableLoopBack(sci_Reg_Handle);
*/
return;
} // end of HAL_setupSciB() function
scib_loop_init & scib_fifo_init (mentioned in the comments, above) were the subroutines I used when communicating using the C2000Ware examples. I had working serial comm, but there was interference of some sort when I tried to integrate the C2000Ware code with MotorWare code. There are several subroutines listed in the comments at the end of “HAL_setupSciB.” Maybe I should use one or more of those? I’ve tried a couple of them, but I’m not sure of the appropriate order of operations here.
Thanks,
Dave