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.

Ti-RTOS 1-wire communication timing

Other Parts Discussed in Thread: MSP430FR6989

I am using TI-RTOS on a MSP430FR6989, running at 8MHz MCK and ACK at 9400 Hz using the VLO.

I need to communicate with a Atmel ATSHA204A chip using only 1 wire. 

I follow the datasheet of the chip. timing is crucial. I must be able to do short pulses of 4-6 microsecs during transmission to send zeros and ones.

For example:

One is line low for 6 usec , then line high until next bit (bit period is 54 usec)

Zero is line low for 6 usec, line high for 6 usec, line low for 6 usec then line high until next bit.

After a while I could manage to send the correct stream of bits to the chip, and the chip responds.

Then comes the receiver part: I need to decode the data coming from the chip.

I tried in different ways, using a timer and capture/compare, and using directly the line input interrupt.

When the chip replies, it sends for example 10 bytes. It is 80 sequences of 0/1 symbol. During the chip transmission, my ISR should be extremely quick in doing the following steps for each bit:

- detect the first line low

- wait 6 usec 

- check the input line and decide the bit value (0 if line is low, 1 if line is high)

My problem is that I some bits. i investigate with an oscilloscope and I could find the reason. The RTOS clock tick.

With a clock tick period of 1000 us I miss some bits, with a period of 10000 us everything is OK. but of course for my application 10000us of clock tick is not acceptable.

Any idea on what to try next? Is there a way to disable/slow down the RTOS clock ticks just for the time when I am receiving data from the chip?

Any idea is appreciated. Thank you.

Claudio.

PS

To try to solve the problem I did the tests on a minimal project where only 1 task is running and no HWIs are enabled. only the system clock is active with no SWIs.

I could not use HWIs for my ISR since the latency was too high and I could not catch the signal value after 6 us.

I do not call any RTOS api from the ISR.

The task sends data to the chip then goes suspended on a semaphore with timeout (this cause the ticks to run), then check for the received data. (I may try also a task_sleep). I do not know yet how exactly synchronize with the receiving ISR since I cannot use RTOS APIs in it)

  • Hi Claudio,

    Hmm.  It sounds like you are having an issue due to being interrupted by the timer interrupt - your data transfer is being interrupted (and messed up) by that interrupt.

    When you change the timer period to 10,000 ticks, you are "safer" because there is a much larger time gap in between interrupts, and your data transfer isn't happening at those times. (Note that you are probably getting lucky - I think you would still have the same issue of data loss if the interrupt happened to land during your data transfer).

    Anyway, there is a setting in the Clock module itself, but it's typically used as a feature for low power mode.  I'm not sure if this would help you, thinking about it more, I think it may just result in "increasing your luck" with the interrupt not falling on top of your data transfer by chance.

    How long exactly is your data transfer?  Since it seems it's on the order of a small number of microseconds, maybe the best way is to globally disable interrupts just before your data transfer begins, and then re-enable interrupts once the transfer is complete.

    Steve

  • Thanks Steve, this was also my conclusion. I would like to stop all interrupts for a while, but I need to keep the input line interrupt active. In this case disabling GIE does not work, since I would disable also my communication line. I need to disable all the other interrupts one by one. I do not know of an elegant solution to do it.

    Claudio.

  • Claudio,

    You can try using the API Hwi_disableInterrupt(). This allows you to disable a single interrupt. You could do that for the interrupt(s) that you want to avoid while doing your critical operations.

    Hwi_restoreInterrupt() is used to re-enable the interrupt that was disabled with this call.

    Steve
  • I tried and got an error. it looks as if Hwi_disableInterrupt is not ok on my platform.

    This is coming from Hwi.c (generated by ti-rtos)

    /*
     *  ======== Hwi_disableInterrupt ========
     */
    UInt Hwi_disableInterrupt(UInt intNum)
    {
        Error_raise(NULL, Hwi_E_notImplemented, "Hwi_disableInterrupt", 0);
        return (1);
    }

    So, no success in disabling just one interrupt.

  • Hmm. Yes, looking at the code I see that, too. What's strange is that the documentation for the MSP430 Hwi APIs show the disableInterrupt function is supported (that's what I based my previous response on).

    Let me continue on this and get back to you tomorrow.

    Steve
  • Claudio,

    Were you able to get past this issue?

    Steve
  • My current working solution includes the manual disable of the clock interrupt, working directly on TA1CCTL0 clearing CCIE bit and restoring it after receiving the bytes.

    I also needed to disable tick suppression mode in the power optimization of MSP430 TI-RTOS settings.

    Not the perfect solution, but it works. Now I have to tweak the project to reduce the power consumption when not using the single wire protocol.