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.

TMS320F28379D: Writing to a register not working

Part Number: TMS320F28379D
Other Parts Discussed in Thread: C2000WARE, CONTROLSUITE

Hi, I am trying to read data from and write data to a ePWM register. I can read the whole register, but when I try to read half or just a single bit (e.g., EPwm2Regs.TBCTL.bit.PHSDIR), I get a compiling error:

error: taking the address of a bit field is not allowed

As a workaround, I read a whole register (EPwm2Regs.TBCTL), and then extract a single bit (PHSDIR = bit 13).

However, if I try to write to a single bit, I also get the same error.

I tried to use a similar approach: reading the whole register, changing a particular bit and then writing a new value to the same register, but this does not work. I can see the 13th bit changing on the DAC, but there is no ramp signal (TBCTR is zero).

Is it possible to write to only one bit? I suspect that I am overwriting some other bits of the TBCTL Register during this process, hence my ramp is zero

The model is attached.

TBCTL_Write_test_R2018a.zip

  • Hi Mike,

    Is it possible to write to only one bit?

    Yes, it is possible to write to one bit. I recommend referring to one of the epwm software examples within C2000Ware for an example of this. After looking at the examples I would compare the project setup with yours to make sure you are linking to the right header files.

    C:\ti\c2000\C2000Ware_version\device_support\f2837xd\examples\cpu1

    Best Regards,

    Marlyn

  • Hi Marlyn,

    thank you for the reply.

    I have gone through some of the code examples. I am using the same syntax as in the examples to point to the register, but somehow it does not work in my case. Even when I try to write to half of the register, it does not change.

    In this application, I am reading the whole TBPHS register, and writing to the upper half of the TBPHS register a new value, but it seems the memory copy block cannot overwrite the existing value and the offset I am seeing on the DAC output does not change.

    Memory Copy destination settings | Application code | ePWM settings

    TBPHS register:

    In the other example (changing a single bit), If I use the address and not the names, for TBCTL Register Offset = 0h, which I have entered, but don't know how to move to the 13th bit?

    Update

    Write to a single bit

    This post says to put the code between EALLOW and EDIS, which I did.

    I also put the Memory Copy block inside the triggered subsystem, but I still get the error when compiling:

    "TBCTL_Write_test_R2018a_2.c", line 858: error: taking the address of a bit field is not allowed
    1 error detected in the compilation of "TBCTL_Write_test_R2018a_2.c".
    >> Compilation failure
    gmake: *** [TBCTL_Write_test_R2018a_2.obj] Error 1

    The code extract from TBCTL_Write_test_R2018a_2.c is shown below, where line 7 below corresponds to the line 858 referenced in the error message.

      /* ConstCode for S-Function (memorycopy): '<S2>/Memory Copy4' incorporates:
       *  Constant: '<Root>/Constant6'
       */
      {
        boolean_T *memindsrc = (boolean_T *)
          (&TBCTL_Write_test_R2018a_2_P.Constant6_Value);
        boolean_T *meminddst = (boolean_T *) (&EPwm2Regs.TBCTL.bit.PHSDIR);
        EALLOW;
        *(boolean_T *) (meminddst) = *(boolean_T *) (memindsrc);
        EDIS;
      }
    
      /* End of ConstCode for S-Function (c28xisr_c2000): '<Root>/C28x Hardware Interrupt' */
    

    Read from a single bit

    Compiling error message:

    "TBCTL_Write_test_R2018a_2.c", line 136: error: taking the address of a bit field is not allowed
    1 error detected in the compilation of "TBCTL_Write_test_R2018a_2.c".
    >> Compilation failure

    The code extract from TBCTL_Write_test_R2018a_2.c is shown below, where line 3 below corresponds to the line 136 referenced in the error message.

    /* S-Function (memorycopy): '<Root>/Memory Copy8' */
    {
    boolean_T *memindsrc = (boolean_T *) (&EPwm2Regs.TBCTL.bit.PHSDIR);
    boolean_T *meminddst = (boolean_T *) (&rtb_MemoryCopy8);
    *(boolean_T *) (meminddst) = *(boolean_T *) (memindsrc);
    }

    As mentioned in my inial post, when I read a whole register (EPwm2Regs.TBCTL), and then extract a single bit (PHSDIR = bit 13), it works OK.

    /* S-Function (memorycopy): '<Root>/Memory Copy2' */
    {
    uint32_T *memindsrc = (uint32_T *) (&EPwm2Regs.TBCTL);
    uint32_T *meminddst = (uint32_T *) (&rtb_MemoryCopy);
    *(uint32_T *) (meminddst) = *(uint32_T *) (memindsrc);
    }
    
    /* DataTypeConversion: '<Root>/Data Type Conversion1' incorporates:
    *  DataTypeConversion: '<S1>/Extract Desired Bits'
    */
    rtb_DataTypeConversion1 = (int16_T)(rtb_MemoryCopy >> 13U) & 1;

    Update 2

    Write to a register

    I tried to write to a TBPRD register (the whole register this time). I tried three different approaches; all inside hardware interrupt subroutine

    1. Using Memory Copy and setting source code symbol to: &EPwm2Regs.TBPRD with both EALLOW; and EDIS; before and after. -- can compile & load
    2. Using Memory Copy and setting address and offset for TBPRD: hex2dec('00004100') and hex2dec('00000063'), respectively, with both EALLOW; and EDIS; before and after. -- can compile & load
    3. Using Data Store Memory and Custom Code Blocks as an alternative as seen here. -- can't compile. Getting Data Store Memory parameter undefined error.

    In all cases all monitored signals drop to zero. C code for case 1 (_a) and 2 (_b) is attached.

    3566.TBCTL_Write_test_R2018a_3.zip

     

     

  • Hi Mike,

    Thank you for providing the additional details. I am going to loop in MathWorks since they can best comment on the the MathWorks side of things, especially the Memory Copy block and the issues you are getting.

    Best Regards,

    Marlyn

  • Mike,

    For MathWorks support, please post it at MathWorks support forum. We do not have internal resource to support it and we rely on MathWorks team. It is best answered at their forum as they have group of engineers monitoring the support questions. Hare are the links for support forum.

    If you have further questions, the best way to get support on MathWorks products is to contact MathWorks live tech support.

     

    You can also search for answers or post a question on MATLAB Answers C2000 forum. Additionally, there is info on MathWorks support C2000 in Documentation and Examples.

    Thanks & Regards,

    Santosh

  • HI Santosh,

    Thank you for the advice.

    I have already posted my enquiry to MATLAB Forum (1, 2 and 3), but still no answers. I have also done an extensive search through the MATLAB Forum, but couldn't find any reference to Memory Block used for writing to a register; mainly questions refereeing to reading from a register. 

    Do you maybe have a contact details for MathWorks team supporting C2000 product, so I can contact them directly?

    Thank you in advance and kind regards.

  • Mike,

    Can you please send the link of your post on MathWorks forum so that I can follow it up with MathWorks engineers?

    Regards,

    Santosh

  • Mike,

    I sent email to MathWorks engineers with link of this thread, hopefully we should hear soon.

    Regards, Santosh

  • Hi Mike,

    Looks like you are using MATLAB Version R2018a.
    The C2000 support package uses ControlSUITE driver library files for code generation for F28379D target board in R2018a but not C2000Ware.
    As the ControlSUITE does not support accessing the bit fields, accessing the individual bits in the registers is not supported in R2018a.
    However, the support for C2000Ware for F2837x targets is added in R2022a for TI C2000 support package.
    If you want to access the individual bits in the registers, you may need to migrate to the latest MATLAB release.

    However, the workflow of reading the entire register, modifying the value and writing the value back to the register will work in case of ControlSUITE.
    But when I looked into your model, you are extracting lower 12 bits (0-11), upper 2 bits (14-15) and setting bit 13 which is not proper.
    You are skipping bit 12 in your model which is why you are not getting proper DAC value.
    Instead, you need to extract lower 13 bits instead of 12 bits.

    As an alternative, you may use Bitwise XOR operator with value of 8192 to toggle bit 13, OR operator to set bit 13 respectively.
    Refer to the attached image.

    For any further queries, please connect to us at:
    www.mathworks.com/support.html

    Best Regards,
    Ram Alla | MathWorks

  • Thanks Ram!!

    I am attaching the image from Ram here.

    Regards, Santosh

  • Hi Ram,

    thank you very much for the reply. I will try the code in R2022a.

    Can you just quickly please take a look at the example for writing to a register? In this example, I am trying to overwrite the ePWM2 TBPRD register, i.e., change the ePWM2 switching frequency. But when I add a C28x Hardware Interrupt block (Memory Copy is inside the Hardware Interrupt block), nothing changes. Is this also something related to older MATLAB versions? I can change TBPRD and see the change on Memory Copy -> DAC, but the ePWM2 EPwm2Regs.TBCTR output is zero on DAC output.

    MATLAB Simulink Model: 7610.TBCTL_Write_test_R2018a_3.zip

    Thank you in advance

    Update

    I have tried reading a single bit in MATLAB R2022a and

    But I am still getting the same error when trying to read from a single bit &EPwm2Regs.TBCTL.bit.PHSDIR:

    line 101: error: taking the address of a bit field is not allowed

    /* S-Function (memorycopy): '<Root>/Memory Copy8' */
      {
        boolean_T *memindsrc = (boolean_T *) (&EPwm2Regs.TBCTL.bit.PHSDIR);
        boolean_T *meminddst = (boolean_T *) (&rtb_MemoryCopy8);
        *(boolean_T *) (meminddst) = *(boolean_T *) (memindsrc);
      }

    Version C2000Ware_4_00_00_00 gives the same error.

    MATLAB SImulink Model: TBCTL_Write_test_R2022a_2.zip

  • Hi Mike,

    Look like it is a limitation of accessing bit fields using the Memory Copy block. 
    You may try the previously suggested workaround to modify the register value by masking the unnecessary bits using bit wise operators as shown in the above image.

    If you have any further queries, please connect to us at:
    www.mathworks.com/support.html

    Best Regards,
    Ram Alla | MathWorks