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.

SYS/BIOS and SCI interrupt for TMS320F28335.

Other Parts Discussed in Thread: TMS320F28335

I'm attempting to write a c++ class for handling the SCI modules in a TMS320F28335.

So far I've got a class defined which has two circular buffers, one for tx and one for rx.  Now I want to include the ISR routines to handle receiving and transmitting data.  I'm not sure if I should use the Hwitask within sys bios or even how to set it up to handle interrupts from one of the SCI modules.

There is a small example in the BIOS users guide but it is still a little vague.

I want my SCI ISR code implemented dynamically in code, not in the cfg file.  Any good examples of using the SCI with SYS/BIOS?

A real example on how to use the HWI type would help alot.  I'm quite lost.  I've written many MSP430 programs but I'm just learning sys bios and the TMS320.

  • In fact, you can add a wrapper for your HWI. and then initilize this function pointer before BIOS start.

  • Ok, I'm making progress but the engineer in me wants the implementation to work a particular way.  I want to set the arg parameter in the Hwi_Params struct equal to the pointer value of the class instance that is handling the SCI like this (it's just a code snippet, not the full thing)

    class SCI_A : public SCI
    {
    protected:
        Void hw_init(Uint32 SysClk);
        Void start_tx_pump(Void);
        bool isr_init(void);
    public:
        SCI_A(Uint32 SysClk, Uint32 baud, Uint16 data_bits, Parity parity, Stop_Bits stop_bits, Mode mode);
        ~SCI_A();
    }

    bool SCI_A::isr_init(Void)
    {
        // The SCITXINTA is interrupt INT9.2 This maps to interrupt ID 97
        // The SCIRXINTA is interrupt INT9.1 This maps to interrupt ID 96
        bool result = true;
        Hwi_Params hwiParams;
        Error_Block eb;
        Error_init(&eb);
        Hwi_Params_init(&hwiParams);
        hwiParams.arg = (xdc_UArg) self;
        hwi0 = Hwi_create(97, SCITXAFunc, &hwiParams, &eb);
        if (hwi0 == NULL) {
            System_abort("Hwi create failed");
            result = false;
        }
        return (result);
    };

    With this implementation I can cast the parameter passed to the ISR as an instance of the SCI_A class and use this pointer to get the data out of the SCI FIFO.  This would be part of a larger framework where applications would have an instance of the SCI and not have to worry about the low level details of the ISRs, configuration, or FIFO. 

    My problem is that the xdc_UArg parameter is only 16 bits wide but the memory map for the TMS32f28335 can be upto 22 bits wide and I have no guarantee that the linker will put the isr and the object within 64k of each other.  What I need to do is pass a 32 bit value to the ISR to guarantee  the cast will work correctly.   I'm trying to avoid using a global SCI_A pointer that gets used by the ISR, but to me it looks like I will not have a choice.

    Any advice would be greatly appreciated.

  • Hi Andrew,

    UArg can hold a pointer.

    From the following website: http://rtsc.eclipse.org/cdoc-tip/xdc/package.html#xdoc-sect-3

    UArg
    this unsigned integer type is large enough to hold a Fxn, Ptr, or Int.

    Todd

  • Hi Todd,

    Thanks for the reply but the problem is that it is an unsigned integer type.

    From the TMS320C28x Optimizing C/C++ Compiler v6.1 Section 6.4 Data Types (Pg 87)

    Type                      Size              Representation                Minimum         Maximum

    unsigned int          16 bits           Binary                              0                      65535

    This indicates that the UArg type ( which is a unsigned int) can only hold a pointer to a function that resides in the lower 16 bits of the address space. What happens if my interrupt function is a far pointer away from the heap instance of a dynamically created c++ object?

  • But UArg is not an "Int". It can hold either an "Int" or a pointer. I run the following code on a C28_float device

    System_printf("sizeof(UArg)   = %d\n", (Int)sizeof(UArg));
    System_printf("sizeof(Int)    = %d\n", (Int)sizeof(Int));
    System_printf("sizeof(Void *) = %d\n", (Int)sizeof(Void *));

    And the output was as follows:

    sizeof(UArg)   = 2
    sizeof(Int)    = 1
    sizeof(Void *) = 2

    Todd

  • Thanks Todd,

    This is great news.  I got tripped up by the documentation.  Where is UArg defined?

  • xdc\std.h defines the types. 

    The <xdctools_install_dir>\packages\ti\targets\<target>.xdc files drives alot of this and are interesting to look at. For example in the C28.xdc file, at the bottom is the following:

    override readonly config xdc.bld.ITarget.StdTypes stdTypes = {
            t_IArg          : { size: 2, align: 2 },
            t_Char          : { size: 1, align: 1 },
            t_Double        : { size: 2, align: 2 },
            t_Float         : { size: 2, align: 2 },
            t_Fxn           : { size: 2, align: 1 }, /* near */
            t_Int           : { size: 1, align: 1 },
            t_Int8          : { size: 1, align: 1 },
            t_Int16         : { size: 1, align: 1 },
            t_Int32         : { size: 2, align: 2 },
            t_Int64         : { size: 4, align: 2 },
            t_Long          : { size: 2, align: 2 },
            t_LDouble       : { size: 2, align: 2 },
            t_LLong         : { size: 4, align: 2 },
            t_Ptr           : { size: 1, align: 1 },
            t_Short         : { size: 1, align: 1 },
            t_Size          : { size: 2, align: 2 },
        };

    Todd