Jump to content

Adding CC430 support

Recommended Posts

Hi everyone,


I'm working on Energia CC430 support. It's the first time I do this kind of work, it allowed me to understand a lot of things but not everything of course :) So I have a lot of questions !


So for now where I am : I'm working on a eZ430 - Chronos 433 mhz (==> CC430F6137). I program it with the ez430 USB stick (I will see later for upload using radio BSL). 


For now I just tried to get something working, I made a pin_energia.h creating a new MSP430 variant. I edited the board.h and I had to modify wiring.c to get the clock system working  :


Original line 168 :


#if defined(__MSP430_HAS_UCS__)


Modified to :


#if defined(__MSP430_HAS_UCS__) || defined(__MSP430_HAS_UCS_RF__)


I used some function from the eZChronos firmware provided by TI to test if the system was running, here is the code : 



Upload using Energia integrated in CCS v6 ==> IT WORKS :) the heart on the LCD is beating !


Now I am trying to understand if my modification of wiring.c is enought, and if other Energia features are OK.


All files are here : https://github.com/battosai30/CC430_EnergiaSupport


Now my questions :


1) What is interesting me the most is the radio core. TI provides some interesting low level libraries I can re-use, but I don't know how to integrate it directly in the core. I plans to work on others features like LCD_B, AES ... I think it would be better to directly integrate it and to do not have to add a library each time.


2) I found some defines in msp430's pins_energia.h :


#define TWISDA_SET_MODE  (PORT_SELECTION0 | PORT_SELECTION1 /* | INPUT_PULLUP*/) /* do not enable the pull ups for this device */

I don't really understand what they mean ...


3) How the PMAP is used in Energia ? I found a PMAP maping in fraunchpad pins_energia.h but I did not found where it's used.


4) I just need a confirmation : function "const uint8_t digital_pin_to_timer[]" is used to define pins PWM compatible ?


5) In wiring.c init() :


/* Clear P2.6 and P2.7 bits to default to GPIO */
#ifdef P2SEL2
P2SEL &= ~(BIT6|BIT7);
Why this lines ?

Thanks !


Link to post
Share on other sites
  • Replies 48
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

Cool.  The stock Chronos 433 antenna is absolute rubbish, though, so it is a low bar.   In any case, I can mail you a hand-built ~5cm reference monopole, if you want to compare RSSI readings (send m

Hey all!   This is Adrian from TI. We absolutely love this effort! To show our support, we'd like to enable you folks with some CC430 Chronos dev kits to help you out! Please send me a PM with your

Hi everyone,   I'm working on Energia CC430 support. It's the first time I do this kind of work, it allowed me to understand a lot of things but not everything of course So I have a lot of question

I know ... But they are adding since severall month so I'm a little bit impatient :)


And doing this I learn a lot of things so, even if we do the same work, they may not support everything at the beginning so I'll be able to add features

Link to post
Share on other sites

Awesome to hear that you are working on Chronos support! I have been wanting to add this for a long time but just lack the time.

To answer your questions:


1) I recommend to only keep the core the core and add things like the Radio and AES as a library. This keeps it modular and easier to maintain. 


2) the XXX_SET_MODE are meant to be used with pinMode_int() that is implemented in hardware/msp430/cores/msp430/wiring_digital.c. All the different flavors of MSP430 have different settings for the peripherals in SEL0, SEL1 and SEL2. By using the XXX_SET_MODE in combination with pinMode_int() the differences get abstracted. So for instance to set the right bits for a UART you define DEBUG_UARTRX_SET_MODE with the SELx and OUTPUT/INPUT for the specific MSP430 in pins_energia.h. The UART implementation now only has to call pinMode_int(DEBUG_UARTRXD, DEBUG_UARTRX_SET_MODE). DEBUG_UARTRXD is also defined in pins_energia.h.


3) The PMAP settings are stored in the upper 8 bits of the XXX_SET_MODE. So for instance on the F5529 the RX pin of the debug UART is on pin 4.5. By default the UART is not mapped to these pins. So to have pinMode_int() map it you store PM_UCA1RXD in the upper 8 bits. As an example the F5529 debug uart looks like this: DEBUG_UARTRXD_SET_MODE (PORT_SELECTION0 | (PM_UCA1RXD << 8) | INPUT).


4) Correct. digital_pin_to_timer maps to digitalPinToTimer in Energia.h and is used by analogWrite() (PWM)


5) By default the MSP430GXXXX have the XTAL pins set to XTAL functionality. This line turns them into GPIO's. I am working on Low Power modes and it will try to use the XTAL if present. This line will therefor be moved to another function and will only be executed if the starting the XTAL fails.

Link to post
Share on other sites

Thank for your answers :)


I have additionnal questions : I discovered pmap with CC430, and as I have unsderstand it, it allows features like UART,  i2c or timer outs to be routed on the different ports. Am I right ? Is there any final user fonctions that use pmap ?

Link to post
Share on other sites

Thank for your answers :)


I have additionnal questions : I discovered pmap with CC430, and as I have unsderstand it, it allows features like UART,  i2c or timer outs to be routed on the different ports. Am I right ? Is there any final user fonctions that use pmap ?

That seems to be the case, yes.  I have a project where I'll be using the PM feature (on an MSP430F5172) soon.  As I understand it, you can map a peripheral feature to multiple pins if you want (although I'm not sure what implication that has on the input side).


edit: According to the F5xxx user guide, when mapping a peripheral function to multiple pins, the pin values are OR'd together before being sent to the peripheral:

13.2.2 Mapping

For each port pin, Px.y, on ports providing the mapping functionality, a mapping register, PxMAPy, is available. Setting this register to a certain value maps a module's input and output signals to the respective port pin Px.y. The port pin itself is switched from a general purpose I/O to the selected peripheral/secondary function by setting the corresponding PxSEL.y bit to 1. If the input or the output function of the module is used, it is typically defined by the setting the PxDIR.y bit. If PxDIR.y = 0, the pin is an input, if PxDIR.y = 1, the pin is an output. There are also peripherals (for example, the USCI module) that control the direction or even other functions of the pin (for example, open drain), and these options are documented in the mapping table.

With the port mapping functionality the output of a module can be mapped to multiple pins. Also the input of a module can receive inputs from multiple pins. When mapping multiple inputs onto one function, care needs to be taken because the input signals are logically ORed together without applying any priority; therefore, a logic one on any of the inputs results in a logic one at the module. If the PxSEL.y bit is 0, the corresponding input signal is a logic zero.
Link to post
Share on other sites



I read another time the CC430 user guide and it's very much clear for me. Now I have to understand its implementation in Energia xD


Another question : I read this remark somewhere but I couldnt refind it. It's still not possible to add compilation defines -D by the board.txt ? My idea is for example to precise for example that a 32khz crystal is present and configure the UCS taking account this fact (so use the XT1CLK as FLL ref) or change  a little the pin mapping, I explain : CC430F6137 as USCI_A and USCI_B. the _A can feature UART, SPI or i2c as the _B only i2c or SPI. So it would be interesting to let the choise ? If someone wants SPI and i2c, he can't because _A will be used for UART by default ... 


EDIT : I have just found the Github Panstamp branch xD but now I understand everything and I see they made the same as me ;) but my pins_energia.h is more versatile because they only worked on CC430f5137 implemented on panStamp board


EDIT 2 : and I found a lot of errors in their pin_energia.h ...

Link to post
Share on other sites

Some good news :
With this simple code :

#include <display.h>

char str[]="    ENERGIA    ";
void setup()
  display_symbol(LCD_ICON_HEART ,SEG_ON);
  display_chars(LCD_SEG_L2_5_0," ROCKS",SEG_ON_BLINK_ON);

void loop()
  for(int i =0;i<12;i++) {

I have to clean the library : I just made a bulk transfer from TI firmware and it's not very clean as I haven't understand everything yet.
It was an important step for me because serial debuging is not possible (I have to solder wires to do that and I don't want to for now).
I looked RTC_A peripheral and it seems a piece of cake to get it working (strangely, TI don't use it in his firmware and use classic timer ).
Finally everything I could tried like analogRead() digitalRead() and digitalWrite() worked. I have to test PWM, i2c and SPI now

Link to post
Share on other sites
  • 3 weeks later...

Another good news : after a week of fight, I've build a beta library which allowed radio communication between my ez430 Chronos and a CC1101 connected to a Launchpad :)


The library is cross platform compatible : Energia & Arduino. As I used high level Arduino core functionnalities, it will work on all platforms. I just meet troubles on Energia because of that http://forum.43oh.com/topic/5362-conflict-between-digitalread-and-spi/  If no modification is done directly in Energia core, I'll have to make a configuration for each

Link to post
Share on other sites

Finally got it !! I had some inexplicable problems driving CC430's radiocore and I finally found the reasons. And now I understand why, I just can't understand how it could work before ... And more, my CC430 driver is based on rf1a.c provided by TI in his Chronos firmware, it's also used by a lot of librairies I found, and I found in it two big mistakes.


 Complete code : https://github.com/battosai30/Energia/blob/panstamp/hardware/msp430/libraries/panStamp/utility/rf1a.c


The first (I discovered this one very early) is located in Strobe() exactly here :

// Check for valid strobe command 
  if((strobe == 0xBD) || ((strobe > RF_SRES) && (strobe < RF_SNOP)))

The first condition for the strobe command to work is that the command is > RF_SRES and strobe < RF_SNOP, so  SNOP and Reset are simply not possible !


I changed it to :

// Check for valid strobe command  
if((strobe == 0xBD) || ((strobe >= RF_SRES) && (strobe <= RF_SNOP)))

And it was OK, can get status register with a SNOP command and be able to reset the radio core.


The second was a pain ... It takes me so much time to found it ... In ReadSingleReg(unsigned char addr), this line :


needs to be changed to :


If you want to read a single register, you have to read the register without auto read or when you read back the register, DOUT is loaded with a new byte.


Now I finally got a robust link between CC1101 + Launchapd and CC430 :)



Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...