Can't compile samples from BitCloud (ZigBee) with WinAVR

Go To Last Post
986 posts / 0 new

Pages

Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi! I have meshnetics MeshBean ZigBit dev.kit with samples on CD. This samples compiling fine (use new version of AVR studio & WinAVR). I download latest Atmel BitCloud SDK (Atmel buy meshnetics some time ago), but this new samples don't compile (its identical to those of meshnetics, but with some modifications of source code, makefiles and configuration files). I have problem when try to build new samples. What coud be wrong? Thank you for help!

Log of the error:

Build started 15.5.2009 at 12:36:41
make all -C
make: option requires an argument -- C
Usage: make [options] [target] ...
...
This program built for i386-pc-mingw32
Report bugs to
make: *** [cs] Error 2
Build failed with 1 errors and 0 warnings...

Last Edited: Fri. Oct 16, 2015 - 01:46 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Seems like SDK path contains spaces. Try installing it into different location without spaces in path.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Spasibo, alexru. Tolyko pochemu primery meshnetics compilirovalisy normalyno dazhe s probelami v puti :j

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeshcho po angliskii pozhalsta!
Hotyel bi znaty esli problyema rezolyuzhonirovanna.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did it worked with short paths?

There were some changes to build procedure.

PS: may be we will use english? :)

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ok.
1. some one have correspondence between Atmega 1281 and meshbean ZDM-A1281 pinout?
2. I look for sources to program ZDM-A1281 without using ZigBee Net stack.
3. also I need source for ZigBeeNet for read ADC channels.
Thank a lot :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

code-by wrote:
ok.
1. some one have correspondence between Atmega 1281 and meshbean ZDM-A1281 pinout?

You may ask tech support. But since HAL is open source now You can just look for it by yourself.

code-by wrote:

2. I look for sources to program ZDM-A1281 without using ZigBee Net stack.

Start with "main" function :) It is just regular micro + rf.

code-by wrote:

3. also I need source for ZigBeeNet for read ADC channels.
Thank a lot :)

ZigBeeNet is not supported anymore. Currently supported stack called BitCloud.

There should be example for this.

BSP\MESHBEAN\src\battery.c from SDK is a good example of using ADC.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I need to develop ZigBee network with one Coordinator and 20 End-devices without routers.

So if I will don't use BitCloud stack, I need to programin myself link with RF using SPI, organize network between nodes, (remember their addresses, ...), ..., something else?

Maybe some one have regular C-program for using ZigBee with mega 1281?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You should look at the Lowpower sample code. Its set up to use Coordinator and multiple end devices. You just need to make a few adjustments to get it to 20 end devices. If you want to use the bitcloud stack. Or you can use Star_Nobeacon example in the MAC code atmel also provides.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I try to add ADC from "battery.c" to "lowpower" sample, but compiler show error "D:\ZigBit\Sample Applications 2\Lowpower/src/coordinator.c:286: undefined reference to `bspPostTask0'".
I can post here source code if needed :)

I don't realy understand how this BitCloud stack works with these postTask functions... :(

How much maximum end-devices could host one coordinator?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

code-by wrote:
I try to add ADC from "battery.c" to "lowpower" sample, but compiler show error "D:\ZigBit\Sample Applications 2\Lowpower/src/coordinator.c:286: undefined reference to `bspPostTask0'".
I can post here source code if needed :)

Just copy-pasting will not work.

This code might help. I did not tried it actually, but it should work.

  adcParam.bufferPointer = &bufferForData;
    adcParam.callback = batteryCalback;
    adcParam.resolution = RESOLUTION_8_BIT;
    adcParam.sampleRate = ADC_4800SPS;
    adcParam.selectionsAmount = 1;
    adcParam.voltageReference = AREF;
    batteryState = BUSY;
    HAL_OpenAdc(&adcParam);

    // This function will start conversion and exit. After conversion completed adcParam.callback will be called.
    HAL_ReadAdc(HAL_ADC_CHANNEL0);

So you haver to wait for callback. After it is called data is available at bufferForData.

code-by wrote:

I don't realy understand how this BitCloud stack works with these postTask functions... :(

Just another one (and not so bad) multitasking approach.

code-by wrote:

How much maximum end-devices could host one coordinator?

It depends on other stack parameters (buffer sizes) and limited by memory available. See documentation on atmel's site for actual numbers.

20 EDs should be easy.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

PS: Low power reads temperature by default. WsnDemo reads light, temperature and battery. Combine them :)

Or you can start with WsnDemo. Just remove reading of anything except battery.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

code-by wrote:

Maybe some one have regular C-program for using ZigBee with mega 1281?

BitCloud is a regular C-program. ZigBee Pro standard is 600+ pages document. So it is not that easy to implement.

But if you do not need mesh networking, routing, network management and some other feautures, you can just use 802.15.4 frames. But it is not that easy anyway (BitCloud is much easier).

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I need call readBatteryData to read data from ADC.
Please help what parameter I should use to call function:

readBatteryData(void (*callback)(uint8_t data))

----

I call readBatteryData from this:

if (openBattery() == SUCCESS)
{
 length = sprintf((char *) str, "ADC init ok\n\r");
 sendDataToUsart(str, length);

 if (readBatteryData( ??? ) == SUCCESS)
  length = sprintf((char *) str, "ADC read ok\n\r");
 else
  length = sprintf((char *) str, "ADC read err\n\r");

 sendDataToUsart(str, length);
}
Last Edited: Wed. May 20, 2009 - 02:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Try something like this (this code reads ADC dedicated to battery only)

In APL_TaskHandler():

BSP_OpenBatterySensor();
BSP_ReadBatteryData(batteryDataReady);

And batteryDataReady() should be defined like this:

static void batteryDataReady(uint8_t battery)
{
  // battery contains battery voltage
}

The point is that function not just reads value and returns it, but it returns right away and calls callback function as data is ready.

The reason for this is that HAL ADC functions can read a set of values. This can take awhile and waiting will be just wasting of CPU time.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If I compile usual program for standalone mega1281 with main() function w/o initializing ports, usart, timers, etc., could it damage meshbean board? Coud it be damaged if I initialize ports,...,etc. erroneously?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I hardly doubt you can damage anything. Just remember common AVR advices. Like do not disable JTAG in fuses, etc.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I try to create program and burn it ZigBit module like making program for standalone Mega1281. I have hex file and don't understand how create SREC file.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What USART (0 or 1) I need to use in ZigBit board to send data to PC for dislay in HyperTerminal?
thank

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On MeshBean boards USART_CHANNEL_1 is connected to UART-to-USB converter and USART_CHANNEL_0 is on the P2 connector. Use any you like.

PS: srec from hex can be obtained by avr-objcopy programm.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank. I make SREC from HEX using avr-objcopy, it work fine, but SREC from compiling in AVRStudio is large, that created by avr-objcopy :)

It is possible to find some examples for ZigBit to create simple data transmission without using ZigBit/BitCloud stack?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Thank. I make SREC from HEX using avr-objcopy, it work fine, but SREC from compiling in AVRStudio is large, that created by avr-objcopy

You probably didn't -R the sections that need to be discarded (.fuse, .eeprom etc)

(why do you need Srec anyway? Don't all AVR tools use Intel Hex ?)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I need SREC because I program my board via USB, I haven't JTAG :)

When I use WSN Monitor, boards powered by battery shows values about 200 units, but when I insert battery function into lowpower sample, it shows -45, -50, -55, -60? It's right?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So what is the USB software you use that prefers SRec in favour of Intel Hex when programming AVR? It just seems an odd choice when everything else associated with AVR works using Intel

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use SiliconLabs USB-COM driver and Atmel (ex. meshnetics) bootloader that works only with SREC-files :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah there's nothing like consistency! So even though everything else Atmel is Intel Hex they issue a bootloader (even if it originally came from somewhere else) that uses a "non (their) standard" file format.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
It is possible to find some examples for ZigBit to create simple data transmission without using ZigBit/BitCloud stack?

I do not think so. This way of using it is not officially supported.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Ah there's nothing like consistency! So even though everything else Atmel is Intel Hex they issue a bootloader (even if it originally came from somewhere else) that uses a "non (their) standard" file format.

SAM-BA for example uses .bin files.

Changing bootloader is not that easy since there are a lot of units already deployed.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

code-by wrote:

When I use WSN Monitor, boards powered by battery shows values about 200 units, but when I insert battery function into lowpower sample, it shows -45, -50, -55, -60? It's right?

Treat this numbers as unsigned values. So they will be about 200.

PS: Good progress :)

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank, with uint allright :)

Now I search examples for zigbit to work w/o zigbit/bitcloud stack, because it consume much memory and it's difficult to make more flexible programs :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

code-by wrote:

Now I search examples for zigbit to work w/o zigbit/bitcloud stack, because it consume much memory and it's difficult to make more flexible programs :)

Have a look at Contiki. I have not seen by myself, but i heard that they ported their stack to MeshBean board.

Working with radio directly is relatively easy. But even implementing MAC layer is not that simple at all. BitCloud consumes all this memory for a reason. We doing our best to lower memory consuption though.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Coud somebody explain why coordinator immediately found network after pressing SW1 button in Lowpower sample of Bitcloud SDK 1.5 even there no any powered meshbean boards?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

code-by wrote:
Coud somebody explain why coordinator immediately found network after pressing SW1 button in Lowpower sample of Bitcloud SDK 1.5 even there no any powered meshbean boards?

I don't quite understand what do mean. Blinking led in all applications means that device is searching for the network to join. Coordinator is not joining to any existing network, it setts up its own one. So coordinator will start network any way (assuming channel is clear enough).

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

alexru wrote:
coordinator will start network any way (assuming channel is clear enough).

I didn't know that :) Now I understand

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi!

I need to add processing of two ADC channel with my algorithm of acquisition data (how much samples, etc) to my program based on Bitcloud stack.

How much samples doing Bitcloud stack when reading battery level?

Coud somebody help?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BitCloud by itself does nothing with ADC. Battery level is read by BSP. Only one sample is used to read battery level. But ADC API is very reach. Just read documentation :)

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm found project for mega644 and at86rf230 containing following:

//SPI data direction register (DDR)
#define DDR_SS   DDRB.4  //Slave Select
#define DDR_MOSI DDRB.5  //Master Out - Slave In
#define DDR_MISO DDRB.6  //Master In - Slave Out
#define DDR_SCLK DDRB.7  //SPI Clock
//SPI chip select (CS)
#define RF230_SEL        PORTC.3
#define DDR_RF230_SEL    DDRC.3
//GPIO (General purpose input output) interface
#define RF230_IRQ        PINC.0
#define DDR_RF230_IRQ    DDRC.0
#define RF230_SLP_TR     PORTC.1
#define DDR_RF230_SLP_TR DDRC.1
#define RF230_RESET      PORTC.2
#define DDR_RF230_RESET  DDRC.2

How to change ports defenitions for use with ZigBit modules?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
//SPI data direction register (DDR)
#define DDR_SS   DDRB.0  //Slave Select
#define DDR_MOSI DDRB.2  //Master Out - Slave In
#define DDR_MISO DDRB.3  //Master In - Slave Out
#define DDR_SCLK DDRB.1  //SPI Clock

//SPI chip select (CS)
#define RF230_SEL        ???
#define DDR_RF230_SEL    ???

//GPIO (General purpose input output) interface
#define RF230_IRQ        PINE.5
#define DDR_RF230_IRQ    DDRE.5

#define RF230_SLP_TR     PORTB.4
#define DDR_RF230_SLP_TR DDRB.4

#define RF230_RESET      PORTA.7
#define DDR_RF230_RESET  DDRA.7

Something like this. Not sure about SPI chip select.

BTW all this from file HAL\avr\atmega1281\zigBit\include\halRfPio.h.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The full code of founded project is following:

/****************************************************************************/
//List of Transceiver Registers
#define TRX_STATUS       0x01
#define TRX_STATE        0x02
#define TRX_CTRL_0       0x03
#define PHY_TX_PWR       0x05
#define PHY_RSSI         0x06
#define PHY_ED_LEVEL     0x07
#define PHY_CC_CCA       0x08
#define CCA_THRES        0x09
#define IRQ_MASK         0x0E
#define IRQ_STATUS       0x0F
#define VREG_CTRL        0x10
#define BATMON           0x11
#define XOSC_CTRL        0x12
#define FTN_CTRL         0x18
#define PLL_CF           0x1A
#define PLL_DCU          0x1B
#define PART_NUM         0x1C
#define VERSION_NUM      0x1D
#define MAN_ID_0         0x1E
#define MAN_ID_1         0x1F
#define SHORT_ADDR_0     0x20
#define SHORT_ADDR_1     0x21
#define PAN_ID_0         0x22
#define PAN_ID_1         0x23
#define IEEE_ADDR_0      0x24
#define IEEE_ADDR_1      0x25
#define IEEE_ADDR_2      0x26
#define IEEE_ADDR_3      0x27
#define IEEE_ADDR_4      0x28
#define IEEE_ADDR_5      0x29
#define IEEE_ADDR_6      0x2A
#define IEEE_ADDR_7      0x2B
#define XAH_CTRL         0x2C
#define CSMA_SEED_0      0x2D
#define CSMA_SEED_1      0x2E

//List of Transceiver States
#define NOP              0x00
#define TX_START         0x02
#define FORCE_TRX_OFF    0x03
#define RX_ON            0x06
#define TRX_OFF          0x08
#define PLL_ON           0x09
#define RX_AACK_ON       0x22
#define TX_ARET_ON       0x25

//SPI data direction register (DDR)
#define DDR_SS   DDRB.4  //Slave Select
#define DDR_MOSI DDRB.5  //Master Out - Slave In
#define DDR_MISO DDRB.6  //Master In - Slave Out
#define DDR_SCLK DDRB.7  //SPI Clock
//SPI chip select (CS)
#define RF230_SEL        PORTC.3
#define DDR_RF230_SEL    DDRC.3
//GPIO (General purpose input output) interface
#define RF230_IRQ        PINC.0
#define DDR_RF230_IRQ    DDRC.0
#define RF230_SLP_TR     PORTC.1
#define DDR_RF230_SLP_TR DDRC.1
#define RF230_RESET      PORTC.2
#define DDR_RF230_RESET  DDRC.2

//IRQ status masks
#define IRQ_BAT_LOW      0x80  //Battery low signal
#define IRQ_TRX_UR       0x40  //FIFO underrun signal
#define IRQ_TRX_END      0x08  //End of frame (transmit and receive)
#define IRQ_RX_START     0x04  //Beginning of receive frame
#define IRQ_PLL_UNLOCK   0x02  //PLL goes from lock to unlock state
#define IRQ_PLL_LOCK     0x01  //PLL goes from unlock to lock state

//Protocol Commands
#define PING             0xA1  //See if there is a transmitter in range
#define DATA_REQ         0xA5  //Request data from transmitter

//energy detection threshold
#define ED_THRESH        0x10

/****************************************************************************/
//Function Prototypes
unsigned char RF_RX_channel_scan(void);
unsigned char RF_TX_channel_scan(void);
void init_spi(void);
void set_transceiver_clock(void);
void RF_init_spi(void);
unsigned char RF_read_register(unsigned char address);
void RF_write_register(unsigned char address, unsigned char data);
void RF_init_transmitter(void);
void RF_transmit_test(void);
void RF_init_receiver(void);
void RF_receive_test(void);
void RF_download_frame(void);
void RF_transmit_frame(void);
void RF_receiver_listen(void);
void RF_upload_frame(void);
unsigned char RF_update_IRQ_status(void);
unsigned char RF_transmit_done(void);
unsigned char RF_receiver_listen_timeout(unsigned char loop_count);
unsigned char RF_TX_channel_scan(void);
void RF_TX_sync(void);
void RF_tx_to_rx(void);
void RF_rx_to_tx(void);
void RF_RX_sync(void);

/****************************************************************************/
//Global Variables to use for interfacing
unsigned char transmit_frame[20];  //User code fills transmit_frame
unsigned char receive_frame[20];   //User code reads receive_frame
unsigned char LQI;                 //User may use LQI after receiving frame
unsigned char tx_frame_length;     //User can set frame length before transmit
unsigned char rx_frame_length;     //Read frame length while receiving
unsigned char curr_IRQ_status;

/****************************************************************************/
void RF_clear_IRQ(void)  {
  curr_IRQ_status = RF_read_register(IRQ_STATUS);
  curr_IRQ_status = 0;
}

/****************************************************************************/
//Function determines if channel is clear or not using CCA
//CCA = clear channel assessment
//channel parameter must be between 11 and 26
//Returns 0 if channel is busy and 1 if channel is clear
unsigned char RF_CCA(unsigned char channel)  {
  unsigned char status = 0;
  if ((channel < 11) || (channel > 26)) return 0;  //invalid input
  channel = (channel | 0b10000000); //Set bit 7 to 1 to start CCA check
  RF_write_register(PHY_CC_CCA,channel);
  delay_us(140);
  status = RF_read_register(TRX_STATUS);
  if ((status&0b01000000) != 0) return 1;  //channel is available
  else return 0;
}

/****************************************************************************/
//Function scans for clear channel using CCA. Sets channel to best option
//for reception. Need another function to transmit beacon frame over that 
//channel, listen for a response. This function returns 0 if there is no good 
//channel, or it returns the value of the channel with the strongest signal.
unsigned char RF_RX_channel_scan(void)  {
  unsigned char i = 0;
  unsigned char status;
  for (i=16;i<=26;i++)  {
    RF_write_register(PHY_CC_CCA,(0b10000000 | i));  
    //see if channel i is available
    do {
      status = RF_read_register(TRX_STATUS);
    } while((status&0b10000000) == 0);
    if ((status&0b01000000) == 0)  return i;  //return clear channel
  }
  for (i = 11; i<16; i++)  {
    RF_write_register(PHY_CC_CCA,(0b10000000 | i));  
    //see if channel i is available
    do {
      status = RF_read_register(TRX_STATUS);
    } while((status&0b10000000) == 0);
    if ((status&0b01000000) != 0)  return i;  //return clear channel
  }
  return 0;
}

/****************************************************************************/
//Function scans for channel with highest signal quality above a certain
//threshold, returns best channel. Need another function to listen for beacon 
//frame, respond with acknowledgement frame.
unsigned char RF_TX_channel_scan(void)  {
  unsigned char max_channel_strength = 0;
  unsigned char max_channel = 0;
  unsigned char curr_channel_strength;
  unsigned char i;

  for (i=11;i<=26;i++)  {
    RF_write_register(PHY_CC_CCA,i);  //change to specific channel
    delay_us(400);  //wait for channel change to complete
    RF_write_register(PHY_ED_LEVEL,0x00);  //start ED calculation
    delay_us(130);  //wait for conversion to complete
    curr_channel_strength = RF_read_register(PHY_ED_LEVEL);
    if ((curr_channel_strength > ED_THRESH) && 
        (curr_channel_strength > max_channel_strength))  {
      max_channel_strength = curr_channel_strength;
      max_channel = i;
    }
  }
  return max_channel;
}

/****************************************************************************/
void RF_TX_sync(void)  {
  unsigned char channel;
  while (1)  {   //keep searching until a receiver is found
    do  {
      //find best channel, if any available
      channel = RF_TX_channel_scan();
    } while(channel == 0);
    RF_write_register(PHY_CC_CCA,channel);  //switch to channel
    delay_us(200);
    RF_tx_to_rx();  //switch to reception mode
    delay_us(200);
    if (RF_receiver_listen_timeout(50) == 1)  break;  
    //wait for a short time for a frame to be received
  }
  RF_rx_to_tx();
  delay_us(200);
  tx_frame_length = 1;
  transmit_frame[0] = 0xAA;
  RF_download_frame();
  RF_transmit_frame();
}

/****************************************************************************/
void RF_RX_sync(void)  {
  unsigned char channel,i;
  do  {
    channel = RF_RX_channel_scan();
  } while(channel==0);
  RF_write_register(PHY_CC_CCA,channel);  //switch to channel
  delay_us(200);
  while (1)  {
    RF_rx_to_tx();  //switch to transmission mode
    delay_us(200);
    tx_frame_length = 10;
    for (i=0;i<10;i++)  {
      transmit_frame[i] = 0xAA;
    }
    RF_download_frame();
    RF_transmit_frame();
    RF_tx_to_rx();  //switch to reception mode
    delay_us(200);
    if (RF_receiver_listen_timeout(50) == 1) break;
  }
}

/****************************************************************************/
unsigned char RF_receiver_listen_timeout(unsigned char loop_count)  {
  do {
    if (RF230_IRQ != 0)  {
      curr_IRQ_status = RF_read_register(IRQ_STATUS);
    }
    delay_us(250);
    loop_count--;
  } while (((curr_IRQ_status & IRQ_TRX_END) == 0 )&&((loop_count) > 0));
  if ((curr_IRQ_status&IRQ_TRX_END) != 0) {
    curr_IRQ_status = 0;
    return (loop_count+1);
  }
  curr_IRQ_status = 0;
  return loop_count;
}

/****************************************************************************/
void init_spi(void) {
  //Set up SPI I/O data direction
  DDR_MOSI = 1;
  DDR_MISO = 0;
  DDR_SCLK = 1;
  DDR_SS = 1;  //SS must be configured as output to set MCU as SPI master
  PORTB.4 = 0;

  //Set up SPI Control Registers
  //Bit 7 - Interrupt Enable SPIE=0 -> no ISR
  //Bit 6 - SPI Enable SPE=1 -> enable spi
  //Bit 5 - Data Order DORD=0 -> msb first
  //Bit 4 - Master/Slave Select MSTR=1 ->MCU is SPI master
  //Bit 3 - Clock Polarity CPLO=0 (for the transceiver initially)
  //Bit 2 - Clock Phase CPHA=0 (for the transceiver initially)
  //Bits 1:0 - SPR1, SPR0: SPI Clock Rate Select 1 and 0
  //SPR1:SPR0=00 along with SPI2X=1 sets SCK to f_osc/2 = 8MHz/2 = 4MHz
  SPCR0 = 0b01010000;  //SPI Control Register
  SPSR0 = 1;           //SPI Status Register (SPI2X)

}

/****************************************************************************/
void set_transceiver_clock(void) {
  //Set the clock polarity and phase for the transceiver if other slaves
  //(with different clock settings) are also being used by the MCU
  SPCR0 = 0b01010000;
  SPSR0 = 1;
  //SPCR0 &= 0b11110111;  //Bit 3 – Clock Polarity CPLO=0
  //SPCR0 &= 0b11111011;  //Bit 2 – Clock Phase CPHA=0
}

/****************************************************************************/
void RF_init_spi(void) {
  //Set up GPIO data directions
  DDR_RF230_IRQ = 0;
  DDR_RF230_SLP_TR = 1;
  DDR_RF230_RESET = 1;
  DDR_RF230_SEL = 1;

  RF230_SEL = 1;  //Initialize chip select signal high
  RF230_RESET = 1;
  RF230_SLP_TR = 0;

}

/****************************************************************************/
//2 byte SPI transmit. Information in second byte is thrown away, just
//transmit junk data to receive byte.
unsigned char RF_read_register(unsigned char address) {
  unsigned char junk;
  RF230_SEL = 0;
  //Address should only be 6 bits. MSB should be 1, bit 6 should be 0.
  //Writing to SPDR0 starts transmission
  SPDR0 = 128 + (address & 0b00111111);
  while((SPSR0&0x80) == 0); //Wait for transfer to complete
  junk = SPDR0;
  //Start next transmission, transmit junk, get back data from register
  SPDR0 = 0x00;
  while((SPSR0&0x80) == 0); //Wait for transfer to complete
  RF230_SEL = 1;
  return SPDR0; //Return contents of register in transceiver
}

/****************************************************************************/
//2 byte SPI transmit. Information in second byte is data to write to register
void RF_write_register(unsigned char address, unsigned char data) {
  unsigned char junk;
  RF230_SEL = 0;
  //First 2 bits are 11, rest is address. Start transmitting command
  SPDR0 = 192 + (address & 0b00111111);
  while((SPSR0&0x80) == 0);  //Wait for transfer to complete
  junk = SPDR0;
  SPDR0 = data;
  while ((SPSR0&0x80) == 0);  //Wait for transfer to complete
  RF230_SEL = 1;
}

/****************************************************************************/
//Initialize basic one-way transmitter
void RF_init_transmitter(void) {
  //RF_write_register(TRX_CTRL_0,
  //Should write to TRX_CTRL_0 register to set output current and
  //clockspeed settings.
  RF230_RESET = 0;
  #asm
    nop
    nop
    nop
    nop
    nop
  #endasm
  RF230_RESET = 1;
  RF_write_register(TRX_CTRL_0,0b01001000);
  delay_us(800);
  //enable ONLY the TRX_done interrupt
  RF_write_register(IRQ_MASK,0b00001000);
  delay_us(200);
  RF_write_register(PHY_TX_PWR,0);  //reduced power on transmit
  delay_us(200);
  RF_write_register(PHY_CC_CCA,11);  //channel 11
  delay_us(200);
  RF_write_register(TRX_STATE,FORCE_TRX_OFF);
  delay_us(1880);
  RF_write_register(TRX_STATE,PLL_ON);
  delay_us(200);
  RF_write_register(TRX_CTRL_0,0b01001000);
  delay_us(800);
  RF_write_register(TRX_STATE,FORCE_TRX_OFF);
  delay_us(1880);
  RF_write_register(TRX_STATE,PLL_ON);
  delay_us(200);
}

/****************************************************************************/
void RF_tx_to_rx(void)  {
  RF_write_register(TRX_STATE,FORCE_TRX_OFF);
  delay_us(1880);
  RF_write_register(TRX_STATE,RX_ON);
  delay_us(200);
}

/****************************************************************************/
void RF_rx_to_tx(void)  {
  RF_write_register(TRX_STATE,FORCE_TRX_OFF);
  delay_us(1880);
  RF_write_register(TRX_STATE,PLL_ON);
  delay_us(200);
}

/****************************************************************************/
//Transmit once per second... call this once every second
void RF_transmit_test(void) {
  unsigned char i;
  RF_write_register(TRX_STATE,PLL_ON);
  RF230_SEL = 0;
  SPDR0 = 0b01100000;  //Frame transmit mode
  while((SPSR0&0x80) == 0);  //Wait for transfer to complete
  SPDR0 = 100;  //Frame length
  while((SPSR0&0x80) == 0);  //Wait for transfer to complete
  for (i=0;i<100;i++) {
    SPDR0 = i;
    while((SPSR0&0x80) == 0);  //Wait for transfer to complete
  }
  RF230_SEL = 1;

  RF230_SLP_TR = 1;  //Signal to transmit frame
  #asm
    nop
    nop
    nop
    nop
    nop
  #endasm
  RF230_SLP_TR = 0;
  do {  //Loop until end of transmit frame, when we break out of loop
    if (RF230_IRQ != 0) {
      //Get the status of the IRQ
      curr_IRQ_status = RF_read_register(IRQ_STATUS);
      PORTA = curr_IRQ_status;
    }
    //Loop until done done transmitting frame
  } while ((curr_IRQ_status & IRQ_TRX_END) == 0);

}

/****************************************************************************/
void RF_init_receiver(void) {
  RF230_RESET = 0;
  #asm
    nop
    nop
    nop
    nop
    nop
  #endasm
  RF230_RESET = 1;
  RF_write_register(TRX_CTRL_0,0b01001000);
  delay_us(800);
  //enable ONLY the TRX_done interrupt
  RF_write_register(IRQ_MASK,0b00001000);
  delay_us(200);
  RF_write_register(TRX_STATE,FORCE_TRX_OFF);
  delay_us(1880);
  RF_write_register(TRX_STATE,RX_ON);
  delay_us(200);
}

/****************************************************************************/
void RF_receive_test(void) {
  //Put transceiver in listen mode
  //Wait for IRQ indicating end of frame
  //Upload frame, digest
  //Done, start again immediately
  unsigned char length,LQI;
  unsigned char junk = 0;
  unsigned char frame[128];
  unsigned char index = 0;

  do {
    if (RF230_IRQ != 0)  {
      curr_IRQ_status = RF_read_register(IRQ_STATUS);
    }
    //Loop until done receiving frame, then we can start uploading
  } while ((curr_IRQ_status & IRQ_TRX_END) == 0);

  RF230_SEL = 0;
  SPDR0 = 0b00100000;  //Frame receive mode
  while((SPSR0&0x80)==0);  //Wait for frame transfer to complete
  SPDR0 = junk;  //Transmit a junk byte to receive a byte of frame
  while((SPSR0&0x80) == 0);  //Wait for transfer to complete
  length = SPDR0;
  while (length>0)  {
    SPDR0 = junk;
    while((SPSR0&0x80) == 0);  //Wait for transfer to complete
    frame[index++]=SPDR0;  //Get byte of frame
    length--;
  }
  SPDR0 = junk;
  while((SPSR0&0x80) == 0);
  LQI = SPDR0;  //LQI is a byte between 0 (bad) and 255(excellent)
  PORTA = LQI;
  RF230_SEL = 1;
}

/****************************************************************************/
//Transceiver must be in appropriate state before calling this
void RF_download_frame(void) {
  unsigned char i;
  RF_write_register(TRX_STATE,PLL_ON);
  RF230_SEL = 0;
  SPDR0 = 0b01100000;  //Frame transmit mode
  while((SPSR0&0x80) == 0);  //Wait for transfer to complete
  SPDR0 = tx_frame_length;  //Frame length
  while((SPSR0&0x80) == 0);  //Wait for transfer to complete
  for (i=0;i
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I definitely won't read 20k of code :)

What do You want from it? Making it working on ZigBit can be tricky. If you still want to do it yourself I'd recommend you read rf230 datasheet.

I'll be glad to answer any particular questions but I won't do yours work for you.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

no at all, I don't like when somebody doing work for me, I only want to show full header file and to understand how to make my project w/o bitcloud.

Does I need to setup IEEE_ADDR for transmission? If for example I need to make 2 different networks with 10 devices in each, all devices in radius 20-30 meters, and I need devices from first one don't able communicate from second one, it's enought to set only PAN_ID and/or SHORT_ADDR if IEEE_ADDR isn't required?

Thank you!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok. Let's do it step-by-step. First of all we must assume that there is no ready-available working code for simple communication (although I am sure it is, but as a part of complex project, so still requires a lot of work).

For the beginning write simple program that just communicates to chip. Just writes/reads some registers. After that adopting code you posted will be easy.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How to determine in coordinator event when new node joined network (in lowpower sample)? It's possible in coordinator to determine how much enddevices are in network and catch when one of them disconnected?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

use peer to peer topology. No coordinator. No associations.
just put the destination 64 bit MAC (IEEE) address and send the data, for a given PAN ID and channel.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

code-by wrote:
How to determine in coordinator event when new node joined network (in lowpower sample)? It's possible in coordinator to determine how much enddevices are in network and catch when one of them disconnected?

Sorry. I'm on bussines trip now. So have limited access to sources.

But You should look for function ZDO_NwkUpdateNtfy(). Or something like this. It is called once some network event happened (joining/leaving device is one of them). But you can not detrmine actual amount of nodes in network without implementing someting.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

stevech wrote:
use peer to peer topology. No coordinator. No associations.
just put the destination 64 bit MAC (IEEE) address and send the data, for a given PAN ID and channel.

It is not possible with BitCloud. And doing it without BitCloud will lead to writing huge amount of code.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I need to add ability to send data from coordinator to enddevie in lowpower sample, for example, to enddevice with short add. 0x0002. What apsDataReq need to be for this?

apsDataReq.dstAddrMode 		= 0x0002;
apsDataReq.dstAddress.shortAddress = 0;
apsDataReq.dstEndpoint		= APP_ENDPOINT;
apsDataReq.profileId		= APP_PROFILE_ID;
apsDataReq.clusterId		= APP_CLUSTER_ID;
apsDataReq.srcEndpoint		= APP_ENDPOINT;
apsDataReq.asduLength		= sizeof (AppMessage_t);
apsDataReq.asdu			= (uint8_t *) &appMessageBuffer.message;
apsDataReq.txOptions.acknowledgedTransmission = 1;
apsDataReq.radius               = 0;
apsDataReq.APS_DataConf         = APS_DataConf;
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

apsDataReq.dstAddrMode = APS_SHORT_ADDRESS;
apsDataReq.dstAddress.shortAddress = 0x0002;

And you will be fine.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, I mix up first lines.
So I add to coordinator initialization:

apsDataReq.dstAddrMode       = APS_SHORT_ADDRESS;
apsDataReq.dstAddress.shortAddress = 0x0002; 
apsDataReq.dstEndpoint      = APP_ENDPOINT; 
apsDataReq.profileId      = APP_PROFILE_ID; 
apsDataReq.clusterId      = APP_CLUSTER_ID; 
apsDataReq.srcEndpoint      = APP_ENDPOINT; 
apsDataReq.asduLength      = sizeof (AppMessage_t); 
apsDataReq.asdu         = (uint8_t *) &appMessageBuffer.message; 
apsDataReq.txOptions.acknowledgedTransmission = 1; 
apsDataReq.radius               = 0; 
apsDataReq.APS_DataConf         = APS_DataConf;

I have one coordinator and two enddevices (A & B), sleep time changed from 10 to 2 seconds. When I send data to A, B lost network and rejoin. May be I change number of retries when send from B to coordinator in time it busy with sending to A?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

code-by wrote:

I have one coordinator and two enddevices (A & B), sleep time changed from 10 to 2 seconds. When I send data to A, B lost network and rejoin. May be I change number of retries when send from B to coordinator in time it busy with sending to A?

Try changing these parameters in config server:

CS_APS_DATA_REQ_BUFFER_SIZE = 4
CS_APS_ACK_FRAME_BUFFER_SIZE = 4
CS_NWK_DATA_REQ_BUFFER_SIZE = 4
CS_NWK_DATA_IND_BUFFER_SIZE = 4

Also new release of BitCloud is coming soon and it should have demo of coordinator sending data to end-device.

NOTE: I no longer actively read this forum. Please ask your question on www.eevblog.com/forum if you want my answer.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What is default values for these variables?

1. Can an enddevice send data to another enddevice in network (if yes, it send via coordinator or directly)?

2. Can an router send data to another router in network (if yes, it send via coordinator or directly)?

3. If there coordinator, router and enddevice, and enddevice in range to direct send data to coordinator - does router envolved in this transaction or not?

Pages