This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Setting up interrupt driven SCI communication

Other Parts Discussed in Thread: CONTROLSUITE

I am working with F 28027F chip on a custom board based on BoostXL 8301 Rev B. I am using lab 20 as my basse and developing that project to enable SCI communication with a PC using RTU MODBUS protocol. I have set up the sci.c and sci.h files and when I call the read and write functions in the main loop it seems to be working properly. However I want the receive function to be interrupt driven and transmit function to remain in the main loop. 

I have noticed that whenever a string comes in, the interrup is not  generated and the SCI ISR never gets executed so basically all the values get overwritten in the Rx Buffer with only the CRC value  still there after (as it is the last byte)

I have set up the SCI ISR as follows;

---------------------------------------------------------------------------------------------------------------------

in main.c

interrupt void sciaISR(void)
{
//Sets the sleep bit to zero so that the SCI receive port wakes up.
HAL_sciaDisableSleep(halHandle);
gChar = HAL_sciaRead(halHandle);

if (gRxCount == 0)
{
// If gRxCount is zero it means more than defined time has passed and the incoming
// string is the address byte.
ReceivedString[0] = HAL_sciaRead(halHandle) & 0x00FF;
HAL_pieAckInt(halHandle,PIE_GroupNumber_9); // Issue PIE ack INT9
gReceivePositoin = 1;

}
else
{
// If gRxCount is not zero it means that less than defined time has passed and the incoming
// byte is still a part of the current string.
// check here for while loop attached to the receive flag.
for ( gReceivePositoin=1; gReceivePositoin<239; gReceivePositoin++)
{
ReceivedString[gReceivePositoin] = HAL_sciaRead(halHandle) & 0x0FF;
HAL_pieAckInt(halHandle, PIE_GroupNumber_9);

}
}

gRxCount = 10;
HAL_sciaEnableSleep(halHandle);
return;
}// end of sciaISR(void) function.

----------------------------------------------------------------------------------------------------------------------------------

In hal.c 

void HAL_setupSCI(HAL_Handle handle)
{
HAL_Obj *obj = (HAL_Obj *) handle;


// SCIFFTX = 0xE040
SCI_enableChannels(obj->sciaHandle); // SCI reset
SCI_enableTxFifoEnh(obj->sciaHandle); // SCI FIFO transmit enable
SCI_enableTxFifo(obj->sciaHandle); // SCI FIFO transmit reset/reenable
SCI_clearTxFifoInt(obj->sciaHandle); // SCI clear FIFO transmit interrupt flag
SCI_disableTxFifoInt(obj->sciaHandle); // disable FIFO transmit interrupt
SCI_setTxFifoIntLevel(obj->sciaHandle, SCI_FifoLevel_Empty); // FIFO interrupt level


SCI_enableRxFifo(obj->sciaHandle); // SCI FIFO receive reset/reenable
SCI_clearRxFifoInt(obj->sciaHandle); // SCI clear FIFO receive interrupt flag
SCI_enableRxInt(obj->sciaHandle); //Enables SCI Receive interrupt
SCI_setRxFifoIntLevel(obj->sciaHandle, SCI_FifoLevel_1_Word); // FIFO interrupt level

// SCI stop bit, parity, loopback, char bits, idle/address mode (SCICCR = 0x07)

SCI_setNumStopBits(obj->sciaHandle, SCI_NumStopBits_One); 
SCI_setParity(obj->sciaHandle, SCI_Parity_Odd);
SCI_disableParity(obj->sciaHandle);
SCI_disableLoopBack(obj->sciaHandle); 
SCI_setMode(obj->sciaHandle, SCI_Mode_IdleLine);
SCI_setCharLength(obj->sciaHandle, SCI_CharLength_8_Bits);

// TX enable, RX enable, RX ERR INT enable, SLEEP, TXWAKE (SCICTL1 = 0x03)


SCI_disableRxErrorInt(obj->sciaHandle);
SCI_disable(obj->sciaHandle);
SCI_disableTxWake(obj->sciaHandle);
SCI_disableSleep(obj->sciaHandle);
SCI_enableTx(obj->sciaHandle);
SCI_enableRx(obj->sciaHandle);

// TXINT enable, RXINT enable, TXEMPTY, TXRDY (SCICTL2 = 0x03)
SCI_enableRxInt(obj->sciaHandle);
SCI_disableTxInt(obj->sciaHandle);

// SCIH-SCIL BAUD - SCI_BAUD = (LSPCLK/(SCI_BRR*8)) - 1
SCI_setBaudRate(obj->sciaHandle, SCI_BaudRate_9_6_kBaud);

// Reset SCI
SCI_enable(obj->sciaHandle);

PIE_enableInt(obj->pieHandle, PIE_GroupNumber_9, PIE_InterruptSource_SCIARX);

CPU_enableInt(obj->cpuHandle, CPU_IntNumber_9); 
} //End of Setup SCI function.

--------------------------------------------------------------------------------------------------------------------------------

In hal.h

extern interrupt void mainISR(void);

//JEDL HV Drive
//Nikhil Bapat
//SCI Interrupt
extern interrupt void sciaISR(void);

static inline void HAL_initIntVectorTable(HAL_Handle handle)
{
HAL_Obj *obj = (HAL_Obj *)handle;
PIE_Obj *pie = (PIE_Obj *)obj->pieHandle;


ENABLE_PROTECTED_REGISTER_WRITE_MODE;

pie->ADCINT1 = &mainISR;


//JEDL HV Drive
//Nikhil Bapat

pie->SCIRXINTA = &sciaISR;


DISABLE_PROTECTED_REGISTER_WRITE_MODE;

return;
} // end of HAL_initIntVectorTable() function

-----------------------------------------------------------------------------------------------------------------------

I suspect that I might have missed something in setting up the SCI Interrupt function. Any help would be appreciated.

  • Hi Nikhil,

    Did you refer this example code?
    C:\ti\controlSUITE\device_support\f2802x\v230\f2802x_examples_structs\scia_loopback_interrupts

    Regards,
    Gautam
  • Gautam,

    I have found a couple of things that I need to change. But the office is closed for a couple of days. I will try them out and report back on Friday.

    Regards,
    Nikhil
  • I do have a couple of questions though, I did post these in another thread a while ago but did not get any response. For SCI there are several functions related to read and write.
    1. SCI_getDataBlocking
    2. SCI_getDataNonBlocking
    3. SCI_read

    I understand the difference between blocking and non blocking. But what is the difference between getData and read functions?

    And similarly what is the difference between SCI_putData and SCI_write functions?
  • Sorry Nikhil, I'm unaware of the above functions. Generally I prefer the structured approach instead of the above driver based approach.

    Regards,
    Gautam
  • Nikhil,

    SCI_getDataBlocking 

    Waits until Rx data is ready, then returns SCIRXBUF

    SCI_getDataNonBlocking

    Checks if the Rx data is ready      , if true returns SCIRXBUF data and sets a pointer = True

    ,if false Returns NULL and sets pointer = False

    SCI_getData

    Returns the data in the SCIRXBUF.

    I would recommend using "SCI_getData", and only call the function if the RxReady flag is set. The same is true for the write functions. The source for all of these functions and more can be found in "sci.c" and "sci.h" in ControlSuite.

    Regards,

    Cody

  • Hi Cody,

    Thanks for the info. But I have another question. What is the difference between the SCI_getData and SCI_read? I have used SCI_read and SCI_write functions in my code, but the example codes do not use these functions.

    Nikhil

  • Gautam,

    I tried by setting the Rx ISR like the one in the above example. I can see that the IER bit for the 9th group is 1 and IFR bit is 0 (same as for mainISR for the motor) But I am still not getting into my SCI ISR. When I put the read function in the main loop I do not see that working either. I can see that the RXEMU register updates with the values that I am sending from the PC but the RXBUF register does not change.
  • Nikhil,

    the source code for SCI_read can be found in "sci_io.c", and the source code for SCI_getData is found in "sci.h". SCI_read requires more parameters and allows you to choose how many characters to read. One function returns the number of reads and uses a pointer to store the data, and the other simply returns the data read.

    I recommend that you should look at the source code, it will help you understand how these functions work!

    Best of luck,

    Cody

  • Gautam,

    I tested a little bit with my code and here is what I have found

    1. I set up the code based on the example from ControSuit and also from here.

    2. IER INT9 bit is set (and IER INT10 bit too, which is the interrupt for the mainISR)

    3. IFR all bits are 0. So I believe interrup is set up properly.

    The SCI registers look like this:

    I suspect that the RXRDY flag is never set so the interrup is never generated as all other registers seem okay. Any idea why this would be so?

  • Are you able to receive data at SCIRXEMU register? I can see 0x3 in SCIRXEMU.
  • The SCIRXEMU updates every time a string comes in. The 0x3 is the CRC of the string that I am sending in. But since I am not able to get data from SCI, I think that each character is overwriting the previous one in the register. So I see the CRC of each string in the SCIRXEMU register.
  • I redid the project from start and the SCI is working now. Just one question though, do you know if the Rx interrup is generated for each byte or for each data block (string of bytes)?