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.

TMS570 NHET use of register A

Other Parts Discussed in Thread: HALCOGEN

Hi,

I am using the TMS570 Microcontroller Development Stick, with a TMS570LS20216 MCU (ASPGEQQ1).
I have a short NHET program to measure time periods:

P01   PCNT { next=C00,type=FALL2FALL,pin=10,period=0,data=0,hr_data=0};
C00   CNT { next=P01,reg=A,control=OFF,max=10,data=0};

I have run this in the simulator and I can see the register A incrementing. But I need to be able to read this data in the main CPU program. How can I get access to the data?

regards,
Dave

  • Hello Dave,

    first you have to run the NHET assembler (hetp.exe) to create the corresponding .c and .h file, if not already done. Assume your NHET program file is called "PCNT.het" then you need to execute on the command line "hetp -n0 -hc32 PCNT.het". This will create a PCNT.c and PCNT.h file. Basically the NHET program is represented as a structure with the opcode of each NHET instruction of your program.

    This structure needs to be linked to your application project. Below is a way to do it in the linker command file.

    MEMORY
    {

       .....

        NHETRAM (RW) : origin=0xFF460000 length=0x00000800
       .....
    }

    /*----------------------------------------------------------------------------*/
    /* Section Configuration                                                      */

    SECTIONS
    {
        .....
        .HETCODE : { e_HETPROGRAM0_UN = .;} > 0xFF460000      /* HET PROGRAM */
        .....

    }

     

    Then the code needs to be copied to the NHET RAM.

    memcpy( (void *)&e_HETPROGRAM0_UN, HET_INIT0_PST, sizeof (HET_INIT0_PST));

    The PCNT data field can then be accessed with the corresponding structure definition.

     

    Some of this information can also be found in the "NHET Getting Started Guide" SPRAB0B.pdf (http://focus.ti.com/mcu/docs/litabsmultiplefilelist.tsp?sectionId=96&tabId=1502&literatureNumber=spraba0b&docCategoryId=1&familyId=1870), although it only discusses the generation of a PWM, but the principle of generating the code and loading it to the NHET RAM is the same.

     

    One more comment on your NHET program. I don't exactly know what you intend to do with the CNT instruction, but just to get a period/pulse measurement done you only need the PCNT instruction.

     

    Please let us know if you have more questions or issues.

     

    Regards

    Frank

  • Thank you for your help. I can now see the data changing in the NHETRAM area.
    I have removed the CNT instruction, which as you suggested I did not need.
    I have tried to use the HTU as a DMA to copy the data into an array, but the data is not getting to the arrays.
    The data in buffers dest_buffer_A and dest_buffer_B is not changing.
    Any ideas what I might be doing wrong?

    I have initialised the NHET as follows:

    void NHET_init(void)
    {
        /* Prescale Factor Register - loop resolution and high resolution */
        hetREG -> PFR = 0x00000300;            /* lr = 8; hr = 1             */
        /* Directiom Register - 0 for input pins, 1 for output */
        hetREG -> DIR = 0x00004000;            /* NHET[10] = input, NHET[14] = output    */

        /* Request Enable Set Register */
        hetREG -> REQENS = 0x000000FF;      /* enable all NHET request lines */
        /* Request Destination Select Register */
        hetREG -> REQDS = 0x00000000;      /* select HTU for all request lines */

        /* HET Parity Control Register */
        hetREG -> PCREG = 0x00000005;      /* disable parity check */

        /* HET Interrupt enable set register */
        hetREG -> INTENAS = 0x00000001; /* Enable interrupt on NHET address x+0 */
       
        /* Global Configuration Register */
        hetREG -> GCR = 0x00070001;         /* Protect Program field     */
                                            /* Ignore Suspend            */
                                            /* NHET is master            */
                                            /* Turn NHET on                */
    }  

    I have set up some static RAM buffers to receive the NHET data from the HTU:

    /* Define static RAM buffers for NHET data from HTU */
    static unsigned int dest_buffer_A[120];
    static unsigned int dest_buffer_B[120];

    void HTU_Init(void)
    {

          /** - Disable HTU */
        htuREG->GC = 0;

           /** - Enable Control Packet */
        htuREG->CPENA = 0x01; /* DCP 0 - need both buffer A and B */

        /* Bus full interrupt enable registers */
        /* Enable interrupt for DCP 0 Control Packet buffer A and CP buffer B */
        htuREG->BFINTENA = 0x03;

        /* Set the interrupt mapping select bit (16) */
        /* Set interrupts for CP A and CP B for DCP 0 bits (0 and 1) */
        htuREG->INTMAP = 0x13;

        /* Buffer full interrupt flag register (offset 0x44) */
        /* Check to see if this flag is getting set - bits 0 or 1 */
        /* This can be used in the interrupt handler */

        /* Section 19.5 */
        /** - Configure Initial Address of the Buffer A */
        /* Need to allocate RAM for this */
        htuDCBCP->DCBCP_ST[0].IFADDRA =  (unsigned int) dest_buffer_A;
        htuDCBCP->DCBCP_ST[0].IFADDRB =  (unsigned int) dest_buffer_B;

        /** - Configure Initial Element Count - transfer 1 32 bit element per frame */
        htuDCBCP->DCBCP_ST[0].IETCOUNT = 1;
        /** - Configure Initial Frame Count - transfer 120 frames before flagging the interrupt */   
        htuDCBCP->DCBCP_ST[0].IFTCOUNT = 120; /* Change to 150 and clock to 34MHz */


        /* Bit 23 DIR 0 NHET Read main memory write, 22 SIZE 0 32 bit, Bit 21 0 inc 16 bytes, Bit 20 0 post increment main memory */
        /* Bits 16-17 and 18-19 TMBA and TMBB are auto switch */
        /** - Address of PCNT Data Field in NHET (8). This is just the offset, do I need 0xFF46 0008? */
        htuDCBCP->DCBCP_ST[0].IHADDR = 0x00078008;

        /* Clear current full address registers */
        htuDCBCCP->DCBCCP_ST[0].CFADDRA = 0x00000000;
        htuDCBCCP->DCBCCP_ST[0].CFADDRB = 0x00000000;
        /* Clear current frame count registers */
        htuDCBCCP->DCBCCP_ST[0].CFTCTA = 0x00000000;
        htuDCBCCP->DCBCCP_ST[0].CFTCTB = 0x00000000;


          /** - Configure Memory Protection Registers */
        htuREG->MPCS =      (1 << 2)    /* Error Signalling is Enabled */
                        |(1 << 1)    /* Any access to the region is forbidden */
                        | 1;        /* Enable Region 0 */

           /** - Configure Start Address */
        htuREG->MPS = (unsigned long) dest_buffer_A;

        /** - Configure End Address */
        htuREG->MPE = (unsigned long) dest_buffer_B + 120; /* Error on access to Buffer B */

           /** - Enable HTU */           
        htuREG->GC = 0x00010000;  /* HTUEN is TRUE - enable the HTU */
    }

    regards,

    Dave

  • Hello Dave,

    I only had a quick glance at your code and didn't see anything glaringly wrong. I will have a closer look later.

    Could you also provide the PCNT instruction settings? I'm interested if you've set the "reqnum" and "request" parameters as well.

     

    Regards

    Frank

  • Hello Frank,

    I am not setting the reqnum and request parameters:

    P01   PCNT { next=P01,irq=ON,type=FALL2FALL,pin=10,period=0,data=0,hr_data=0};

    I will experiment with putting in reqnum and request parameters.

    Regards,

    Dave

  • Hello Dave,

    without this, the PCNT instruction will not know which request to trigger. Since you configured double control packet 0 (DCP0) in the HTU, you should also configure reqnum=0 and request=GENREQ in the PCNT instruction.

    Regards,

    Frank

  • Hello Frank,

    I have put in the changes you suggested:

    P01   PCNT { next=P01,reqnum=0,request=GENREQ,irq=ON,type=FALL2FALL,pin=10,period=0,data=0,hr_data=0};

    However, I am not getting any data in my buffers (dest_buffer_A and dest_buffer_B).

    Is there anything else I could try?

     

    Regards,

    Dave

  • Hello Dave,

    sorry for the delay in my response.

    I forgot to mention that a single instruction NHET program doesn't work. Can you please try something like:

    P01   PCNT { next=P02,reqnum=0,request=GENREQ,irq=ON,type=FALL2FALL,pin=10,period=0,data=0,hr_data=0}
    P02      BR    {next=P01,cond_addr=P01,event=NOCOND}

    Also your code:

    htuDCBCP->DCBCP_ST[0].IHADDR = 0x00078008;

    doesn't seem to be correct. It writes a 1 to bit 15 which is a reserved bit. Perhaps it would be better to try to implement a single buffer and just see if this works, before doing a double buffer implementation.

    Lacking your complete code, I just tried it with a simple testcase and didn't see an issue. I'd suggest you try something like htuDCBCP->DCBCP_ST[0].IHADDR = 0x00000008;

    and see if this works.

    Please let me know if you still have issues.

    Regards

    Frank

  • Hello Frank,

    thank you very much for your help.
    I am now able to see double control buffers A and B filling up and then swapping back to buffer A and so on. (I have set IHADDR to 0x000F 0008).

    I think this should be my last problem on this project:
    I am trying to get an interrupt for every time each buffer fills up. I have mapped buffer CP A to interrupt request 0 and CP B to interrupt request 1 (using INTMAP). When I run the program I see BFINTFL showing a buffer full condition is detected on CP A and CP B of DCP 0, INTOFF0 shows an interrupt caused by full buffer on DCP 0 CP A and INTOFF1 shows an interrupt caused by full buffer on DCP 0 CP B. So it looks like the interrupts should be happening, but the program is not entering the interrupt service routine.

    I think the interrupt lines for HTU should be at 11 and 25, so I have set the following entries in sys_startup:

    #if 0x00000800
            htuHighLevelInterrupt,
    #else
            phantomInterrupt,
    #endif

    #if 0x02000000
            htuLowLevelInterrupt,
    #else
            phantomInterrupt,
    #endif

    and I have set the same bits in vimREG->REQMASKSET0.

    However, my ISRs are not entered (I have set a breakpoint in each of the ISRs)

    Can you think of any reason why my interrupts do not appear to work?

    Regards,
    Dave

  • Hello Dave,

    it can have a number of reasons why the interrupts are not happening.

    Have you checked that the start addresses of your interrupt service routines are at the correct locations in the VIM RAM? "htuHighLevelInterrupt" should be at address 0xFFF82030 and "htuLowLevelInterrupt" should be at 0xFFF82068, if you are using the standard request to channel mapping. If you are using the standard HalCoGen generated startup file, the HW interrupt vector mechanism should already be enabled, so that shouldn't be a problem. Another thing you can check is if the "I" bit (IRQ disable) in the CPU CPSR register is set to 0. If it's 1 then the IRQs coming from the VIM will be ignored.

    Regards

    Frank

  • Hello Frank,

    Thank you for this. I can now see interrupts happening.

    I am getting the htuHighLevelInterrupt, but the frequency of the interrupt is too quick. It should be triggered when the buffer A is full, but it seems to be a fixed frquency. When I change the frequency of the input signal, the frequency of the interrupt does not change at all. The interrupt handler should be triggered about avery 15ms, but is is triggered every 225microseconds. I am toggling a HET pin in the interrupt handler to check the frequency of the interrupt.

    I am clearing the BFINTFL register each time the ISR is entered. Is this the right thing to do?

    I was assuming that the data from the PCNT instruction would only be sent after the falling edge on the input signal and that the interrupt would only go off after the buffer is full, which should be about every 15ms.

    Can you think of any reason why the interrupt should not have the expected frequency?

    Regards,

    Dave

  • Hello Dave,

    this is strange. I assume you still have the frame count of the control packet set to 120 and that should translate to a 8kHz (?) input signal. Have you checked that you actually get valid input data in the buffer? Are there interrupts from other modules enabled in the system? Perhaps the request to channel mapping in the VIM is off and a different module (e.g. RTI) is generating the interrupt. Have you tried stopping the input signal completely and checked that you don't get any interrupts?

    Clearing the BFINTFL register is ok in the ISR. I assume you are doing this by writing a '1' to the respective bit.

    Regards

    Frank

  • Hello Frank,

    The data is valid in the input buffer. I have upped the frame count to 150 and the buffer sizes accordingly. The interrupts continue even with the input signal removed, so I will have to try and find out where the interrupt is coming from.

    Thanks for your help.

    Regards,

    Dave

  • Hi Dave,


    I'm about to work on an update to the HTU User's Guide section of the TRM, and am curious if you ever got an answer or figured out the interrupt question.

    Also if you have any suggestions for sections of the HTU User's guide that need to be improved / beefed up would be interested in hearing.

    Thanks and Best Regards,

    Anthony

  • Hi Anthony,

    I managed to get the HTU interrupts working fine in the end. Thank you for asking.

    When I get a minute I hope to be able to address your request for suggestions to the HTU User's Guide section of the TRM.

    Regards,

    Dave

  • Thanks Dave,

    Glad to hear you finally got it working - I couldn't tell from the post.

    Any feedback you do have on the doc would definitely be appreciated - especially since it'll take you time.

    Also if there are any questions that are 'open' in your mind but not immediately blocking progress with HTU - if you post them here

    then we'll run them down and get them answered.   It's invaluable to hear from someone actually trying to use the chip to get a task done.

    Thanks and Best Regards,

    Anthony