TI MSP430 Interrupt Issues After UART Code Port

I am using the MSP430F2013 processor for an application that does not have UART. I need UART, so I used the TI sample code "msp430x20x3_ta_uart2400.c" to emulate one using the Timer module. It all worked perfectly (compiled with the IAR Embedded Workbench), testing it with PuTTY to transfer characters to the development board and loopback to track them to the terminal.

It was a disintegrating exercise, and now I have come to transfer this code to my application state machine. By doing this, I had problems with timer interrupts and low power modes. Here's a snippet of my code around entering low power (sleep) mode:

// Prepare the UART to receive one byte. prepare_receiver(); // Enter low power mode 1. __bis_SR_register(LPM1_bits + GIE); // Check whether the full message has been received. if(true == get_message_complete()) { process_event(e_euart_message_received, NULL); } 

What I see in the debugger (C-Spy) is that sometimes it will execute the line bis_SR_register() on the first record, and then go to the if , i.e. ignoring the fact that I asked it to go to bed. In other cases, when he goes to sleep, when necessary, the ISR starts up correctly and ultimately returns me to the if to continue executing the program (as I expect). However, if I try to move on to the next statement, the application freezes in this first line, that is, I cannot move forward.

I can’t think of anything functionally different from the TI example I am doing, so I believe that my problem should be related to the way I ported it. For example, my timer ISR and the code that I posted here are in different compilation units - will such a decision have anything to do with things? I know that my question may be a little vague, but unfortunately I cannot post all my code, so instead I am looking for someone with MSP experience who could offer some things to look at or some potential problems, which I may have fallen.

+4
source share
2 answers

The answer to this question is to configure debugging and, more specifically, about what types of breakpoints are used. I had a rather complicated series of macros that were executed when the program was loaded, which set various hooks in memory for testing purposes. These hooks were based on the created moments of program creation, which would then call functions outside the application. I did not see any problems using these breakpoints during normal use, however their existence means that the debugging session is not running in real time (i.e. the device is under the control of the host computer). This, for some reason, not yet fully known to me, caused problems when trying to debug interrupts and low power modes. (I suspect that if I looked a little deeper, I would see the need to use the clock control during debugging, but I will keep it for another day).

So, to solve this problem and allow me to debug the heavy interrupt code and low power mode that I ported to my larger final autostart application, I had to do the following:

  • Disable software breakpoints in the IAR.
    They are not enabled by default, but if you are doing smart things with macros like me, you probably would need to be able to use them since most MSP430 lack hardware breakpoints (for example, I only have two breakpoints in MSP430F2013, and C-SPY is more often than not one of them!). The obvious drawback to this is that debugging becomes a little more time consuming, but at least reliable.
  • Remove Mac Macro Links.
    In other words, if you use macros, do not do this. In my case, this meant that I had to hack some kind of logic of the state machine in order to force myself along some specific route (which the macro had done for me before). This is clearly not ideal, but it will allow you to debug the interrupt / low power mode code. After that, macros can be re-enabled.

So, it turned out that there were no problems with my port. I am not very happy with this hacking decision, but at least it is a step forward. If I have time, I will investigate if I can develop a way to use software breakpoints and add to this answer.

+4
source

Debugging interrupts using C-Spy in low-power mode will be challenging. According to Section A.3 Debugging (C-Spy) - IAR User Guide :

5) C-SPY can debug applications using interrupts and low power modes

But there are some "gotchas" that you should be aware of that can cause a headache.

In particular:

14) When C-SPY controls the device, the CPU is in a state (that is, it is not in low power mode) regardless of the settings of the low-power mode bit in the status register. Any conditions of the low power mode restored to a step or transition. Therefore, do not measure the power consumed by the device, but C-SPY controls the device. Instead, launch the app using Go with the JTAG release.

19) C-SPY uses the system clock to control the device during debugging. Therefore , device counters, etc., which are synchronized. The main system clock (MCLK) is affected when C-SPY monitors the device . Special precautions are taken to minimize exposure to the Watchdog Timer. CPU registers are saved. All other clock sources (SMCLK, ACLK) and peripherals continue to function normally during emulation. In other words, the Flash Emulation Tool is a partially intrusive tool .

Devices that support synchronization control (emulator β†’ Advanced β†’ Clock Control) can further minimize these effects by choosing to stop the clock (s) during debugging

24) The peripheral bits that are cleared when reading during a regular program execution (i.e. interrupt flags) are cleared when reading while being debugged (that is, a memory dump, peripheral registers).

When using some MSP430 devices (such as MSP430F15x, MSP430F16x, MSP430F43x and MSP430F44x), the bits do not behave this way (that is, the bits are not cleared using C-SPY reads).

26) While one step with active and enabled interrupts, it can only active interrupt service (ISR) is active (that, non-ISR code is never executed, and one step the operation always stops in the first line of the ISR ) However, this behavior is correct because the device always processes the active and enabled interrupt before processing code other than the ISR (that is, the main one). A workaround for this behavior is to disable the GIE bit on the stack within the ISR, so interrupts are disabled after the ISR exits. This allows you to debug code without ISR (but without interrupting). Interrupts can later be re-enabled by setting GIE to in the register.

On devices with the synchronization control emulation function, it is possible to pause synchronization between individual steps and delay the interrupt request (Emulator β†’ Advanced β†’ Clock Management).

One thing to try is to comment out all the low-power code and see if your UART code works. Then go back and try turning low power mode back on.

+5
source

Source: https://habr.com/ru/post/1434660/


All Articles