| : |
libmc1322x is a library, build system, test code, and utilities for the MC13224V from Freescale.
First clone libmc1322x.git:
$ git clone git://git.devl.org/git/malvira/libmc1322x.git
You need to have sane build environment for the mc13224. If you do not, then take a look at the excellent tutorial see the MC13224 Ubuntu and OE setup guide.
Otherwise, try building the test programs included in libmc1322x
$ cd libmc1322x/tests $ make
this will build all the test programs in libmc1322x/tests for each board defined in libmc1322x/board. You should now have programs like:
$ ls *.bin blink-allio_redbee-dev.bin blink-red_redbee-dev.bin nvm-read_redbee-dev.bin rftest-tx_redbee-dev.bin tmr-ints_redbee-dev.bin blink-allio_redbee-r1.bin blink-red_redbee-r1.bin nvm-read_redbee-r1.bin rftest-tx_redbee-r1.bin tmr-ints_redbee-r1.bin blink-blue_redbee-dev.bin blink-white_redbee-dev.bin nvm-write_redbee-dev.bin romimg_redbee-dev.bin tmr_redbee-dev.bin blink-blue_redbee-r1.bin blink-white_redbee-r1.bin nvm-write_redbee-r1.bin romimg_redbee-r1.bin tmr_redbee-r1.bin blink-green_redbee-dev.bin flasher_redbee-dev.bin rftest-rx_redbee-dev.bin sleep_redbee-dev.bin uart1-loopback_redbee-dev.bin blink-green_redbee-r1.bin flasher_redbee-r1.bin rftest-rx_redbee-r1.bin sleep_redbee-r1.bin uart1-loopback_redbee-r1.bin
if you only wanted to build binaries for one board you can do:
$ make BOARD=redbee-dev
The set of boards made is defined in the initial line of libmc1322x/board/Makefile.board:
BOARDS := redbee-dev redbee-r1
edit this line if you want to make a different set of boards.
You can load programs on to your mc13224 over UART1 with mc1322x-load.pl in libmc1322x/tools. To run your code:
$ ../tools/mc1322x-load.pl -f rftest-tx_redbee-dev.bin -t /dev/ttyUSB0
You must make sure that you are using the correct serial device. With the econotag, for instance, two serial devices show up if you are not using one for openocd. UART1 is usually second device, however. Generally, it's best not to assume that a newly plugged in device will get a particular number.
The following example will flash a program into the NVM storage on the mc13224. Be sure that you are familiar with the erase options for your hardware.
The program libmc1322x/tests/flasher.c works with mc1322x-load.pl to flash an executable image into the NVM memory of the mc13224. mc1322x-load.pl first downloads flasher.bin using the UART1 bootloader and then sends a second file. Now, flasher.bin (which is running on the mc13224), writes this second image to NVM. Then on reset or power up, the mc13224 bootloader will detect this image, copy it to SRAM, and then execute it.
An example of this procedure is shown below:
$ ./mc1322x-load.pl -f flasher_redbee-econotag.bin -s blink-red_redbee-econotag.bin -t /dev/ttyUSB1 <press reset button> CONNECT Size: 9552 bytes Sending flasher.bin secondary send... .Detecting internal nvm nvm_detect returned: 0x00 type is: 0x00000001 nvm_erase returned: 0x00 type is: 0x00000001 ready Size: 4820 bytes Sending blink-red.bin done sending files. len: 000012d4 type is: 0x00000001 nvm_write returned: 0x00 flasher done <press reset button>
You can also specify additional data to flash from the command line (such as hardware MAC address) as follows:
$ ./mc1322x-load.pl -f flasher.bin -s nvm-read.bin -t /dev/ttyUSB0 0x1e000,0x01020304,0x05060708 <press reset button> ....CONNECT Size: 9552 bytes Sending flasher.bin secondary send... .Detecting internal nvm nvm_detect returned: 0x00 type is: 0x00000001 nvm_erase returned: 0x00 type is: 0x00000001 ready Size: 8916 bytes Sending nvm-read.bin done sending files. sending 0x1e000,0x01020304,0x05060708, len: 000022d4 type is: 0x00000001 nvm_write returned: 0x00 flasher done writing addr 0001e000 data 01020304 writing addr 0001e004 data 05060708 <press reset button> Detecting internal nvm nvm_detect returned: 0x00 type is: 0x00000001 nvm_read returned: 0x00 0x01020304 0x05060708 0xffffffff 0xffffffff
this example programs 0x01020304 and 0x05060708 starting at address 0x1e000.
flashing a 30kB image takes approximately 10 seconds total.
Just as important as flashing and image is erasing an image. There are two good ways to do this:
The best way to incorporate libmc1322x into your code is as a git submodule:
$ mkdir newproject $ cd newproject $ git init Initialized empty Git repository in /home/malvira/newproject/.git/ $ git submodule add git://git.devl.org/git/malvira/libmc1322x.git libmc1322x
This will add libmc1322x to your repository. Now to setup the Makefile:
$ cp libmc1322x/tests/Makefile .
You need to edit the Makefile to point MC1322X to your libmc1322x submodule.
change:
MC1322X := ..
to
MC1322X := libmc1322x
or to wherever you've located the submodule
you also need to edit COBJS and TARGETS accordings. COBJS are all of your common code for any of your programs and are rebuilt for each board. TARGETS are the names of your programs.
For instance, say you have a common routine that prints a welcome message and it is used by two programs a and b. You would add common.o to COBJS:
COBJS:= common.o
and your target line would read:
TARGETS := a b
Since COBJS are made for each board, it is ok to have board specific code in there. As an example, tests uses this in tests.c to print the name of the board in your welcome message. You could also use to have different GPIO mappings between boards.
Sending and receiving packets with the MC13224 is straightforward using libmc1322x. The maca driver keeps internally a fixed pool of packets. A packet looks as follows:
struct packet {
uint8_t length;
/* offset into data for first byte of the packet payload */
/* On TX this should be 0 */
/* On RX this should be 1 since the maca puts the length as the first byte*/
uint8_t offset;
uint8_t data[MAX_PAYLOAD_SIZE+2+1]; /* +2 for FCS; + 1 since maca returns the length as the first byte */
};
typedef struct packet packet_t;
you initialize the radio hardware:
trim_xtal(); vreg_init(); maca_init(); set_channel(0); /* 802.15.4 channel 11 */ set_power(0x12); /* 0x12 is the highest, 4.5dBm */
trim_xtal() trims the on-board crystal to exactly 24 MHz. vreg_init() enables the voltage regulators for the NVM. maca_init() initializes the radio hardware and starts the interrupt driven receive and transmit cycle.
To send a packet in your main code, you request a free packet using get_free_packet(), which returns a pointer the packet (which isn't free anymore, so don't lose it!) or NULL (if there are no free packets available). You then fill the packet however you choose, set the length, set the offset to 0, and call tx_packet() and pass it the pointer to the packet you want transmitted. tx_packet() inserts the packet into the driver's transmit queue and the radio will transmit it as soon as possible.
p = get_free_packet();
if(p) {
fill_packet(p);
tx_packet(p);
} else {
printf("can't get free packet\n");
}
packets are received automatically and stored in the receive queue. rx_head is the head of the queue and is non-zero if there is a packet waiting. You can test for this if you'd like. To receive the packet you call rx_packet(), which returns a pointer to the packet or NULL. Like before, the returned packet is removed from the receive queue --- it is not free yet. You can then do what you like to the packet. The payload starts at p->offset and is p->length long. When you are done, free the packet with free_packet():
if((p = rx_packet())) {
/* print and free the packet */
print_packet(p);
free_packet(p);
}
That's it! Now go do lots of wireless things!