Jump to content
bolton

Anaren TI CC110L RF AIR Booster Pack

Recommended Posts

I don't see you clearing P2SEL. On 2xx MCUs that powers-up as 0xC0, meaning P2.6 and P2.7 are not GPIOs but are set for their peripheral function. Try setting P2SEL &= 0x3F during initialization and see if that helps.

 

Also, you're setting P2.7 as an input by clearing its bit in P2DIR. You want P2SEL &= 0x3F, P2DIR |= 0xC0, P2OUT |= BIT7.

Share this post


Link to post
Share on other sites

I'm still experiencing the same results, even when using or not using the I2C calls in the earlier post.

 

Edit: my bad, I haven't noticed the other two port settings, only the first (P2SEL &= 0x3F). I'll test it by tomorrow. Meanwhile, if I still experience failure, what other changes may I do?

Share this post


Link to post
Share on other sites

Hi,

 

The modifications aren't working. I also did some port settings before, but they still don't do any effect (in MSP430G2553 provided in the Launchpad, P2.7 = XOUT. I don't have any crystal soldered, and by the manual I presume that if this port is high, the chip would be inactive).

 

P2SEL &= 0x3F;

P2DIR |= 0xC0;

P2OUT |= BIT7;

OPEN_I2C_ON_P1_6();

OPEN_I2C_ON_P1_7();

 

How could I turn on/off or activate/deactivate the RF module? Or any other change that could work? It seems that there is the possibility to create a manual I2C, however there's someone who already did that to say if this is feasible or not?

Share this post


Link to post
Share on other sites

Since we're using completely different environments (I'm using BSP430, you're using those macros and other code), I can't say for sure what's wrong. But I can say that I2C on a LaunchPad with the Anaren board attached does work, and give maybe a clue as to the problem. (I'm using the I2C EEPROM on an HH10D since it's an I2C device I have that I know works; I haven't uncrated the BMP085 yet.)

 

On the G2553, we have: I2C Pins: MOSI/SDA=P1.7; MISO/SCL=P1.6; CLK=P1.5; STE=P1.4

 

The issue I ran into was where previous use of the radio with a different application left it configured to pull GDO1 low. This interfered with I2C's weak pull-ups on SCL.

 

For completeness: you do need this, to shut down the crystal pins and set the radio CSn:

P2SEL &= ~(BIT6 | BIT7);
P2DIR |= BIT7;
P2OUT |= BIT7;

Which is essentially covered by the code you posted.

 

Then try this at the point just before you configure for I2C:

P1SEL &= ~(BIT4 | BIT5 | BIT6 | BIT7);
P1DIR &= ~(BIT4 | BIT5 | BIT6 | BIT7);
printf("P1: SEL %02x DIR %02x OUT %02x IN %02x\n", P1SEL, P1DIR, P1OUT, P1IN);

You want to see something like:

P1: SEL 06 DIR 01 OUT ce IN c6

Specifically, P1IN has bits 0xc0 set. If instead you see something like:

P1: SEL 06 DIR 01 OUT ce IN 86

then because P1.6 (SCL) is low the MSP430 I2C peripheral will assume the bus is active and won't use it.

 

If that's the problem, it's hardware and I can't help. My guess would be your I2C device didn't have adequate pullups. On power-up the Anaren board has GDO1 (P1.6) configured to function 0x2e which is high impedance, so if you haven't used the radio you should be OK.

 

In summary, there's no need for special radio configuration to share the bus between the CC110L and an I2C device. Things should work on power-up. However, if you're mixing radio use with I2C use, you'll need to ensure GDO1 is configured to function 0x2e at the times I2C is required.

Share this post


Link to post
Share on other sites

Well, in the last weeks I tried to change the pins to use the UCA instead of UCB of the MSP430 Launchpad. It worked, but I need to use the ADC ports. So, back to your post: in fact I'm reading P1.6 low, and I'm using 10K pullups. What should I do, then? I'm using the following settings to enable I2C, and I'm afraid I'm forgetting something:

 

P2SEL &= ~(BIT6 | BIT7);
P2DIR |= BIT7;
P2OUT |= BIT7;    //P2.7: CSn, putting it as high
P1SEL |= BIT6; P1SEL2 |= BIT6; P1DIR |= BIT6;
P1SEL |= BIT7; P1SEL2 |= BIT7; P1DIR &= ~BIT7;

Share this post


Link to post
Share on other sites

Question for anyone (or ADIDAlllini in particular):

My goal:

  1. I'm trying to get SimpliciTI running on the LaunchPad + Anaren's Boosterpack.
  2. (I got the LarsRF code to work, and I'm much obliged ....but this post is not about that.)

Process thus far:

  1. I followed GWDeveloper's tutorial (SimpiciTI Tutorial for CC2500), and I can compile code in CCS without errors.
  2. I followed ADIDAlllini's recommendations (post #26 in this thread) and did the following:
    a) I did not make any SmartRF alterations - different from ADIDAlllini.  (I couldn't figure out how to export them, and then I didn't know if I needed to export CC110L or CC1101, etc.)
    B) I did not install the LaunchPad crystal - same as ADIDAlllini.
    c) I altered the Csn definition in mrfi_boards_defs.h from P1.4 to P2.7 such that I didn't have to alter the JP3 jumper on the Anaren boosterpack.  (ADIDAlllini opted to connect jumper JP3 (CSN) to position 3 instead.) - see code alteration below.
    d) I altered the GDO2 definition in mrfi_boards_defs.h from P2.7 to P1.0. - see code alteration below.  Same as ADIDAlllini.
  3. I even tried defining BSP_NO_LEDS (since LED #1 is defined on P1.0 in bsp_led_defs.h which could conflict with GDO2) with no effect on code execution.

Result:

  1. The main_rx.c and main_tx.c code compiles fine.
  2. When I run main_rx.c or main_tx.c, the assert on line 375 in mrfi_radio.c always stops the execution:

    /* verify that SPI is working, PKTLEN is an arbitrary read/write register used for testing */
    #define TEST_VALUE 0xA5
    mrfiSpiWriteReg( PKTLEN, TEST_VALUE );
    MRFI_ASSERT( mrfiSpiReadReg( PKTLEN ) == TEST_VALUE ); /* SPI is not responding */ /*troublesome line for me*/

Questions:

  1. I'm looking to see if there's something I'm overlooking in getting this code to work - impressions?
  2. Is there a specific reason as to why I would need to modify the LaunchPad hardware (connect jumper J3 (CSN)) instead of just changing the CSn definition as I've done in mrfi_board_defs.h?  (per ADIDAlllini's instruction in post #26).
  3. Why is the SmartRF register dump needed as a replacement for c:\Texas Instruments\SimpliciTI-CCS-1.1.1\Components\mrfi\smartrf\CC1101\smartrf_CC1101.h ?  (per ADIDAlllini's instruction in post #26).
  4. I'm open to learning, so if there's anything else someone wants to throw at me, I'd be grateful.
  5. Oh, is there some trick to seeing the pictures on gwdeveloper's tutorial (SimpiciTI Tutorial for CC2500) as well?


These are the code alterations in mrfi_board_defs.h:

//#define __mrfi_GDO2_BIT__                     7
//#define MRFI_CONFIG_GDO2_PIN_AS_INPUT()       st( P2SEL &= ~BV(__mrfi_GDO2_BIT__); ) /* clear pin special function default */
//#define MRFI_GDO2_PIN_IS_HIGH()               (P2IN & BV(__mrfi_GDO2_BIT__))
//
//#define MRFI_GDO2_INT_VECTOR                  PORT2_VECTOR
//#define MRFI_ENABLE_GDO2_INT()                st( P2IE  |=  BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
//#define MRFI_DISABLE_GDO2_INT()               st( P2IE  &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
//#define MRFI_GDO2_INT_IS_ENABLED()             (  P2IE  &   BV(__mrfi_GDO2_BIT__) )
//#define MRFI_CLEAR_GDO2_INT_FLAG()            st( P2IFG &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
//#define MRFI_GDO2_INT_FLAG_IS_SET()            (  P2IFG &   BV(__mrfi_GDO2_BIT__) )
//#define MRFI_CONFIG_GDO2_RISING_EDGE_INT()    st( P2IES &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
//#define MRFI_CONFIG_GDO2_FALLING_EDGE_INT()   st( P2IES |=  BV(__mrfi_GDO2_BIT__); ) /* atomic operation */

#define __mrfi_GDO2_BIT__                     0
#define MRFI_CONFIG_GDO2_PIN_AS_INPUT()       st( P1SEL &= ~BV(__mrfi_GDO2_BIT__); ) /* clear pin special function default */
#define MRFI_GDO2_PIN_IS_HIGH()               (P1IN & BV(__mrfi_GDO2_BIT__))

#define MRFI_GDO2_INT_VECTOR                  PORT1_VECTOR
#define MRFI_ENABLE_GDO2_INT()                st( P1IE  |=  BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
#define MRFI_DISABLE_GDO2_INT()               st( P1IE  &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
#define MRFI_GDO2_INT_IS_ENABLED()             (  P1IE  &   BV(__mrfi_GDO2_BIT__) )
#define MRFI_CLEAR_GDO2_INT_FLAG()            st( P1IFG &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
#define MRFI_GDO2_INT_FLAG_IS_SET()            (  P1IFG &   BV(__mrfi_GDO2_BIT__) )
#define MRFI_CONFIG_GDO2_RISING_EDGE_INT()    st( P1IES &= ~BV(__mrfi_GDO2_BIT__); ) /* atomic operation */
#define MRFI_CONFIG_GDO2_FALLING_EDGE_INT()   st( P1IES |=  BV(__mrfi_GDO2_BIT__); ) /* atomic operation */

 

 

//#define __mrfi_SPI_CSN_GPIO_BIT__             4
//#define MRFI_SPI_CONFIG_CSN_PIN_AS_OUTPUT()   st( P1DIR |=  BV(__mrfi_SPI_CSN_GPIO_BIT__); )
//#define MRFI_SPI_DRIVE_CSN_HIGH()             st( P1OUT |=  BV(__mrfi_SPI_CSN_GPIO_BIT__); ) /* atomic operation */
//#define MRFI_SPI_DRIVE_CSN_LOW()              st( P1OUT &= ~BV(__mrfi_SPI_CSN_GPIO_BIT__); ) /* atomic operation */
//#define MRFI_SPI_CSN_IS_HIGH()                 (  P1OUT &   BV(__mrfi_SPI_CSN_GPIO_BIT__) )

#define __mrfi_SPI_CSN_GPIO_BIT__             7
#define MRFI_SPI_CONFIG_CSN_PIN_AS_OUTPUT()   st( P2DIR |=  BV(__mrfi_SPI_CSN_GPIO_BIT__); )
#define MRFI_SPI_DRIVE_CSN_HIGH()             st( P2OUT |=  BV(__mrfi_SPI_CSN_GPIO_BIT__); ) /* atomic operation */
#define MRFI_SPI_DRIVE_CSN_LOW()              st( P2OUT &= ~BV(__mrfi_SPI_CSN_GPIO_BIT__); ) /* atomic operation */
#define MRFI_SPI_CSN_IS_HIGH()                 (  P2OUT &   BV(__mrfi_SPI_CSN_GPIO_BIT__) )

Share this post


Link to post
Share on other sites

Its a bit unclear why you want to move to the SimpliciTI code when you got the LarsRF code running as planned ... THe LarsRF code is compact and allows easy use, at least for my purposes.

 

cheers

CorB

Share this post


Link to post
Share on other sites

CorB,

I'm interested in establishing a wireless sensor network (wsn), and the code from LarsRF is great for lower-level wireless interactions, but it doesn't include much of the higher-level protocols.  (I could always build my own protocol on top of LarsRF's code in order to implement a wsn, but I didn't want to reinvent the wheel.)  SimpliciTI is already supported on the Chronos watch, and I wanted to interface the Chronos as an access point on the wsn as well.  Good question - thanks for asking.

Share this post


Link to post
Share on other sites

I use the chronos and several sensornodes together using the basic larsRF code. The only thing I have programmed is a setup for a package structure that is used by all the transceivers as a base. With that package I can send messages around etc. I even have one of the nodes listening in at 433Mhz for OOK messages coming from several LaCrosse temp/humidity sensors and relay them onto my sensornetwork. The simplicity  :) of doing it with the simple code is really easy. It indeed means you need to think about your network but also allows great flexibility. 

 

Hope you find a good solution, the Anaren nodes are easy to use.

 

 

cheers

Cor

Share this post


Link to post
Share on other sites

Hope you find a good solution, the Anaren nodes are easy to use.

 

I was wishing all kinds of hell on you after reading that , but having given LarsRF a go, you're right!  It's the only code example I've found that compiles and runs straight out of the box.  I can't get back the wasted hours with anaren's firmware, but LarsRF certainly seems to be the way to go, and I believe you contributed to the build and test of it, so thank you Cor and Larsie :)

 

Bluehash/Admin - If I have questions regarding LarsRF, should I put them in this thread or create a separate LarsRF thread (I've got a feeling I'll have a question or two over the next few days)?

Share this post


Link to post
Share on other sites

Hi.

 

Not so nice to wish me all kinds of hell ;-) ... luckily I am safe.

The original code from Anaren is probably strong but most of us using this have found out that it was so difficult to understand due to the layering of code that we jumped over to the very basic code. The advantage of that is also larger than just having simple code, you have more space to let your launchpad do some real work with the bytes that you dont need for the communications.

 

have fun,

 

Cor

Share this post


Link to post
Share on other sites

I'm sure you know the rage directed at you was misplaced rage :smile: (rage which should have been directed at myself for not being capable).  As you almost certainly know, working with the Anaren code can get you like that   :oops: .

 

I completely agree with you regarding using LarsRF - I can see it's going to offer the flexibility I need for what I eventually aim to do.  I need a simple but specific RF protocol, its going to be easier manipulating LarsRF as opposed to SimpliciTi (or *cough* AIR).

 

Tomorrow the project starts in anger, I'm sure I'll have plenty of fun :grin:  Thanks again!

Share this post


Link to post
Share on other sites

This link shows how I uses packages to send information around:

http://forum.43oh.com/topic/1433-anaren-ti-cc110l-rf-air-booster-pack/?p=17770

 

Below a bit more on the secrets ;) You can define the payload any way you wish with any data you want to transfer. As you can see my setup uses ACKs and also nodeIDs but you could do that completely different. The only mandatory thing (at least its wise) is to start with an addr part in your payloadframe since the receivers can check automatically for this. I am using 2 payload variables In_Payload and Out_Payload to do all the exchanges, next to that there are 2 buffers declared for receiving/sending payloads. Makes sure they are large enough.

 

After receiving a package I use the following code to decipher the package into to In_Payload variable

LoadRxBuffer((char *)&In_Payload,len); // translate rxBuffferdata into In_Payload

 

Sending a package is simple, you first set your packagedata in the Out_Payload structure and then call

send_Msg(xxxx)  where xxxx is a command you want to send around. 

 

Have fun !

 

CorB

 

 

 

 

 

//PAYLOADS

typedef volatile struct StatusStruct
{
  enum TxACKMessageType {                                                       //!< Flags to ACK transfer
    REQUEST_NO_ACK                       = 0,
    REQUEST_ACK                          = 1
  } TxACKMessageType;

   enum RxACKMessageType {                                                       //!< Flags to ACK transfer
    RECEIVED_NO_ACK                   = 0,
    RECEIVED_ACK                      = 1
  } RxACKMessageType;

  char channel;
  char power;
  char RSSI;
  unsigned int msgNodeId;
} StatusStruct;

typedef struct PayloadFrame 
{    
  char addr; // payloads need to start with char addr as the receiver can check this !
  char msg; // messagetype 0x00 - 0xFF options
  char msgdata0; // var1 that belongs to the message
  char msgdata1; // var2 that belongs to the message
  StatusStruct Status;
  // USER DESIGNED PAYLOAD SECTION
  unsigned int data1;
  //unsigned int data2;
  char DataUnit;
        
} PayloadFrame;

PayloadFrame In_Payload;  // receiving payload
PayloadFrame Out_Payload; // sending payload

#define maxPayload 40 // reserve space for the payloadsize in the buffers

char txBuffer[maxPayload]; // sizeof(PayloadFrame) !!
char rxBuffer[maxPayload];

// this routine sets default settings for payloads that will be send
PayloadFrame * DefaultPayload () 
{  Out_Payload.addr=0x01; // force adress
   Out_Payload.msg=DATA_PAYLOAD;
   Out_Payload.msgdata0=0;
   Out_Payload.msgdata1=0;
   Out_Payload.DataUnit='_';
   Out_Payload.Status.RxACKMessageType=RECEIVED_NO_ACK  ;
   Out_Payload.Status.TxACKMessageType=  REQUEST_ACK;
   Out_Payload.Status.msgNodeId=NodeId;
   return &Out_Payload;
}

// transfer of a payload
PayloadFrame * MakeTxPayload () 
{	Out_Payload.Status.msgNodeId=NodeId; // always enforce !
	return &Out_Payload;
}

// load a payload into the RxBuffer
char LoadRxBuffer (char *buffer, char len)
{
int i = 0;
  for (i = len; i >= 0; i--)
         {   buffer[i] = rxBuffer[i];                  // Recreate Payload from received data
         }
  return 0;	
}

// load a payload into the TxBuffer
char PreparetxBuffer (char *payload, char len)
{
int i = 0;  
   for (i = len; i >= 0; i--)
         {   txBuffer[i+1] = payload[i];                  // Create DataPacket from Payload
         }
   txBuffer[0]=len; 	// byte 0 in the pack should be the package length
  return 0;	
}

// Send a payload
void send_Msg(char message)
{
  Out_Payload.addr=0x01;//force address
  Out_Payload.msg=message;
  PreparetxBuffer( (char *)(MakeTxPayload()), sizeof(PayloadFrame));
  RFSendPacket(txBuffer, txBuffer[0]+1); // 1 byte larger than payloadframe due to the packagesize byte
  __delay_cycles(5000); //5ms waiting
}  



Share this post


Link to post
Share on other sites

Larsie and CorB,

Thank you again for the code and recommendations.

 

By the way, larsie, in reference to the LarsRF code example - the uart code not working.  If you call uartInit() before RF_init() (in main_acktest.c), then the uart code works.  I'm wondering if it may have to do with changing PxSEL after the interrupt lines for the switch (P1.3) have been set.  In the MSP430x2xx Family datasheet under the PxSEL and PxSEL2 info (p337), there's a note stating that when PxSEL=1, P1 or P2 interrupts are disabled - regardless of the corresponding P1IE or P2IE state.  I'm just glad that P1IE seems to still work after P1SEL is already used to make use of the USCI_A0 functionality (for uart).

Share this post


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.

Guest
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...