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.

MSP-EXP432E401Y: MSP-EXP432E401Y

Part Number: MSP-EXP432E401Y

Hi,

In my application I am using all 8 UARTs. Which are connected to external 8 devices and these devices sending some characters for up to 12 seconds when they turn on. MSP432E401 will wait for particular character and then turn off and turn on that particular device from that 8 devices. And again wait for that particular character. MSP423E401Y will do 100 times this on/off cycles for 1 device. This same thing it do for all 8 devices. 

Now my problem is if I start the application running then all UARTs ISR's are triggered. And MSP432E401Y is missing that particular character for any 2 or 3 UARTs. If I put 2 sec delay in between the on cycle of all 8 devices means 1st turn on then 2nd turn on after 2 sec and 3rd turn on after another 2 sec and so on.. then also some UARTs are missing that character. These all 8 devices sending the characters at 115200 baud, 8-1-N.

I have tried to decode the example code for DMA. But I need more clarification related to use of DMA. Because I have to use all UARTs for external communication with 8 individual devices. If you give the basic guidelines or structure for my application for one UART then it would be great. In my application I am getting maximum 85 characters at a time and then new line is the last character after that another characters coming on UART. this will run up to 12 sec. in those received characters I have to find out the required string.

Can you help on this with DMA? with out DMA for 1to 3  UARTs its working fine. but if I connects more then its missing characters. I have also taken out all the process for characters and 100 time on/off to the main loop.

please help in this regard.

k

  • Restating your specification:

    1) Your master (MSP432) has 8 clients, each of which sends a continuous (no delay between bytes), unknown-length stream to the master.

    2) The master recognizes a particular terminator sequence from the client, and takes some Action.

    The first questions are:

    A) Is the terminator sequence a single byte or multiple (consecutive) bytes? You refer both to "character" and "string". (Recognizing a single byte is pretty easy.)

    B) What is your system/CPU clock set to?

    C) Does the client keep sending data after the terminator?

    D) Do you care about what's in the streams (and thus have to save them somewhere), or only about the terminator?

    E) How much latency is acceptable between receiving the terminator and initiating the Action?

    If each stream is of unknown length (see (1)), I suggest that using DMA will be a headache. The DMA understands only counts, so it doesn't know enough to interrupt you until the count is reached. If the client stops after the terminator (see (C)), the DMA won't notify you at all.

    At 115.2k, each client is providing a byte every ~100usec; with 8 clients, you're seeing a byte every 12.5usec. If you're using the PIOSC (16MHz). that's 200 CPU clocks to process each byte. This isn't enormous, but is more than adequate.

    My first guess is that you're trying to do too much in your ISR; it should store the Rx byte and get out, and let main() make the decisions.

  • hi,

    A)master is getting 14bytes word from the clients

    B)system CPU clock set to 120MHz

    C)after getting termination word master gives signal to client for cycle the power and master count its one boot cycle. and after client gets turn on it again send the same pattern. 

    D)only about the terminator

    E)needs at least one second 

    From the ISR I removed everything to the main loop now. Only one thing I kept in ISR to check for the new line from the client is started or not.

    k  

  • So what does it do now?

  • Hi Sorry for the late replay, but still for some client UART missing the required string. can you please suggest what should I have to implement? in the ISR?

  • Hi,

    One thing I noticed the client transfer data through the ADM3202 rs232 transivers and I have used ADM202E. is that the problem?

  • I don't know much about those line drivers, but I don't see any obvious incompatibilities between them. Is there anything shared here, or is it a real star topology? Are the cables particularly long?

    I thought I read that your system works OK with a few clients, and only starts to fail when you increase the number, but going back I don't see it. Is that the case?

    In any case, at 120MHz you should have plenty of time to service all the clients. Could you post one of your ISRs? (I assume they're mostly identical.) Maybe someone will see something.

  • Nothing is shared and cables are just 2 meters long.

    yes systems works fine with 4 to5 clients after that there is a problem.

    the ISR is as below and other are identical to this.

    /******************************************************************************

    *

    *UART_0 Interrupt Handler

    *

    ******************************************************************************/

    void

    UART0_IRQHandler(void)

    {

    uint32_t ui32Status_0;

    Rcv_Flag_0 = 1;

    ui32Status_0 = MAP_UARTIntStatus(UART0_BASE, true); //Get interrupt status

    MAP_UARTIntClear(UART0_BASE, ui32Status_0); // Clear the asserted interrupt

    while(MAP_UARTCharsAvail(UART0_BASE)) //Loop while there are characters in receive FIFO

    {

       String_0[Rcv_Ch_0] = MAP_UARTCharGetNonBlocking(UART0_BASE); //Read character from the UART and store it.

       if(String_0[Rcv_Ch_0]=='\x0d') // check for the new line

              {

                    Rcv_Ch_0 = 0;

                  New_Line_0 = 1;

               }

       else

               {

                Rcv_Ch_0++;

               }

        }

    }

  • It's hard to get much smaller than that.

    What is your FIFO threshold set to? If you haven't changed it, the FIFO could be "hiding" up to 8 bytes from you.

    Unsolicited:

    > MAP_UARTIntClear(UART0_BASE, ui32Status_0); // Clear the asserted interrupt

    I suggest you not do this. Emptying the FIFO will cause RXRIS to clear on its own, and I wonder if there's some possible race (though I admit I haven't been able to contrive one, that's why I'm going with "suggest"). 

  • Hi,

    I haven't changed FIFO threshold.

    I have removed MAP_UARTIntClear(UART0_BASE, ui32Status_0); from the routine and kept it under test.

    my question is "is there any possibility with this ISR UART will miss any receiving character under 115200 baud if all 8 UARTs are sending simultaneously at same baud?"

  • I don't see any logical hazards, and I would estimate this code would cost perhaps as much as 100 CPU clocks/byte, where at 120MHz you should have 120MHz/(8*115200/10)=1300 CPU clocks/byte to work with.

    I would be looking elsewhere.

  • Hi,

    That's why I doubted on the line driver which I used on the general purpose board. I may be have to try the ADM3202E instead of ADM202E for all UART. Because out of 8 some UART missing randomly. there is no particular UART missing. if anything else you think please let me know. I am using strstr() to compare the string in the main for all UARTs.

  • I don't much trust UART/RS-232 (at least not in a "bet my project" kind of way), but it tends to fail randomly, rather than under load. 

    I think I'm starting to catch up now -- you're using the 0x0D as a forwarding character ("time to look at this stream") and then main looks for the (14-byte?) trigger string in the line you've just captured? If so, is the missing byte(s) the 0x0D or something in the string?

    Due to the FIFO, each call of this ISR will receive at least 8 bytes; if the 0x0D is in the middle, it will do the forwarding signal (New_Line_0=1) but will also wrap back to the beginning of the input line (Rcv_Ch_0=0), so main() won't know how long the line was. (Also, if you're using strstr(), are you terminating the string somewhere?)

    The first experiment I would try -- because it's simple if nothing else -- is turn off the FIFO (UARTFIFODisable()). I was a bit surprised to discover that UARTEnable() automatically turns it on -- dealing with a FIFO on a UART Rx stream is not always easy. By my estimation, you have plenty of CPU cycles to deal with the streams one byte at a time.

  • Hi,

    you are right for your point related to the 0x0D. but its working fine with 4 to5 clients so I have a doubt on that.

    In the main loop once I get the required string I am turning off and on the client look the below code.

    if((strstr(String_0, SubString))!=NULL) //Find out the required characters form the whole received line.

    {

    memset(String_0, NULL, BUFFER_SIZE_MAIN);

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0); //Client off

    SysCtlDelay(g_ui32SysClock / (1 * 3)); // delay

    GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1); //Client on

    Boot_Cycle_0+=1; // increment one boot cycle for client 

    }

    In this loop I am doubting on the delay function which can cause the issue. what do you think? because if I remove the delay and sent the same characters from the PC through tera term macro UART is not missing anything. I think I have to handle the delay in a way that it resolve my issue. if you feel this delay function is the problem please suggest the alternate option for cycle the power of client.

  • SysCtlDelay, based on the Driverlib source, is pretty innocent (assuming interrupts are enabled) -- it's just a two-instruction countdown loop. It's 3 CPU clocks/loop, so your delay is roughly 1 second.

    During that 1 second, we expect that 8*10kB=80kB have arrived from the client, so if normal lines are shorter than 80k/8=10kB long (seems likely) you've probably cycled each buffer multiple times, possibly overwriting the one line you were interested in.

    Where did the 1 second timing come from? Most reset (as in /RST pin) sequences are measured in microseconds, or occasionally 10s of microseconds. What does that pin actually control?

  • Hi,

    I could not understood the following lines,

    During that 1 second, we expect that 8*10kB=80kB have arrived from the client, so if normal lines are shorter than 80k/8=10kB long (seems likely) you've probably cycled each buffer multiple times, possibly overwriting the one line you were interested in.

    The pin is configure as output and gives 0 when particular string arrived from client and makes it 1 after roughly 1second through SysCtlDelay.  The client sending characters in duration of 12 seconds.my required string comes at  the end of transmission means at 12sec. after getting that string I cycle the power of client and it starts sending again. same way all 8 client do. This all going parallel. I took buffer size 85 for long line. but I required only 14 characters of that line to boot power for that particular client.

  • The problem is that while main is spinning power-cycling one of the clients, the other clients are continuing to send data but main isn't checking it. Assuming data is arriving continuously, each client will send multiple lines (ending in 0x0D) while main isn't looking. If the first is the line you're looking for, that text will have been overwritten in string_0 by the time main finishes its delay and looks again.

    If that GPIO is really a power control, I would think that holding it low for a millisecond or so would be plenty, and a millisecond (g_ui32SysClock / 3 / 1000) probably wouldn't be long enough to get in the way.

    If you really have to hold it low for a full second, consider setting it low and marking that node with a timestamp; each time through the main loop, check to see if a second has passed for that client and then set it high again. That way main will spend most of its time scanning data rather than spinning.

    [Edit: Minor clarification]

  • yes exactly this is the problem.

    I have to hold it low for 1 sec so I have to implement the software.

    can you please guide me for implementing so that UART will m=not missing any character while delay is asserted?

    Thanks 

  • I've only seen small pieces of your program, so I don't know what timing facilities you already have. 

    If you're already running the RTC, or have a system clock that counts e.g. milliseconds, you could keep an array of 8 clock times, and if the difference between the clock time "now" and the clock time in the array is > 1 second, set the GPIO high.

    Alternatively, if you already have a periodic timer that interrupts every e.g. 10ms, you could put 100 in the array element and decrement it each time through; when it counts down to 0 set the GPIO high.

    There's an example of setting up a periodic timer here:

    http://dev.ti.com/tirex/explore/node?node=AE4FHLknRuEXTBy6LcOqWA__J4.hfJy__LATEST

  • Thanks but the provided example link is not working.

  • Ok I got it browser was not supporting that's why ,

    I will check this example code for the periodic timer and implement it accordingly. will let you know after implement.

  • Can you clear one thing ?

    How i use one timer interrupt for all  client ? I can do that but want some effective way so that it will not creat any problem again.

  • I have updated with timer for 1 sec will check and let you know if any problem or working correctly.

    thanks.

  • You've probably already figured this out while I was asleep, but just in case:

    0) Supposing that your periodic timer goes off every 10 milliseconds (100Hz):

    1) Define an 8-element unsigned vector e.g. "timer[8]"

    2) To do a power cycle, set GPIO[client] low (power down), and store 100 (for 100Hz) in timer[client].

    3) In your periodic timer, for each client (0-7):

    a) If timer[client]==0 don't do anything

    b) Otherwise,

       i) decrement timer[client]

      ii) if timer[client] == 0 set GPIO[client] high (power up)

    This is actually pretty quick, and the (few) races are harmless.

    Let us know how it turns out.

  • Thanks,

    I will make  it snd let you know definitely about results.

  • Hi, Thanks a lot for your kind help.

    I checked it was overwriting the particular word that word I want. After implement now its working fine.

    thanks again

**Attention** This is a public forum