Jump to content


  • Content Count

  • Joined

  • Last visited

About RobertWoodruff

  • Rank
    Advanced Member

Profile Information

  • Location
    US - Florida
  1. Yes, that had occurred to me as well. If this app was awake at all times that would be easier to implement. But this one spends most of its life in LPM3 (it is a battery powered system). I am too lazy to want to complicate the for loop with logic to see if LPM3 should be delayed or not because a human user is awaiting a response. It is just easier to send the response during the RX ISR routine and let the system fall back into LPM3 when the RX ISR terminates. Essentially the for loop is not running most of the time, if that makes sense. Thank you,
  2. The replies make good points, thank you. I am going to look into disabling the RX ISR while the command is being processed within the RX ISR. That fits within the use-cases for this app. hopefully the HC-05 BT module has enough buffering to hold any few characters that may come in while RX ISR is disabled. Another option is to place the commands in a queue to be processed "later" when not in the RX ISR. Without an OS to support queueing, threading and scheduling issues that is just too much trouble, for this project on this little MCU (running out of code space anyway) Thank you for the replies,
  3. This is a recap of a little adventure in the hopes that it helps someone else out there. This application is on an MSP430G2553 MCU. CSS is used as the IDE and the Energia libraries are in play (a good tooling combination, highly recommend J). The app spends most of its time in LPM3. It wakes up periodically to do certain tasks and also wakes up when traffic comes in on the UART RX channel. The ISR for the RX channel detects the arrival of a command and acts on the command during the ISR. Part of servicing a command is sending a response, which is transmitted via the UART TX channel. Sometimes the app would respond to the command and other times the MCU just hangs. Digging in deeper with the CSS debugger showed it hanging in the Energia libraries waiting for the Serial TX ISR to fire and make space in the TX ring buffer. Why was the TX ISR not firing? Here is what was happening: If the response string was short enough to fit in the ring buffer it would be stored there, the TX ISR would eventually fire and send the response. If the response was too large the write routine would hang waiting for space to become available in the ring buffer. Energia disables GIE when it is in its TX or RX ISR routines. This app is trying to transmit while in the RX ISR. That will have the effect of filling the TX ring buffer but the TX ISR is not firing because GIE is disabled. So the buffer fills and the app hangs waiting for space to become available. Easy enough to fix: In the app code that is responding to commands and sending the responses do this (remember, this is inside the RX ISR thread of execution) __istate_t iState = __get_interrupt_state(); /* Current state of SR */ __bis_status_register(GIE); /* Enable GIE */ /* Process the command, send response */ __set_interrupt_state(iState); /* Restore GIE to previous state */ What this does is enable interrupts within the interrupt. Now the TX ISR will fire as Energia places bytes in the TX buffer. All is good!
  4. The "secret" to having the compiler/linker erase/set the flash memory when a program is flashed in has been solved. In CSS right-click on the project and select Properties. Select Debug then MSP43x Options. In there select under Erase Options "Erase main and information memory." Now whenever a new program is flashed to the MCU the SEGMENTB, C, and D are initialized to 0xFF in every byte. Perfect! Hope this helps someone else out there!
  5. Hi Bob, Your app looks doable to me, though not trivial. The hardware connections and interfaces are straight forward to make work for your prototype. Of course, moving the h
  6. Hi Bob, I use CSS with the Energia libraries (CSS now has explicit support for Energia). It is a reasonable choice, you can
  7. I had come across this article as well and it looks to have the answers. In my attempts to use the CCS #pragma statements the compiler warns it does not recognize them. Hopefully it is a setting somewhere that will let them work. Still researching. Thank you for the effort!
  8. My recommendation is to use the Energia Setup()/Loop() construct, And use CCS as the IDE rather than the Energia IDE. CCS is Eclipse and so the its debugger can be used.. Without the debugger progress will be tough. LPM3 is encapsulated in Energia by the sleep() methods so you make sleep() calls rather than LP3 directly. I have the MCU to respond to traffic on the UART RX channel while in LPM3 by processing the requests during the RX ISR wakeup. Thank you,
  9. I have had good success with using Energia libraries via Code Composer Studio for the TI MSP430. And for low power, interrupt driven application needs. Energia is a framework/libraries that help with some of the nitty stuff. And you have the source to Energia which helps with learning. I have made my own version of certain Energia modules, specifically to extend them to help with event driven needs You are right that it is C++. It always amazes me that we can use full object oriented C++ on these little MCUs. But we can. Classes, encapsulation, methods, and so forth. The UARTs work well and are straight-forward to use via Energia. It all takes a bit of learning and experimenting, that's for sure!. BTW, one of the low power apps I've built the system spends most of its time in LP3 but is awakened when traffic comes in from the Bluetooth module to the UART RX channel. After it processes the command it falls back into LP3 till next time or until the internal timer wakes it up to do periodic work.
  10. I have figured out how to use flash memory to persist values in the MCU, like to survive across a power failure. So that is cool. One last thing is how does one get the CCS C++ compiler/linker to initialize a flash segment? Does anyone have a technique for initializing a segment? For example, I am mapping the persistent values into SEGMENT_C. The C++ compiler/linker does not, at least as mine is setup, initialize the flash segment. It always has the same values from the last time the program wrote values in there, even when the program is rebuilt and reloaded into the MCU. I have been experimenting with #pragma location= and #pragma LOCATION(x,address) in an attempt to initialize a static variable into SEGMENT_C. But the C++ compiler is saying those are unknown pragmas. Does anyone know the technique to get the CCS C++ compiler/linker to initialize a flash memory segment like SEGMENT_C to something like all 0x00 or all 0xFF? Thank you,
  11. Hi Roboticus, You are correct, the parameter values to AT+CLASS= are hex numbers. There is a overview in the Bluetooth spec about formatting and interpreting the 32 bit class value (CoD). I am not going to learn all that now but have learned enough to carry forward with this application. Here is a translation between what is sent to the AT command and what is seen on the Android side /* Android Java code segment */ BluetoothClass bluetoothClass = btDevice.getBluetoothClass(); int deviceClass = bluetoothClass.getDeviceClass(); int majorDeviceclass = bluetoothClass.getMajorDeviceClass(); Apparently the default in the HC-05 is that lowest two bits of whatever hex value is sent to AT+CLASS= are set to 0 by the time it can be picked up on the Android side by deviceClass = bluetoothClass.getDeviceClass(); The majorDeviceclass is coming in at 0x100. Here are a few test cases I tried AT value(hex, binary) deviceClass majorDeviceClass 128, 0001 0010 1000 0x128 0x100 129, 0001 0010 1001 0x128 0x100 12A, 0001 0010 1010 0x128 0x100 12B, 0001 0010 1011 0x128 0x100 12C, 0001 0010 1100 0x12C 0x100 12D, 0001 0010 1101 0x12C 0x100 There are also web sites where you can enter the characteristics of your BT device and it will generate a CoD (class of device) hex number for you. Hope this info is useful to someone out there. Thank you,
  12. Has anyone figured out how to translate the value supplied to the HC-05 Bluetooth module's AT+CLASS= command to the value that is retrieved on the far end from the Bluetooth device connection? I can find explanations of how the individual bits of a standard BT 32 bit class value are to be interpreted. But I cannot figure out how to encode that value in the HC-05's AT+CLASS= command nor how any value set there translates to the value picked up when doing the BT paring on the far end. For example, if pairing with an Android the Java code on the Android to retrieve the class is something like BluetoothClass bluetoothClass = btDevice.getBluetoothClass(); int deviceClass = bluetoothClass.getDeviceClass(); int majorDeviceclass = bluetoothClass.getMajorDeviceClass(); Does anyone know how to encode class values in AT+CLASS= on the HC-05 and how they are translated into values on the other end? For example, say the Android was looking for deviceClass to be 99. What would be placed in the AT+CLASS= command to the HC-05 so that 99 was seen by the Android? (I know it is not AT+CLASS=99). Thank you,
  13. RX can be monitored by watching, with the CSS debugger, what characters are coming in from the UART interrupts being placed in the "ring_buffer" (HardwareSerial.cpp in Energia). They can also be reliably seen by watching, again with the debugger, the traffic to your serialEvent routine. It is a little tricky because the debugger sort of interferes with the ISRs used to capture the RX traffic. /* * From BT device on UART */ void serialEvent(void) { while(Serial.available()) { int cInt = Serial.read(); /* fetch next char from the UART buffer */ command.addChar(cInt); if (command.commandIsAvailable()) /* Call the command processor */ commandProcessor.processCommand(command); } } Hopefully this helps, at least a little bit
  14. Hi, again, tripwire, Let me ask, what is the difference between these two statements 1. String aStr = String("abc"); 2. String *aStr = new String("abc"); Is this this: In stmt 1 when aStr goes out of scope ~String is called and the object is deleted/freed. In stmt 2 when aStr goes out of scope the object remains allocated and no destructor call?
  15. Hi tripwire, Thank for for the explain. Programming on the TI MCU has brought me back to C++ for the first time in quite a long while (mostly use Java and its JRE on larger platforms). It is interesting getting reacquainted with C++ memory management. Thanks!
  • Create New...