diff --git a/.gitmodules b/.gitmodules index 710a8a0e3..29e886554 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,13 @@ [submodule "tools/cc2538-bsl"] path = tools/cc2538-bsl url = https://github.com/JelmerT/cc2538-bsl.git -[submodule "cpu/cc26xx/lib/cc26xxware"] - path = cpu/cc26xx/lib/cc26xxware +[submodule "cpu/cc26xx-cc13xx/lib/cc26xxware"] + path = cpu/cc26xx-cc13xx/lib/cc26xxware url = https://github.com/g-oikonomou/cc26xxware.git +[submodule "cpu/cc26xx-cc13xx/lib/cc13xxware"] + path = cpu/cc26xx-cc13xx/lib/cc13xxware + url = https://github.com/g-oikonomou/cc13xxware.git [submodule "platform/stm32nucleo-spirit1/stm32cube-lib"] path = platform/stm32nucleo-spirit1/stm32cube-lib url = https://github.com/STclab/stm32nucleo-spirit1-lib + diff --git a/.travis.yml b/.travis.yml index 9fb8295c5..98f98edff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,14 +10,14 @@ before_script: ## Install doxygen - if [ ${BUILD_CATEGORY:-0} = doxygen ] ; then - sudo add-apt-repository ppa:libreoffice/libreoffice-4-3 -y && sudo apt-get -qq update && + sudo add-apt-repository ppa:libreoffice/libreoffice-4-4 -y && sudo apt-get -qq update && sudo apt-get --no-install-suggests --no-install-recommends -qq install doxygen && doxygen --version ; fi ## Install msp430 toolchain - sudo apt-get -qq install lib32z1 - - $WGET http://adamdunkels.github.io/contiki-fork/mspgcc-4.7.0-compiled.tar.bz2 && + - $WGET http://simonduq.github.io/resources/mspgcc-4.7.2-compiled.tar.bz2 && tar xjf mspgcc*.tar.bz2 -C /tmp/ && sudo cp -f -r /tmp/msp430/* /usr/local/ && rm -rf /tmp/msp430 mspgcc*.tar.bz2 && @@ -103,6 +103,7 @@ env: - BUILD_TYPE='collect' - BUILD_TYPE='collect-lossy' - BUILD_TYPE='rpl' + - BUILD_TYPE='large-rpl' - BUILD_TYPE='rime' - BUILD_TYPE='ipv6' - BUILD_TYPE='ip64' MAKE_TARGETS='cooja' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ab4aba7e0..8ed3d23a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -136,7 +136,7 @@ Contiki maintainers to look at! All code contributions to Contiki are submitted as [Github pull requests](https://help.github.com/articles/using-pull-requests). Pull requests will be reviewed and accepted according to the guidelines -found in the [[Pull Request Policy]] +found in the next section. The basic guidelines to to start a Pull-Request: * Create a new branch for your modifications. This branch should be based on the latest contiki master branch. @@ -183,6 +183,21 @@ $ git push origin my_new_feature -f ``` * NOTE: To avoid all the pain of selectively picking commits, rebasing and force-pushing - begin your development with a branch OTHER THAN your master branch, and push changes to that branch after any local commits. +Pull Request Merging Policy +--------------------------- + +Pull requests (PRs) are reviewed by the [merge team](https://github.com/orgs/contiki-os/people). +Generally, PRs require two "+1" before they can be merged by someone on the merge team. +The since Contiki 3.0, the merging policy is the following: +* The PR receives **one "-1"** from a merge team member (along with specific feedback). The PR is closed. A "-1" must be accompanied with a clear explanation why the PR will not be considered for inclusion. +* The PR receives **two "+1"** from merge team members. The PR is merged. +* The PR was inactive for **two months**. A team member may either: + * Comment "Is there any interest for this PR? Is there any work pending on it? If not I will close it in **one month**." Back to initial state in case of activity, close otherwise. + * Comment "I approve this PR. If nobody disapproves within **one month**, I will merge it." Back to initial state in case of activity, merge otherwise. + +There is an exception to the rule. +Code that requires esoteric expertise such as some applications, platforms or tools can be merged after a single "+1" from its domain expert. + Travis / Regression testing --------------------------- diff --git a/README.md b/README.md index 53ff3f06a..b838212c8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ The Contiki Operating System ============================ -[![Build Status](https://secure.travis-ci.org/contiki-os/contiki.png)](http://travis-ci.org/contiki-os/contiki) +[![Build Status](https://travis-ci.org/contiki-os/contiki.svg?branch=master)](https://travis-ci.org/contiki-os/contiki/branches) Contiki is an open source operating system that runs on tiny low-power microcontrollers and makes it possible to develop applications that diff --git a/apps/codeprop/Makefile.codeprop-tmp b/apps/codeprop/Makefile.codeprop-tmp new file mode 100644 index 000000000..e725df070 --- /dev/null +++ b/apps/codeprop/Makefile.codeprop-tmp @@ -0,0 +1,10 @@ +codeprop-tmp_src = codeprop-tmp.c + +# Enable LARGE MEMORY MODEL supports for WISMOTE and EXP5438 platform +ifeq ($(TARGET),wismote) + TARGET_MEMORY_MODEL = large +endif + +ifeq ($(TARGET),exp5438) + TARGET_MEMORY_MODEL = large +endif diff --git a/apps/er-coap/er-coap-engine.c b/apps/er-coap/er-coap-engine.c index 4871368b4..2f58eda94 100644 --- a/apps/er-coap/er-coap-engine.c +++ b/apps/er-coap/er-coap-engine.c @@ -104,7 +104,7 @@ coap_receive(void) coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr, UIP_UDP_BUF->srcport))) { uint32_t block_num = 0; - uint16_t block_size = REST_MAX_CHUNK_SIZE; + uint16_t block_size = COAP_MAX_BLOCK_SIZE; uint32_t block_offset = 0; int32_t new_offset = 0; @@ -125,8 +125,8 @@ coap_receive(void) if(coap_get_header_block2 (message, &block_num, NULL, &block_size, &block_offset)) { PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n", - block_num, block_size, REST_MAX_CHUNK_SIZE, block_offset); - block_size = MIN(block_size, REST_MAX_CHUNK_SIZE); + block_num, block_size, COAP_MAX_BLOCK_SIZE, block_offset); + block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE); new_offset = block_offset; } diff --git a/apps/webbrowser/www.c b/apps/webbrowser/www.c index 3e84c7cb9..70af0332b 100644 --- a/apps/webbrowser/www.c +++ b/apps/webbrowser/www.c @@ -810,6 +810,7 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type, textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN); add_forminput((struct inputattrib *)textptr); textptr->formptr = formptr; + petsciiconv_topetscii(text, strlen(text)); strcpy(textptr->textentry.text, text); strcpy(textptr->name, attrib); if(size) { diff --git a/core/dev/slip.c b/core/dev/slip.c index 6b8a24ceb..451b9ec6c 100644 --- a/core/dev/slip.c +++ b/core/dev/slip.c @@ -293,7 +293,7 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); #endif } else { - uip_len = 0; + uip_clear_buf(); SLIP_STATISTICS(slip_ip_drop++); } #else /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/core/lib/aes-128.c b/core/lib/aes-128.c index 59b16421e..23e4356b7 100644 --- a/core/lib/aes-128.c +++ b/core/lib/aes-128.c @@ -71,12 +71,8 @@ static uint8_t round_keys[11][AES_128_KEY_LENGTH]; static uint8_t galois_mul2(uint8_t value) { - if(value >> 7) { - value = value << 1; - return value ^ 0x1b; - } else { - return value << 1; - } + uint8_t xor_val = (value >> 7) * 0x1b; + return ((value << 1) ^ xor_val); } /*---------------------------------------------------------------------------*/ static void diff --git a/core/loader/elfloader-msp430x.c b/core/loader/elfloader-msp430x.c new file mode 100644 index 000000000..32e1126f3 --- /dev/null +++ b/core/loader/elfloader-msp430x.c @@ -0,0 +1,810 @@ +/* + * Copyright (c) 2015, Indian Institute of Science + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + */ + +/** + * \file + * MSP430x elfloader. + * \author + * Sumankumar Panchal + * + */ + +#include "contiki.h" +#include "loader/elfloader.h" +#include "loader/elfloader-arch.h" +#include "cfs/cfs.h" +#include "loader/symtab.h" +#include +#include +#include +#include "dev/flash.h" + +#define DEBUG 0 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) do {} while(0) +#endif + +#define EI_NIDENT 16 + +struct elf32_ehdr { + unsigned char e_ident[EI_NIDENT]; /* ident bytes */ + elf32_half e_type; /* file type */ + elf32_half e_machine; /* target machine */ + elf32_word e_version; /* file version */ + elf32_addr e_entry; /* start address */ + elf32_off e_phoff; /* phdr file offset */ + elf32_off e_shoff; /* shdr file offset */ + elf32_word e_flags; /* file flags */ + elf32_half e_ehsize; /* sizeof ehdr */ + elf32_half e_phentsize; /* sizeof phdr */ + elf32_half e_phnum; /* number phdrs */ + elf32_half e_shentsize; /* sizeof shdr */ + elf32_half e_shnum; /* number shdrs */ + elf32_half e_shstrndx; /* shdr string index */ +}; + +/* Values for e_type. */ +#define ET_NONE 0 /* Unknown type. */ +#define ET_REL 1 /* Relocatable. */ +#define ET_EXEC 2 /* Executable. */ +#define ET_DYN 3 /* Shared object. */ +#define ET_CORE 4 /* Core file. */ + +struct elf32_shdr { + elf32_word sh_name; /* section name */ + elf32_word sh_type; /* SHT_... */ + elf32_word sh_flags; /* SHF_... */ + elf32_addr sh_addr; /* virtual address */ + elf32_off sh_offset; /* file offset */ + elf32_word sh_size; /* section size */ + elf32_word sh_link; /* misc info */ + elf32_word sh_info; /* misc info */ + elf32_word sh_addralign; /* memory alignment */ + elf32_word sh_entsize; /* entry size if table */ +}; + +/* sh_type */ +#define SHT_NULL 0 /* inactive */ +#define SHT_PROGBITS 1 /* program defined information */ +#define SHT_SYMTAB 2 /* symbol table section */ +#define SHT_STRTAB 3 /* string table section */ +#define SHT_RELA 4 /* relocation section with addends*/ +#define SHT_HASH 5 /* symbol hash table section */ +#define SHT_DYNAMIC 6 /* dynamic section */ +#define SHT_NOTE 7 /* note section */ +#define SHT_NOBITS 8 /* no space section */ +#define SHT_REL 9 /* relation section without addends */ +#define SHT_SHLIB 10 /* reserved - purpose unknown */ +#define SHT_DYNSYM 11 /* dynamic symbol table section */ +#define SHT_LOPROC 0x70000000 /* reserved range for processor */ +#define SHT_HIPROC 0x7fffffff /* specific section header types */ +#define SHT_LOUSER 0x80000000 /* reserved range for application */ +#define SHT_HIUSER 0xffffffff /* specific indexes */ + +struct elf32_rel { + elf32_addr r_offset; /* Location to be relocated. */ + elf32_word r_info; /* Relocation type and symbol index. */ +}; + +struct elf32_sym { + elf32_word st_name; /* String table index of name. */ + elf32_addr st_value; /* Symbol value. */ + elf32_word st_size; /* Size of associated object. */ + unsigned char st_info; /* Type and binding information. */ + unsigned char st_other; /* Reserved (not used). */ + elf32_half st_shndx; /* Section index of symbol. */ +}; + +#define ELF32_R_SYM(info) ((info) >> 8) + +struct relevant_section { + unsigned char number; + unsigned int offset; + char *address; +}; + +char elfloader_unknown[30]; /* Name that caused link error. */ + +struct process *const *elfloader_autostart_processes; + +static struct relevant_section bss, data, rodata, rodatafar, text, textfar; + +static const unsigned char elf_magic_header[] = +{ 0x7f, 0x45, 0x4c, 0x46, /* 0x7f, 'E', 'L', 'F' */ + 0x01, /* Only 32-bit objects. */ + 0x01, /* Only LSB data. */ + 0x01, /* Only ELF version 1. */ +}; + +/* relocation type */ +#define R_MSP430_NONE 0 +#define R_MSP430_32 1 +#define R_MSP430_10_PCREL 2 +#define R_MSP430_16 3 +#define R_MSP430_16_PCREL 4 +#define R_MSP430_16_BYTE 5 +#define R_MSP430_16_PCREL_BYTE 6 +#define R_MSP430_2X_PCREL 7 +#define R_MSP430_RL_PCREL 8 +#define R_MSP430X_SRC_BYTE 9 +#define R_MSP430X_SRC 10 +#define R_MSP430X_DST_BYTE 11 +#define R_MSP430X_DST 12 +#define R_MSP430X_DST_2ND_BYTE 13 +#define R_MSP430X_DST_2ND 14 +#define R_MSP430X_PCREL_SRC_BYTE 15 +#define R_MSP430X_PCREL_SRC 16 +#define R_MSP430X_PCREL_DST_BYTE 17 +#define R_MSP430X_PCREL_DST 18 +#define R_MSP430X_PCREL_DST_2ND 19 +#define R_MSP430X_PCREL_DST_2ND_BYTE 20 +#define R_MSP430X_S_BYTE 21 +#define R_MSP430X_S 22 +#define R_MSP430X_D_BYTE 23 +#define R_MSP430X_D 24 +#define R_MSP430X_PCREL_D 25 +#define R_MSP430X_INDXD 26 +#define R_MSP430X_PCREL_INDXD 27 +#define R_MSP430_10 28 + +#define ELF32_R_TYPE(info) ((unsigned char)(info)) + +static uint16_t datamemory_aligned[ELFLOADER_DATAMEMORY_SIZE / 2 + 1]; +static uint8_t *datamemory = (uint8_t *)datamemory_aligned; +#if ELFLOADER_CONF_TEXT_IN_ROM +static const char textmemory[ELFLOADER_TEXTMEMORY_SIZE] = { 0 }; +#else /* ELFLOADER_CONF_TEXT_IN_ROM */ +static char textmemory[ELFLOADER_TEXTMEMORY_SIZE]; +#endif /* ELFLOADER_CONF_TEXT_IN_ROM */ + +/*---------------------------------------------------------------------------*/ +static void +seek_read(int fd, unsigned int offset, char *buf, int len) +{ + cfs_seek(fd, offset, CFS_SEEK_SET); + cfs_read(fd, buf, len); +#if DEBUG + { + int i; + PRINTF("seek_read: Read len %d from offset %d\n", + len, offset); + for(i = 0; i < len; ++i) { + PRINTF("%02x ", buf[i]); + } + printf("\n"); + } +#endif /* DEBUG */ +} +/*---------------------------------------------------------------------------*/ +static void * +find_local_symbol(int fd, const char *symbol, + unsigned int symtab, unsigned short symtabsize, + unsigned int strtab) +{ + struct elf32_sym s; + unsigned int a; + char name[30]; + struct relevant_section *sect; + + for(a = symtab; a < symtab + symtabsize; a += sizeof(s)) { + seek_read(fd, a, (char *)&s, sizeof(s)); + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + if(strcmp(name, symbol) == 0) { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == rodatafar.number) { + sect = &rodatafar; + } else if(s.st_shndx == textfar.number) { + sect = &textfar; + } else { + return NULL; + } + return &(sect->address[s.st_value]); + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +static int +relocate_section(int fd, + unsigned int section, unsigned short size, + unsigned int sectionaddr, + char *sectionbase, + unsigned int strs, + unsigned int strtab, + unsigned int symtab, unsigned short symtabsize, + unsigned char using_relas) +{ + /* + * sectionbase added; runtime start address of current section + */ + struct elf32_rela rela; /* Now used both for rel and rela data! */ + int rel_size = 0; + struct elf32_sym s; + unsigned int a; + char name[30]; + char *addr; + struct relevant_section *sect; + + /* determine correct relocation entry sizes */ + if(using_relas) { + rel_size = sizeof(struct elf32_rela); + } else { + rel_size = sizeof(struct elf32_rel); + } + + for(a = section; a < section + size; a += rel_size) { + seek_read(fd, a, (char *)&rela, rel_size); + seek_read(fd, + symtab + sizeof(struct elf32_sym) * ELF32_R_SYM(rela.r_info), + (char *)&s, sizeof(s)); + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + PRINTF("name: %s\n", name); + addr = (char *)symtab_lookup(name); + if(addr == NULL) { + PRINTF("name not found in global: %s\n", name); + addr = find_local_symbol(fd, name, symtab, symtabsize, strtab); + PRINTF("found address %p\n", addr); + } + if(addr == NULL) { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == rodatafar.number) { + sect = &rodatafar; + } else if(s.st_shndx == textfar.number) { + sect = &textfar; + } else { + PRINTF("elfloader unknown name: '%30s'\n", name); + memcpy(elfloader_unknown, name, sizeof(elfloader_unknown)); + elfloader_unknown[sizeof(elfloader_unknown) - 1] = 0; + return ELFLOADER_SYMBOL_NOT_FOUND; + } + + addr = sect->address; + } + } else { + if(s.st_shndx == bss.number) { + sect = &bss; + } else if(s.st_shndx == data.number) { + sect = &data; + } else if(s.st_shndx == rodatafar.number) { + sect = &rodatafar; + } else if(s.st_shndx == textfar.number) { + sect = &textfar; + } else { + return ELFLOADER_SEGMENT_NOT_FOUND; + } + + addr = sect->address; + } + + if(!using_relas) { + /* copy addend to rela structure */ + seek_read(fd, sectionaddr + rela.r_offset, (char *)&rela.r_addend, 4); + } + + elfloader_arch_relocate(fd, sectionaddr, sectionbase, &rela, addr); + } + + return ELFLOADER_OK; +} +/*---------------------------------------------------------------------------*/ +static void * +find_program_processes(int fd, + unsigned int symtab, unsigned short size, + unsigned int strtab) +{ + struct elf32_sym s; + unsigned int a; + char name[30]; + + for(a = symtab; a < symtab + size; a += sizeof(s)) { + seek_read(fd, a, (char *)&s, sizeof(s)); + + if(s.st_name != 0) { + seek_read(fd, strtab + s.st_name, name, sizeof(name)); + if(strcmp(name, "autostart_processes") == 0) { + return &data.address[s.st_value]; + } + } + } + return NULL; +} +/*---------------------------------------------------------------------------*/ +void +elfloader_init(void) +{ + elfloader_autostart_processes = NULL; +} +/*---------------------------------------------------------------------------*/ +int +elfloader_load(int fd) +{ + struct elf32_ehdr ehdr; + struct elf32_shdr shdr; + struct elf32_shdr strtable; + unsigned int strs; + unsigned int shdrptr; + unsigned int nameptr; + char name[17]; + + int i; + unsigned short shdrnum, shdrsize; + + unsigned char using_relas = -1; + unsigned short textoff = 0, textfaroff = 0, textsize, textfarsize, + textrelaoff = 0, textrelasize, textfarrelaoff = 0, textfarrelasize; + unsigned short dataoff = 0, datasize, datarelaoff = 0, datarelasize; + unsigned short rodataoff = 0, rodatafaroff = 0, rodatasize, rodatafarsize, + rodatarelaoff = 0, rodatarelasize, rodatafarrelaoff = 0, + rodatafarrelasize; + unsigned short symtaboff = 0, symtabsize; + unsigned short strtaboff = 0, strtabsize; + unsigned short bsssize = 0; + + struct process **process; + int ret; + + elfloader_unknown[0] = 0; + + /* The ELF header is located at the start of the buffer. */ + seek_read(fd, 0, (char *)&ehdr, sizeof(ehdr)); + + /* Make sure that we have a correct and compatible ELF header. */ + if(memcmp(ehdr.e_ident, elf_magic_header, sizeof(elf_magic_header)) != 0) { + PRINTF("ELF header problems\n"); + return ELFLOADER_BAD_ELF_HEADER; + } + + /* Grab the section header. */ + shdrptr = ehdr.e_shoff; + seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr)); + + /* Get the size and number of entries of the section header. */ + shdrsize = ehdr.e_shentsize; + shdrnum = ehdr.e_shnum; + + PRINTF("Section header: size %d num %d\n", shdrsize, shdrnum); + + /* The string table section: holds the names of the sections. */ + seek_read(fd, ehdr.e_shoff + shdrsize * ehdr.e_shstrndx, + (char *)&strtable, sizeof(strtable)); + + /* + * Get a pointer to the actual table of strings. This table holds + * the names of the sections, not the names of other symbols in the + * file (these are in the sybtam section). + */ + strs = strtable.sh_offset; + + PRINTF("Strtable offset %d\n", strs); + + /* + * Go through all sections and pick out the relevant ones. The + * ".text" and ".far.text" segments holds the actual code from + * the ELF file. The ".data" segment contains initialized data. + * The ".bss" segment holds the size of the unitialized data segment. + * The ".rodata" and ".far.rodata" segments contains constant data. + * The ".rela[a].text" and ".rela[a].far.text" segments contains + * relocation information for the contents of the ".text" and + * ".far.text" segments, respectively. The ".rela[a].rodata" and + * ".rela[a].far.rodata" segments contains relocation information + * for the contents of the ".rodata" and ".far.rodata" segments, + * respectively. The ".rela[a].data" segment contains relocation + * information for the contents of the ".data" segment. The ".symtab" + * segment contains the symbol table for this file. The ".strtab" + * segment points to the actual string names used by the symbol table. + * + * In addition to grabbing pointers to the relevant sections, we + * also save the section number for resolving addresses in the + * relocator code. + */ + + /* + * Initialize the segment sizes to zero so that we can check if + * their sections was found in the file or not. + */ + textsize = textfarsize = textrelasize = textfarrelasize = + datasize = datarelasize = rodatasize = rodatafarsize = + rodatarelasize = rodatafarrelasize = symtabsize = strtabsize = 0; + + bss.number = data.number = rodata.number = rodatafar.number = + text.number = textfar.number = -1; + + shdrptr = ehdr.e_shoff; + for(i = 0; i < shdrnum; ++i) { + seek_read(fd, shdrptr, (char *)&shdr, sizeof(shdr)); + + /* The name of the section is contained in the strings table. */ + nameptr = strs + shdr.sh_name; + seek_read(fd, nameptr, name, sizeof(name)); + PRINTF("Section shdrptr 0x%x, %d + %d type %d\n", + shdrptr, + strs, shdr.sh_name, + (int)shdr.sh_type); + /* + * Match the name of the section with a predefined set of names + * (.text, .far.text, .data, .bss, .rodata, .far.rodata, .rela.text, .rela.far.text, + * .rela.data, .rela.rodata, .rela.far.rodata, .symtab, and .strtab). + */ + + if(shdr.sh_type == SHT_SYMTAB) { + PRINTF("symtab\n"); + symtaboff = shdr.sh_offset; + symtabsize = shdr.sh_size; + } else if(shdr.sh_type == SHT_STRTAB) { + PRINTF("strtab\n"); + strtaboff = shdr.sh_offset; + strtabsize = shdr.sh_size; + } else if(strncmp(name, ".text", 5) == 0) { + textoff = shdr.sh_offset; + textsize = shdr.sh_size; + text.number = i; + text.offset = textoff; + } else if(strncmp(name, ".far.text", 9) == 0) { + textfaroff = shdr.sh_offset; + textfarsize = shdr.sh_size; + textfar.number = i; + textfar.offset = textfaroff; + } else if(strncmp(name, ".rel.text", 9) == 0) { + using_relas = 0; + textrelaoff = shdr.sh_offset; + textrelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.text", 10) == 0) { + using_relas = 1; + textrelaoff = shdr.sh_offset; + textrelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.far.text", 14) == 0) { + using_relas = 1; + textfarrelaoff = shdr.sh_offset; + textfarrelasize = shdr.sh_size; + } else if(strncmp(name, ".data", 5) == 0) { + dataoff = shdr.sh_offset; + datasize = shdr.sh_size; + data.number = i; + data.offset = dataoff; + } else if(strncmp(name, ".rodata", 7) == 0) { + /* read-only data handled the same way as regular text section */ + rodataoff = shdr.sh_offset; + rodatasize = shdr.sh_size; + rodata.number = i; + rodata.offset = rodataoff; + } else if(strncmp(name, ".far.rodata", 11) == 0) { + rodatafaroff = shdr.sh_offset; + rodatafarsize = shdr.sh_size; + rodatafar.number = i; + rodatafar.offset = rodataoff; + } else if(strncmp(name, ".rel.rodata", 11) == 0) { + /* using elf32_rel instead of rela */ + using_relas = 0; + rodatarelaoff = shdr.sh_offset; + rodatarelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.rodata", 12) == 0) { + using_relas = 1; + rodatarelaoff = shdr.sh_offset; + rodatarelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.far.rodata", 16) == 0) { + using_relas = 1; + rodatafarrelaoff = shdr.sh_offset; + rodatafarrelasize = shdr.sh_size; + } else if(strncmp(name, ".rel.data", 9) == 0) { + /* using elf32_rel instead of rela */ + using_relas = 0; + datarelaoff = shdr.sh_offset; + datarelasize = shdr.sh_size; + } else if(strncmp(name, ".rela.data", 10) == 0) { + using_relas = 1; + datarelaoff = shdr.sh_offset; + datarelasize = shdr.sh_size; + } else if(strncmp(name, ".bss", 4) == 0) { + bsssize = shdr.sh_size; + bss.number = i; + bss.offset = 0; + } + + /* Move on to the next section header. */ + shdrptr += shdrsize; + } + if(symtabsize == 0) { + return ELFLOADER_NO_SYMTAB; + } + if(strtabsize == 0) { + return ELFLOADER_NO_STRTAB; + } + if(textfarsize == 0) { + return ELFLOADER_NO_TEXT; + } + + PRINTF("before allocate ram\n"); + bss.address = (char *)elfloader_arch_allocate_ram(bsssize + datasize); + data.address = (char *)bss.address + bsssize; + PRINTF("before allocate rom\n"); + textfar.address = (char *)elfloader_arch_allocate_rom(textfarsize + rodatafarsize); + rodatafar.address = (char *)textfar.address + textfarsize; + + PRINTF("bss base address: bss.address = 0x%08x\n", bss.address); + PRINTF("data base address: data.address = 0x%08x\n", data.address); + PRINTF("textfar base address: textfar.address = 0x%08x\n", textfar.address); + PRINTF("rodatafar base address: rodatafar.address = 0x%08x\n", rodatafar.address); + + /* If we have text segment relocations, we process them. */ + PRINTF("elfloader: relocate textfar\n"); + if(textfarrelasize > 0) { + ret = relocate_section(fd, + textfarrelaoff, textfarrelasize, + textfaroff, + textfar.address, + strs, + strtaboff, + symtaboff, symtabsize, using_relas); + if(ret != ELFLOADER_OK) { + return ret; + } + } + + /* If we have any rodata segment relocations, we process them too. */ + PRINTF("elfloader: relocate rodata\n"); + if(rodatafarrelasize > 0) { + ret = relocate_section(fd, + rodatafarrelaoff, rodatafarrelasize, + rodatafaroff, + rodatafar.address, + strs, + strtaboff, + symtaboff, symtabsize, using_relas); + if(ret != ELFLOADER_OK) { + PRINTF("elfloader: data failed\n"); + return ret; + } + } + + /* If we have any data segment relocations, we process them too. */ + PRINTF("elfloader: relocate data\n"); + if(datarelasize > 0) { + ret = relocate_section(fd, + datarelaoff, datarelasize, + dataoff, + data.address, + strs, + strtaboff, + symtaboff, symtabsize, using_relas); + if(ret != ELFLOADER_OK) { + PRINTF("elfloader: data failed\n"); + return ret; + } + } + + /* Write text and rodata segment into flash and data segment into RAM. */ + elfloader_arch_write_rom(fd, textfaroff, textfarsize, textfar.address); + elfloader_arch_write_rom(fd, rodatafaroff, rodatafarsize, rodatafar.address); + + memset(bss.address, 0, bsssize); + seek_read(fd, dataoff, data.address, datasize); + + PRINTF("elfloader: autostart search\n"); + process = (struct process **)find_local_symbol(fd, "autostart_processes", + symtaboff, symtabsize, strtaboff); + if(process != NULL) { + PRINTF("elfloader: autostart found\n"); + elfloader_autostart_processes = process; + return ELFLOADER_OK; + } else { + PRINTF("elfloader: no autostart\n"); + process = (struct process **)find_program_processes(fd, symtaboff, + symtabsize, strtaboff); + if(process != NULL) { + PRINTF("elfloader: FOUND PRG\n"); + } + return ELFLOADER_NO_STARTPOINT; + } +} +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_ram(int size) +{ + return datamemory; +} +/*---------------------------------------------------------------------------*/ +void * +elfloader_arch_allocate_rom(int size) +{ +#if ELFLOADER_CONF_TEXT_IN_ROM + /* Return an 512-byte aligned pointer. */ + return (char *) + ((unsigned long)&textmemory[0] & 0xfffffe00) + + (((unsigned long)&textmemory[0] & 0x1ff) == 0 ? 0 : 0x200); +#else /* ELFLOADER_CONF_TEXT_IN_ROM */ + return textmemory; +#endif /* ELFLOADER_CONF_TEXT_IN_ROM */ +} +/*---------------------------------------------------------------------------*/ +#define READSIZE 32 +void +elfloader_arch_write_rom(int fd, unsigned short textoff, unsigned int size, char *mem) +{ +#if ELFLOADER_CONF_TEXT_IN_ROM + int i; + unsigned int ptr; + unsigned short *flashptr; + + flash_setup(); + + flashptr = (unsigned short *)mem; + + cfs_seek(fd, textoff, CFS_SEEK_SET); + for(ptr = 0; ptr < size; ptr += READSIZE) { + + /* Read data from file into RAM. */ + cfs_read(fd, (unsigned char *)datamemory, READSIZE); + + /* Clear flash page on 512 byte boundary. */ + if((((unsigned short)flashptr) & 0x01ff) == 0) { + flash_clear(flashptr); + } + + /* + * Burn data from RAM into flash ROM. Flash is burned one 16-bit + * word at a time, so we need to be careful when incrementing + * pointers. The flashptr is already a short pointer, so + * incrementing it by one will actually increment the address by + * two. + */ + for(i = 0; i < READSIZE / 2; ++i) { + flash_write(flashptr, ((unsigned short *)datamemory)[i]); + ++flashptr; + } + } + + flash_done(); +#else /* ELFLOADER_CONF_TEXT_IN_ROM */ + cfs_seek(fd, textoff, CFS_SEEK_SET); + cfs_read(fd, (unsigned char *)mem, size); +#endif /* ELFLOADER_CONF_TEXT_IN_ROM */ +} +/*---------------------------------------------------------------------------*/ +/* Relocate an MSP430X ELF section. */ +void +elfloader_arch_relocate(int fd, unsigned int sectionoffset, + char *sectionaddr, + struct elf32_rela *rela, char *addr) +{ + unsigned int type; + unsigned char instr[2]; + + type = ELF32_R_TYPE(rela->r_info); + addr += rela->r_addend; + + switch(type) { + case R_MSP430_16: + case R_MSP430_16_PCREL: + case R_MSP430_16_BYTE: + case R_MSP430_16_PCREL_BYTE: + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430_32: + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_S: + case R_MSP430X_S_BYTE: + /* src(19:16) located at positions 11:8 of opcode */ + /* src(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xf0 | (((long int)addr >> 8) & 0x0f00); + instr[0] = (int)(instr[0]) & 0xff; + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_D: + case R_MSP430X_PCREL_D: + case R_MSP430X_D_BYTE: + /* dst(19:16) located at positions 3:0 of opcode */ + /* dst(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xff; + instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_PCREL_SRC_BYTE: + case R_MSP430X_SRC_BYTE: + case R_MSP430X_PCREL_SRC: + case R_MSP430X_SRC: + /* src(19:16) located at positions 10:7 of extension word */ + /* src(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + /* 4 most-significant bits */ + instr[1] = (int)(instr[1]) & 0xf8 | (((long int)addr >> 9) & 0x0780); + instr[0] = (int)(instr[0]) & 0x7f | (((long int)addr >> 9) & 0x0780); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + /* 16 least-significant bits */ + cfs_seek(fd, sectionoffset + rela->r_offset + 0x04, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_DST_BYTE: + case R_MSP430X_PCREL_DST_BYTE: + case R_MSP430X_DST: + case R_MSP430X_PCREL_DST: + /* dst(19:16) located at positions 3:0 of extension word */ + /* dst(15:0) located just after opcode */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xff; + instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_seek(fd, sectionoffset + rela->r_offset + 0x04, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_DST_2ND: + case R_MSP430X_PCREL_DST_2ND: + case R_MSP430X_DST_2ND_BYTE: + case R_MSP430X_PCREL_DST_2ND_BYTE: + /* dst(19:16) located at positions 3:0 of extension word */ + /* dst(15:0) located after src(15:0) */ + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_read(fd, instr, 2); + instr[1] = (int)(instr[1]) & 0xff; + instr[0] = (int)(instr[0]) & 0xf0 | (((long int)addr >> 16) & 0x000f); + cfs_seek(fd, sectionoffset + rela->r_offset, CFS_SEEK_SET); + cfs_write(fd, instr, 2); + cfs_seek(fd, sectionoffset + rela->r_offset + 0x06, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + case R_MSP430X_INDXD: + case R_MSP430X_PCREL_INDXD: + cfs_seek(fd, sectionoffset + rela->r_offset + 0x02, CFS_SEEK_SET); + cfs_write(fd, (char *)&addr, 2); + break; + default: + PRINTF("Unknown relocation type!\n"); + break; + } +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/ip/dhcpc.c b/core/net/ip/dhcpc.c index 46ba826da..08023f1e4 100644 --- a/core/net/ip/dhcpc.c +++ b/core/net/ip/dhcpc.c @@ -300,7 +300,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data)) } selecting: - xid++; s.ticks = CLOCK_SECOND; do { while(ev != tcpip_event) { @@ -366,7 +365,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data)) } /* renewing: */ - xid++; do { while(ev != tcpip_event) { tcpip_poll_udp(s.conn); diff --git a/core/net/ip/tcpip.c b/core/net/ip/tcpip.c index 1c75d1bc9..0505b3d47 100644 --- a/core/net/ip/tcpip.c +++ b/core/net/ip/tcpip.c @@ -529,10 +529,7 @@ void tcpip_input(void) { process_post_synch(&tcpip_process, PACKET_INPUT, NULL); - uip_len = 0; -#if NETSTACK_CONF_WITH_IPV6 - uip_ext_len = 0; -#endif /*NETSTACK_CONF_WITH_IPV6*/ + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ #if NETSTACK_CONF_WITH_IPV6 @@ -548,13 +545,13 @@ tcpip_ipv6_output(void) if(uip_len > UIP_LINK_MTU) { UIP_LOG("tcpip_ipv6_output: Packet to big"); - uip_len = 0; + uip_clear_buf(); return; } if(uip_is_addr_unspecified(&UIP_IP_BUF->destipaddr)){ UIP_LOG("tcpip_ipv6_output: Destination address unspecified"); - uip_len = 0; + uip_clear_buf(); return; } @@ -591,7 +588,7 @@ tcpip_ipv6_output(void) #else PRINTF("tcpip_ipv6_output: Destination off-link but no route\n"); #endif /* !UIP_FALLBACK_INTERFACE */ - uip_len = 0; + uip_clear_buf(); return; } @@ -643,7 +640,7 @@ tcpip_ipv6_output(void) #if UIP_CONF_IPV6_RPL if(rpl_update_header_final(nexthop)) { - uip_len = 0; + uip_clear_buf(); return; } #endif /* UIP_CONF_IPV6_RPL */ @@ -651,7 +648,7 @@ tcpip_ipv6_output(void) if(nbr == NULL) { #if UIP_ND6_SEND_NA if((nbr = uip_ds6_nbr_add(nexthop, NULL, 0, NBR_INCOMPLETE)) == NULL) { - uip_len = 0; + uip_clear_buf(); return; } else { #if UIP_CONF_IPV6_QUEUE_PKT @@ -689,7 +686,7 @@ tcpip_ipv6_output(void) uip_packetqueue_set_buflen(&nbr->packethandle, uip_len); } #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - uip_len = 0; + uip_clear_buf(); return; } /* Send in parallel if we are running NUD (nbc state is either STALE, @@ -719,15 +716,14 @@ tcpip_ipv6_output(void) } #endif /*UIP_CONF_IPV6_QUEUE_PKT*/ - uip_len = 0; + uip_clear_buf(); return; } return; } /* Multicast IP destination address. */ tcpip_output(NULL); - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); } #endif /* NETSTACK_CONF_WITH_IPV6 */ /*---------------------------------------------------------------------------*/ diff --git a/core/net/ip/uip.h b/core/net/ip/uip.h index cb12f52ab..a85929554 100644 --- a/core/net/ip/uip.h +++ b/core/net/ip/uip.h @@ -1326,6 +1326,22 @@ extern uint8_t uip_ext_len; extern uint16_t uip_urglen, uip_surglen; #endif /* UIP_URGDATA > 0 */ +/* + * Clear uIP buffer + * + * This function clears the uIP buffer by reseting the uip_len and + * uip_ext_len pointers. + */ +#if NETSTACK_CONF_WITH_IPV6 +#define uip_clear_buf() { \ + uip_len = 0; \ + uip_ext_len = 0; \ +} +#else /*NETSTACK_CONF_WITH_IPV6*/ +#define uip_clear_buf() { \ + uip_len = 0; \ +} +#endif /*NETSTACK_CONF_WITH_IPV6*/ /** * Representation of a uIP TCP connection. diff --git a/core/net/ip64/ip64-dhcpc.c b/core/net/ip64/ip64-dhcpc.c index fdb1dd0ec..1ed3ac249 100644 --- a/core/net/ip64/ip64-dhcpc.c +++ b/core/net/ip64/ip64-dhcpc.c @@ -308,7 +308,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data)) } selecting: - xid++; s.ticks = CLOCK_SECOND; do { while(ev != tcpip_event) { @@ -374,7 +373,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data)) } /* renewing: */ - xid++; do { while(ev != tcpip_event) { tcpip_poll_udp(s.conn); diff --git a/core/net/ip64/ip64-slip-interface.c b/core/net/ip64/ip64-slip-interface.c index 05fe704c7..8d46d78a8 100644 --- a/core/net/ip64/ip64-slip-interface.c +++ b/core/net/ip64/ip64-slip-interface.c @@ -59,7 +59,7 @@ input_callback(void) /*PRINTF("SIN: %u\n", uip_len);*/ if(uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); #if 0 if(uip_buf[1] == 'P') { uip_ipaddr_t prefix; @@ -87,7 +87,7 @@ input_callback(void) slip_send(); } - uip_len = 0; + uip_clear_buf(); } else { /* Save the last sender received over SLIP to avoid bouncing the @@ -101,7 +101,7 @@ input_callback(void) uip_len = len; /* PRINTF("send len %d\n", len); */ } else { - uip_len = 0; + uip_clear_buf(); } } } diff --git a/core/net/ipv4/uip-fw.c b/core/net/ipv4/uip-fw.c index c152231c0..530a0b7c0 100644 --- a/core/net/ipv4/uip-fw.c +++ b/core/net/ipv4/uip-fw.c @@ -229,7 +229,7 @@ time_exceeded(void) /* We don't send out ICMP errors for ICMP messages (unless they are pings). */ if(ICMPBUF->proto == UIP_PROTO_ICMP && ICMPBUF->type != ICMP_ECHO) { - uip_len = 0; + uip_clear_buf(); return; } /* Copy fields from packet header into payload of this ICMP packet. */ diff --git a/core/net/ipv4/uip.c b/core/net/ipv4/uip.c index 1c3c24aaf..48366a114 100644 --- a/core/net/ipv4/uip.c +++ b/core/net/ipv4/uip.c @@ -709,7 +709,7 @@ uip_process(uint8_t flag) } /* Reset the length variables. */ - uip_len = 0; + uip_clear_buf(); uip_slen = 0; #if UIP_TCP @@ -1589,7 +1589,7 @@ uip_process(uint8_t flag) uip_add_rcv_nxt(1); uip_flags = UIP_CONNECTED | UIP_NEWDATA; uip_connr->len = 0; - uip_len = 0; + uip_clear_buf(); uip_slen = 0; UIP_APPCALL(); goto appsend; @@ -1934,7 +1934,7 @@ uip_process(uint8_t flag) return; drop: - uip_len = 0; + uip_clear_buf(); uip_flags = 0; return; } diff --git a/core/net/ipv4/uip_arp.c b/core/net/ipv4/uip_arp.c index 5abad8b40..10015295e 100644 --- a/core/net/ipv4/uip_arp.c +++ b/core/net/ipv4/uip_arp.c @@ -284,10 +284,10 @@ uip_arp_arpin(void) { if(uip_len < sizeof(struct arp_hdr)) { - uip_len = 0; + uip_clear_buf(); return; } - uip_len = 0; + uip_clear_buf(); switch(BUF->opcode) { case UIP_HTONS(ARP_REQUEST): diff --git a/core/net/ipv6/multicast/roll-tm.c b/core/net/ipv6/multicast/roll-tm.c index 20a562084..bed0b6b0f 100644 --- a/core/net/ipv6/multicast/roll-tm.c +++ b/core/net/ipv6/multicast/roll-tm.c @@ -1107,26 +1107,26 @@ icmp_input() PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("\n"); ROLL_TM_STATS_ADD(icmp_bad); - return; + goto discard; } if(!uip_is_addr_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr) && !uip_is_addr_linklocal_allrouters_mcast(&UIP_IP_BUF->destipaddr)) { PRINTF("ROLL TM: ICMPv6 In, bad destination\n"); ROLL_TM_STATS_ADD(icmp_bad); - return; + goto discard; } if(UIP_ICMP_BUF->icode != ROLL_TM_ICMP_CODE) { PRINTF("ROLL TM: ICMPv6 In, bad ICMP code\n"); ROLL_TM_STATS_ADD(icmp_bad); - return; + goto discard; } if(UIP_IP_BUF->ttl != ROLL_TM_IP_HOP_LIMIT) { PRINTF("ROLL TM: ICMPv6 In, bad TTL\n"); ROLL_TM_STATS_ADD(icmp_bad); - return; + goto discard; } #endif @@ -1311,6 +1311,9 @@ drop: t[1].c++; } +discard: + + uip_len = 0; return; } /*---------------------------------------------------------------------------*/ @@ -1380,8 +1383,7 @@ out() drop: uip_slen = 0; - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static uint8_t diff --git a/core/net/ipv6/multicast/smrf.c b/core/net/ipv6/multicast/smrf.c index b1dccbd19..d62547ef6 100644 --- a/core/net/ipv6/multicast/smrf.c +++ b/core/net/ipv6/multicast/smrf.c @@ -81,7 +81,7 @@ mcast_fwd(void *p) uip_len = mcast_len; UIP_IP_BUF->ttl--; tcpip_output(NULL); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static uint8_t diff --git a/core/net/ipv6/uip-ds6-route.c b/core/net/ipv6/uip-ds6-route.c index 49e3d3588..a5c00d384 100644 --- a/core/net/ipv6/uip-ds6-route.c +++ b/core/net/ipv6/uip-ds6-route.c @@ -367,6 +367,9 @@ uip_ds6_route_add(uip_ipaddr_t *ipaddr, uint8_t length, num_routes++; PRINTF("uip_ds6_route_add num %d\n", num_routes); + + /* lock this entry so that nexthop is not removed */ + nbr_table_lock(nbr_routes, routes); } uip_ipaddr_copy(&(r->ipaddr), ipaddr); @@ -423,7 +426,7 @@ uip_ds6_route_rm(uip_ds6_route_t *route) list_remove(route->neighbor_routes->route_list, neighbor_route); if(list_head(route->neighbor_routes->route_list) == NULL) { /* If this was the only route using this neighbor, remove the - neibhor from the table */ + neighbor from the table - this implicitly unlocks nexthop */ PRINTF("uip_ds6_route_rm: removing neighbor too\n"); nbr_table_remove(nbr_routes, route->neighbor_routes->route_list); } diff --git a/core/net/ipv6/uip-ds6.c b/core/net/ipv6/uip-ds6.c index ce75ca485..ff2ccd1db 100644 --- a/core/net/ipv6/uip-ds6.c +++ b/core/net/ipv6/uip-ds6.c @@ -275,6 +275,7 @@ uip_ds6_prefix_add(uip_ipaddr_t *ipaddr, uint8_t ipaddrlen, PRINTF("Adding prefix "); PRINT6ADDR(&locprefix->ipaddr); PRINTF("length %u, vlifetime%lu\n", ipaddrlen, interval); + return locprefix; } return NULL; } diff --git a/core/net/ipv6/uip-icmp6.c b/core/net/ipv6/uip-icmp6.c index ee8d94c77..a9dc9e352 100644 --- a/core/net/ipv6/uip-icmp6.c +++ b/core/net/ipv6/uip-icmp6.c @@ -210,12 +210,12 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { /* check if originating packet is not an ICMP error*/ if (uip_ext_len) { if(UIP_EXT_BUF->next == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128){ - uip_len = 0; + uip_clear_buf(); return; } } else { if(UIP_IP_BUF->proto == UIP_PROTO_ICMP6 && UIP_ICMP_BUF->type < 128){ - uip_len = 0; + uip_clear_buf(); return; } } @@ -250,7 +250,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { /* the source should not be unspecified nor multicast, the check for multicast is done in uip_process */ if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)){ - uip_len = 0; + uip_clear_buf(); return; } @@ -260,7 +260,7 @@ uip_icmp6_error_output(uint8_t type, uint8_t code, uint32_t param) { if(type == ICMP6_PARAM_PROB && code == ICMP6_PARAMPROB_OPTION){ uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &tmp_ipaddr); } else { - uip_len = 0; + uip_clear_buf(); return; } } else { @@ -385,7 +385,7 @@ echo_reply_input(void) } } - uip_len = 0; + uip_clear_buf(); return; } /*---------------------------------------------------------------------------*/ diff --git a/core/net/ipv6/uip-nd6.c b/core/net/ipv6/uip-nd6.c index 72b1badfa..a86de7021 100644 --- a/core/net/ipv6/uip-nd6.c +++ b/core/net/ipv6/uip-nd6.c @@ -127,6 +127,8 @@ static uip_ds6_addr_t *addr; /** Pointer to an interface address */ #if !UIP_CONF_ROUTER // TBD see if we move it to ra_input static uip_nd6_opt_prefix_info *nd6_opt_prefix_info; /** Pointer to prefix information option in uip_buf */ static uip_ipaddr_t ipaddr; +#endif +#if (!UIP_CONF_ROUTER || UIP_ND6_SEND_RA) static uip_ds6_prefix_t *prefix; /** Pointer to a prefix list entry */ #endif @@ -321,7 +323,7 @@ create_na: return; discard: - uip_len = 0; + uip_clear_buf(); return; } #endif /* UIP_ND6_SEND_NA */ @@ -360,7 +362,7 @@ uip_nd6_ns_output(uip_ipaddr_t * src, uip_ipaddr_t * dest, uip_ipaddr_t * tgt) } if (uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) { PRINTF("Dropping NS due to no suitable source address\n"); - uip_len = 0; + uip_clear_buf(); return; } UIP_IP_BUF->len[1] = @@ -557,7 +559,7 @@ na_input(void) #endif /*UIP_CONF_IPV6_QUEUE_PKT */ discard: - uip_len = 0; + uip_clear_buf(); return; } #endif /* UIP_ND6_SEND_NA */ @@ -646,7 +648,7 @@ rs_input(void) uip_ds6_send_ra_sollicited(); discard: - uip_len = 0; + uip_clear_buf(); return; } @@ -687,7 +689,6 @@ uip_nd6_ra_output(uip_ipaddr_t * dest) nd6_opt_offset = UIP_ND6_RA_LEN; -#if !UIP_CONF_ROUTER /* Prefix list */ for(prefix = uip_ds6_prefix_list; prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) { @@ -704,7 +705,6 @@ uip_nd6_ra_output(uip_ipaddr_t * dest) uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN; } } -#endif /* !UIP_CONF_ROUTER */ /* Source link-layer option */ create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO); @@ -1029,7 +1029,7 @@ ra_input(void) #endif /*UIP_CONF_IPV6_QUEUE_PKT */ discard: - uip_len = 0; + uip_clear_buf(); return; } #endif /* !UIP_CONF_ROUTER */ diff --git a/core/net/ipv6/uip6.c b/core/net/ipv6/uip6.c index 73abd1115..416edf813 100644 --- a/core/net/ipv6/uip6.c +++ b/core/net/ipv6/uip6.c @@ -538,8 +538,7 @@ remove_ext_hdr(void) uip_ext_len, uip_len); if(uip_len < UIP_IPH_LEN + uip_ext_len) { PRINTF("ERROR: uip_len too short compared to ext len\n"); - uip_ext_len = 0; - uip_len = 0; + uip_clear_buf(); return; } memmove(((uint8_t *)UIP_TCP_BUF), (uint8_t *)UIP_TCP_BUF + uip_ext_len, @@ -825,8 +824,7 @@ uip_reass_over(void) * any RFC, we decided not to include it as it reduces the size of * the packet. */ - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); memcpy(UIP_IP_BUF, FBUF, UIP_IPH_LEN); /* copy the header for src and dest address*/ uip_icmp6_error_output(ICMP6_TIME_EXCEEDED, ICMP6_TIME_EXCEED_REASSEMBLY, 0); @@ -971,7 +969,7 @@ uip_process(uint8_t flag) } else if(flag == UIP_TIMER) { /* Reset the length variables. */ #if UIP_TCP - uip_len = 0; + uip_clear_buf(); uip_slen = 0; /* Increase the initial sequence number. */ @@ -1456,7 +1454,7 @@ uip_process(uint8_t flag) UIP_STAT(++uip_stat.icmp.drop); UIP_STAT(++uip_stat.icmp.typeerr); UIP_LOG("icmp6: unknown ICMPv6 message."); - uip_len = 0; + uip_clear_buf(); } if(uip_len > 0) { @@ -1978,7 +1976,7 @@ uip_process(uint8_t flag) uip_add_rcv_nxt(1); uip_flags = UIP_CONNECTED | UIP_NEWDATA; uip_connr->len = 0; - uip_len = 0; + uip_clear_buf(); uip_slen = 0; UIP_APPCALL(); goto appsend; @@ -2310,8 +2308,7 @@ uip_process(uint8_t flag) return; drop: - uip_len = 0; - uip_ext_len = 0; + uip_clear_buf(); uip_ext_bitmap = 0; uip_flags = 0; return; diff --git a/core/net/mac/contikimac/contikimac.c b/core/net/mac/contikimac/contikimac.c index b7083e83d..3d1f6a277 100644 --- a/core/net/mac/contikimac/contikimac.c +++ b/core/net/mac/contikimac/contikimac.c @@ -136,11 +136,15 @@ static int we_are_receiving_burst = 0; /* CCA_SLEEP_TIME is the time between two successive CCA checks. */ /* Add 1 when rtimer ticks are coarse */ +#ifdef CONTIKIMAC_CONF_CCA_SLEEP_TIME +#define CCA_SLEEP_TIME CONTIKIMAC_CONF_CCA_SLEEP_TIME +#else #if RTIMER_ARCH_SECOND > 8000 #define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000 #else #define CCA_SLEEP_TIME (RTIMER_ARCH_SECOND / 2000) + 1 -#endif +#endif /* RTIMER_ARCH_SECOND > 8000 */ +#endif /* CONTIKIMAC_CONF_CCA_SLEEP_TIME */ /* CHECK_TIME is the total time it takes to perform CCA_COUNT_MAX CCAs. */ @@ -153,7 +157,11 @@ static int we_are_receiving_burst = 0; /* LISTEN_TIME_AFTER_PACKET_DETECTED is the time that we keep checking for activity after a potential packet has been detected by a CCA check. */ +#ifdef CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED +#define LISTEN_TIME_AFTER_PACKET_DETECTED CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED +#else #define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80 +#endif /* MAX_SILENCE_PERIODS is the maximum amount of periods (a period is CCA_CHECK_TIME + CCA_SLEEP_TIME) that we allow to be silent before @@ -195,6 +203,12 @@ static int we_are_receiving_burst = 0; to a neighbor for which we have a phase lock. */ #define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60 +#ifdef CONTIKIMAC_CONF_SEND_SW_ACK +#define CONTIKIMAC_SEND_SW_ACK CONTIKIMAC_CONF_SEND_SW_ACK +#else +#define CONTIKIMAC_SEND_SW_ACK 0 +#endif + #define ACK_LEN 3 #include @@ -865,10 +879,26 @@ static void input_packet(void) { static struct ctimer ct; + int duplicate = 0; + +#if CONTIKIMAC_SEND_SW_ACK + int original_datalen; + uint8_t *original_dataptr; + + original_datalen = packetbuf_datalen(); + original_dataptr = packetbuf_dataptr(); +#endif + if(!we_are_receiving_burst) { off(); } + if(packetbuf_datalen() == ACK_LEN) { + /* Ignore ack packets */ + PRINTF("ContikiMAC: ignored ack\n"); + return; + } + /* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/ if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) { @@ -896,12 +926,13 @@ input_packet(void) #if RDC_WITH_DUPLICATE_DETECTION /* Check for duplicate packet. */ - if(mac_sequence_is_duplicate()) { + duplicate = mac_sequence_is_duplicate(); + if(duplicate) { /* Drop the packet. */ - /* printf("Drop duplicate ContikiMAC layer packet\n");*/ - return; + PRINTF("contikimac: Drop duplicate\n"); + } else { + mac_sequence_register_seqno(); } - mac_sequence_register_seqno(); #endif /* RDC_WITH_DUPLICATE_DETECTION */ #if CONTIKIMAC_CONF_COMPOWER @@ -919,7 +950,30 @@ input_packet(void) #endif /* CONTIKIMAC_CONF_COMPOWER */ PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen()); - NETSTACK_MAC.input(); + +#if CONTIKIMAC_SEND_SW_ACK + { + frame802154_t info154; + frame802154_parse(original_dataptr, original_datalen, &info154); + if(info154.fcf.frame_type == FRAME802154_DATAFRAME && + info154.fcf.ack_required != 0 && + linkaddr_cmp((linkaddr_t *)&info154.dest_addr, + &linkaddr_node_addr)) { + uint8_t ackdata[ACK_LEN] = {0, 0, 0}; + + we_are_sending = 1; + ackdata[0] = FRAME802154_ACKFRAME; + ackdata[1] = 0; + ackdata[2] = info154.seq; + NETSTACK_RADIO.send(ackdata, ACK_LEN); + we_are_sending = 0; + } + } +#endif /* CONTIKIMAC_SEND_SW_ACK */ + + if(!duplicate) { + NETSTACK_MAC.input(); + } return; } else { PRINTDEBUG("contikimac: data not for us\n"); diff --git a/core/net/nbr-table.c b/core/net/nbr-table.c index 4c9fab4fb..6b990a020 100644 --- a/core/net/nbr-table.c +++ b/core/net/nbr-table.c @@ -40,6 +40,18 @@ #include "lib/list.h" #include "net/nbr-table.h" +#define DEBUG 0 +#if DEBUG +#include +#include "sys/ctimer.h" +static void handle_periodic_timer(void *ptr); +static struct ctimer periodic_timer; +static uint8_t initialized = 0; +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + /* List of link-layer addresses of the neighbors, used as key in the tables */ typedef struct nbr_table_key { struct nbr_table_key *next; @@ -143,6 +155,7 @@ static int nbr_set_bit(uint8_t *bitmap, nbr_table_t *table, nbr_table_item_t *item, int value) { int item_index = index_from_item(table, item); + if(table != NULL && item_index != -1) { if(value) { bitmap[item_index] |= 1 << table->index; @@ -229,6 +242,13 @@ nbr_table_allocate(void) int nbr_table_register(nbr_table_t *table, nbr_table_callback *callback) { +#if DEBUG + if(!initialized) { + initialized = 1; + /* schedule a debug printout per minute */ + ctimer_set(&periodic_timer, CLOCK_SECOND * 60, handle_periodic_timer, NULL); + } +#endif if(num_tables < MAX_NUM_TABLES) { table->index = num_tables++; table->callback = callback; @@ -331,6 +351,10 @@ nbr_table_remove(nbr_table_t *table, void *item) int nbr_table_lock(nbr_table_t *table, void *item) { +#if DEBUG + int i = index_from_item(table, item); + PRINTF("*** Lock %d\n", i); +#endif return nbr_set_bit(locked_map, table, item, 1); } /*---------------------------------------------------------------------------*/ @@ -338,6 +362,10 @@ nbr_table_lock(nbr_table_t *table, void *item) int nbr_table_unlock(nbr_table_t *table, void *item) { +#if DEBUG + int i = index_from_item(table, item); + PRINTF("*** Unlock %d\n", i); +#endif return nbr_set_bit(locked_map, table, item, 0); } /*---------------------------------------------------------------------------*/ @@ -348,3 +376,25 @@ nbr_table_get_lladdr(nbr_table_t *table, const void *item) nbr_table_key_t *key = key_from_item(table, item); return key != NULL ? &key->lladdr : NULL; } +/*---------------------------------------------------------------------------*/ +#if DEBUG +static void +handle_periodic_timer(void *ptr) +{ + int i, j; + /* Printout all neighbors and which tables they are used in */ + PRINTF("NBR TABLE:\n"); + for(i = 0; i < NBR_TABLE_MAX_NEIGHBORS; i++) { + if(used_map[i] > 0) { + PRINTF(" %02d %02d",i , key_from_index(i)->lladdr.u8[LINKADDR_SIZE - 1]); + for(j = 0; j < num_tables; j++) { + PRINTF(" [%d:%d]", (used_map[i] & (1 << j)) != 0, + (locked_map[i] & (1 << j)) != 0); + } + PRINTF("\n"); + } + } + ctimer_reset(&periodic_timer); +} +#endif + diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 767c58968..89be40184 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -1408,10 +1408,4 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) p->dtsn = dio->dtsn; } /*---------------------------------------------------------------------------*/ -void -rpl_lock_parent(rpl_parent_t *p) -{ - nbr_table_lock(rpl_parents, p); -} -/*---------------------------------------------------------------------------*/ /** @} */ diff --git a/core/net/rpl/rpl-icmp6.c b/core/net/rpl/rpl-icmp6.c index 66e311d51..c4db3c8fa 100644 --- a/core/net/rpl/rpl-icmp6.c +++ b/core/net/rpl/rpl-icmp6.c @@ -175,7 +175,7 @@ dis_input(void) } } } - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void @@ -256,7 +256,8 @@ dio_input(void) PRINTF(", "); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTF("\n"); - return; + + goto discard; } } else { PRINTF("RPL: Neighbor already in neighbor cache\n"); @@ -306,7 +307,7 @@ dio_input(void) if(len + i > buffer_length) { PRINTF("RPL: Invalid DIO packet\n"); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } PRINTF("RPL: DIO option %u, length: %u\n", subopt_type, len - 2); @@ -316,7 +317,7 @@ dio_input(void) if(len < 6) { PRINTF("RPL: Invalid DAG MC, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } dio.mc.type = buffer[i + 2]; dio.mc.flags = buffer[i + 3] << 1; @@ -342,14 +343,14 @@ dio_input(void) dio.mc.obj.energy.energy_est = buffer[i + 7]; } else { PRINTF("RPL: Unhandled DAG MC type: %u\n", (unsigned)dio.mc.type); - return; + goto discard; } break; case RPL_OPTION_ROUTE_INFO: if(len < 9) { PRINTF("RPL: Invalid destination prefix option, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } /* The flags field includes the preference value. */ @@ -365,7 +366,7 @@ dio_input(void) } else { PRINTF("RPL: Invalid route info option, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } break; @@ -373,7 +374,7 @@ dio_input(void) if(len != 16) { PRINTF("RPL: Invalid DAG configuration option, len = %d\n", len); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } /* Path control field not yet implemented - at i + 2 */ @@ -395,7 +396,7 @@ dio_input(void) if(len != 32) { PRINTF("RPL: Invalid DAG prefix info, len != 32\n"); RPL_STAT(rpl_stats.malformed_msgs++); - return; + goto discard; } dio.prefix_info.length = buffer[i + 2]; dio.prefix_info.flags = buffer[i + 3]; @@ -418,7 +419,8 @@ dio_input(void) rpl_process_dio(&from, &dio); - uip_len = 0; + discard: + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void @@ -622,7 +624,7 @@ dao_input(void) if(instance == NULL) { PRINTF("RPL: Ignoring a DAO for an unknown RPL instance(%u)\n", instance_id); - return; + goto discard; } lifetime = instance->default_lifetime; @@ -637,7 +639,7 @@ dao_input(void) if(flags & RPL_DAO_D_FLAG) { if(memcmp(&dag->dag_id, &buffer[pos], sizeof(dag->dag_id))) { PRINTF("RPL: Ignoring a DAO for a DAG different from ours\n"); - return; + goto discard; } pos += 16; } @@ -658,7 +660,7 @@ dao_input(void) DAG_RANK(parent->rank, instance), DAG_RANK(dag->rank, instance)); parent->rank = INFINITE_RANK; parent->flags |= RPL_PARENT_FLAG_UPDATED; - return; + goto discard; } /* If we get the DAO from our parent, we also have a loop. */ @@ -666,7 +668,7 @@ dao_input(void) PRINTF("RPL: Loop detected when receiving a unicast DAO from our parent\n"); parent->rank = INFINITE_RANK; parent->flags |= RPL_PARENT_FLAG_UPDATED; - return; + goto discard; } } @@ -743,7 +745,7 @@ dao_input(void) dao_ack_output(instance, &dao_sender_addr, sequence); } } - return; + goto discard; } PRINTF("RPL: adding DAO route\n"); @@ -765,19 +767,17 @@ dao_input(void) PRINTF(", "); PRINTLLADDR((uip_lladdr_t *)packetbuf_addr(PACKETBUF_ADDR_SENDER)); PRINTF("\n"); - return; + goto discard; } } else { PRINTF("RPL: Neighbor already in neighbor cache\n"); } - rpl_lock_parent(parent); - rep = rpl_add_route(dag, &prefix, prefixlen, &dao_sender_addr); if(rep == NULL) { RPL_STAT(rpl_stats.mem_overflows++); PRINTF("RPL: Could not add a route after receiving a DAO\n"); - return; + goto discard; } rep->state.lifetime = RPL_LIFETIME(instance, lifetime); @@ -801,7 +801,9 @@ fwd_dao: dao_ack_output(instance, &dao_sender_addr, sequence); } } - uip_len = 0; + + discard: + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void @@ -931,7 +933,7 @@ dao_ack_input(void) PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); #endif /* DEBUG */ - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void diff --git a/core/net/rpl/rpl-private.h b/core/net/rpl/rpl-private.h index b49d71089..a1adc0d6f 100644 --- a/core/net/rpl/rpl-private.h +++ b/core/net/rpl/rpl-private.h @@ -303,9 +303,6 @@ uip_ds6_route_t *rpl_add_route(rpl_dag_t *dag, uip_ipaddr_t *prefix, int prefix_len, uip_ipaddr_t *next_hop); void rpl_purge_routes(void); -/* Lock a parent in the neighbor cache. */ -void rpl_lock_parent(rpl_parent_t *p); - /* Objective function. */ rpl_of_t *rpl_find_of(rpl_ocp_t); diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index db5230611..e4724408e 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -89,11 +89,17 @@ rpl_set_mode(enum rpl_mode m) } else if(m == RPL_MODE_FEATHER) { PRINTF("RPL: switching to feather mode\n"); - mode = m; if(default_instance != NULL) { + PRINTF("rpl_set_mode: RPL sending DAO with zero lifetime\n"); + if(default_instance->current_dag != NULL) { + dao_output(default_instance->current_dag->preferred_parent, RPL_ZERO_LIFETIME); + } rpl_cancel_dao(default_instance); + } else { + PRINTF("rpl_set_mode: no default instance\n"); } + mode = m; } else { mode = m; } @@ -277,9 +283,9 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr) rpl_instance_t *instance; rpl_instance_t *end; - PRINTF("RPL: Removing neighbor "); + PRINTF("RPL: Neighbor state changed for "); PRINT6ADDR(&nbr->ipaddr); - PRINTF("\n"); + PRINTF(", nscount=%u, state=%u\n", nbr->nscount, nbr->state); for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) { if(instance->used == 1 ) { p = rpl_find_parent_any_dag(instance, &nbr->ipaddr); diff --git a/core/net/rpl/rpl.h b/core/net/rpl/rpl.h index e6e385375..70c877aeb 100644 --- a/core/net/rpl/rpl.h +++ b/core/net/rpl/rpl.h @@ -108,7 +108,6 @@ struct rpl_dag; #define RPL_PARENT_FLAG_LINK_METRIC_VALID 0x2 struct rpl_parent { - struct rpl_parent *next; struct rpl_dag *dag; #if RPL_DAG_MC != RPL_DAG_MC_NONE rpl_metric_container_t mc; diff --git a/core/sys/ctimer.c b/core/sys/ctimer.c index c72f247f5..66698a8e6 100644 --- a/core/sys/ctimer.c +++ b/core/sys/ctimer.c @@ -98,9 +98,16 @@ ctimer_init(void) void ctimer_set(struct ctimer *c, clock_time_t t, void (*f)(void *), void *ptr) +{ + ctimer_set_with_process(c, t, f, ptr, PROCESS_CURRENT()); +} +/*---------------------------------------------------------------------------*/ +void +ctimer_set_with_process(struct ctimer *c, clock_time_t t, + void (*f)(void *), void *ptr, struct process *p) { PRINTF("ctimer_set %p %u\n", c, (unsigned)t); - c->p = PROCESS_CURRENT(); + c->p = p; c->f = f; c->ptr = ptr; if(initialized) { diff --git a/core/sys/ctimer.h b/core/sys/ctimer.h index bebe8a532..dabf43d8a 100644 --- a/core/sys/ctimer.h +++ b/core/sys/ctimer.h @@ -109,10 +109,28 @@ void ctimer_restart(struct ctimer *c); * sometime in the future. When the callback timer expires, * the callback function f will be called with ptr as argument. * + * This essentially does ctimer_set_process(c, t, f, ptr, PROCESS_CURRENT()); + * */ void ctimer_set(struct ctimer *c, clock_time_t t, void (*f)(void *), void *ptr); +/** + * \brief Set a callback timer. + * \param c A pointer to the callback timer. + * \param t The interval before the timer expires. + * \param f A function to be called when the timer expires. + * \param ptr An opaque pointer that will be supplied as an argument to the callback function. + * \param p A pointer to the process the timer belongs to + * + * This function is used to set a callback timer for a time + * sometime in the future. When the callback timer expires, + * the callback function f will be called with ptr as argument. + * + */ +void ctimer_set_with_process(struct ctimer *c, clock_time_t t, + void (*f)(void *), void *ptr, struct process *p); + /** * \brief Stop a pending callback timer. * \param c A pointer to the pending callback timer. diff --git a/core/sys/etimer.c b/core/sys/etimer.c index 719401115..17ac74285 100644 --- a/core/sys/etimer.c +++ b/core/sys/etimer.c @@ -181,6 +181,14 @@ etimer_set(struct etimer *et, clock_time_t interval) } /*---------------------------------------------------------------------------*/ void +etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval) +{ + timer_reset(&et->timer); + et->timer.interval = interval; + add_timer(et); +} +/*---------------------------------------------------------------------------*/ +void etimer_reset(struct etimer *et) { timer_reset(&et->timer); diff --git a/core/sys/etimer.h b/core/sys/etimer.h index b1f57b01a..ebbcfc7fd 100644 --- a/core/sys/etimer.h +++ b/core/sys/etimer.h @@ -114,6 +114,19 @@ CCIF void etimer_set(struct etimer *et, clock_time_t interval); */ CCIF void etimer_reset(struct etimer *et); +/** + * \brief Reset an event timer with a new interval. + * \param et A pointer to the event timer. + * \param interval The interval before the timer expires. + * + * This function very similar to etimer_reset. Opposed to + * etimer_reset it is possible to change the timout. + * This allows accurate, non-periodic timers without drift. + * + * \sa etimer_reset() + */ +void etimer_reset_with_new_interval(struct etimer *et, clock_time_t interval); + /** * \brief Restart an event timer from the current point in time * \param et A pointer to the event timer. diff --git a/cpu/6502/6502def.h b/cpu/6502/6502def.h index 352acc5a5..164af5e67 100644 --- a/cpu/6502/6502def.h +++ b/cpu/6502/6502def.h @@ -61,7 +61,7 @@ typedef int32_t s32_t; #define HAVE_SNPRINTF #define snprintf(buf, len, ...) sprintf(buf, __VA_ARGS__) -#define CLOCK_CONF_SECOND 2 +#define CLOCK_CONF_SECOND 4 typedef unsigned short clock_time_t; typedef unsigned short uip_stats_t; diff --git a/cpu/6502/sys/clock.c b/cpu/6502/sys/clock.c index c23e14f65..33d2da865 100644 --- a/cpu/6502/sys/clock.c +++ b/cpu/6502/sys/clock.c @@ -45,11 +45,8 @@ clock_time(void) * of overhead for cc65 targets. * On the other hand we want to avoid wrapping around frequently so the idea * is to reduce the clock resolution to the bare minimum. This is defined by - * the TCP/IP stack using a 1/2 second periodic timer. So CLOCK_CONF_SECOND - * needs to be defined at least as 2. - * The value 2 works out especially nicely as it allows us to implement the - * clock frequency devider below purely in (32 bit) integer arithmetic based - * on the educated guess of CLK_TCK being an even value. */ + * the DNS resolver using a 1/4 second timer. So CLOCK_CONF_SECOND needs to + * be defined at least as 4. */ return clock() / (CLK_TCK / CLOCK_CONF_SECOND); } /*---------------------------------------------------------------------------*/ diff --git a/cpu/cc253x/dev/cc2530-rf.c b/cpu/cc253x/dev/cc2530-rf.c index 3bd769142..55e7d3125 100644 --- a/cpu/cc253x/dev/cc2530-rf.c +++ b/cpu/cc253x/dev/cc2530-rf.c @@ -486,7 +486,7 @@ transmit(unsigned short transmit_len) } /*---------------------------------------------------------------------------*/ static int -send(void *payload, unsigned short payload_len) +send(const void *payload, unsigned short payload_len) { prepare(payload, payload_len); return transmit(payload_len); diff --git a/cpu/cc26xx-cc13xx/Makefile.cc13xx b/cpu/cc26xx-cc13xx/Makefile.cc13xx new file mode 100644 index 000000000..56593ee9f --- /dev/null +++ b/cpu/cc26xx-cc13xx/Makefile.cc13xx @@ -0,0 +1,7 @@ +TI_XXWARE_PATH = lib/cc13xxware + +CONTIKI_CPU_SOURCEFILES += smartrf-settings.c prop-mode.c + +CFLAGS += -DCPU_FAMILY_CC13XX=1 + +include $(CONTIKI_CPU)/Makefile.cc26xx-cc13xx diff --git a/cpu/cc26xx-cc13xx/Makefile.cc26xx b/cpu/cc26xx-cc13xx/Makefile.cc26xx new file mode 100644 index 000000000..4bc2cdcad --- /dev/null +++ b/cpu/cc26xx-cc13xx/Makefile.cc26xx @@ -0,0 +1,3 @@ +TI_XXWARE_PATH = lib/cc26xxware + +include $(CONTIKI_CPU)/Makefile.cc26xx-cc13xx diff --git a/cpu/cc26xx/Makefile.cc26xx b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx similarity index 80% rename from cpu/cc26xx/Makefile.cc26xx rename to cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx index 7c09c75ee..781f79b3f 100644 --- a/cpu/cc26xx/Makefile.cc26xx +++ b/cpu/cc26xx-cc13xx/Makefile.cc26xx-cc13xx @@ -8,25 +8,24 @@ NM = arm-none-eabi-nm SIZE = arm-none-eabi-size SREC_CAT = srec_cat -CPU_ABS_PATH = cpu/cc26xx -TI_CC26XXWARE_PATH = lib/cc26xxware -TI_CC26XXWARE = $(CONTIKI_CPU)/$(TI_CC26XXWARE_PATH) +CPU_ABS_PATH = cpu/cc26xx-cc13xx +TI_XXWARE = $(CONTIKI_CPU)/$(TI_XXWARE_PATH) ### cc26xxware sources under driverlib will be added to the MODULES list -TI_CC26XXWARE_SRC = $(CPU_ABS_PATH)/$(TI_CC26XXWARE_PATH)/driverlib +TI_XXWARE_SRC = $(CPU_ABS_PATH)/$(TI_XXWARE_PATH)/driverlib ### The directory with startup sources will be added to the CONTIKI_CPU_DIRS ### and the sources therein are added to the sources list explicitly. They are ### also listed explicitly in the linker command (through TARGET_STARTFILES), ### to make sure they always get linked in the image -TI_CC26XXWARE_STARTUP_DIR = $(TI_CC26XXWARE_PATH)/startup_files -TI_CC26XXWARE_STARTUP_SRCS = ccfg.c startup_gcc.c +TI_XXWARE_STARTUP_DIR = $(TI_XXWARE_PATH)/startup_files +TI_XXWARE_STARTUP_SRCS = ccfg.c startup_gcc.c ### MODULES will add some of these to the include path, but we need to add ### them earlier to prevent filename clashes with Contiki core files -CFLAGS += -I$(TI_CC26XXWARE) -I$(CONTIKI)/$(TI_CC26XXWARE_SRC) -CFLAGS += -I$(TI_CC26XXWARE)/inc -MODULES += $(TI_CC26XXWARE_SRC) +CFLAGS += -I$(TI_XXWARE) -I$(CONTIKI)/$(TI_XXWARE_SRC) +CFLAGS += -I$(TI_XXWARE)/inc +MODULES += $(TI_XXWARE_SRC) LDSCRIPT = $(CONTIKI_CPU)/cc26xx.ld @@ -35,10 +34,6 @@ CFLAGS += -ffunction-sections -fdata-sections CFLAGS += -fshort-enums -fomit-frame-pointer -fno-strict-aliasing CFLAGS += -Wall -std=c99 -### Workaround for driverlib's cpu.h which tests if defined(gcc) -### Delete if it gets fixed or if we stop using the driverlib -CFLAGS += -Dgcc=__GNUC__ - LDFLAGS += -mcpu=cortex-m3 -mthumb -mlittle-endian -nostartfiles LDFLAGS += -T $(LDSCRIPT) LDFLAGS += -Wl,--gc-sections,--sort-section=alignment @@ -62,23 +57,24 @@ endif CLEAN += symbols.c symbols.h *.d *.elf *.hex ### CPU-dependent directories -CONTIKI_CPU_DIRS = . dev dev/rfc-api $(TI_CC26XXWARE_STARTUP_DIR) +CONTIKI_CPU_DIRS = . dev rf-core rf-core/api $(TI_XXWARE_STARTUP_DIR) ### Use the existing debug I/O in cpu/arm/common CONTIKI_CPU_DIRS += ../arm/common/dbg-io ### CPU-dependent source files -CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c cc26xx-rtc.c uart.c -CONTIKI_CPU_SOURCEFILES += cc26xx-rf.c contiki-watchdog.c +CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c soc-rtc.c uart.c +CONTIKI_CPU_SOURCEFILES += contiki-watchdog.c CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.c CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c cc26xx-uart.c lpm.c CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.c +CONTIKI_CPU_SOURCEFILES += rf-core.c rf-ble.c ieee-mode.c DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES) -TARGET_START_SOURCEFILES += fault-handlers.c $(TI_CC26XXWARE_STARTUP_SRCS) +TARGET_START_SOURCEFILES += fault-handlers.c $(TI_XXWARE_STARTUP_SRCS) TARGET_STARTFILES = $(addprefix $(OBJECTDIR)/,$(call oname, $(TARGET_START_SOURCEFILES))) ### Don't treat the .elf as intermediate diff --git a/cpu/cc26xx/cc26xx.ld b/cpu/cc26xx-cc13xx/cc26xx.ld similarity index 93% rename from cpu/cc26xx/cc26xx.ld rename to cpu/cc26xx-cc13xx/cc26xx.ld index 5902161c3..84601ced6 100644 --- a/cpu/cc26xx/cc26xx.ld +++ b/cpu/cc26xx-cc13xx/cc26xx.ld @@ -44,8 +44,11 @@ MEMORY */ FLASH_CCFG (RX) : ORIGIN = 0x0001FFA8, LENGTH = 88 - /* RAM Size 20KB (PG2.1) */ + /* RAM Size 20KB */ SRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00005000 + + /* Application can use GPRAM region as RAM if cache is disabled in CCFG */ + GPRAM (RWX) : ORIGIN = 0x11000000, LENGTH = 0x00002000 } /*. Highest address of the stack. Used in startup file .*/ @@ -99,5 +102,10 @@ SECTIONS . = . + _Min_Heap_Size; . = . + _Min_Stack_Size; . = ALIGN(4); - } >SRAM + } > SRAM + + .gpram : + { + } > GPRAM + } diff --git a/cpu/cc26xx/clock.c b/cpu/cc26xx-cc13xx/clock.c similarity index 81% rename from cpu/cc26xx/clock.c rename to cpu/cc26xx-cc13xx/clock.c index 701971e16..fd8165d0d 100644 --- a/cpu/cc26xx/clock.c +++ b/cpu/cc26xx-cc13xx/clock.c @@ -35,30 +35,35 @@ * \defgroup cc26xx-platforms TI CC26xx-powered Platforms * @{ * - * \defgroup cc26xx The TI CC26xx CPU + * \defgroup cc26xx The TI CC26xx and CC13xx CPUs + * + * This group documents the TI CC26xx and CC13xx CPUs. The two CPU families are + * very similar, with the main difference being related to radio capability. + * + * Documentation in this group should be considered to be applicable to both + * families, unless explicitly stated otherwise. + * * @{ * * \addtogroup cc26xx-clocks * @{ * - * \defgroup cc26xx-software-clock CC26xx Software Clock + * \defgroup cc26xx-software-clock Software Clock * - * Implementation of the clock module for the cc26xx. + * Implementation of the clock module for the CC26xx and CC13xx. * * The software clock uses the facilities provided by the AON RTC driver * @{ * * \file - * Software clock implementation for the TI CC26xx + * Software clock implementation for the TI CC13xx/CC26xx */ /*---------------------------------------------------------------------------*/ #include "contiki.h" #include "ti-lib.h" /*---------------------------------------------------------------------------*/ -static volatile clock_time_t count; -static volatile clock_time_t second_countdown; -static volatile unsigned long secs; +static volatile uint64_t count; /*---------------------------------------------------------------------------*/ static void power_domain_on(void) @@ -72,8 +77,6 @@ void clock_init(void) { count = 0; - secs = 0; - second_countdown = CLOCK_SECOND; /* * Here, we configure GPT0 Timer A, which we subsequently use in @@ -120,33 +123,50 @@ clock_init(void) CCIF clock_time_t clock_time(void) { - return count; + return (clock_time_t)(count & 0xFFFFFFFF); } /*---------------------------------------------------------------------------*/ void clock_update(void) { - count++; + bool interrupts_disabled; + uint32_t aon_rtc_secs_now; + uint16_t aon_rtc_ticks_now; + + interrupts_disabled = ti_lib_int_master_disable(); + + aon_rtc_secs_now = HWREG(AON_RTC_BASE + AON_RTC_O_SEC); + aon_rtc_ticks_now = HWREG(AON_RTC_BASE + AON_RTC_O_SUBSEC) >> 16; + + /* Convert AON RTC ticks to clock tick counter */ + count = (aon_rtc_secs_now * CLOCK_SECOND) + (aon_rtc_ticks_now >> 9); + + /* Re-enable interrupts */ + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + if(etimer_pending()) { etimer_request_poll(); } - - if(--second_countdown == 0) { - secs++; - second_countdown = CLOCK_SECOND; - } -} -/*---------------------------------------------------------------------------*/ -void -clock_set_seconds(unsigned long sec) -{ - secs = sec; } /*---------------------------------------------------------------------------*/ CCIF unsigned long clock_seconds(void) { - return secs; + bool interrupts_disabled; + uint32_t secs_now; + + interrupts_disabled = ti_lib_int_master_disable(); + + secs_now = ti_lib_aon_rtc_sec_get(); + + /* Re-enable interrupts */ + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + return (unsigned long)secs_now; } /*---------------------------------------------------------------------------*/ void diff --git a/cpu/cc26xx/dbg.h b/cpu/cc26xx-cc13xx/dbg.h similarity index 93% rename from cpu/cc26xx/dbg.h rename to cpu/cc26xx-cc13xx/dbg.h index a5bff7513..9b28477f4 100644 --- a/cpu/cc26xx/dbg.h +++ b/cpu/cc26xx-cc13xx/dbg.h @@ -32,13 +32,13 @@ * \addtogroup cc26xx * @{ * - * \defgroup cc26xx-char-io CC26xx Character I/O + * \defgroup cc26xx-char-io CC13xx/CC26xx Character I/O * - * CC26xx CPU-specific functions for debugging and SLIP I/O + * CC13xx/CC26xx CPU-specific functions for debugging and SLIP I/O * @{ * * \file - * Header file for the CC26xx Debug I/O module + * Header file for the CC13xx/CC26xx Debug I/O module */ #ifndef DBG_H_ #define DBG_H_ diff --git a/cpu/cc26xx/debug-uart.h b/cpu/cc26xx-cc13xx/debug-uart.h similarity index 100% rename from cpu/cc26xx/debug-uart.h rename to cpu/cc26xx-cc13xx/debug-uart.h diff --git a/cpu/cc26xx/dev/batmon-sensor.c b/cpu/cc26xx-cc13xx/dev/batmon-sensor.c similarity index 98% rename from cpu/cc26xx/dev/batmon-sensor.c rename to cpu/cc26xx-cc13xx/dev/batmon-sensor.c index 3af7a578a..795b55dec 100644 --- a/cpu/cc26xx/dev/batmon-sensor.c +++ b/cpu/cc26xx-cc13xx/dev/batmon-sensor.c @@ -33,7 +33,7 @@ * @{ * * \file - * Driver for the CC26xx AON battery monitor + * Driver for the CC13xx/CC26xx AON battery monitor */ /*---------------------------------------------------------------------------*/ #include "contiki-conf.h" diff --git a/cpu/cc26xx/dev/batmon-sensor.h b/cpu/cc26xx-cc13xx/dev/batmon-sensor.h similarity index 95% rename from cpu/cc26xx/dev/batmon-sensor.h rename to cpu/cc26xx-cc13xx/dev/batmon-sensor.h index 12b0c6bbd..014e9a17d 100644 --- a/cpu/cc26xx/dev/batmon-sensor.h +++ b/cpu/cc26xx-cc13xx/dev/batmon-sensor.h @@ -32,13 +32,13 @@ * \addtogroup cc26xx * @{ * - * \defgroup cc26xx-batmon CC26xx BatMon sensor driver + * \defgroup cc26xx-batmon CC13xx/CC26xx BatMon sensor driver * * Driver for the on-chip battery voltage and chip temperature sensor. * @{ * * \file - * Header file for the CC26xx battery monitor + * Header file for the CC13xx/CC26xx battery monitor */ /*---------------------------------------------------------------------------*/ #ifndef BATMON_SENSOR_H_ diff --git a/cpu/cc26xx/dev/cc26xx-uart.c b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.c similarity index 97% rename from cpu/cc26xx/dev/cc26xx-uart.c rename to cpu/cc26xx-cc13xx/dev/cc26xx-uart.c index 5d6c5403d..d7753066f 100644 --- a/cpu/cc26xx/dev/cc26xx-uart.c +++ b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.c @@ -27,6 +27,15 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-uart + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx UART driver. + */ +/*---------------------------------------------------------------------------*/ #include "contiki-conf.h" #include "cc26xx-uart.h" #include "hw_types.h" @@ -41,6 +50,7 @@ #include #include +#include /*---------------------------------------------------------------------------*/ /* Which events to trigger a UART interrupt */ #define CC26XX_UART_RX_INTERRUPT_TRIGGERS (UART_INT_RX | UART_INT_RT) @@ -382,3 +392,5 @@ cc26xx_uart_isr(void) ENERGEST_OFF(ENERGEST_TYPE_IRQ); } +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx/dev/cc26xx-uart.h b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.h similarity index 96% rename from cpu/cc26xx/dev/cc26xx-uart.h rename to cpu/cc26xx-cc13xx/dev/cc26xx-uart.h index 8ff04502f..0e5a905c2 100644 --- a/cpu/cc26xx/dev/cc26xx-uart.h +++ b/cpu/cc26xx-cc13xx/dev/cc26xx-uart.h @@ -31,13 +31,13 @@ * \addtogroup cc26xx * @{ * - * \defgroup cc26xx-uart CC26xx UARTs + * \defgroup cc26xx-uart CC13xx/CC26xx UARTs * - * Driver for the CC26xx UART controller + * Driver for the CC13xx/CC26xx UART controller * @{ * * \file - * Header file for the CC26xx UART driver + * Header file for the CC13xx/CC26xx UART driver */ #ifndef CC26XX_UART_H_ #define CC26XX_UART_H_ diff --git a/cpu/cc26xx/dev/contiki-watchdog.c b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c similarity index 89% rename from cpu/cc26xx/dev/contiki-watchdog.c rename to cpu/cc26xx-cc13xx/dev/contiki-watchdog.c index 2c833c9d4..471c6f3cb 100644 --- a/cpu/cc26xx/dev/contiki-watchdog.c +++ b/cpu/cc26xx-cc13xx/dev/contiki-watchdog.c @@ -31,16 +31,16 @@ * \addtogroup cc26xx-clocks * @{ * - * \defgroup cc26xx-wdt CC26xx watchdog timer driver + * \defgroup cc26xx-wdt CC13xx/CC26xx watchdog timer driver * - * Driver for the CC26xx Watchdog Timer + * Driver for the CC13xx/CC26xx Watchdog Timer * * This file is not called watchdog.c because the filename is in use by - * TI CC26xxware + * TI CC26xxware/CC13xxware * @{ * * \file - * Implementation of the cc26xx watchdog driver. + * Implementation of the CC13xx/CC26xx watchdog driver. */ #include "watchdog.h" #include "ti-lib.h" @@ -75,14 +75,6 @@ watchdog_periodic(void) ti_lib_watchdog_int_clear(); } /*---------------------------------------------------------------------------*/ -/** - * \brief Stub function to satisfy API requirements - */ -void -watchdog_stop(void) -{ -} -/*---------------------------------------------------------------------------*/ /** * \brief Manually trigger a WDT reboot */ diff --git a/cpu/cc26xx/dev/gpio-interrupt.c b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.c similarity index 94% rename from cpu/cc26xx/dev/gpio-interrupt.c rename to cpu/cc26xx-cc13xx/dev/gpio-interrupt.c index a2c6dd42b..b080a5d3f 100644 --- a/cpu/cc26xx/dev/gpio-interrupt.c +++ b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.c @@ -28,6 +28,14 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ /*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-gpio-interrupts + * @{ + * + * \file + * Implementation of CC13xx/CC26xx GPIO interrupt handling. + */ +/*---------------------------------------------------------------------------*/ #include "ioc.h" #include "gpio-interrupt.h" #include "sys/energest.h" @@ -94,4 +102,4 @@ gpio_interrupt_isr(void) ENERGEST_OFF(ENERGEST_TYPE_IRQ); } /*---------------------------------------------------------------------------*/ - +/** @} */ diff --git a/cpu/cc26xx/dev/gpio-interrupt.h b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.h similarity index 90% rename from cpu/cc26xx/dev/gpio-interrupt.h rename to cpu/cc26xx-cc13xx/dev/gpio-interrupt.h index 6a64f26f6..1a993d3be 100644 --- a/cpu/cc26xx/dev/gpio-interrupt.h +++ b/cpu/cc26xx-cc13xx/dev/gpio-interrupt.h @@ -32,15 +32,15 @@ * \addtogroup cc26xx * @{ * - * \defgroup cc26xx-gpio-interrupts CC26xx GPIO interrupt handling + * \defgroup cc26xx-gpio-interrupts CC13xx/CC26xx GPIO interrupt handling * - * The CC26xx GPIO interrupt handler and an API which can be used by other - * parts of the code when they wish to be notified of a GPIO interrupt + * The CC13xx/CC26xx GPIO interrupt handler and an API which can be used by + * other parts of the code when they wish to be notified of a GPIO interrupt * * @{ * * \file - * Header file for the CC26xx GPIO interrupt management + * Header file for the CC13xx/CC26xx GPIO interrupt management */ /*---------------------------------------------------------------------------*/ #ifndef GPIO_INTERRUPT_H_ diff --git a/cpu/cc26xx/dev/oscillators.c b/cpu/cc26xx-cc13xx/dev/oscillators.c similarity index 99% rename from cpu/cc26xx/dev/oscillators.c rename to cpu/cc26xx-cc13xx/dev/oscillators.c index 06f97a92a..99ba8f841 100644 --- a/cpu/cc26xx/dev/oscillators.c +++ b/cpu/cc26xx-cc13xx/dev/oscillators.c @@ -166,7 +166,4 @@ oscillators_switch_to_hf_rc(void) osc_interface_dis(smph_clk_state); } /*---------------------------------------------------------------------------*/ -/** - * @} - * @} - */ +/** @} */ diff --git a/cpu/cc26xx/dev/oscillators.h b/cpu/cc26xx-cc13xx/dev/oscillators.h similarity index 94% rename from cpu/cc26xx/dev/oscillators.h rename to cpu/cc26xx-cc13xx/dev/oscillators.h index 2de1b5bb7..47e95a311 100644 --- a/cpu/cc26xx/dev/oscillators.h +++ b/cpu/cc26xx-cc13xx/dev/oscillators.h @@ -32,9 +32,9 @@ * \addtogroup cc26xx * @{ * - * \defgroup cc26xx-oscillators CC26XX oscillator control + * \defgroup cc26xx-oscillators CC13xx/CC26xx oscillator control * - * Wrapper around those CC26xxware OSC functions that we need in Contiki. + * Wrapper around CC26xxware/CC13xxware OSC functions that we need in Contiki. * * All CC26xxware OSC control requires access to the semaphore module within * AUX. Thus, in addition to enabling the oscillator interface, we need to @@ -43,7 +43,7 @@ * @{ * * \file - * Header file for the CC26XX oscillator control + * Header file for the CC13xx/CC26xx oscillator control */ /*---------------------------------------------------------------------------*/ #ifndef OSCILLATORS_H_ diff --git a/cpu/cc26xx/dev/cc26xx-rtc.c b/cpu/cc26xx-cc13xx/dev/soc-rtc.c similarity index 57% rename from cpu/cc26xx/dev/cc26xx-rtc.c rename to cpu/cc26xx-cc13xx/dev/soc-rtc.c index e9c01a7b5..16a967b9d 100644 --- a/cpu/cc26xx/dev/cc26xx-rtc.c +++ b/cpu/cc26xx-cc13xx/dev/soc-rtc.c @@ -27,15 +27,15 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*---------------------------------------------------------------------------*/ /** - * \addtogroup cc26xx-rtc + * \addtogroup cc13xx-cc26xx-rtc * @{ * - */ -/** * \file - * Implementation of the CC26xx AON RTC driver + * Implementation of the CC13xx/CC26xx AON RTC driver */ +/*---------------------------------------------------------------------------*/ #include "contiki.h" #include "sys/energest.h" #include "rtimer.h" @@ -46,16 +46,31 @@ #include #include /*---------------------------------------------------------------------------*/ -#define cc26xx_rtc_isr(...) AONRTCIntHandler(__VA_ARGS__) +#define soc_rtc_isr(...) AONRTCIntHandler(__VA_ARGS__) /*---------------------------------------------------------------------------*/ /* Prototype of a function in clock.c. Called every time the handler fires */ void clock_update(void); /*---------------------------------------------------------------------------*/ +#define COMPARE_INCREMENT (RTIMER_SECOND / CLOCK_SECOND) +#define MULTIPLE_512_MASK 0xFFFFFE00 +/*---------------------------------------------------------------------------*/ +/* + * Used to test timer wraparounds. + * + * Set to 0xFFFFFFFA to test AON RTC second counter wraparound + * Set to 0xFFFA to test AON RTC 16.16 format wraparound + */ +#ifdef SOC_RTC_CONF_START_TICK_COUNT +#define SOC_RTC_START_TICK_COUNT SOC_RTC_CONF_START_TICK_COUNT +#else +#define SOC_RTC_START_TICK_COUNT 0 +#endif +/*---------------------------------------------------------------------------*/ void -cc26xx_rtc_init(void) +soc_rtc_init(void) { - uint32_t compare_value; bool interrupts_disabled; + uint32_t next; /* Disable and clear interrupts */ interrupts_disabled = ti_lib_int_master_disable(); @@ -63,22 +78,22 @@ cc26xx_rtc_init(void) ti_lib_aon_rtc_disable(); ti_lib_aon_rtc_event_clear(AON_RTC_CH0); - ti_lib_aon_rtc_event_clear(AON_RTC_CH2); + ti_lib_aon_rtc_event_clear(AON_RTC_CH1); /* Setup the wakeup event */ - ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU0, AON_EVENT_RTC0); - ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU1, AON_EVENT_RTC2); - ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH2); + ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU0, AON_EVENT_RTC_CH0); + ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU1, AON_EVENT_RTC_CH1); + ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1); - /* Configure channel 2 in continuous compare, 128 ticks / sec */ - ti_lib_aon_rtc_inc_value_ch2_set(RTIMER_SECOND / CLOCK_SECOND); - ti_lib_aon_rtc_mode_ch2_set(AON_RTC_MODE_CH2_CONTINUOUS); - compare_value = (RTIMER_SECOND / CLOCK_SECOND) + - ti_lib_aon_rtc_current_compare_value_get(); - ti_lib_aon_rtc_compare_value_set(AON_RTC_CH2, compare_value); + HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = SOC_RTC_START_TICK_COUNT; - /* Enable channel 2 and the RTC */ - ti_lib_aon_rtc_channel_enable(AON_RTC_CH2); + next = ti_lib_aon_rtc_current_compare_value_get() + COMPARE_INCREMENT; + + /* Configure channel 1 to start generating clock ticks. First tick at 512 */ + ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next); + + /* Enable channel 1 and the RTC */ + ti_lib_aon_rtc_channel_enable(AON_RTC_CH1); ti_lib_aon_rtc_enable(); ti_lib_int_enable(INT_AON_RTC); @@ -90,41 +105,60 @@ cc26xx_rtc_init(void) } /*---------------------------------------------------------------------------*/ rtimer_clock_t -cc26xx_rtc_get_next_trigger() +soc_rtc_get_next_trigger() { - rtimer_clock_t ch2 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH2); + rtimer_clock_t ch1 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH1); if(HWREG(AON_RTC_BASE + AON_RTC_O_CHCTL) & AON_RTC_CHCTL_CH0_EN) { - rtimer_clock_t ch0 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH2); + rtimer_clock_t ch0 = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0); - return RTIMER_CLOCK_LT(ch0, ch2) ? ch0 : ch2; + return RTIMER_CLOCK_LT(ch0, ch1) ? ch0 : ch1; } - return ch2; + return ch1; } /*---------------------------------------------------------------------------*/ void -cc26xx_rtc_schedule_one_shot(uint32_t ticks) +soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks) { + if((channel != AON_RTC_CH0) && (channel != AON_RTC_CH1)) { + return; + } + /* Set the channel to fire a one-shot compare event at time==ticks */ - ti_lib_aon_rtc_compare_value_set(AON_RTC_CH0, ticks); - ti_lib_aon_rtc_channel_enable(AON_RTC_CH0); + ti_lib_aon_rtc_compare_value_set(channel, ticks); + ti_lib_aon_rtc_channel_enable(channel); } /*---------------------------------------------------------------------------*/ /* The AON RTC interrupt handler */ void -cc26xx_rtc_isr(void) +soc_rtc_isr(void) { + uint32_t now, next; + ENERGEST_ON(ENERGEST_TYPE_IRQ); - if(ti_lib_aon_rtc_event_get(AON_RTC_CH0)) { - ti_lib_aon_rtc_event_clear(AON_RTC_CH0); - rtimer_run_next(); + now = ti_lib_aon_rtc_current_compare_value_get(); + + /* Adjust the s/w tick counter irrespective of which event trigger this */ + clock_update(); + + if(ti_lib_aon_rtc_event_get(AON_RTC_CH1)) { + HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH1; + + /* + * We need to keep ticking while we are awake, so we schedule the next + * event on the next 512 tick boundary. If we drop to deep sleep before it + * happens, lpm_drop() will reschedule us in the 'distant' future + */ + next = (now + COMPARE_INCREMENT) & MULTIPLE_512_MASK; + ti_lib_aon_rtc_compare_value_set(AON_RTC_CH1, next); } - if(ti_lib_aon_rtc_event_get(AON_RTC_CH2)) { - ti_lib_aon_rtc_event_clear(AON_RTC_CH2); - clock_update(); + if(ti_lib_aon_rtc_event_get(AON_RTC_CH0)) { + ti_lib_aon_rtc_channel_disable(AON_RTC_CH0); + HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH0; + rtimer_run_next(); } ENERGEST_OFF(ENERGEST_TYPE_IRQ); diff --git a/cpu/cc26xx/dev/cc26xx-rtc.h b/cpu/cc26xx-cc13xx/dev/soc-rtc.h similarity index 72% rename from cpu/cc26xx/dev/cc26xx-rtc.h rename to cpu/cc26xx-cc13xx/dev/soc-rtc.h index 4fbaa1795..ff6a266ff 100644 --- a/cpu/cc26xx/dev/cc26xx-rtc.h +++ b/cpu/cc26xx-cc13xx/dev/soc-rtc.h @@ -31,34 +31,28 @@ * \addtogroup cc26xx * @{ * - * \defgroup cc26xx-clocks CC26xx clock and timer subsystem + * \defgroup cc26xx-clocks CC13xx/CC26xx clock and timer subsystem * - * For the CC26xx cpu we use the AON RTC as the basis for all clocks and timers + * For the CC13xx/CC26xx cpu we use the AON RTC as the basis for all clocks and + * timers * - * We configure the AON RTC's channel 2 to run in continuous mode, generating - * 128 interrupts / second. In continuous mode, the next compare event is - * scheduled by the hardware automatically; the events are equidistant and - * this also means we don't need the overhead of re-scheduling within the - * interrupt handler - * - * For rtimers, we use the RTC's channel 0 in one-shot compare mode. When the - * compare event fires, we call rtimer_run_next + * We use two of the aviable AON RTC channels. Channel 0 is used by the rtimer + * sub-system. Channel 1 is used by the system clock and the LPM module. * * The RTC runs in all power modes except 'shutdown' * - * \sa cpu/cc26xx/clock.c cpu/cc26xx/rtimer-arch.c * @{ * - * \defgroup cc26xx-rtc CC26xx AON RTC driver + * \defgroup cc13xx-cc26xx-rtc CC13xx/CC26xx AON RTC driver * * Underpins the platform's software clocks and timers * * @{ * \file - * Header file for the CC26XX AON RTC driver + * Header file for the CC13xx/CC26xx AON RTC driver */ -#ifndef CC26XX_RTC_H_ -#define CC26XX_RTC_H_ +#ifndef SOC_RTC_H_ +#define SOC_RTC_H_ /*---------------------------------------------------------------------------*/ #include "contiki.h" @@ -67,12 +61,13 @@ #include /*---------------------------------------------------------------------------*/ /** - * \brief Initialise the CC26XX AON RTC module + * \brief Initialise the CC13XX/CC26XX AON RTC module + * + * This timer configures AON RTC channels. * - * This timer configures the AON RTC's channel 2 to run in continuous mode * This function must be called before clock_init() and rtimer_init() */ -void cc26xx_rtc_init(void); +void soc_rtc_init(void); /** * \brief Return the time of the next scheduled rtimer event @@ -81,17 +76,24 @@ void cc26xx_rtc_init(void); * This function will check both AON RTC channels and will only take CH0's * compare into account if the channel is actually enabled */ -rtimer_clock_t cc26xx_rtc_get_next_trigger(void); +rtimer_clock_t soc_rtc_get_next_trigger(void); /** * \brief Schedule an AON RTC channel 0 one-shot compare event + * \param channel AON_RTC_CH0 or AON_RTC_CH1 * \param t The time when the event will be fired. This is an absolute * time, in other words the event will fire AT time \e t, * not IN \e t ticks + * + * Channel AON_RTC_CH0 is reserved for the rtimer. AON_RTC_CH1 is reserved + * for the system clock. + * + * User applications should not use this function. User applications should + * instead use Contiki's timer-related libraries */ -void cc26xx_rtc_schedule_one_shot(uint32_t t); +void soc_rtc_schedule_one_shot(uint32_t channel, uint32_t t); /*---------------------------------------------------------------------------*/ -#endif /* CC26XX_RTC_H_ */ +#endif /* SOC_RTC_H_ */ /*---------------------------------------------------------------------------*/ /** * @} diff --git a/cpu/cc26xx/dev/uart1.h b/cpu/cc26xx-cc13xx/dev/uart1.h similarity index 100% rename from cpu/cc26xx/dev/uart1.h rename to cpu/cc26xx-cc13xx/dev/uart1.h diff --git a/cpu/cc26xx/fault-handlers.c b/cpu/cc26xx-cc13xx/fault-handlers.c similarity index 100% rename from cpu/cc26xx/fault-handlers.c rename to cpu/cc26xx-cc13xx/fault-handlers.c diff --git a/cpu/cc26xx/ieee-addr.c b/cpu/cc26xx-cc13xx/ieee-addr.c similarity index 98% rename from cpu/cc26xx/ieee-addr.c rename to cpu/cc26xx-cc13xx/ieee-addr.c index 1d70aff18..6f7e9a296 100644 --- a/cpu/cc26xx/ieee-addr.c +++ b/cpu/cc26xx-cc13xx/ieee-addr.c @@ -34,7 +34,7 @@ * @{ * * \file - * Driver for the CC26xx IEEE addresses + * Driver for the CC13xx/CC26xx IEEE addresses */ /*---------------------------------------------------------------------------*/ #include "contiki-conf.h" diff --git a/cpu/cc26xx/ieee-addr.h b/cpu/cc26xx-cc13xx/ieee-addr.h similarity index 98% rename from cpu/cc26xx/ieee-addr.h rename to cpu/cc26xx-cc13xx/ieee-addr.h index 3cd97d72a..582854d49 100644 --- a/cpu/cc26xx/ieee-addr.h +++ b/cpu/cc26xx-cc13xx/ieee-addr.h @@ -33,7 +33,7 @@ * \addtogroup cc26xx * @{ * - * \defgroup cc26xx-ieee-addr CC26xx IEEE Address Control + * \defgroup cc26xx-ieee-addr CC13xx/CC26xx IEEE Address Control * * Driver for the retrieval of an IEEE address from flash * diff --git a/cpu/cc26xx-cc13xx/lib/cc13xxware b/cpu/cc26xx-cc13xx/lib/cc13xxware new file mode 160000 index 000000000..63ed52888 --- /dev/null +++ b/cpu/cc26xx-cc13xx/lib/cc13xxware @@ -0,0 +1 @@ +Subproject commit 63ed52888467ea7d403b0c743852162395232c9e diff --git a/cpu/cc26xx-cc13xx/lib/cc26xxware b/cpu/cc26xx-cc13xx/lib/cc26xxware new file mode 160000 index 000000000..0e82b18bf --- /dev/null +++ b/cpu/cc26xx-cc13xx/lib/cc26xxware @@ -0,0 +1 @@ +Subproject commit 0e82b18bf2c69fb0a40af4d2496db2a3dc721cec diff --git a/cpu/cc26xx/lpm.c b/cpu/cc26xx-cc13xx/lpm.c similarity index 91% rename from cpu/cc26xx/lpm.c rename to cpu/cc26xx-cc13xx/lpm.c index a0d633472..2f7b964f8 100644 --- a/cpu/cc26xx/lpm.c +++ b/cpu/cc26xx-cc13xx/lpm.c @@ -32,12 +32,12 @@ * \addtogroup cc26xx-lpm * @{ * - * Implementation of CC26xx low-power operation functionality + * Implementation of CC13xx/CC26xx low-power operation functionality * * @{ * * \file - * Driver for CC26xx's low-power operation + * Driver for CC13xx/CC26xx low-power operation */ /*---------------------------------------------------------------------------*/ #include "prcm.h" @@ -48,8 +48,11 @@ #include "lib/list.h" #include "dev/leds.h" #include "dev/watchdog.h" -#include "dev/cc26xx-rtc.h" +#include "dev/soc-rtc.h" #include "dev/oscillators.h" + +#include +#include /*---------------------------------------------------------------------------*/ #if ENERGEST_CONF_ON static unsigned long irq_energest = 0; @@ -72,7 +75,10 @@ LIST(modules_list); * Don't consider standby mode if the next AON RTC event is scheduled to fire * in less than STANDBY_MIN_DURATION rtimer ticks */ -#define STANDBY_MIN_DURATION (RTIMER_SECOND >> 8) +#define STANDBY_MIN_DURATION (RTIMER_SECOND >> 11) +/*---------------------------------------------------------------------------*/ +/* Prototype of a function in clock.c. Called every time we come out of DS */ +void clock_update(void); /*---------------------------------------------------------------------------*/ void lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on) @@ -93,10 +99,10 @@ lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on) /* Reset AON even fabric to default wakeup sources */ for(i = AON_EVENT_MCU_WU0; i <= AON_EVENT_MCU_WU3; i++) { - ti_lib_aon_event_mcu_wake_up_set(i, AON_EVENT_NULL); + ti_lib_aon_event_mcu_wake_up_set(i, AON_EVENT_NONE); } for(i = AON_EVENT_AUX_WU0; i <= AON_EVENT_AUX_WU2; i++) { - ti_lib_aon_event_aux_wake_up_set(i, AON_EVENT_NULL); + ti_lib_aon_event_aux_wake_up_set(i, AON_EVENT_NONE); } ti_lib_sys_ctrl_aon_sync(); @@ -222,6 +228,14 @@ wake_up(void) /* Check operating conditions, optimally choose DCDC versus GLDO */ ti_lib_sys_ctrl_dcdc_voltage_conditional_control(); + /* + * We may or may not have been woken up by an AON RTC tick. If not, we need + * to adjust our software tick counter + */ + clock_update(); + + watchdog_periodic(); + /* Notify all registered modules that we've just woken up */ for(module = list_head(modules_list); module != NULL; module = module->next) { @@ -237,10 +251,11 @@ lpm_drop() lpm_registered_module_t *module; uint8_t max_pm = LPM_MODE_MAX_SUPPORTED; uint8_t module_pm; + clock_time_t next_event; uint32_t domains = LOCKABLE_DOMAINS; - if(RTIMER_CLOCK_LT(cc26xx_rtc_get_next_trigger(), + if(RTIMER_CLOCK_LT(soc_rtc_get_next_trigger(), RTIMER_NOW() + STANDBY_MIN_DURATION)) { lpm_sleep(); return; @@ -269,6 +284,18 @@ lpm_drop() /* Critical. Don't get interrupted! */ ti_lib_int_master_disable(); + /* + * Reschedule AON RTC CH1 to fire an event N ticks before the next etimer + * event + */ + next_event = etimer_next_expiration_time(); + + if(next_event) { + next_event = next_event - clock_time(); + soc_rtc_schedule_one_shot(AON_RTC_CH1, RTIMER_NOW() + + (next_event * (RTIMER_SECOND / CLOCK_SECOND))); + } + /* * Notify all registered modules that we are dropping to mode X. We do not * need to do this for simple sleep. @@ -357,7 +384,7 @@ lpm_drop() while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON); /* Configure the recharge controller */ - ti_lib_sys_ctrl_set_recharge_before_power_down(false); + ti_lib_sys_ctrl_set_recharge_before_power_down(XOSC_IN_HIGH_POWER_MODE); /* * If both PERIPH and SERIAL PDs are off, request the uLDO as the power @@ -436,6 +463,9 @@ void lpm_init() { list_init(modules_list); + + /* Always wake up on any DIO edge detection */ + ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU2, AON_EVENT_IO); } /*---------------------------------------------------------------------------*/ void diff --git a/cpu/cc26xx/lpm.h b/cpu/cc26xx-cc13xx/lpm.h similarity index 97% rename from cpu/cc26xx/lpm.h rename to cpu/cc26xx-cc13xx/lpm.h index 8b701baff..cc144809b 100644 --- a/cpu/cc26xx/lpm.h +++ b/cpu/cc26xx-cc13xx/lpm.h @@ -32,14 +32,14 @@ * \addtogroup cc26xx * @{ * - * \defgroup cc26xx-lpm CC26xx Low-Power management + * \defgroup cc26xx-lpm CC13xx/CC26xx Low-Power management * - * CC26xx low-power operation + * CC13xx/CC26xx low-power operation * * @{ * * \file - * Header file for the management of CC26xx low-power operation + * Header file for the management of CC13xx/CC26xx low-power operation */ /*---------------------------------------------------------------------------*/ #ifndef LPM_H_ diff --git a/cpu/cc26xx/mtarch.h b/cpu/cc26xx-cc13xx/mtarch.h similarity index 100% rename from cpu/cc26xx/mtarch.h rename to cpu/cc26xx-cc13xx/mtarch.h diff --git a/cpu/cc26xx/putchar.c b/cpu/cc26xx-cc13xx/putchar.c similarity index 100% rename from cpu/cc26xx/putchar.c rename to cpu/cc26xx-cc13xx/putchar.c diff --git a/cpu/cc26xx/dev/rfc-api/ble_cmd.h b/cpu/cc26xx-cc13xx/rf-core/api/ble_cmd.h similarity index 98% rename from cpu/cc26xx/dev/rfc-api/ble_cmd.h rename to cpu/cc26xx-cc13xx/rf-core/api/ble_cmd.h index f7320fe4d..01324401f 100644 --- a/cpu/cc26xx/dev/rfc-api/ble_cmd.h +++ b/cpu/cc26xx-cc13xx/rf-core/api/ble_cmd.h @@ -1,1082 +1,1081 @@ -/****************************************************************************** -* Filename: ble_cmd.h -* Revised: $ $ -* Revision: $ $ -* -* Description: CC26xx/CC13xx API for Bluetooth Low Energy commands -* -* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -******************************************************************************/ - -#ifndef __BLE_CMD_H -#define __BLE_CMD_H - -#ifndef __RFC_STRUCT -#ifdef __GNUC__ -#define __RFC_STRUCT __attribute__ ((aligned (4))) -#else -#define __RFC_STRUCT -#endif -#endif - -//! \addtogroup rfc -//! @{ - -//! \addtogroup ble_cmd -//! @{ - -#include -#include "mailbox.h" -#include "common_cmd.h" - -typedef struct __RFC_STRUCT rfc_bleMasterPar_s rfc_bleMasterPar_t; -typedef struct __RFC_STRUCT rfc_bleMasterSlavePar_s rfc_bleMasterSlavePar_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_INITIATOR_s rfc_CMD_BLE_INITIATOR_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_TX_TEST_s rfc_CMD_BLE_TX_TEST_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_MASTER_s rfc_CMD_BLE_MASTER_t; -typedef struct __RFC_STRUCT rfc_bleWhiteListEntry_s rfc_bleWhiteListEntry_t; -typedef struct __RFC_STRUCT rfc_bleGenericRxPar_s rfc_bleGenericRxPar_t; -typedef struct __RFC_STRUCT rfc_bleTxTestPar_s rfc_bleTxTestPar_t; -typedef struct __RFC_STRUCT rfc_bleInitiatorOutput_s rfc_bleInitiatorOutput_t; -typedef struct __RFC_STRUCT rfc_bleWhiteListEntryWords_s rfc_bleWhiteListEntryWords_t; -typedef struct __RFC_STRUCT rfc_bleMasterSlaveOutput_s rfc_bleMasterSlaveOutput_t; -typedef struct __RFC_STRUCT rfc_bleRxStatus_s rfc_bleRxStatus_t; -typedef struct __RFC_STRUCT rfc_bleRadioOp_s rfc_bleRadioOp_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_NC_s rfc_CMD_BLE_ADV_NC_t; -typedef struct __RFC_STRUCT rfc_bleTxTestOutput_s rfc_bleTxTestOutput_t; -typedef struct __RFC_STRUCT rfc_bleAdvPar_s rfc_bleAdvPar_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_SCAN_s rfc_CMD_BLE_ADV_SCAN_t; -typedef struct __RFC_STRUCT rfc_bleAdvOutput_s rfc_bleAdvOutput_t; -typedef struct __RFC_STRUCT rfc_bleScannerOutput_s rfc_bleScannerOutput_t; -typedef struct __RFC_STRUCT rfc_bleSlavePar_s rfc_bleSlavePar_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_DIR_s rfc_CMD_BLE_ADV_DIR_t; -typedef struct __RFC_STRUCT rfc_bleInitiatorPar_s rfc_bleInitiatorPar_t; -typedef struct __RFC_STRUCT rfc_bleScannerPar_s rfc_bleScannerPar_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_SLAVE_s rfc_CMD_BLE_SLAVE_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_s rfc_CMD_BLE_ADV_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_SCANNER_s rfc_CMD_BLE_SCANNER_t; -typedef struct __RFC_STRUCT rfc_bleGenericRxOutput_s rfc_bleGenericRxOutput_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_GENERIC_RX_s rfc_CMD_BLE_GENERIC_RX_t; -typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_PAYLOAD_s rfc_CMD_BLE_ADV_PAYLOAD_t; - -//! \addtogroup bleRadioOp -//! @{ -struct __RFC_STRUCT rfc_bleRadioOp_s { - uint16_t commandNo; //!< The command ID number - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - uint8_t* pParams; //!< Pointer to command specific parameter structure - uint8_t* pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_SLAVE -//! @{ -#define CMD_BLE_SLAVE 0x1801 -struct __RFC_STRUCT rfc_CMD_BLE_SLAVE_s { - uint16_t commandNo; //!< The command ID number 0x1801 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleSlavePar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleMasterSlaveOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_MASTER -//! @{ -#define CMD_BLE_MASTER 0x1802 -struct __RFC_STRUCT rfc_CMD_BLE_MASTER_s { - uint16_t commandNo; //!< The command ID number 0x1802 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleMasterPar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleMasterSlaveOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_ADV -//! @{ -#define CMD_BLE_ADV 0x1803 -struct __RFC_STRUCT rfc_CMD_BLE_ADV_s { - uint16_t commandNo; //!< The command ID number 0x1803 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_ADV_DIR -//! @{ -#define CMD_BLE_ADV_DIR 0x1804 -struct __RFC_STRUCT rfc_CMD_BLE_ADV_DIR_s { - uint16_t commandNo; //!< The command ID number 0x1804 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_ADV_NC -//! @{ -#define CMD_BLE_ADV_NC 0x1805 -struct __RFC_STRUCT rfc_CMD_BLE_ADV_NC_s { - uint16_t commandNo; //!< The command ID number 0x1805 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_ADV_SCAN -//! @{ -#define CMD_BLE_ADV_SCAN 0x1806 -struct __RFC_STRUCT rfc_CMD_BLE_ADV_SCAN_s { - uint16_t commandNo; //!< The command ID number 0x1806 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_SCANNER -//! @{ -#define CMD_BLE_SCANNER 0x1807 -struct __RFC_STRUCT rfc_CMD_BLE_SCANNER_s { - uint16_t commandNo; //!< The command ID number 0x1807 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleScannerPar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleScannerOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_INITIATOR -//! @{ -#define CMD_BLE_INITIATOR 0x1808 -struct __RFC_STRUCT rfc_CMD_BLE_INITIATOR_s { - uint16_t commandNo; //!< The command ID number 0x1808 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleInitiatorPar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleInitiatorOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_GENERIC_RX -//! @{ -#define CMD_BLE_GENERIC_RX 0x1809 -struct __RFC_STRUCT rfc_CMD_BLE_GENERIC_RX_s { - uint16_t commandNo; //!< The command ID number 0x1809 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleGenericRxPar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleGenericRxOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_TX_TEST -//! @{ -#define CMD_BLE_TX_TEST 0x180A -struct __RFC_STRUCT rfc_CMD_BLE_TX_TEST_s { - uint16_t commandNo; //!< The command ID number 0x180A - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to use
- //!< 0–39: BLE advertising/data channel number - //!< 60–207: Custom frequency; (2300 + channel) MHz - //!< 255: Use existing frequency - //!< Others: Reserved - struct { - uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
- //!< 0: Do not use whitening
- //!< Other value: Initialization for 7-bit LFSR whitener - uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
- //!< 1: Override whitening initialization with value of init - } whitening; - rfc_bleTxTestPar_t *pParams; //!< Pointer to command specific parameter structure - rfc_bleTxTestOutput_t *pOutput; //!< Pointer to command specific output structure -}; - -//! @} - -//! \addtogroup CMD_BLE_ADV_PAYLOAD -//! @{ -#define CMD_BLE_ADV_PAYLOAD 0x1001 -struct __RFC_STRUCT rfc_CMD_BLE_ADV_PAYLOAD_s { - uint16_t commandNo; //!< The command ID number 0x1001 - uint8_t payloadType; //!< \brief 0: Advertising data
- //!< 1: Scan response data - uint8_t newLen; //!< Length of the new payload - uint8_t* pNewData; //!< Pointer to the buffer containing the new data - rfc_bleAdvPar_t *pParams; //!< Pointer to the parameter structure to update -}; - -//! @} - -//! \addtogroup bleMasterSlavePar -//! @{ -struct __RFC_STRUCT rfc_bleMasterSlavePar_s { - dataQueue_t* pRxQ; //!< Pointer to receive queue - dataQueue_t* pTxQ; //!< Pointer to transmit queue - struct { - uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue - uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue - uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue - uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it - uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it - uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue - uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue - uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue - } rxConfig; //!< Configuration bits for the receive queue entries - struct { - uint8_t lastRxSn:1; //!< The SN bit of the header of the last packet received with CRC OK - uint8_t lastTxSn:1; //!< The SN bit of the header of the last transmitted packet - uint8_t nextTxSn:1; //!< The SN bit of the header of the next packet to transmit - uint8_t bFirstPkt:1; //!< For slave: 0 if a packet has been transmitted on the connection, 1 otherwise - uint8_t bAutoEmpty:1; //!< 1 if the last transmitted packet was an auto-empty packet - uint8_t bLlCtrlTx:1; //!< 1 if the last transmitted packet was an LL control packet (LLID = 11) - uint8_t bLlCtrlAckRx:1; //!< 1 if the last received packet was the ACK of an LL control packet - uint8_t bLlCtrlAckPending:1; //!< 1 if the last successfully received packet was an LL control packet which has not yet been ACK'ed - } seqStat; - uint8_t maxNack; //!< Maximum number of NACKs received before operation ends. 0: No limit - uint8_t maxPkt; //!< Maximum number of packets transmitted in the operation before it ends. 0: No limit - uint32_t accessAddress; //!< Access address used on the connection - uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte - uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte - uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte -}; - -//! @} - -//! \addtogroup bleMasterPar -//! @{ -//! Parameter structure for master (CMD_BLE_MASTER) - -struct __RFC_STRUCT rfc_bleMasterPar_s { - dataQueue_t* pRxQ; //!< Pointer to receive queue - dataQueue_t* pTxQ; //!< Pointer to transmit queue - struct { - uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue - uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue - uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue - uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it - uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it - uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue - uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue - uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue - } rxConfig; //!< Configuration bits for the receive queue entries - struct { - uint8_t lastRxSn:1; //!< The SN bit of the header of the last packet received with CRC OK - uint8_t lastTxSn:1; //!< The SN bit of the header of the last transmitted packet - uint8_t nextTxSn:1; //!< The SN bit of the header of the next packet to transmit - uint8_t bFirstPkt:1; //!< For slave: 0 if a packet has been transmitted on the connection, 1 otherwise - uint8_t bAutoEmpty:1; //!< 1 if the last transmitted packet was an auto-empty packet - uint8_t bLlCtrlTx:1; //!< 1 if the last transmitted packet was an LL control packet (LLID = 11) - uint8_t bLlCtrlAckRx:1; //!< 1 if the last received packet was the ACK of an LL control packet - uint8_t bLlCtrlAckPending:1; //!< 1 if the last successfully received packet was an LL control packet which has not yet been ACK'ed - } seqStat; - uint8_t maxNack; //!< Maximum number of NACKs received before operation ends. 0: No limit - uint8_t maxPkt; //!< Maximum number of packets transmitted in the operation before it ends. 0: No limit - uint32_t accessAddress; //!< Access address used on the connection - uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte - uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte - uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to end the connection event as soon as allowed - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the - //!< connection event as soon as allowed -}; - -//! @} - -//! \addtogroup bleSlavePar -//! @{ -//! Parameter structure for slave (CMD_BLE_SLAVE) - -struct __RFC_STRUCT rfc_bleSlavePar_s { - dataQueue_t* pRxQ; //!< Pointer to receive queue - dataQueue_t* pTxQ; //!< Pointer to transmit queue - struct { - uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue - uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue - uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue - uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it - uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it - uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue - uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue - uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue - } rxConfig; //!< Configuration bits for the receive queue entries - struct { - uint8_t lastRxSn:1; //!< The SN bit of the header of the last packet received with CRC OK - uint8_t lastTxSn:1; //!< The SN bit of the header of the last transmitted packet - uint8_t nextTxSn:1; //!< The SN bit of the header of the next packet to transmit - uint8_t bFirstPkt:1; //!< For slave: 0 if a packet has been transmitted on the connection, 1 otherwise - uint8_t bAutoEmpty:1; //!< 1 if the last transmitted packet was an auto-empty packet - uint8_t bLlCtrlTx:1; //!< 1 if the last transmitted packet was an LL control packet (LLID = 11) - uint8_t bLlCtrlAckRx:1; //!< 1 if the last received packet was the ACK of an LL control packet - uint8_t bLlCtrlAckPending:1; //!< 1 if the last successfully received packet was an LL control packet which has not yet been ACK'ed - } seqStat; - uint8_t maxNack; //!< Maximum number of NACKs received before operation ends. 0: No limit - uint8_t maxPkt; //!< Maximum number of packets transmitted in the operation before it ends. 0: No limit - uint32_t accessAddress; //!< Access address used on the connection - uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte - uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte - uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } timeoutTrigger; //!< Trigger that defines timeout of the first receive operation - ratmr_t timeoutTime; //!< \brief Time used together with timeoutTrigger that defines timeout of the first - //!< receive operation - uint16_t __dummy0; - uint8_t __dummy1; - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to end the connection event as soon as allowed - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the - //!< connection event as soon as allowed -}; - -//! @} - -//! \addtogroup bleAdvPar -//! @{ -//! Parameter structure for advertiser (CMD_BLE_ADV*) - -struct __RFC_STRUCT rfc_bleAdvPar_s { - dataQueue_t* pRxQ; //!< Pointer to receive queue - struct { - uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue - uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue - uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue - uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it - uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it - uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue - uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue - uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue - } rxConfig; //!< Configuration bits for the receive queue entries - struct { - uint8_t advFilterPolicy:2; //!< \brief The advertiser filter policy, as defined in Volume 2, Part E, Section 7.8.5 of - //!< the Bluetooth 4.0 spec - uint8_t deviceAddrType:1; //!< The type of the device address – public (0) or random (1) - uint8_t peerAddrType:1; //!< Directed advertiser: The type of the peer address – public (0) or random (1) - uint8_t bStrictLenFilter:1; //!< 1: Discard messages with illegal length - } advConfig; - uint8_t advLen; //!< Size of advertiser data - uint8_t scanRspLen; //!< Size of scan response data - uint8_t* pAdvData; //!< Pointer to buffer containing ADV*_IND data - uint8_t* pScanRspData; //!< Pointer to buffer containing SCAN_RSP data - uint16_t* pDeviceAddress; //!< Pointer to device address used for this device - rfc_bleWhiteListEntry_t *pWhiteList; //!< Pointer to white list or peer address (directed advertiser) - uint16_t __dummy0; - uint8_t __dummy1; - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to end the advertiser event as soon as allowed - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the - //!< advertiser event as soon as allowed -}; - -//! @} - -//! \addtogroup bleScannerPar -//! @{ -//! Parameter structure for scanner (CMD_BLE_SCANNER) - -struct __RFC_STRUCT rfc_bleScannerPar_s { - dataQueue_t* pRxQ; //!< Pointer to receive queue - struct { - uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue - uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue - uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue - uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it - uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it - uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue - uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue - uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue - } rxConfig; //!< Configuration bits for the receive queue entries - struct { - uint8_t scanFilterPolicy:1; //!< \brief The advertiser filter policy, as defined in Volume 2, Part E, Section 7.8.10 of - //!< the Bluetooth 4.0 spec - uint8_t bActiveScan:1; //!< \brief 0: Passive scan
- //!< 1: Active scan - uint8_t deviceAddrType:1; //!< The type of the device address – public (0) or random (1) - uint8_t :1; - uint8_t bStrictLenFilter:1; //!< 1: Discard messages with illegal length - uint8_t bAutoWlIgnore:1; //!< 1: Automatically set ignore bit in white list - uint8_t bEndOnRpt:1; //!< 1: End scanner operation after each reported ADV*_IND and potentially SCAN_RSP - } scanConfig; - uint16_t randomState; //!< State for pseudo-random number generation used in backoff procedure - uint16_t backoffCount; //!< Parameter backoffCount used in backoff procedure, cf. Bluetooth 4.0 spec - struct { - uint8_t logUpperLimit:4; //!< Binary logarithm of parameter upperLimit used in scanner backoff procedure - uint8_t bLastSucceeded:1; //!< \brief 1 if the last SCAN_RSP was successfully received and upperLimit - //!< not changed - uint8_t bLastFailed:1; //!< \brief 1 if reception of the last SCAN_RSP failed and upperLimit was not - //!< changed - } backoffPar; - uint8_t scanReqLen; //!< Size of scan request data - uint8_t* pScanReqData; //!< Pointer to buffer containing SCAN_REQ data - uint16_t* pDeviceAddress; //!< Pointer to device address used for this device - rfc_bleWhiteListEntry_t *pWhiteList; //!< Pointer to white list - uint16_t __dummy0; - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } timeoutTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed - ratmr_t timeoutTime; //!< \brief Time used together with timeoutTrigger that causes the device to stop - //!< receiving as soon as allowed, ending with BLE_DONE_RXTIMEOUT - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to stop - //!< receiving as soon as allowed, ending with BLE_DONE_ENDED -}; - -//! @} - -//! \addtogroup bleInitiatorPar -//! @{ -//! Parameter structure for initiator (CMD_BLE_INITIATOR) - -struct __RFC_STRUCT rfc_bleInitiatorPar_s { - dataQueue_t* pRxQ; //!< Pointer to receive queue - struct { - uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue - uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue - uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue - uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it - uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it - uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue - uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue - uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue - } rxConfig; //!< Configuration bits for the receive queue entries - struct { - uint8_t bUseWhiteList:1; //!< \brief Initiator filter policy, cf. Volume 2, Part E, Section 7.8.10 of the - //!< Bluetooth 4.0 spec:
- //!< 0: Use specific peer address
- //!< 1: Use white list - uint8_t bDynamicWinOffset:1; //!< 1: Use dynamic WinOffset insertion - uint8_t deviceAddrType:1; //!< The type of the device address – public (0) or random (1) - uint8_t peerAddrType:1; //!< The type of the peer address – public (0) or random (1) - uint8_t bStrictLenFilter:1; //!< 1: Discard messages with illegal length - } initConfig; - uint8_t __dummy0; - uint8_t connectReqLen; //!< Size of connect request data - uint8_t* pConnectReqData; //!< Pointer to buffer containing LLData to go in the CONNECT_REQ - uint16_t* pDeviceAddress; //!< Pointer to device address used for this device - rfc_bleWhiteListEntry_t *pWhiteList; //!< Pointer to white list or peer address - ratmr_t connectTime; //!< \brief Indication of timer value of the first possible start time of the first connection event. - //!< Set to the calculated value if a connection is made and to the next possible connection - //!< time if not. - uint16_t __dummy1; - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } timeoutTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed - ratmr_t timeoutTime; //!< \brief Time used together with timeoutTrigger that causes the device to stop - //!< receiving as soon as allowed, ending with BLE_DONE_RXTIMEOUT - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to stop - //!< receiving as soon as allowed, ending with BLE_DONE_ENDED -}; - -//! @} - -//! \addtogroup bleGenericRxPar -//! @{ -//! Parameter structure for generic Rx (CMD_BLE_GENERIC_RX) - -struct __RFC_STRUCT rfc_bleGenericRxPar_s { - dataQueue_t* pRxQ; //!< Pointer to receive queue. May be NULL; if so, received packets are not stored - struct { - uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue - uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue - uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue - uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it - uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it - uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue - uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue - uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue - } rxConfig; //!< Configuration bits for the receive queue entries - uint8_t bRepeat; //!< \brief 0: End operation after receiving a packet
- //!< 1: Restart receiver after receiving a packet - uint16_t __dummy0; - uint32_t accessAddress; //!< Access address used on the connection - uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte - uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte - uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to end the Rx operation - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the - //!< Rx operation -}; - -//! @} - -//! \addtogroup bleTxTestPar -//! @{ -//! Parameter structure for Tx test (CMD_BLE_TX_TEST) - -struct __RFC_STRUCT rfc_bleTxTestPar_s { - uint16_t numPackets; //!< \brief Number of packets to transmit
- //!< 0: Transmit unlimited number of packets - uint8_t payloadLength; //!< The number of payload bytes in each packet. - uint8_t packetType; //!< \brief The packet type to be used, encoded according to the Bluetooth 4.0 spec, Volume 2, Part E, - //!< Section 7.8.29 - ratmr_t period; //!< Number of radio timer cycles between the start of each packet - struct { - uint8_t bOverrideDefault:1; //!< \brief 0: Use default packet encoding
- //!< 1: Override packet contents - uint8_t bUsePrbs9:1; //!< \brief If bOverride is 1:
- //!< 1: Use PRBS9 encoding of packet - uint8_t bUsePrbs15:1; //!< \brief If bOverride is 1:
- //!< 1: Use PRBS15 encoding of packet - } config; - uint8_t byteVal; //!< If config.bOverride is 1, value of each byte to be sent - uint8_t __dummy0; - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to end the Test Tx operation - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the - //!< Test Tx operation -}; - -//! @} - -//! \addtogroup bleMasterSlaveOutput -//! @{ -//! Output structure for master and slave (CMD_BLE_MASTER/CMD_BLE_SLAVE) - -struct __RFC_STRUCT rfc_bleMasterSlaveOutput_s { - uint8_t nTx; //!< \brief Total number of packets (including auto-empty and retransmissions) that have been - //!< transmitted - uint8_t nTxAck; //!< Total number of transmitted packets (including auto-empty) that have been ACK'ed - uint8_t nTxCtrl; //!< Number of unique LL control packets from the Tx queue that have been transmitted - uint8_t nTxCtrlAck; //!< Number of LL control packets from the Tx queue that have been finished (ACK'ed) - uint8_t nTxCtrlAckAck; //!< \brief Number of LL control packets that have been ACK'ed and where an ACK has been sent in - //!< response - uint8_t nTxRetrans; //!< Number of retransmissions that has been done - uint8_t nTxEntryDone; //!< Number of packets from the Tx queue that have been finished (ACK'ed) - uint8_t nRxOk; //!< Number of packets that have been received with payload, CRC OK and not ignored - uint8_t nRxCtrl; //!< Number of LL control packets that have been received with CRC OK and not ignored - uint8_t nRxCtrlAck; //!< \brief Number of LL control packets that have been received with CRC OK and not ignored, and - //!< then ACK'ed - uint8_t nRxNok; //!< Number of packets that have been received with CRC error - uint8_t nRxIgnored; //!< \brief Number of packets that have been received with CRC OK and ignored due to repeated - //!< sequence number - uint8_t nRxEmpty; //!< Number of packets that have been received with CRC OK and no payload - uint8_t nRxBufFull; //!< Number of packets that have been received and discarded due to lack of buffer space - int8_t lastRssi; //!< RSSI of last received packet - struct { - uint8_t bTimeStampValid:1; //!< 1 if a valid time stamp has been written to timeStamp; 0 otherwise - uint8_t bLastCrcErr:1; //!< 1 if the last received packet had CRC error; 0 otherwise - uint8_t bLastIgnored:1; //!< 1 if the last received packet with CRC OK was ignored; 0 otherwise - uint8_t bLastEmpty:1; //!< 1 if the last received packet with CRC OK was empty; 0 otherwise - uint8_t bLastCtrl:1; //!< 1 if the last received packet with CRC OK was empty; 0 otherwise - uint8_t bLastMd:1; //!< 1 if the last received packet with CRC OK had MD = 1; 0 otherwise - uint8_t bLastAck:1; //!< \brief 1 if the last received packet with CRC OK was an ACK of a transmitted packet; - //!< 0 otherwise - } pktStatus; - ratmr_t timeStamp; //!< Slave operation: Time stamp of first received packet -}; - -//! @} - -//! \addtogroup bleAdvOutput -//! @{ -//! Output structure for advertiser (CMD_BLE_ADV*) - -struct __RFC_STRUCT rfc_bleAdvOutput_s { - uint16_t nTxAdvInd; //!< Number of ADV*_IND packets completely transmitted - uint8_t nTxScanRsp; //!< Number of SCAN_RSP packets transmitted - uint8_t nRxScanReq; //!< Number of SCAN_REQ packets received OK and not ignored - uint8_t nRxConnectReq; //!< Number of CONNECT_REQ packets received OK and not ignored - uint8_t __dummy0; - uint16_t nRxNok; //!< Number of packets received with CRC error - uint16_t nRxIgnored; //!< Number of packets received with CRC OK, but ignored - uint8_t nRxBufFull; //!< Number of packets received that did not fit in Rx queue - int8_t lastRssi; //!< The RSSI of the last received packet - ratmr_t timeStamp; //!< Time stamp of the last received packet -}; - -//! @} - -//! \addtogroup bleScannerOutput -//! @{ -//! Output structure for scanner (CMD_BLE_SCANNER) - -struct __RFC_STRUCT rfc_bleScannerOutput_s { - uint16_t nTxScanReq; //!< Number of transmitted SCAN_REQ packets - uint16_t nBackedOffScanReq; //!< Number of SCAN_REQ packets not sent due to backoff procedure - uint16_t nRxAdvOk; //!< Number of ADV*_IND packets received with CRC OK and not ignored - uint16_t nRxAdvIgnored; //!< Number of ADV*_IND packets received with CRC OK, but ignored - uint16_t nRxAdvNok; //!< Number of ADV*_IND packets received with CRC error - uint16_t nRxScanRspOk; //!< Number of SCAN_RSP packets received with CRC OK and not ignored - uint16_t nRxScanRspIgnored; //!< Number of SCAN_RSP packets received with CRC OK, but ignored - uint16_t nRxScanRspNok; //!< Number of SCAN_RSP packets received with CRC error - uint8_t nRxAdvBufFull; //!< Number of ADV*_IND packets received that did not fit in Rx queue - uint8_t nRxScanRspBufFull; //!< Number of SCAN_RSP packets received that did not fit in Rx queue - int8_t lastRssi; //!< The RSSI of the last received packet - uint8_t __dummy0; - ratmr_t timeStamp; //!< Time stamp of the last successfully received ADV*_IND packet that was not ignored -}; - -//! @} - -//! \addtogroup bleInitiatorOutput -//! @{ -//! Output structure for initiator (CMD_BLE_INITIATOR) - -struct __RFC_STRUCT rfc_bleInitiatorOutput_s { - uint8_t nTxConnectReq; //!< Number of transmitted CONNECT_REQ packets - uint8_t nRxAdvOk; //!< Number of ADV*_IND packets received with CRC OK and not ignored - uint16_t nRxAdvIgnored; //!< Number of ADV*_IND packets received with CRC OK, but ignored - uint16_t nRxAdvNok; //!< Number of ADV*_IND packets received with CRC error - uint8_t nRxAdvBufFull; //!< Number of ADV*_IND packets received that did not fit in Rx queue - int8_t lastRssi; //!< The RSSI of the last received packet - ratmr_t timeStamp; //!< Time stamp of the received ADV*_IND packet that caused transmission of CONNECT_REQ -}; - -//! @} - -//! \addtogroup bleGenericRxOutput -//! @{ -//! Output structure for generic Rx (CMD_BLE_GENERIC_RX) - -struct __RFC_STRUCT rfc_bleGenericRxOutput_s { - uint16_t nRxOk; //!< Number of packets received with CRC OK - uint16_t nRxNok; //!< Number of packets received with CRC error - uint16_t nRxBufFull; //!< Number of packets that have been received and discarded due to lack of buffer space - int8_t lastRssi; //!< The RSSI of the last received packet - uint8_t __dummy0; - ratmr_t timeStamp; //!< Time stamp of the last received packet -}; - -//! @} - -//! \addtogroup bleTxTestOutput -//! @{ -//! Output structure for Tx test (CMD_BLE_TX_TEST) - -struct __RFC_STRUCT rfc_bleTxTestOutput_s { - uint16_t nTx; //!< Number of packets transmitted -}; - -//! @} - -//! \addtogroup bleWhiteListEntry -//! @{ -//! White list entry structure - -struct __RFC_STRUCT rfc_bleWhiteListEntry_s { - uint8_t size; //!< Number of while list entries. Used in the first entry of the list only - struct { - uint8_t bEnable:1; //!< 1 if the entry is in use, 0 if the entry is not in use - uint8_t addrType:1; //!< The type address in the entry – public (0) or random (1) - uint8_t bWlIgn:1; //!< \brief 1 if the entry is to be ignored by a scanner, 0 otherwise. Used to mask out - //!< entries that have already been scanned and reported. - } conf; - uint16_t address; //!< Least significant 16 bits of the address contained in the entry - uint32_t addressHi; //!< Most significant 32 bits of the address contained in the entry -}; - -//! @} - -//! \addtogroup bleRxStatus -//! @{ -//! Receive status byte that may be appended to message in receive buffer - -struct __RFC_STRUCT rfc_bleRxStatus_s { - struct { - uint8_t channel:6; //!< \brief The channel on which the packet was received, provided channel is in the range - //!< 0–39; otherwise 0x3F - uint8_t bIgnore:1; //!< 1 if the packet is marked as ignored, 0 otherwise - uint8_t bCrcErr:1; //!< 1 if the packet was received with CRC error, 0 otherwise - } status; -}; - -//! @} - -//! @} -//! @} -#endif +/****************************************************************************** +* Filename: ble_cmd.h +* Revised: $ $ +* Revision: $ $ +* +* Description: CC26xx/CC13xx API for Bluetooth Low Energy commands +* +* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef BLE_CMD_H_ +#define BLE_CMD_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup ble_cmd +//! @{ + +#include +#include "mailbox.h" +#include "common_cmd.h" + +typedef struct __RFC_STRUCT rfc_bleRadioOp_s rfc_bleRadioOp_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_SLAVE_s rfc_CMD_BLE_SLAVE_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_MASTER_s rfc_CMD_BLE_MASTER_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_s rfc_CMD_BLE_ADV_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_DIR_s rfc_CMD_BLE_ADV_DIR_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_NC_s rfc_CMD_BLE_ADV_NC_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_SCAN_s rfc_CMD_BLE_ADV_SCAN_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_SCANNER_s rfc_CMD_BLE_SCANNER_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_INITIATOR_s rfc_CMD_BLE_INITIATOR_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_GENERIC_RX_s rfc_CMD_BLE_GENERIC_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_TX_TEST_s rfc_CMD_BLE_TX_TEST_t; +typedef struct __RFC_STRUCT rfc_CMD_BLE_ADV_PAYLOAD_s rfc_CMD_BLE_ADV_PAYLOAD_t; +typedef struct __RFC_STRUCT rfc_bleMasterSlavePar_s rfc_bleMasterSlavePar_t; +typedef struct __RFC_STRUCT rfc_bleMasterPar_s rfc_bleMasterPar_t; +typedef struct __RFC_STRUCT rfc_bleSlavePar_s rfc_bleSlavePar_t; +typedef struct __RFC_STRUCT rfc_bleAdvPar_s rfc_bleAdvPar_t; +typedef struct __RFC_STRUCT rfc_bleScannerPar_s rfc_bleScannerPar_t; +typedef struct __RFC_STRUCT rfc_bleInitiatorPar_s rfc_bleInitiatorPar_t; +typedef struct __RFC_STRUCT rfc_bleGenericRxPar_s rfc_bleGenericRxPar_t; +typedef struct __RFC_STRUCT rfc_bleTxTestPar_s rfc_bleTxTestPar_t; +typedef struct __RFC_STRUCT rfc_bleMasterSlaveOutput_s rfc_bleMasterSlaveOutput_t; +typedef struct __RFC_STRUCT rfc_bleAdvOutput_s rfc_bleAdvOutput_t; +typedef struct __RFC_STRUCT rfc_bleScannerOutput_s rfc_bleScannerOutput_t; +typedef struct __RFC_STRUCT rfc_bleInitiatorOutput_s rfc_bleInitiatorOutput_t; +typedef struct __RFC_STRUCT rfc_bleGenericRxOutput_s rfc_bleGenericRxOutput_t; +typedef struct __RFC_STRUCT rfc_bleTxTestOutput_s rfc_bleTxTestOutput_t; +typedef struct __RFC_STRUCT rfc_bleWhiteListEntry_s rfc_bleWhiteListEntry_t; +typedef struct __RFC_STRUCT rfc_bleRxStatus_s rfc_bleRxStatus_t; + +//! \addtogroup bleRadioOp +//! @{ +struct __RFC_STRUCT rfc_bleRadioOp_s { + uint16_t commandNo; //!< The command ID number + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + uint8_t* pParams; //!< Pointer to command specific parameter structure + uint8_t* pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_SLAVE +//! @{ +#define CMD_BLE_SLAVE 0x1801 +struct __RFC_STRUCT rfc_CMD_BLE_SLAVE_s { + uint16_t commandNo; //!< The command ID number 0x1801 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleSlavePar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleMasterSlaveOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_MASTER +//! @{ +#define CMD_BLE_MASTER 0x1802 +struct __RFC_STRUCT rfc_CMD_BLE_MASTER_s { + uint16_t commandNo; //!< The command ID number 0x1802 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleMasterPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleMasterSlaveOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV +//! @{ +#define CMD_BLE_ADV 0x1803 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_s { + uint16_t commandNo; //!< The command ID number 0x1803 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV_DIR +//! @{ +#define CMD_BLE_ADV_DIR 0x1804 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_DIR_s { + uint16_t commandNo; //!< The command ID number 0x1804 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV_NC +//! @{ +#define CMD_BLE_ADV_NC 0x1805 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_NC_s { + uint16_t commandNo; //!< The command ID number 0x1805 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV_SCAN +//! @{ +#define CMD_BLE_ADV_SCAN 0x1806 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_SCAN_s { + uint16_t commandNo; //!< The command ID number 0x1806 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleAdvPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleAdvOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_SCANNER +//! @{ +#define CMD_BLE_SCANNER 0x1807 +struct __RFC_STRUCT rfc_CMD_BLE_SCANNER_s { + uint16_t commandNo; //!< The command ID number 0x1807 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleScannerPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleScannerOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_INITIATOR +//! @{ +#define CMD_BLE_INITIATOR 0x1808 +struct __RFC_STRUCT rfc_CMD_BLE_INITIATOR_s { + uint16_t commandNo; //!< The command ID number 0x1808 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleInitiatorPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleInitiatorOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_GENERIC_RX +//! @{ +#define CMD_BLE_GENERIC_RX 0x1809 +struct __RFC_STRUCT rfc_CMD_BLE_GENERIC_RX_s { + uint16_t commandNo; //!< The command ID number 0x1809 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleGenericRxPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleGenericRxOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_TX_TEST +//! @{ +#define CMD_BLE_TX_TEST 0x180A +struct __RFC_STRUCT rfc_CMD_BLE_TX_TEST_s { + uint16_t commandNo; //!< The command ID number 0x180A + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to use
+ //!< 0–39: BLE advertising/data channel number + //!< 60–207: Custom frequency; (2300 + channel) MHz + //!< 255: Use existing frequency + //!< Others: Reserved + struct { + uint8_t init:7; //!< \brief If bOverride = 1 or custom frequency is used:
+ //!< 0: Do not use whitening
+ //!< Other value: Initialization for 7-bit LFSR whitener + uint8_t bOverride:1; //!< \brief 0: Use default whitening for BLE advertising/data channels
+ //!< 1: Override whitening initialization with value of init + } whitening; + rfc_bleTxTestPar_t *pParams; //!< Pointer to command specific parameter structure + rfc_bleTxTestOutput_t *pOutput; //!< Pointer to command specific output structure +}; + +//! @} + +//! \addtogroup CMD_BLE_ADV_PAYLOAD +//! @{ +#define CMD_BLE_ADV_PAYLOAD 0x1001 +struct __RFC_STRUCT rfc_CMD_BLE_ADV_PAYLOAD_s { + uint16_t commandNo; //!< The command ID number 0x1001 + uint8_t payloadType; //!< \brief 0: Advertising data
+ //!< 1: Scan response data + uint8_t newLen; //!< Length of the new payload + uint8_t* pNewData; //!< Pointer to the buffer containing the new data + rfc_bleAdvPar_t *pParams; //!< Pointer to the parameter structure to update +}; + +//! @} + +//! \addtogroup bleMasterSlavePar +//! @{ +struct __RFC_STRUCT rfc_bleMasterSlavePar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + dataQueue_t* pTxQ; //!< Pointer to transmit queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t lastRxSn:1; //!< The SN bit of the header of the last packet received with CRC OK + uint8_t lastTxSn:1; //!< The SN bit of the header of the last transmitted packet + uint8_t nextTxSn:1; //!< The SN bit of the header of the next packet to transmit + uint8_t bFirstPkt:1; //!< For slave: 0 if a packet has been transmitted on the connection, 1 otherwise + uint8_t bAutoEmpty:1; //!< 1 if the last transmitted packet was an auto-empty packet + uint8_t bLlCtrlTx:1; //!< 1 if the last transmitted packet was an LL control packet (LLID = 11) + uint8_t bLlCtrlAckRx:1; //!< 1 if the last received packet was the ACK of an LL control packet + uint8_t bLlCtrlAckPending:1; //!< 1 if the last successfully received packet was an LL control packet which has not yet been ACK'ed + } seqStat; + uint8_t maxNack; //!< Maximum number of NACKs received before operation ends. 0: No limit + uint8_t maxPkt; //!< Maximum number of packets transmitted in the operation before it ends. 0: No limit + uint32_t accessAddress; //!< Access address used on the connection + uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte + uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte + uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte +}; + +//! @} + +//! \addtogroup bleMasterPar +//! @{ +//! Parameter structure for master (CMD_BLE_MASTER) + +struct __RFC_STRUCT rfc_bleMasterPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + dataQueue_t* pTxQ; //!< Pointer to transmit queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t lastRxSn:1; //!< The SN bit of the header of the last packet received with CRC OK + uint8_t lastTxSn:1; //!< The SN bit of the header of the last transmitted packet + uint8_t nextTxSn:1; //!< The SN bit of the header of the next packet to transmit + uint8_t bFirstPkt:1; //!< For slave: 0 if a packet has been transmitted on the connection, 1 otherwise + uint8_t bAutoEmpty:1; //!< 1 if the last transmitted packet was an auto-empty packet + uint8_t bLlCtrlTx:1; //!< 1 if the last transmitted packet was an LL control packet (LLID = 11) + uint8_t bLlCtrlAckRx:1; //!< 1 if the last received packet was the ACK of an LL control packet + uint8_t bLlCtrlAckPending:1; //!< 1 if the last successfully received packet was an LL control packet which has not yet been ACK'ed + } seqStat; + uint8_t maxNack; //!< Maximum number of NACKs received before operation ends. 0: No limit + uint8_t maxPkt; //!< Maximum number of packets transmitted in the operation before it ends. 0: No limit + uint32_t accessAddress; //!< Access address used on the connection + uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte + uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte + uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the connection event as soon as allowed + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< connection event as soon as allowed +}; + +//! @} + +//! \addtogroup bleSlavePar +//! @{ +//! Parameter structure for slave (CMD_BLE_SLAVE) + +struct __RFC_STRUCT rfc_bleSlavePar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + dataQueue_t* pTxQ; //!< Pointer to transmit queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t lastRxSn:1; //!< The SN bit of the header of the last packet received with CRC OK + uint8_t lastTxSn:1; //!< The SN bit of the header of the last transmitted packet + uint8_t nextTxSn:1; //!< The SN bit of the header of the next packet to transmit + uint8_t bFirstPkt:1; //!< For slave: 0 if a packet has been transmitted on the connection, 1 otherwise + uint8_t bAutoEmpty:1; //!< 1 if the last transmitted packet was an auto-empty packet + uint8_t bLlCtrlTx:1; //!< 1 if the last transmitted packet was an LL control packet (LLID = 11) + uint8_t bLlCtrlAckRx:1; //!< 1 if the last received packet was the ACK of an LL control packet + uint8_t bLlCtrlAckPending:1; //!< 1 if the last successfully received packet was an LL control packet which has not yet been ACK'ed + } seqStat; + uint8_t maxNack; //!< Maximum number of NACKs received before operation ends. 0: No limit + uint8_t maxPkt; //!< Maximum number of packets transmitted in the operation before it ends. 0: No limit + uint32_t accessAddress; //!< Access address used on the connection + uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte + uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte + uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } timeoutTrigger; //!< Trigger that defines timeout of the first receive operation + ratmr_t timeoutTime; //!< \brief Time used together with timeoutTrigger that defines timeout of the first + //!< receive operation + uint16_t __dummy0; + uint8_t __dummy1; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the connection event as soon as allowed + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< connection event as soon as allowed +}; + +//! @} + +//! \addtogroup bleAdvPar +//! @{ +//! Parameter structure for advertiser (CMD_BLE_ADV*) + +struct __RFC_STRUCT rfc_bleAdvPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t advFilterPolicy:2; //!< \brief The advertiser filter policy, as defined in Volume 2, Part E, Section 7.8.5 of + //!< the Bluetooth 4.0 spec + uint8_t deviceAddrType:1; //!< The type of the device address – public (0) or random (1) + uint8_t peerAddrType:1; //!< Directed advertiser: The type of the peer address – public (0) or random (1) + uint8_t bStrictLenFilter:1; //!< 1: Discard messages with illegal length + } advConfig; + uint8_t advLen; //!< Size of advertiser data + uint8_t scanRspLen; //!< Size of scan response data + uint8_t* pAdvData; //!< Pointer to buffer containing ADV*_IND data + uint8_t* pScanRspData; //!< Pointer to buffer containing SCAN_RSP data + uint16_t* pDeviceAddress; //!< Pointer to device address used for this device + rfc_bleWhiteListEntry_t *pWhiteList; //!< Pointer to white list or peer address (directed advertiser) + uint16_t __dummy0; + uint8_t __dummy1; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the advertiser event as soon as allowed + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< advertiser event as soon as allowed +}; + +//! @} + +//! \addtogroup bleScannerPar +//! @{ +//! Parameter structure for scanner (CMD_BLE_SCANNER) + +struct __RFC_STRUCT rfc_bleScannerPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t scanFilterPolicy:1; //!< \brief The advertiser filter policy, as defined in Volume 2, Part E, Section 7.8.10 of + //!< the Bluetooth 4.0 spec + uint8_t bActiveScan:1; //!< \brief 0: Passive scan
+ //!< 1: Active scan + uint8_t deviceAddrType:1; //!< The type of the device address – public (0) or random (1) + uint8_t :1; + uint8_t bStrictLenFilter:1; //!< 1: Discard messages with illegal length + uint8_t bAutoWlIgnore:1; //!< 1: Automatically set ignore bit in white list + uint8_t bEndOnRpt:1; //!< 1: End scanner operation after each reported ADV*_IND and potentially SCAN_RSP + } scanConfig; + uint16_t randomState; //!< State for pseudo-random number generation used in backoff procedure + uint16_t backoffCount; //!< Parameter backoffCount used in backoff procedure, cf. Bluetooth 4.0 spec + struct { + uint8_t logUpperLimit:4; //!< Binary logarithm of parameter upperLimit used in scanner backoff procedure + uint8_t bLastSucceeded:1; //!< \brief 1 if the last SCAN_RSP was successfully received and upperLimit + //!< not changed + uint8_t bLastFailed:1; //!< \brief 1 if reception of the last SCAN_RSP failed and upperLimit was not + //!< changed + } backoffPar; + uint8_t scanReqLen; //!< Size of scan request data + uint8_t* pScanReqData; //!< Pointer to buffer containing SCAN_REQ data + uint16_t* pDeviceAddress; //!< Pointer to device address used for this device + rfc_bleWhiteListEntry_t *pWhiteList; //!< Pointer to white list + uint16_t __dummy0; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } timeoutTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed + ratmr_t timeoutTime; //!< \brief Time used together with timeoutTrigger that causes the device to stop + //!< receiving as soon as allowed, ending with BLE_DONE_RXTIMEOUT + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to stop + //!< receiving as soon as allowed, ending with BLE_DONE_ENDED +}; + +//! @} + +//! \addtogroup bleInitiatorPar +//! @{ +//! Parameter structure for initiator (CMD_BLE_INITIATOR) + +struct __RFC_STRUCT rfc_bleInitiatorPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + struct { + uint8_t bUseWhiteList:1; //!< \brief Initiator filter policy, cf. Volume 2, Part E, Section 7.8.10 of the + //!< Bluetooth 4.0 spec:
+ //!< 0: Use specific peer address
+ //!< 1: Use white list + uint8_t bDynamicWinOffset:1; //!< 1: Use dynamic WinOffset insertion + uint8_t deviceAddrType:1; //!< The type of the device address – public (0) or random (1) + uint8_t peerAddrType:1; //!< The type of the peer address – public (0) or random (1) + uint8_t bStrictLenFilter:1; //!< 1: Discard messages with illegal length + } initConfig; + uint8_t __dummy0; + uint8_t connectReqLen; //!< Size of connect request data + uint8_t* pConnectReqData; //!< Pointer to buffer containing LLData to go in the CONNECT_REQ + uint16_t* pDeviceAddress; //!< Pointer to device address used for this device + rfc_bleWhiteListEntry_t *pWhiteList; //!< Pointer to white list or peer address + ratmr_t connectTime; //!< \brief Indication of timer value of the first possible start time of the first connection event. + //!< Set to the calculated value if a connection is made and to the next possible connection + //!< time if not. + uint16_t __dummy1; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } timeoutTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to stop receiving as soon as allowed + ratmr_t timeoutTime; //!< \brief Time used together with timeoutTrigger that causes the device to stop + //!< receiving as soon as allowed, ending with BLE_DONE_RXTIMEOUT + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to stop + //!< receiving as soon as allowed, ending with BLE_DONE_ENDED +}; + +//! @} + +//! \addtogroup bleGenericRxPar +//! @{ +//! Parameter structure for generic Rx (CMD_BLE_GENERIC_RX) + +struct __RFC_STRUCT rfc_bleGenericRxPar_s { + dataQueue_t* pRxQ; //!< Pointer to receive queue. May be NULL; if so, received packets are not stored + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically remove ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushEmpty:1; //!< If 1, automatically remove empty packets from Rx queue + uint8_t bIncludeLenByte:1; //!< If 1, include the received length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; //!< Configuration bits for the receive queue entries + uint8_t bRepeat; //!< \brief 0: End operation after receiving a packet
+ //!< 1: Restart receiver after receiving a packet + uint16_t __dummy0; + uint32_t accessAddress; //!< Access address used on the connection + uint8_t crcInit0; //!< CRC initialization value used on the connection – least significant byte + uint8_t crcInit1; //!< CRC initialization value used on the connection – middle byte + uint8_t crcInit2; //!< CRC initialization value used on the connection – most significant byte + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the Rx operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< Rx operation +}; + +//! @} + +//! \addtogroup bleTxTestPar +//! @{ +//! Parameter structure for Tx test (CMD_BLE_TX_TEST) + +struct __RFC_STRUCT rfc_bleTxTestPar_s { + uint16_t numPackets; //!< \brief Number of packets to transmit
+ //!< 0: Transmit unlimited number of packets + uint8_t payloadLength; //!< The number of payload bytes in each packet. + uint8_t packetType; //!< \brief The packet type to be used, encoded according to the Bluetooth 4.0 spec, Volume 2, Part E, + //!< Section 7.8.29 + ratmr_t period; //!< Number of radio timer cycles between the start of each packet + struct { + uint8_t bOverrideDefault:1; //!< \brief 0: Use default packet encoding
+ //!< 1: Override packet contents + uint8_t bUsePrbs9:1; //!< \brief If bOverride is 1:
+ //!< 1: Use PRBS9 encoding of packet + uint8_t bUsePrbs15:1; //!< \brief If bOverride is 1:
+ //!< 1: Use PRBS15 encoding of packet + } config; + uint8_t byteVal; //!< If config.bOverride is 1, value of each byte to be sent + uint8_t __dummy0; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the Test Tx operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< Test Tx operation +}; + +//! @} + +//! \addtogroup bleMasterSlaveOutput +//! @{ +//! Output structure for master and slave (CMD_BLE_MASTER/CMD_BLE_SLAVE) + +struct __RFC_STRUCT rfc_bleMasterSlaveOutput_s { + uint8_t nTx; //!< \brief Total number of packets (including auto-empty and retransmissions) that have been + //!< transmitted + uint8_t nTxAck; //!< Total number of transmitted packets (including auto-empty) that have been ACK'ed + uint8_t nTxCtrl; //!< Number of unique LL control packets from the Tx queue that have been transmitted + uint8_t nTxCtrlAck; //!< Number of LL control packets from the Tx queue that have been finished (ACK'ed) + uint8_t nTxCtrlAckAck; //!< \brief Number of LL control packets that have been ACK'ed and where an ACK has been sent in + //!< response + uint8_t nTxRetrans; //!< Number of retransmissions that has been done + uint8_t nTxEntryDone; //!< Number of packets from the Tx queue that have been finished (ACK'ed) + uint8_t nRxOk; //!< Number of packets that have been received with payload, CRC OK and not ignored + uint8_t nRxCtrl; //!< Number of LL control packets that have been received with CRC OK and not ignored + uint8_t nRxCtrlAck; //!< \brief Number of LL control packets that have been received with CRC OK and not ignored, and + //!< then ACK'ed + uint8_t nRxNok; //!< Number of packets that have been received with CRC error + uint8_t nRxIgnored; //!< \brief Number of packets that have been received with CRC OK and ignored due to repeated + //!< sequence number + uint8_t nRxEmpty; //!< Number of packets that have been received with CRC OK and no payload + uint8_t nRxBufFull; //!< Number of packets that have been received and discarded due to lack of buffer space + int8_t lastRssi; //!< RSSI of last received packet + struct { + uint8_t bTimeStampValid:1; //!< 1 if a valid time stamp has been written to timeStamp; 0 otherwise + uint8_t bLastCrcErr:1; //!< 1 if the last received packet had CRC error; 0 otherwise + uint8_t bLastIgnored:1; //!< 1 if the last received packet with CRC OK was ignored; 0 otherwise + uint8_t bLastEmpty:1; //!< 1 if the last received packet with CRC OK was empty; 0 otherwise + uint8_t bLastCtrl:1; //!< 1 if the last received packet with CRC OK was empty; 0 otherwise + uint8_t bLastMd:1; //!< 1 if the last received packet with CRC OK had MD = 1; 0 otherwise + uint8_t bLastAck:1; //!< \brief 1 if the last received packet with CRC OK was an ACK of a transmitted packet; + //!< 0 otherwise + } pktStatus; + ratmr_t timeStamp; //!< Slave operation: Time stamp of first received packet +}; + +//! @} + +//! \addtogroup bleAdvOutput +//! @{ +//! Output structure for advertiser (CMD_BLE_ADV*) + +struct __RFC_STRUCT rfc_bleAdvOutput_s { + uint16_t nTxAdvInd; //!< Number of ADV*_IND packets completely transmitted + uint8_t nTxScanRsp; //!< Number of SCAN_RSP packets transmitted + uint8_t nRxScanReq; //!< Number of SCAN_REQ packets received OK and not ignored + uint8_t nRxConnectReq; //!< Number of CONNECT_REQ packets received OK and not ignored + uint8_t __dummy0; + uint16_t nRxNok; //!< Number of packets received with CRC error + uint16_t nRxIgnored; //!< Number of packets received with CRC OK, but ignored + uint8_t nRxBufFull; //!< Number of packets received that did not fit in Rx queue + int8_t lastRssi; //!< The RSSI of the last received packet + ratmr_t timeStamp; //!< Time stamp of the last received packet +}; + +//! @} + +//! \addtogroup bleScannerOutput +//! @{ +//! Output structure for scanner (CMD_BLE_SCANNER) + +struct __RFC_STRUCT rfc_bleScannerOutput_s { + uint16_t nTxScanReq; //!< Number of transmitted SCAN_REQ packets + uint16_t nBackedOffScanReq; //!< Number of SCAN_REQ packets not sent due to backoff procedure + uint16_t nRxAdvOk; //!< Number of ADV*_IND packets received with CRC OK and not ignored + uint16_t nRxAdvIgnored; //!< Number of ADV*_IND packets received with CRC OK, but ignored + uint16_t nRxAdvNok; //!< Number of ADV*_IND packets received with CRC error + uint16_t nRxScanRspOk; //!< Number of SCAN_RSP packets received with CRC OK and not ignored + uint16_t nRxScanRspIgnored; //!< Number of SCAN_RSP packets received with CRC OK, but ignored + uint16_t nRxScanRspNok; //!< Number of SCAN_RSP packets received with CRC error + uint8_t nRxAdvBufFull; //!< Number of ADV*_IND packets received that did not fit in Rx queue + uint8_t nRxScanRspBufFull; //!< Number of SCAN_RSP packets received that did not fit in Rx queue + int8_t lastRssi; //!< The RSSI of the last received packet + uint8_t __dummy0; + ratmr_t timeStamp; //!< Time stamp of the last successfully received ADV*_IND packet that was not ignored +}; + +//! @} + +//! \addtogroup bleInitiatorOutput +//! @{ +//! Output structure for initiator (CMD_BLE_INITIATOR) + +struct __RFC_STRUCT rfc_bleInitiatorOutput_s { + uint8_t nTxConnectReq; //!< Number of transmitted CONNECT_REQ packets + uint8_t nRxAdvOk; //!< Number of ADV*_IND packets received with CRC OK and not ignored + uint16_t nRxAdvIgnored; //!< Number of ADV*_IND packets received with CRC OK, but ignored + uint16_t nRxAdvNok; //!< Number of ADV*_IND packets received with CRC error + uint8_t nRxAdvBufFull; //!< Number of ADV*_IND packets received that did not fit in Rx queue + int8_t lastRssi; //!< The RSSI of the last received packet + ratmr_t timeStamp; //!< Time stamp of the received ADV*_IND packet that caused transmission of CONNECT_REQ +}; + +//! @} + +//! \addtogroup bleGenericRxOutput +//! @{ +//! Output structure for generic Rx (CMD_BLE_GENERIC_RX) + +struct __RFC_STRUCT rfc_bleGenericRxOutput_s { + uint16_t nRxOk; //!< Number of packets received with CRC OK + uint16_t nRxNok; //!< Number of packets received with CRC error + uint16_t nRxBufFull; //!< Number of packets that have been received and discarded due to lack of buffer space + int8_t lastRssi; //!< The RSSI of the last received packet + uint8_t __dummy0; + ratmr_t timeStamp; //!< Time stamp of the last received packet +}; + +//! @} + +//! \addtogroup bleTxTestOutput +//! @{ +//! Output structure for Tx test (CMD_BLE_TX_TEST) + +struct __RFC_STRUCT rfc_bleTxTestOutput_s { + uint16_t nTx; //!< Number of packets transmitted +}; + +//! @} + +//! \addtogroup bleWhiteListEntry +//! @{ +//! White list entry structure + +struct __RFC_STRUCT rfc_bleWhiteListEntry_s { + uint8_t size; //!< Number of while list entries. Used in the first entry of the list only + struct { + uint8_t bEnable:1; //!< 1 if the entry is in use, 0 if the entry is not in use + uint8_t addrType:1; //!< The type address in the entry – public (0) or random (1) + uint8_t bWlIgn:1; //!< \brief 1 if the entry is to be ignored by a scanner, 0 otherwise. Used to mask out + //!< entries that have already been scanned and reported. + } conf; + uint16_t address; //!< Least significant 16 bits of the address contained in the entry + uint32_t addressHi; //!< Most significant 32 bits of the address contained in the entry +}; + +//! @} + +//! \addtogroup bleRxStatus +//! @{ +//! Receive status byte that may be appended to message in receive buffer + +struct __RFC_STRUCT rfc_bleRxStatus_s { + struct { + uint8_t channel:6; //!< \brief The channel on which the packet was received, provided channel is in the range + //!< 0–39; otherwise 0x3F + uint8_t bIgnore:1; //!< 1 if the packet is marked as ignored, 0 otherwise + uint8_t bCrcErr:1; //!< 1 if the packet was received with CRC error, 0 otherwise + } status; +}; + +//! @} + +//! @} +//! @} +#endif /* BLE_CMD_H_ */ diff --git a/cpu/cc26xx/dev/rfc-api/ble_mailbox.h b/cpu/cc26xx-cc13xx/rf-core/api/ble_mailbox.h similarity index 57% rename from cpu/cc26xx/dev/rfc-api/ble_mailbox.h rename to cpu/cc26xx-cc13xx/rf-core/api/ble_mailbox.h index 607a92f5d..dcce1996c 100644 --- a/cpu/cc26xx/dev/rfc-api/ble_mailbox.h +++ b/cpu/cc26xx-cc13xx/rf-core/api/ble_mailbox.h @@ -1,119 +1,69 @@ -/****************************************************************************** -* Filename: ble_mailbox.h -* Revised: $ $ -* Revision: $ $ -* -* Description: Definitions for BLE interface -* -* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -******************************************************************************/ - -#ifndef _BLE_MAILBOX_H -#define _BLE_MAILBOX_H - -#include "mailbox.h" - -/// \name CPE interrupt definitions for BLE -/// Interrupt masks for the CPE interrupt in RDBELL. These are new names for interrupts in mailbox.h, -/// used for compartibility with previous versions with separate interrupt numbers. -///@{ -#define IRQN_BLE_TX_DONE IRQN_TX_DONE -#define IRQN_BLE_TX_ACK IRQN_TX_ACK -#define IRQN_BLE_TX_CTRL IRQN_TX_CTRL -#define IRQN_BLE_TX_CTRL_ACK IRQN_TX_CTRL_ACK -#define IRQN_BLE_TX_CTRL_ACK_ACK IRQN_TX_CTRL_ACK_ACK -#define IRQN_BLE_TX_RETRANS IRQN_TX_RETRANS -#define IRQN_BLE_TX_ENTRY_DONE IRQN_TX_ENTRY_DONE -#define IRQN_BLE_TX_BUFFER_CHANGED IRQN_TX_BUFFER_CHANGED -#define IRQN_BLE_RX_OK IRQN_RX_OK -#define IRQN_BLE_RX_NOK IRQN_RX_NOK -#define IRQN_BLE_RX_IGNORED IRQN_RX_IGNORED -#define IRQN_BLE_RX_EMPTY IRQN_RX_EMPTY -#define IRQN_BLE_RX_CTRL IRQN_RX_CTRL -#define IRQN_BLE_RX_CTRL_ACK IRQN_RX_CTRL_ACK -#define IRQN_BLE_RX_BUF_FULL IRQN_RX_BUF_FULL -#define IRQN_BLE_RX_ENTRY_DONE IRQN_RX_ENTRY_DONE - -#define IRQ_BLE_TX_DONE (1U << IRQN_BLE_TX_DONE) -#define IRQ_BLE_TX_ACK (1U << IRQN_BLE_TX_ACK) -#define IRQ_BLE_TX_CTRL (1U << IRQN_BLE_TX_CTRL) -#define IRQ_BLE_TX_CTRL_ACK (1U << IRQN_BLE_TX_CTRL_ACK) -#define IRQ_BLE_TX_CTRL_ACK_ACK (1U << IRQN_BLE_TX_CTRL_ACK_ACK) -#define IRQ_BLE_TX_RETRANS (1U << IRQN_BLE_TX_RETRANS) -#define IRQ_BLE_TX_ENTRY_DONE (1U << IRQN_BLE_TX_ENTRY_DONE) -#define IRQ_BLE_TX_BUFFER_CHANGED (1U << IRQN_BLE_TX_BUFFER_CHANGED) -#define IRQ_BLE_RX_OK (1U << IRQN_BLE_RX_OK) -#define IRQ_BLE_RX_NOK (1U << IRQN_BLE_RX_NOK) -#define IRQ_BLE_RX_IGNORED (1U << IRQN_BLE_RX_IGNORED) -#define IRQ_BLE_RX_EMPTY (1U << IRQN_BLE_RX_EMPTY) -#define IRQ_BLE_RX_CTRL (1U << IRQN_BLE_RX_CTRL) -#define IRQ_BLE_RX_CTRL_ACK (1U << IRQN_BLE_RX_CTRL_ACK) -#define IRQ_BLE_RX_BUF_FULL (1U << IRQN_BLE_RX_BUF_FULL) -#define IRQ_BLE_RX_ENTRY_DONE (1U << IRQN_BLE_RX_ENTRY_DONE) -///@} - - - -/// \name Radio operation status -/// Radio operation status format: -/// Bits 15:12: Protocol -/// 0001: BLE -/// Bits 11:10: Type -/// 00: Not finished -/// 01: Done successfully -/// 10: Done with error -/// Bits 9:0: Identifier - -/// \name Operation finished normally -///@{ -#define BLE_DONE_OK 0x1400 ///< Operation ended normally -#define BLE_DONE_RXTIMEOUT 0x1401 ///< Timeout of first Rx of slave operation or end of scan window -#define BLE_DONE_NOSYNC 0x1402 ///< Timeout of subsequent Rx -#define BLE_DONE_RXERR 0x1403 ///< Operation ended because of receive error (CRC or other) -#define BLE_DONE_CONNECT 0x1404 ///< CONNECT_REQ received or transmitted -#define BLE_DONE_MAXNACK 0x1405 ///< Maximum number of retransmissions exceeded -#define BLE_DONE_ENDED 0x1406 ///< Operation stopped after end trigger -#define BLE_DONE_ABORT 0x1407 ///< Operation aborted by command -#define BLE_DONE_STOPPED 0x1408 ///< Operation stopped after stop command -///@} -/// \name Operation finished with error -///@{ -#define BLE_ERROR_PAR 0x1800 ///< Illegal parameter -#define BLE_ERROR_RXBUF 0x1801 ///< No available Rx buffer (Advertiser, Scanner, Initiator) -#define BLE_ERROR_NO_SETUP 0x1802 ///< Operation using Rx or Tx attemted when not in BLE mode -#define BLE_ERROR_NO_FS 0x1803 ///< Operation using Rx or Tx attemted without frequency synth configured -#define BLE_ERROR_SYNTH_PROG 0x1804 ///< Synthesizer programming failed to complete on time -#define BLE_ERROR_RXOVF 0x1805 ///< Receiver overflowed during operation -#define BLE_ERROR_TXUNF 0x1806 ///< Transmitter underflowed during operation -///@} -///@} - -#endif +/****************************************************************************** +* Filename: ble_mailbox.h +* Revised: $ $ +* Revision: $ $ +* +* Description: Definitions for BLE interface +* +* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef BLE_MAILBOX_H_ +#define BLE_MAILBOX_H_ + +/// \name Radio operation status +///@{ +/// \name Operation finished normally +///@{ +#define BLE_DONE_OK 0x1400 ///< Operation ended normally +#define BLE_DONE_RXTIMEOUT 0x1401 ///< Timeout of first Rx of slave operation or end of scan window +#define BLE_DONE_NOSYNC 0x1402 ///< Timeout of subsequent Rx +#define BLE_DONE_RXERR 0x1403 ///< Operation ended because of receive error (CRC or other) +#define BLE_DONE_CONNECT 0x1404 ///< CONNECT_REQ received or transmitted +#define BLE_DONE_MAXNACK 0x1405 ///< Maximum number of retransmissions exceeded +#define BLE_DONE_ENDED 0x1406 ///< Operation stopped after end trigger +#define BLE_DONE_ABORT 0x1407 ///< Operation aborted by command +#define BLE_DONE_STOPPED 0x1408 ///< Operation stopped after stop command +///@} +/// \name Operation finished with error +///@{ +#define BLE_ERROR_PAR 0x1800 ///< Illegal parameter +#define BLE_ERROR_RXBUF 0x1801 ///< No available Rx buffer (Advertiser, Scanner, Initiator) +#define BLE_ERROR_NO_SETUP 0x1802 ///< Operation using Rx or Tx attemted when not in BLE mode +#define BLE_ERROR_NO_FS 0x1803 ///< Operation using Rx or Tx attemted without frequency synth configured +#define BLE_ERROR_SYNTH_PROG 0x1804 ///< Synthesizer programming failed to complete on time +#define BLE_ERROR_RXOVF 0x1805 ///< Receiver overflowed during operation +#define BLE_ERROR_TXUNF 0x1806 ///< Transmitter underflowed during operation +///@} +///@} + +#endif /* BLE_MAILBOX_H_ */ diff --git a/cpu/cc26xx/dev/rfc-api/common_cmd.h b/cpu/cc26xx-cc13xx/rf-core/api/common_cmd.h similarity index 89% rename from cpu/cc26xx/dev/rfc-api/common_cmd.h rename to cpu/cc26xx-cc13xx/rf-core/api/common_cmd.h index bae0a0200..308f0c3ee 100644 --- a/cpu/cc26xx/dev/rfc-api/common_cmd.h +++ b/cpu/cc26xx-cc13xx/rf-core/api/common_cmd.h @@ -1,1043 +1,1031 @@ -/****************************************************************************** -* Filename: common_cmd.h -* Revised: $ $ -* Revision: $ $ -* -* Description: CC26xx API for common/generic commands -* -* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -******************************************************************************/ - -#ifndef __COMMON_CMD_H -#define __COMMON_CMD_H - -#ifndef __RFC_STRUCT -#ifdef __GNUC__ -#define __RFC_STRUCT __attribute__ ((aligned (4))) -#else -#define __RFC_STRUCT -#endif -#endif - -//! \addtogroup rfc -//! @{ - -//! \addtogroup common_cmd -//! @{ - -#include -#include "mailbox.h" - -typedef struct __RFC_STRUCT rfc_CMD_FG_SCH_IMM_s rfc_CMD_FG_SCH_IMM_t; -typedef struct __RFC_STRUCT rfc_CMD_WRITE_FWPAR_s rfc_CMD_WRITE_FWPAR_t; -typedef struct __RFC_STRUCT rfc_CMD_TX_TEST_s rfc_CMD_TX_TEST_t; -typedef struct __RFC_STRUCT rfc_CMD_RX_TEST_s rfc_CMD_RX_TEST_t; -typedef struct __RFC_STRUCT rfc_CMD_FS_POWERDOWN_s rfc_CMD_FS_POWERDOWN_t; -typedef struct __RFC_STRUCT rfc_CMD_DISARM_RAT_CH_s rfc_CMD_DISARM_RAT_CH_t; -typedef struct __RFC_STRUCT rfc_CMD_SCH_IMM_s rfc_CMD_SCH_IMM_t; -typedef struct __RFC_STRUCT rfc_CMD_ANALOG_POWERDOWN_s rfc_CMD_ANALOG_POWERDOWN_t; -typedef struct __RFC_STRUCT rfc_CMD_SET_RAT_CMP_s rfc_CMD_SET_RAT_CMP_t; -typedef struct __RFC_STRUCT rfc_CMD_FS_OFF_s rfc_CMD_FS_OFF_t; -typedef struct __RFC_STRUCT rfc_CMD_ENABLE_DBG_s rfc_CMD_ENABLE_DBG_t; -typedef struct __RFC_STRUCT rfc_CMD_CLEAR_RX_s rfc_CMD_CLEAR_RX_t; -typedef struct __RFC_STRUCT rfc_CMD_FS_s rfc_CMD_FS_t; -typedef struct __RFC_STRUCT rfc_CMD_FG_COUNT_BRANCH_s rfc_CMD_FG_COUNT_BRANCH_t; -typedef struct __RFC_STRUCT rfc_CMD_GET_FW_INFO_s rfc_CMD_GET_FW_INFO_t; -typedef struct __RFC_STRUCT rfc_CMD_TOPSM_COPY_s rfc_CMD_TOPSM_COPY_t; -typedef struct __RFC_STRUCT rfc_CMD_USER_FUN_s rfc_CMD_USER_FUN_t; -typedef struct __RFC_STRUCT rfc_command_s rfc_command_t; -typedef struct __RFC_STRUCT rfc_CMD_WRITE_ADI0REG_s rfc_CMD_WRITE_ADI0REG_t; -typedef struct __RFC_STRUCT rfc_CMD_FS_POWERUP_s rfc_CMD_FS_POWERUP_t; -typedef struct __RFC_STRUCT rfc_CMD_SYNC_STOP_RAT_s rfc_CMD_SYNC_STOP_RAT_t; -typedef struct __RFC_STRUCT rfc_CMD_ADD_DATA_ENTRY_s rfc_CMD_ADD_DATA_ENTRY_t; -typedef struct __RFC_STRUCT rfc_CMD_FG_COUNT_s rfc_CMD_FG_COUNT_t; -typedef struct __RFC_STRUCT rfc_CMD_MEMCPY_s rfc_CMD_MEMCPY_t; -typedef struct __RFC_STRUCT rfc_CMD_SET_RAT_CPT_s rfc_CMD_SET_RAT_CPT_t; -typedef struct __RFC_STRUCT rfc_CMD_DISABLE_DBG_s rfc_CMD_DISABLE_DBG_t; -typedef struct __RFC_STRUCT rfc_CMD_SYNC_START_RAT_s rfc_CMD_SYNC_START_RAT_t; -typedef struct __RFC_STRUCT rfc_CMD_COUNT_s rfc_CMD_COUNT_t; -typedef struct __RFC_STRUCT rfc_CMD_PATTERN_CHECK_s rfc_CMD_PATTERN_CHECK_t; -typedef struct __RFC_STRUCT rfc_CMD_MODIFY_RFREG_s rfc_CMD_MODIFY_RFREG_t; -typedef struct __RFC_STRUCT rfc_CMD_REMOVE_PENDING_ENTRIES_s rfc_CMD_REMOVE_PENDING_ENTRIES_t; -typedef struct __RFC_STRUCT rfc_CMD_UPDATE_RADIO_SETUP_s rfc_CMD_UPDATE_RADIO_SETUP_t; -typedef struct __RFC_STRUCT rfc_CMD_NOP_s rfc_CMD_NOP_t; -typedef struct __RFC_STRUCT rfc_CMD_STOP_s rfc_CMD_STOP_t; -typedef struct __RFC_STRUCT rfc_CMD_TRIGGER_s rfc_CMD_TRIGGER_t; -typedef struct __RFC_STRUCT rfc_CMD_SET_TRIM_s rfc_CMD_SET_TRIM_t; -typedef struct __RFC_STRUCT rfc_CMD_UPDATE_BAW_FREQ_s rfc_CMD_UPDATE_BAW_FREQ_t; -typedef struct __RFC_STRUCT rfc_CMD_READ_FWPAR_s rfc_CMD_READ_FWPAR_t; -typedef struct __RFC_STRUCT rfc_CMD_REMOVE_DATA_ENTRY_s rfc_CMD_REMOVE_DATA_ENTRY_t; -typedef struct __RFC_STRUCT rfc_CMD_UPDATE_FS_s rfc_CMD_UPDATE_FS_t; -typedef struct __RFC_STRUCT rfc_CMD_ARM_RAT_CH_s rfc_CMD_ARM_RAT_CH_t; -typedef struct __RFC_STRUCT rfc_CMD_WRITE_RFREG_s rfc_CMD_WRITE_RFREG_t; -typedef struct __RFC_STRUCT rfc_CMD_SET_TX_SHAPE_s rfc_CMD_SET_TX_SHAPE_t; -typedef struct __RFC_STRUCT rfc_CMD_READ_ADI1REG_s rfc_CMD_READ_ADI1REG_t; -typedef struct __RFC_STRUCT rfc_CMD_WRITE_ADDR_s rfc_CMD_WRITE_ADDR_t; -typedef struct __RFC_STRUCT rfc_CMD_PING_s rfc_CMD_PING_t; -typedef struct __RFC_STRUCT rfc_CMD_SET_RAT_OUTPUT_s rfc_CMD_SET_RAT_OUTPUT_t; -typedef struct __RFC_STRUCT rfc_CMD_DISABLE_RAT_CH_s rfc_CMD_DISABLE_RAT_CH_t; -typedef struct __RFC_STRUCT rfc_CMD_GET_RSSI_s rfc_CMD_GET_RSSI_t; -typedef struct __RFC_STRUCT rfc_CMD_MEMSET_s rfc_CMD_MEMSET_t; -typedef struct __RFC_STRUCT rfc_CMD_COUNT_BRANCH_s rfc_CMD_COUNT_BRANCH_t; -typedef struct __RFC_STRUCT rfc_CMD_ABORT_s rfc_CMD_ABORT_t; -typedef struct __RFC_STRUCT rfc_CMD_TX_s rfc_CMD_TX_t; -typedef struct __RFC_STRUCT rfc_radioOp_s rfc_radioOp_t; -typedef struct __RFC_STRUCT rfc_CMD_FORCE_CLK_ENA_s rfc_CMD_FORCE_CLK_ENA_t; -typedef struct __RFC_STRUCT rfc_CMD_START_RAT_s rfc_CMD_START_RAT_t; -typedef struct __RFC_STRUCT rfc_CMD_READ_RFREG_s rfc_CMD_READ_RFREG_t; -typedef struct __RFC_STRUCT rfc_CMD_RX_s rfc_CMD_RX_t; -typedef struct __RFC_STRUCT rfc_CMD_FG_PATTERN_CHECK_s rfc_CMD_FG_PATTERN_CHECK_t; -typedef struct __RFC_STRUCT rfc_CMD_SET_TX_POWER_s rfc_CMD_SET_TX_POWER_t; -typedef struct __RFC_STRUCT rfc_CMD_BUS_REQUEST_s rfc_CMD_BUS_REQUEST_t; -typedef struct __RFC_STRUCT rfc_CMD_READ_TRIM_s rfc_CMD_READ_TRIM_t; -typedef struct __RFC_STRUCT rfc_CMD_READ_ADI0REG_s rfc_CMD_READ_ADI0REG_t; -typedef struct __RFC_STRUCT rfc_CMD_WRITE_ADI1REG_s rfc_CMD_WRITE_ADI1REG_t; -typedef struct __RFC_STRUCT rfc_CMD_RADIO_SETUP_s rfc_CMD_RADIO_SETUP_t; -typedef struct __RFC_STRUCT rfc_CMD_READ_FS_CAL_s rfc_CMD_READ_FS_CAL_t; -typedef struct __RFC_STRUCT rfc_CMD_FG_NOP_s rfc_CMD_FG_NOP_t; -typedef struct __RFC_STRUCT rfc_CMD_FLUSH_QUEUE_s rfc_CMD_FLUSH_QUEUE_t; - -//! \addtogroup command -//! @{ -struct __RFC_STRUCT rfc_command_s { - uint16_t commandNo; //!< The command ID number -}; - -//! @} - -//! \addtogroup radioOp -//! @{ -//! Common definition for radio operation commands - -struct __RFC_STRUCT rfc_radioOp_s { - uint16_t commandNo; //!< The command ID number - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; -}; - -//! @} - -//! \addtogroup CMD_NOP -//! @{ -#define CMD_NOP 0x0801 -struct __RFC_STRUCT rfc_CMD_NOP_s { - uint16_t commandNo; //!< The command ID number 0x0801 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; -}; - -//! @} - -//! \addtogroup CMD_RADIO_SETUP -//! @{ -#define CMD_RADIO_SETUP 0x0802 -struct __RFC_STRUCT rfc_CMD_RADIO_SETUP_s { - uint16_t commandNo; //!< The command ID number 0x0802 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t mode; //!< \brief The main mode to use
- //!< 0x00: BLE
- //!< 0x01: IEEE 802.15.4
- //!< 0x02: 2 Mbps GFSK
- //!< 0x05: 5 Mbps coded 8-FSK
- //!< 0x06: ANT
- //!< 0xFF: Keep existing mode; update overrides only
- //!< Others: Reserved - uint8_t __dummy0; - struct { - uint16_t frontEndMode:3; //!< \brief 0x00: Differential mode
- //!< 0x01: Single-ended mode RFP
- //!< 0x02: Single-ended mode RFN
- //!< 0x03: Antenna diversity (start RFP)
- //!< 0x04: Antenna diversity (start RFN)
- //!< 0x05 Single-ended mode RFP with external frontend control on RF pins
- //!< 0x06 Single-ended mode RFN with external frontend control on RF pins
- //!< Others: Reserved - uint16_t biasMode:1; //!< \brief 0: Internal bias
- //!< 1: External bias - uint16_t bNoAdi0Setup:1; //!< \brief 0: Program ADI 0 with default values
- //!< 1: Do not program ADI 0 - uint16_t bNoAdi0Trim:1; //!< \brief 0: Apply trim values to ADI 0
- //!< 1: Use default values for ADI 0 - uint16_t bNoAdi0Ovr:1; //!< \brief 0: Apply ADI 0 overrides
- //!< 1: Ignore ADI 0 overrides - uint16_t bNoAdi1Setup:1; //!< \brief 0: Program ADI 1 with default values
- //!< 1: Do not program ADI 1 - uint16_t bNoAdi1Trim:1; //!< \brief 0: Apply trim values to ADI 1
- //!< 1: Use default values for ADI 1 - uint16_t bNoAdi1Ovr:1; //!< \brief 0: Apply ADI 1 overrides
- //!< 1: Ignore ADI 1 overrides - uint16_t bNoFsPowerUp:1; //!< \brief 0: Power up frequency synth
- //!< 1: Do not power up frequency synth - } config; //!< Configuration options - struct { - uint16_t IB:6; //!< Value to write to the PA power control field at 25 °C - uint16_t GC:2; //!< Value to write to the gain control of the 1st stage of the PA - uint16_t tempCoeff:8; //!< Temperature coefficient for IB. 0: No temperature compensation - } txPower; //!< Transmit power - uint32_t* pRegOverride; //!< \brief Pointer to a list of hardware and configuration registers to override. If NULL, no - //!< override is used. -}; - -//! @} - -//! \addtogroup CMD_FS -//! @{ -#define CMD_FS 0x0803 -struct __RFC_STRUCT rfc_CMD_FS_s { - uint16_t commandNo; //!< The command ID number 0x0803 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint16_t frequency; //!< The frequency in MHz to tune to - uint16_t fractFreq; //!< Fractional part of the frequency to tune to - struct { - uint8_t bTxMode:1; //!< \brief 0: Start synth in Rx mode
- //!< 1: Start synth in Tx mode - uint8_t refFreq:6; //!< Reserved - } synthConf; - struct { - uint8_t bOverrideCalib:1; //!< \brief 0: Use standard calibration settings (ignore calibration settings given in command)
- //!< 1: Override calibration settings - uint8_t bSkipTdcCalib:1; //!< \brief 0: Perform TDC calibration
- //!< 1: Skip TDC calibration - uint8_t bSkipCoarseCalib:1; //!< \brief 0: Perform coarse calibration
- //!< 1: Skip coarse calibration - uint8_t bSkipMidCalib:1; //!< \brief 0: Perform mid calibration
- //!< 1: Skip mid calibration - uint8_t coarsePrecal:4; //!< \brief Coarse pre-calibration value to use when bOverrideCalib and - //!< bSkipCoarseCalib are both 1 - } calibConf; - uint8_t midPrecal; //!< Mid pre-calibration value to use when bOverrideCalib and bSkipCoarseCalib are both 1 - uint8_t ktPrecal; //!< KT pre-calibration value to use when bOverrideCalib and bSkipCoarseCalib are both 1 - uint16_t tdcPrecal; //!< TDC pre-calibration value to use when bOverrideCalib and bSkipCoarseCalib are both 1 -}; - -//! @} - -//! \addtogroup CMD_FS_OFF -//! @{ -#define CMD_FS_OFF 0x0804 -struct __RFC_STRUCT rfc_CMD_FS_OFF_s { - uint16_t commandNo; //!< The command ID number 0x0804 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; -}; - -//! @} - -//! \addtogroup CMD_RX -//! @{ -#define CMD_RX 0x0805 -struct __RFC_STRUCT rfc_CMD_RX_s { - uint16_t commandNo; //!< The command ID number 0x0805 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - struct { - uint16_t endianness:1; //!< \brief 0: Least significant bit first
- //!< 1: Most significant bit first - uint16_t numHdrBits:6; //!< Number of bits in the header - uint16_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
- //!< 1: Turn frequency synth off after command - uint16_t bUseCrc:1; //!< \brief 0: No CRC
- //!< 1: The last bytes of the packet are a CRC - uint16_t bCrcIncSw:1; //!< \brief 0: Do not include sync word in CRC calculation
- //!< 1: Include sync word in CRC calculation - uint16_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
- //!< 1: Include header in CRC calculation - uint16_t bReportCrc:1; //!< \brief 0: Do not write CRC to receive buffer
- //!< 1: Write received CRC to receive buffer - uint16_t endType:1; //!< \brief 0: Packet is received to the end if end trigger happens after sync is obtained
- //!< 1: Packet reception is stopped if end trigger happens - uint16_t bDualSw:1; //!< \brief 0: Single sync word
- //!< 1: Dual sync word. - } pktConfig; - uint32_t syncWord; //!< Sync word to receive - uint32_t syncWord2; //!< Secondary sync word to receive if pktConfig.bDualSw = 1 - struct { - uint16_t numLenBits:4; //!< Number of bits in the length field - uint16_t lenFieldPos:5; //!< Bit position of the first bit in the length field - uint16_t lenOffset:7; //!< Signed number to add to the received length field - } lenConfig; - uint16_t maxLen; //!< Maximum number of bytes in the received packet (including header, excluding CRC) - uint8_t* pRecPkt; //!< Pointer to buffer for received packet. NULL: Do not store the contents. - ratmr_t endTime; //!< Time to end the operation - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger classifier for ending the operation - int8_t rssi; //!< RSSI of received packet - uint16_t recLen; //!< Number of bytes written to receive buffer - ratmr_t timeStamp; //!< Time stamp of received packet - uint16_t nRxOk; //!< Counter of number of received packets with CRC OK and first sync word - uint16_t nRxNok; //!< Counter of number of received packets with CRC error and first sync word - uint16_t nRx2Ok; //!< \brief Counter of number of received packets with CRC OK and second sync word; may safely be - //!< omitted if pktConfig.bDualSw is 0 - uint16_t nRx2Nok; //!< \brief Counter of number of received packets with CRC error and second sync word; may safely be - //!< omitted if pktConfig.bDualSw is 0 -}; - -//! @} - -//! \addtogroup CMD_TX -//! @{ -#define CMD_TX 0x0806 -struct __RFC_STRUCT rfc_CMD_TX_s { - uint16_t commandNo; //!< The command ID number 0x0806 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - struct { - uint16_t endianness:1; //!< \brief 0: Least significant bit first
- //!< 1: Most significant bit first - uint16_t numHdrBits:6; //!< Number of bits in the header - uint16_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
- //!< 1: Turn frequency synth off after command - uint16_t bUseCrc:1; //!< \brief 0: No CRC
- //!< 1: Append a CRC to the packet - uint16_t bCrcIncSw:1; //!< \brief 0: Do not include sync word in CRC calculation
- //!< 1: Include sync word in CRC calculation - uint16_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
- //!< 1: Include header in CRC calculation - } pktConfig; - uint32_t syncWord; //!< Sync word to transmit - uint8_t* pTxPkt; //!< Pointer to buffer for transmitted packet. - uint16_t pktLen; //!< Number of bytes in the transmitted packet -}; - -//! @} - -//! \addtogroup CMD_RX_TEST -//! @{ -#define CMD_RX_TEST 0x0807 -struct __RFC_STRUCT rfc_CMD_RX_TEST_s { - uint16_t commandNo; //!< The command ID number 0x0807 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - struct { - uint8_t bEnaFifo:1; //!< \brief 0: Do not enable FIFO in modem, so that received data is not available
- //!< 1: Enable FIFO in modem – the data must be read out by the application - uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
- //!< 1: Turn frequency synth off after command - uint8_t bNoSync:1; //!< \brief 0: Run sync search as normal for the configured mode
- //!< 1: Write correlation thresholds to the maximum value to avoid getting sync - } config; - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger classifier for ending the operation - uint32_t syncWord; //!< Sync word to use for receiver - ratmr_t endTime; //!< Time to end the operation -}; - -//! @} - -//! \addtogroup CMD_TX_TEST -//! @{ -#define CMD_TX_TEST 0x0808 -struct __RFC_STRUCT rfc_CMD_TX_TEST_s { - uint16_t commandNo; //!< The command ID number 0x0808 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - struct { - uint8_t bUseCw:1; //!< \brief 0: Send modulated signal
- //!< 1: Send continuous wave - uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
- //!< 1: Turn frequency synth off after command - uint8_t whitenMode:2; //!< \brief 0: No whitening
- //!< 1: Default whitening
- //!< 2: PRBS-15
- //!< 3: PRBS-32 - } config; - uint8_t __dummy0; - uint16_t txWord; //!< Value to send to the modem before whitening - uint8_t __dummy1; - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger classifier for ending the operation - uint32_t syncWord; //!< Sync word to use for transmitter - ratmr_t endTime; //!< Time to end the operation -}; - -//! @} - -//! \addtogroup CMD_SYNC_STOP_RAT -//! @{ -#define CMD_SYNC_STOP_RAT 0x0809 -struct __RFC_STRUCT rfc_CMD_SYNC_STOP_RAT_s { - uint16_t commandNo; //!< The command ID number 0x0809 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint16_t __dummy0; - ratmr_t rat0; //!< \brief The returned RAT timer value corresponding to the value the RAT would have had when the - //!< RTC was zero -}; - -//! @} - -//! \addtogroup CMD_SYNC_START_RAT -//! @{ -#define CMD_SYNC_START_RAT 0x080A -struct __RFC_STRUCT rfc_CMD_SYNC_START_RAT_s { - uint16_t commandNo; //!< The command ID number 0x080A - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint16_t __dummy0; - ratmr_t rat0; //!< \brief The desired RAT timer value corresponding to the value the RAT would have had when the - //!< RTC was zero. This parameter is returned by CMD_SYNC_STOP_RAT -}; - -//! @} - -//! \addtogroup CMD_COUNT -//! @{ -#define CMD_COUNT 0x080B -struct __RFC_STRUCT rfc_CMD_COUNT_s { - uint16_t commandNo; //!< The command ID number 0x080B - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint16_t counter; //!< \brief Counter. On start, the radio CPU decrements the value, and the end status of the operation - //!< differs if the result is zero -}; - -//! @} - -//! \addtogroup CMD_FS_POWERUP -//! @{ -#define CMD_FS_POWERUP 0x080C -struct __RFC_STRUCT rfc_CMD_FS_POWERUP_s { - uint16_t commandNo; //!< The command ID number 0x080C - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint16_t __dummy0; - uint32_t* pRegOverride; //!< Pointer to a list of hardware and configuration registers to override. If NULL, no override is used. -}; - -//! @} - -//! \addtogroup CMD_FS_POWERDOWN -//! @{ -#define CMD_FS_POWERDOWN 0x080D -struct __RFC_STRUCT rfc_CMD_FS_POWERDOWN_s { - uint16_t commandNo; //!< The command ID number 0x080D - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; -}; - -//! @} - -//! \addtogroup CMD_SCH_IMM -//! @{ -#define CMD_SCH_IMM 0x0810 -struct __RFC_STRUCT rfc_CMD_SCH_IMM_s { - uint16_t commandNo; //!< The command ID number 0x0810 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint16_t __dummy0; - uint32_t cmdrVal; //!< Value as would be written to CMDR - uint32_t cmdstaVal; //!< Value as would be returned in CMDSTA -}; - -//! @} - -//! \addtogroup CMD_COUNT_BRANCH -//! @{ -#define CMD_COUNT_BRANCH 0x0812 -struct __RFC_STRUCT rfc_CMD_COUNT_BRANCH_s { - uint16_t commandNo; //!< The command ID number 0x0812 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint16_t counter; //!< \brief Counter. On start, the radio CPU decrements the value, and the end status of the operation - //!< differs if the result is zero - rfc_radioOp_t *pNextOpIfOk; //!< Pointer to next operation if counter did not expire -}; - -//! @} - -//! \addtogroup CMD_PATTERN_CHECK -//! @{ -#define CMD_PATTERN_CHECK 0x0813 -struct __RFC_STRUCT rfc_CMD_PATTERN_CHECK_s { - uint16_t commandNo; //!< The command ID number 0x0813 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - struct { - uint16_t operation:2; //!< \brief Operation to perform
- //!< 0: True if value == compareVal
- //!< 1: True if value < compareVal
- //!< 2: True if value > compareVal
- //!< 3: Reserved - uint16_t bByteRev:1; //!< \brief If 1, interchange the four bytes of the value, so that they are read - //!< most-significant-byte-first. - uint16_t bBitRev:1; //!< If 1, perform bit reversal of the value - uint16_t signExtend:5; //!< \brief 0: Treat value and compareVal as unsigned
- //!< 1–31: Treat value and compareVal as signed, where the value - //!< gives the number of the most significant bit in the signed number. - uint16_t bRxVal:1; //!< \brief 0: Use pValue as a pointer
- //!< 1: Use pValue as a signed offset to the start of the last - //!< committed Rx entry element - } patternOpt; //!< Options for comparison - rfc_radioOp_t *pNextOpIfOk; //!< Pointer to next operation if comparison result was true - uint8_t* pValue; //!< Pointer to read from, or offset from last Rx entry if patternOpt.bRxVal == 1 - uint32_t mask; //!< Bit mask to apply before comparison - uint32_t compareVal; //!< Value to compare to -}; - -//! @} - -//! \addtogroup CMD_ABORT -//! @{ -#define CMD_ABORT 0x0401 -struct __RFC_STRUCT rfc_CMD_ABORT_s { - uint16_t commandNo; //!< The command ID number 0x0401 -}; - -//! @} - -//! \addtogroup CMD_STOP -//! @{ -#define CMD_STOP 0x0402 -struct __RFC_STRUCT rfc_CMD_STOP_s { - uint16_t commandNo; //!< The command ID number 0x0402 -}; - -//! @} - -//! \addtogroup CMD_GET_RSSI -//! @{ -#define CMD_GET_RSSI 0x0403 -struct __RFC_STRUCT rfc_CMD_GET_RSSI_s { - uint16_t commandNo; //!< The command ID number 0x0403 -}; - -//! @} - -//! \addtogroup CMD_UPDATE_RADIO_SETUP -//! @{ -#define CMD_UPDATE_RADIO_SETUP 0x0001 -struct __RFC_STRUCT rfc_CMD_UPDATE_RADIO_SETUP_s { - uint16_t commandNo; //!< The command ID number 0x0001 - uint16_t __dummy0; - uint32_t* pRegOverride; //!< Pointer to a list of hardware and configuration registers to override -}; - -//! @} - -//! \addtogroup CMD_TRIGGER -//! @{ -#define CMD_TRIGGER 0x0404 -struct __RFC_STRUCT rfc_CMD_TRIGGER_s { - uint16_t commandNo; //!< The command ID number 0x0404 - uint8_t triggerNo; //!< Command trigger number -}; - -//! @} - -//! \addtogroup CMD_GET_FW_INFO -//! @{ -#define CMD_GET_FW_INFO 0x0002 -struct __RFC_STRUCT rfc_CMD_GET_FW_INFO_s { - uint16_t commandNo; //!< The command ID number 0x0002 - uint16_t versionNo; //!< Firmware version number - uint16_t startOffset; //!< The start of free RAM - uint16_t freeRamSz; //!< The size of free RAM - uint16_t availRatCh; //!< Bitmap of available RAT channels -}; - -//! @} - -//! \addtogroup CMD_START_RAT -//! @{ -#define CMD_START_RAT 0x0405 -struct __RFC_STRUCT rfc_CMD_START_RAT_s { - uint16_t commandNo; //!< The command ID number 0x0405 -}; - -//! @} - -//! \addtogroup CMD_PING -//! @{ -#define CMD_PING 0x0406 -struct __RFC_STRUCT rfc_CMD_PING_s { - uint16_t commandNo; //!< The command ID number 0x0406 -}; - -//! @} - -//! \addtogroup CMD_ADD_DATA_ENTRY -//! @{ -#define CMD_ADD_DATA_ENTRY 0x0005 -struct __RFC_STRUCT rfc_CMD_ADD_DATA_ENTRY_s { - uint16_t commandNo; //!< The command ID number 0x0005 - uint16_t __dummy0; - dataQueue_t* pQueue; //!< Pointer to the queue structure to which the entry will be added - uint8_t* pEntry; //!< Pointer to the entry -}; - -//! @} - -//! \addtogroup CMD_REMOVE_DATA_ENTRY -//! @{ -#define CMD_REMOVE_DATA_ENTRY 0x0006 -struct __RFC_STRUCT rfc_CMD_REMOVE_DATA_ENTRY_s { - uint16_t commandNo; //!< The command ID number 0x0006 - uint16_t __dummy0; - dataQueue_t* pQueue; //!< Pointer to the queue structure from which the entry will be removed - uint8_t* pEntry; //!< Pointer to the entry that was removed -}; - -//! @} - -//! \addtogroup CMD_FLUSH_QUEUE -//! @{ -#define CMD_FLUSH_QUEUE 0x0007 -struct __RFC_STRUCT rfc_CMD_FLUSH_QUEUE_s { - uint16_t commandNo; //!< The command ID number 0x0007 - uint16_t __dummy0; - dataQueue_t* pQueue; //!< Pointer to the queue structure to be flushed - uint8_t* pFirstEntry; //!< Pointer to the first entry that was removed -}; - -//! @} - -//! \addtogroup CMD_CLEAR_RX -//! @{ -#define CMD_CLEAR_RX 0x0008 -struct __RFC_STRUCT rfc_CMD_CLEAR_RX_s { - uint16_t commandNo; //!< The command ID number 0x0008 - uint16_t __dummy0; - dataQueue_t* pQueue; //!< Pointer to the queue structure to be cleared -}; - -//! @} - -//! \addtogroup CMD_REMOVE_PENDING_ENTRIES -//! @{ -#define CMD_REMOVE_PENDING_ENTRIES 0x0009 -struct __RFC_STRUCT rfc_CMD_REMOVE_PENDING_ENTRIES_s { - uint16_t commandNo; //!< The command ID number 0x0009 - uint16_t __dummy0; - dataQueue_t* pQueue; //!< Pointer to the queue structure to be flushed - uint8_t* pFirstEntry; //!< Pointer to the first entry that was removed -}; - -//! @} - -//! \addtogroup CMD_SET_RAT_CMP -//! @{ -#define CMD_SET_RAT_CMP 0x000A -struct __RFC_STRUCT rfc_CMD_SET_RAT_CMP_s { - uint16_t commandNo; //!< The command ID number 0x000A - uint8_t ratCh; //!< The radio timer channel number - uint8_t __dummy0; - ratmr_t compareTime; //!< The time at which the compare occurs -}; - -//! @} - -//! \addtogroup CMD_SET_RAT_CPT -//! @{ -#define CMD_SET_RAT_CPT 0x0603 -struct __RFC_STRUCT rfc_CMD_SET_RAT_CPT_s { - uint16_t commandNo; //!< The command ID number 0x0603 - struct { - uint16_t :3; - uint16_t inputSrc:5; //!< Input source indicator - uint16_t ratCh:4; //!< The radio timer channel number - uint16_t bRepeated:1; //!< \brief 0: Single capture mode
- //!< 1: Repeated capture mode - uint16_t inputMode:2; //!< \brief Input mode:
- //!< 0: Capture on rising edge
- //!< 1: Capture on falling edge
- //!< 2: Capture on both edges
- //!< 3: Reserved - } config; -}; - -//! @} - -//! \addtogroup CMD_DISABLE_RAT_CH -//! @{ -#define CMD_DISABLE_RAT_CH 0x0408 -struct __RFC_STRUCT rfc_CMD_DISABLE_RAT_CH_s { - uint16_t commandNo; //!< The command ID number 0x0408 - uint8_t ratCh; //!< The radio timer channel number -}; - -//! @} - -//! \addtogroup CMD_SET_RAT_OUTPUT -//! @{ -#define CMD_SET_RAT_OUTPUT 0x0604 -struct __RFC_STRUCT rfc_CMD_SET_RAT_OUTPUT_s { - uint16_t commandNo; //!< The command ID number 0x0604 - struct { - uint16_t :2; - uint16_t outputSel:3; //!< Output event indicator - uint16_t outputMode:3; //!< \brief 0: Set output line low as default; and pulse on event. Duration of pulse is one RF Core clock period (ca. 41.67 ns).
- //!< 1: Set output line high on event
- //!< 2: Set output line low on event
- //!< 3: Toggle (invert) output line state on event
- //!< 4: Immediately set output line to low (does not change upon event)
- //!< 5: Immediately set output line to high (does not change upon event)
- //!< Others: Reserved - uint16_t ratCh:4; //!< The radio timer channel number - } config; -}; - -//! @} - -//! \addtogroup CMD_ARM_RAT_CH -//! @{ -#define CMD_ARM_RAT_CH 0x0409 -struct __RFC_STRUCT rfc_CMD_ARM_RAT_CH_s { - uint16_t commandNo; //!< The command ID number 0x0409 - uint8_t ratCh; //!< The radio timer channel number -}; - -//! @} - -//! \addtogroup CMD_DISARM_RAT_CH -//! @{ -#define CMD_DISARM_RAT_CH 0x040A -struct __RFC_STRUCT rfc_CMD_DISARM_RAT_CH_s { - uint16_t commandNo; //!< The command ID number 0x040A - uint8_t ratCh; //!< The radio timer channel number -}; - -//! @} - -//! \addtogroup CMD_SET_TX_POWER -//! @{ -#define CMD_SET_TX_POWER 0x0010 -struct __RFC_STRUCT rfc_CMD_SET_TX_POWER_s { - uint16_t commandNo; //!< The command ID number 0x0010 - struct { - uint16_t IB:6; //!< Value to write to the PA power control field at 25 °C - uint16_t GC:2; //!< Value to write to the gain control of the 1st stage of the PA - uint16_t tempCoeff:8; //!< Temperature coefficient for IB. 0: No temperature compensation - } txPower; //!< New Tx power setting -}; - -//! @} - -//! \addtogroup CMD_UPDATE_FS -//! @{ -#define CMD_UPDATE_FS 0x0011 -struct __RFC_STRUCT rfc_CMD_UPDATE_FS_s { - uint16_t commandNo; //!< The command ID number 0x0011 - uint16_t frequency; //!< The frequency in MHz to tune to - uint16_t fractFreq; //!< Fractional part of the frequency to tune to -}; - -//! @} - -//! \addtogroup CMD_BUS_REQUEST -//! @{ -#define CMD_BUS_REQUEST 0x040E -struct __RFC_STRUCT rfc_CMD_BUS_REQUEST_s { - uint16_t commandNo; //!< The command ID number 0x040E - uint8_t bSysBusNeeded; //!< \brief 0: System bus may sleep
- //!< 1: System bus access needed -}; - -//! @} - -//! @} -//! @} -#endif +/****************************************************************************** +* Filename: common_cmd.h +* Revised: 2015-08-04 10:40:45 +0200 (Tue, 04 Aug 2015) +* Revision: 44326 +* +* Description: CC13xx API for common/generic commands +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3) Neither the name of the ORGANIZATION nor the names of its contributors may +* be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef COMMON_CMD_H_ +#define COMMON_CMD_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup common_cmd +//! @{ + +#include +#include "mailbox.h" + +typedef struct __RFC_STRUCT rfc_command_s rfc_command_t; +typedef struct __RFC_STRUCT rfc_radioOp_s rfc_radioOp_t; +typedef struct __RFC_STRUCT rfc_CMD_NOP_s rfc_CMD_NOP_t; +typedef struct __RFC_STRUCT rfc_CMD_RADIO_SETUP_s rfc_CMD_RADIO_SETUP_t; +typedef struct __RFC_STRUCT rfc_CMD_FS_s rfc_CMD_FS_t; +typedef struct __RFC_STRUCT rfc_CMD_FS_OFF_s rfc_CMD_FS_OFF_t; +typedef struct __RFC_STRUCT rfc_CMD_RX_s rfc_CMD_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_TX_s rfc_CMD_TX_t; +typedef struct __RFC_STRUCT rfc_CMD_RX_TEST_s rfc_CMD_RX_TEST_t; +typedef struct __RFC_STRUCT rfc_CMD_TX_TEST_s rfc_CMD_TX_TEST_t; +typedef struct __RFC_STRUCT rfc_CMD_SYNC_STOP_RAT_s rfc_CMD_SYNC_STOP_RAT_t; +typedef struct __RFC_STRUCT rfc_CMD_SYNC_START_RAT_s rfc_CMD_SYNC_START_RAT_t; +typedef struct __RFC_STRUCT rfc_CMD_COUNT_s rfc_CMD_COUNT_t; +typedef struct __RFC_STRUCT rfc_CMD_FS_POWERUP_s rfc_CMD_FS_POWERUP_t; +typedef struct __RFC_STRUCT rfc_CMD_FS_POWERDOWN_s rfc_CMD_FS_POWERDOWN_t; +typedef struct __RFC_STRUCT rfc_CMD_SCH_IMM_s rfc_CMD_SCH_IMM_t; +typedef struct __RFC_STRUCT rfc_CMD_COUNT_BRANCH_s rfc_CMD_COUNT_BRANCH_t; +typedef struct __RFC_STRUCT rfc_CMD_PATTERN_CHECK_s rfc_CMD_PATTERN_CHECK_t; +typedef struct __RFC_STRUCT rfc_CMD_TX_POWER_BOOST_s rfc_CMD_TX_POWER_BOOST_t; +typedef struct __RFC_STRUCT rfc_CMD_ABORT_s rfc_CMD_ABORT_t; +typedef struct __RFC_STRUCT rfc_CMD_STOP_s rfc_CMD_STOP_t; +typedef struct __RFC_STRUCT rfc_CMD_GET_RSSI_s rfc_CMD_GET_RSSI_t; +typedef struct __RFC_STRUCT rfc_CMD_UPDATE_RADIO_SETUP_s rfc_CMD_UPDATE_RADIO_SETUP_t; +typedef struct __RFC_STRUCT rfc_CMD_TRIGGER_s rfc_CMD_TRIGGER_t; +typedef struct __RFC_STRUCT rfc_CMD_GET_FW_INFO_s rfc_CMD_GET_FW_INFO_t; +typedef struct __RFC_STRUCT rfc_CMD_START_RAT_s rfc_CMD_START_RAT_t; +typedef struct __RFC_STRUCT rfc_CMD_PING_s rfc_CMD_PING_t; +typedef struct __RFC_STRUCT rfc_CMD_ADD_DATA_ENTRY_s rfc_CMD_ADD_DATA_ENTRY_t; +typedef struct __RFC_STRUCT rfc_CMD_REMOVE_DATA_ENTRY_s rfc_CMD_REMOVE_DATA_ENTRY_t; +typedef struct __RFC_STRUCT rfc_CMD_FLUSH_QUEUE_s rfc_CMD_FLUSH_QUEUE_t; +typedef struct __RFC_STRUCT rfc_CMD_CLEAR_RX_s rfc_CMD_CLEAR_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_REMOVE_PENDING_ENTRIES_s rfc_CMD_REMOVE_PENDING_ENTRIES_t; +typedef struct __RFC_STRUCT rfc_CMD_SET_RAT_CMP_s rfc_CMD_SET_RAT_CMP_t; +typedef struct __RFC_STRUCT rfc_CMD_SET_RAT_CPT_s rfc_CMD_SET_RAT_CPT_t; +typedef struct __RFC_STRUCT rfc_CMD_DISABLE_RAT_CH_s rfc_CMD_DISABLE_RAT_CH_t; +typedef struct __RFC_STRUCT rfc_CMD_SET_RAT_OUTPUT_s rfc_CMD_SET_RAT_OUTPUT_t; +typedef struct __RFC_STRUCT rfc_CMD_ARM_RAT_CH_s rfc_CMD_ARM_RAT_CH_t; +typedef struct __RFC_STRUCT rfc_CMD_DISARM_RAT_CH_s rfc_CMD_DISARM_RAT_CH_t; +typedef struct __RFC_STRUCT rfc_CMD_SET_TX_POWER_s rfc_CMD_SET_TX_POWER_t; +typedef struct __RFC_STRUCT rfc_CMD_UPDATE_FS_s rfc_CMD_UPDATE_FS_t; +typedef struct __RFC_STRUCT rfc_CMD_BUS_REQUEST_s rfc_CMD_BUS_REQUEST_t; + +//! \addtogroup command +//! @{ +struct __RFC_STRUCT rfc_command_s { + uint16_t commandNo; //!< The command ID number +}; + +//! @} + +//! \addtogroup radioOp +//! @{ +//! Common definition for radio operation commands + +struct __RFC_STRUCT rfc_radioOp_s { + uint16_t commandNo; //!< The command ID number + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_NOP +//! @{ +#define CMD_NOP 0x0801 +struct __RFC_STRUCT rfc_CMD_NOP_s { + uint16_t commandNo; //!< The command ID number 0x0801 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_RADIO_SETUP +//! @{ +#define CMD_RADIO_SETUP 0x0802 +struct __RFC_STRUCT rfc_CMD_RADIO_SETUP_s { + uint16_t commandNo; //!< The command ID number 0x0802 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t mode; //!< \brief The main mode to use
+ //!< 0x00: BLE
+ //!< 0x01: IEEE 802.15.4
+ //!< 0x02: 2 Mbps GFSK
+ //!< 0x05: 5 Mbps coded 8-FSK
+ //!< 0x06: ANT
+ //!< 0xFF: Keep existing mode; update overrides only
+ //!< Others: Reserved + uint8_t loDivider; //!< \brief LO divider setting to use. Supported values: 0 (equivalent to 2), 2, 5, 6, 10, 12, 15, + //!< and 30.
+ //!< Value of 0 or 2 only supported for devices that support 2.4 GHz operation + struct { + uint16_t frontEndMode:3; //!< \brief 0x00: Differential mode
+ //!< 0x01: Single-ended mode RFP
+ //!< 0x02: Single-ended mode RFN
+ //!< 0x05 Single-ended mode RFP with external frontend control on RF pins (RFN and RXTX)
+ //!< 0x06 Single-ended mode RFN with external frontend control on RF pins (RFP and RXTX)
+ //!< Others: Reserved + uint16_t biasMode:1; //!< \brief 0: Internal bias
+ //!< 1: External bias + uint16_t :6; + uint16_t bNoFsPowerUp:1; //!< \brief 0: Power up frequency synth
+ //!< 1: Do not power up frequency synth + } config; //!< Configuration options + struct { + uint16_t IB:6; //!< Value to write to the PA power control field at 25 °C + uint16_t GC:2; //!< Value to write to the gain control of the 1st stage of the PA + uint16_t boost:1; //!< Value of boost bit in synth + uint16_t tempCoeff:7; //!< Temperature coefficient for IB. 0: No temperature compensation + } txPower; //!< Transmit power + uint32_t* pRegOverride; //!< \brief Pointer to a list of hardware and configuration registers to override. If NULL, no + //!< override is used. +}; + +//! @} + +//! \addtogroup CMD_FS +//! @{ +#define CMD_FS 0x0803 +struct __RFC_STRUCT rfc_CMD_FS_s { + uint16_t commandNo; //!< The command ID number 0x0803 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t frequency; //!< The frequency in MHz to tune to + uint16_t fractFreq; //!< Fractional part of the frequency to tune to + struct { + uint8_t bTxMode:1; //!< \brief 0: Start synth in Rx mode
+ //!< 1: Start synth in Tx mode + uint8_t refFreq:6; //!< \brief 0: Use default reference frequency
+ //!< Others: Use reference frequency 24 MHz/refFreq + } synthConf; + uint8_t __dummy0; + uint8_t midPrecal; //!< Mid pre-calibration value to use when bOverrideCalib and bSkipCoarseCalib are both 1 + uint8_t ktPrecal; //!< KT pre-calibration value to use when bOverrideCalib and bSkipCoarseCalib are both 1 + uint16_t tdcPrecal; //!< TDC pre-calibration value to use when bOverrideCalib and bSkipCoarseCalib are both 1 +}; + +//! @} + +//! \addtogroup CMD_FS_OFF +//! @{ +#define CMD_FS_OFF 0x0804 +struct __RFC_STRUCT rfc_CMD_FS_OFF_s { + uint16_t commandNo; //!< The command ID number 0x0804 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_RX +//! @{ +#define CMD_RX 0x0805 +struct __RFC_STRUCT rfc_CMD_RX_s { + uint16_t commandNo; //!< The command ID number 0x0805 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t endianness:1; //!< \brief 0: Least significant bit first
+ //!< 1: Most significant bit first + uint16_t numHdrBits:6; //!< Number of bits in the header + uint16_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
+ //!< 1: Turn frequency synth off after command + uint16_t bUseCrc:1; //!< \brief 0: No CRC
+ //!< 1: The last bytes of the packet are a CRC + uint16_t bCrcIncSw:1; //!< \brief 0: Do not include sync word in CRC calculation
+ //!< 1: Include sync word in CRC calculation + uint16_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
+ //!< 1: Include header in CRC calculation + uint16_t bReportCrc:1; //!< \brief 0: Do not write CRC to receive buffer
+ //!< 1: Write received CRC to receive buffer + uint16_t endType:1; //!< \brief 0: Packet is received to the end if end trigger happens after sync is obtained
+ //!< 1: Packet reception is stopped if end trigger happens + uint16_t bDualSw:1; //!< \brief 0: Single sync word
+ //!< 1: Dual sync word. + } pktConfig; + uint32_t syncWord; //!< Sync word to receive + uint32_t syncWord2; //!< Secondary sync word to receive if pktConfig.bDualSw = 1 + struct { + uint16_t numLenBits:4; //!< Number of bits in the length field + uint16_t lenFieldPos:5; //!< Bit position of the first bit in the length field + uint16_t lenOffset:7; //!< Signed number to add to the received length field + } lenConfig; + uint16_t maxLen; //!< Maximum number of bytes in the received packet (including header, excluding CRC) + uint8_t* pRecPkt; //!< Pointer to buffer for received packet. NULL: Do not store the contents. + ratmr_t endTime; //!< Time to end the operation + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + int8_t rssi; //!< RSSI of received packet + uint16_t recLen; //!< Number of bytes written to receive buffer + ratmr_t timeStamp; //!< Time stamp of received packet + uint16_t nRxOk; //!< Counter of number of received packets with CRC OK and first sync word + uint16_t nRxNok; //!< Counter of number of received packets with CRC error and first sync word + uint16_t nRx2Ok; //!< \brief Counter of number of received packets with CRC OK and second sync word; may safely be + //!< omitted if pktConfig.bDualSw is 0 + uint16_t nRx2Nok; //!< \brief Counter of number of received packets with CRC error and second sync word; may safely be + //!< omitted if pktConfig.bDualSw is 0 +}; + +//! @} + +//! \addtogroup CMD_TX +//! @{ +#define CMD_TX 0x0806 +struct __RFC_STRUCT rfc_CMD_TX_s { + uint16_t commandNo; //!< The command ID number 0x0806 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t endianness:1; //!< \brief 0: Least significant bit first
+ //!< 1: Most significant bit first + uint16_t numHdrBits:6; //!< Number of bits in the header + uint16_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
+ //!< 1: Turn frequency synth off after command + uint16_t bUseCrc:1; //!< \brief 0: No CRC
+ //!< 1: Append a CRC to the packet + uint16_t bCrcIncSw:1; //!< \brief 0: Do not include sync word in CRC calculation
+ //!< 1: Include sync word in CRC calculation + uint16_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
+ //!< 1: Include header in CRC calculation + } pktConfig; + uint32_t syncWord; //!< Sync word to transmit + uint8_t* pTxPkt; //!< Pointer to buffer for transmitted packet. + uint16_t pktLen; //!< Number of bytes in the transmitted packet +}; + +//! @} + +//! \addtogroup CMD_RX_TEST +//! @{ +#define CMD_RX_TEST 0x0807 +struct __RFC_STRUCT rfc_CMD_RX_TEST_s { + uint16_t commandNo; //!< The command ID number 0x0807 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bEnaFifo:1; //!< \brief 0: Do not enable FIFO in modem, so that received data is not available
+ //!< 1: Enable FIFO in modem – the data must be read out by the application + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
+ //!< 1: Turn frequency synth off after command + uint8_t bNoSync:1; //!< \brief 0: Run sync search as normal for the configured mode
+ //!< 1: Write correlation thresholds to the maximum value to avoid getting sync + } config; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + uint32_t syncWord; //!< Sync word to use for receiver + ratmr_t endTime; //!< Time to end the operation +}; + +//! @} + +//! \addtogroup CMD_TX_TEST +//! @{ +#define CMD_TX_TEST 0x0808 +struct __RFC_STRUCT rfc_CMD_TX_TEST_s { + uint16_t commandNo; //!< The command ID number 0x0808 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bUseCw:1; //!< \brief 0: Send modulated signal
+ //!< 1: Send continuous wave + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
+ //!< 1: Turn frequency synth off after command + uint8_t whitenMode:2; //!< \brief 0: No whitening
+ //!< 1: Default whitening
+ //!< 2: PRBS-15
+ //!< 3: PRBS-32 + } config; + uint8_t __dummy0; + uint16_t txWord; //!< Value to send to the modem before whitening + uint8_t __dummy1; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + uint32_t syncWord; //!< Sync word to use for transmitter + ratmr_t endTime; //!< Time to end the operation +}; + +//! @} + +//! \addtogroup CMD_SYNC_STOP_RAT +//! @{ +#define CMD_SYNC_STOP_RAT 0x0809 +struct __RFC_STRUCT rfc_CMD_SYNC_STOP_RAT_s { + uint16_t commandNo; //!< The command ID number 0x0809 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t __dummy0; + ratmr_t rat0; //!< \brief The returned RAT timer value corresponding to the value the RAT would have had when the + //!< RTC was zero +}; + +//! @} + +//! \addtogroup CMD_SYNC_START_RAT +//! @{ +#define CMD_SYNC_START_RAT 0x080A +struct __RFC_STRUCT rfc_CMD_SYNC_START_RAT_s { + uint16_t commandNo; //!< The command ID number 0x080A + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t __dummy0; + ratmr_t rat0; //!< \brief The desired RAT timer value corresponding to the value the RAT would have had when the + //!< RTC was zero. This parameter is returned by CMD_SYNC_STOP_RAT +}; + +//! @} + +//! \addtogroup CMD_COUNT +//! @{ +#define CMD_COUNT 0x080B +struct __RFC_STRUCT rfc_CMD_COUNT_s { + uint16_t commandNo; //!< The command ID number 0x080B + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t counter; //!< \brief Counter. On start, the radio CPU decrements the value, and the end status of the operation + //!< differs if the result is zero +}; + +//! @} + +//! \addtogroup CMD_FS_POWERUP +//! @{ +#define CMD_FS_POWERUP 0x080C +struct __RFC_STRUCT rfc_CMD_FS_POWERUP_s { + uint16_t commandNo; //!< The command ID number 0x080C + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t __dummy0; + uint32_t* pRegOverride; //!< Pointer to a list of hardware and configuration registers to override. If NULL, no override is used. +}; + +//! @} + +//! \addtogroup CMD_FS_POWERDOWN +//! @{ +#define CMD_FS_POWERDOWN 0x080D +struct __RFC_STRUCT rfc_CMD_FS_POWERDOWN_s { + uint16_t commandNo; //!< The command ID number 0x080D + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_SCH_IMM +//! @{ +#define CMD_SCH_IMM 0x0810 +struct __RFC_STRUCT rfc_CMD_SCH_IMM_s { + uint16_t commandNo; //!< The command ID number 0x0810 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t __dummy0; + uint32_t cmdrVal; //!< Value as would be written to CMDR + uint32_t cmdstaVal; //!< Value as would be returned in CMDSTA +}; + +//! @} + +//! \addtogroup CMD_COUNT_BRANCH +//! @{ +#define CMD_COUNT_BRANCH 0x0812 +struct __RFC_STRUCT rfc_CMD_COUNT_BRANCH_s { + uint16_t commandNo; //!< The command ID number 0x0812 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t counter; //!< \brief Counter. On start, the radio CPU decrements the value, and the end status of the operation + //!< differs if the result is zero + rfc_radioOp_t *pNextOpIfOk; //!< Pointer to next operation if counter did not expire +}; + +//! @} + +//! \addtogroup CMD_PATTERN_CHECK +//! @{ +#define CMD_PATTERN_CHECK 0x0813 +struct __RFC_STRUCT rfc_CMD_PATTERN_CHECK_s { + uint16_t commandNo; //!< The command ID number 0x0813 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t operation:2; //!< \brief Operation to perform
+ //!< 0: True if value == compareVal
+ //!< 1: True if value < compareVal
+ //!< 2: True if value > compareVal
+ //!< 3: Reserved + uint16_t bByteRev:1; //!< \brief If 1, interchange the four bytes of the value, so that they are read + //!< most-significant-byte-first. + uint16_t bBitRev:1; //!< If 1, perform bit reversal of the value + uint16_t signExtend:5; //!< \brief 0: Treat value and compareVal as unsigned
+ //!< 1–31: Treat value and compareVal as signed, where the value + //!< gives the number of the most significant bit in the signed number. + uint16_t bRxVal:1; //!< \brief 0: Use pValue as a pointer
+ //!< 1: Use pValue as a signed offset to the start of the last + //!< committed Rx entry element + } patternOpt; //!< Options for comparison + rfc_radioOp_t *pNextOpIfOk; //!< Pointer to next operation if comparison result was true + uint8_t* pValue; //!< Pointer to read from, or offset from last Rx entry if patternOpt.bRxVal == 1 + uint32_t mask; //!< Bit mask to apply before comparison + uint32_t compareVal; //!< Value to compare to +}; + +//! @} + +//! \addtogroup CMD_TX_POWER_BOOST +//! @{ +#define CMD_TX_POWER_BOOST 0x0816 +struct __RFC_STRUCT rfc_CMD_TX_POWER_BOOST_s { + uint16_t commandNo; //!< The command ID number 0x0816 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t vddrLevel; //!< \brief VDDR level to set
+ //!< 0xFD: Trim VDDR voltage to normal level (VDDR_TRIM), nominally 1.68 V
+ //!< 0xFE: Trim VDDR voltage to high level (VDDR_TRIM_H), nominally 1.85 V
+ //!< 0xFF: Trim VDDR voltage to higher level (VDDR_TRIM_HH), nominally 1.95 V
+ //!< Other: reserved + uint8_t paTrimValue; //!< \brief Optional power amplifier trim setting manipulation
+ //!< 0x00-0x1F: Value to write in ADI_0_RF:PACTL0.TRIM register field
+ //!< 0xFE: Set PACTL0.TRIM to its default value from FCFG1
+ //!< 0xFF: Do not write PACTL0.TRIM, use the setting that is already applied
+}; + +//! @} + +//! \addtogroup CMD_ABORT +//! @{ +#define CMD_ABORT 0x0401 +struct __RFC_STRUCT rfc_CMD_ABORT_s { + uint16_t commandNo; //!< The command ID number 0x0401 +}; + +//! @} + +//! \addtogroup CMD_STOP +//! @{ +#define CMD_STOP 0x0402 +struct __RFC_STRUCT rfc_CMD_STOP_s { + uint16_t commandNo; //!< The command ID number 0x0402 +}; + +//! @} + +//! \addtogroup CMD_GET_RSSI +//! @{ +#define CMD_GET_RSSI 0x0403 +struct __RFC_STRUCT rfc_CMD_GET_RSSI_s { + uint16_t commandNo; //!< The command ID number 0x0403 +}; + +//! @} + +//! \addtogroup CMD_UPDATE_RADIO_SETUP +//! @{ +#define CMD_UPDATE_RADIO_SETUP 0x0001 +struct __RFC_STRUCT rfc_CMD_UPDATE_RADIO_SETUP_s { + uint16_t commandNo; //!< The command ID number 0x0001 + uint16_t __dummy0; + uint32_t* pRegOverride; //!< Pointer to a list of hardware and configuration registers to override +}; + +//! @} + +//! \addtogroup CMD_TRIGGER +//! @{ +#define CMD_TRIGGER 0x0404 +struct __RFC_STRUCT rfc_CMD_TRIGGER_s { + uint16_t commandNo; //!< The command ID number 0x0404 + uint8_t triggerNo; //!< Command trigger number +}; + +//! @} + +//! \addtogroup CMD_GET_FW_INFO +//! @{ +#define CMD_GET_FW_INFO 0x0002 +struct __RFC_STRUCT rfc_CMD_GET_FW_INFO_s { + uint16_t commandNo; //!< The command ID number 0x0002 + uint16_t versionNo; //!< Firmware version number + uint16_t startOffset; //!< The start of free RAM + uint16_t freeRamSz; //!< The size of free RAM + uint16_t availRatCh; //!< Bitmap of available RAT channels +}; + +//! @} + +//! \addtogroup CMD_START_RAT +//! @{ +#define CMD_START_RAT 0x0405 +struct __RFC_STRUCT rfc_CMD_START_RAT_s { + uint16_t commandNo; //!< The command ID number 0x0405 +}; + +//! @} + +//! \addtogroup CMD_PING +//! @{ +#define CMD_PING 0x0406 +struct __RFC_STRUCT rfc_CMD_PING_s { + uint16_t commandNo; //!< The command ID number 0x0406 +}; + +//! @} + +//! \addtogroup CMD_ADD_DATA_ENTRY +//! @{ +#define CMD_ADD_DATA_ENTRY 0x0005 +struct __RFC_STRUCT rfc_CMD_ADD_DATA_ENTRY_s { + uint16_t commandNo; //!< The command ID number 0x0005 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure to which the entry will be added + uint8_t* pEntry; //!< Pointer to the entry +}; + +//! @} + +//! \addtogroup CMD_REMOVE_DATA_ENTRY +//! @{ +#define CMD_REMOVE_DATA_ENTRY 0x0006 +struct __RFC_STRUCT rfc_CMD_REMOVE_DATA_ENTRY_s { + uint16_t commandNo; //!< The command ID number 0x0006 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure from which the entry will be removed + uint8_t* pEntry; //!< Pointer to the entry that was removed +}; + +//! @} + +//! \addtogroup CMD_FLUSH_QUEUE +//! @{ +#define CMD_FLUSH_QUEUE 0x0007 +struct __RFC_STRUCT rfc_CMD_FLUSH_QUEUE_s { + uint16_t commandNo; //!< The command ID number 0x0007 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure to be flushed + uint8_t* pFirstEntry; //!< Pointer to the first entry that was removed +}; + +//! @} + +//! \addtogroup CMD_CLEAR_RX +//! @{ +#define CMD_CLEAR_RX 0x0008 +struct __RFC_STRUCT rfc_CMD_CLEAR_RX_s { + uint16_t commandNo; //!< The command ID number 0x0008 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure to be cleared +}; + +//! @} + +//! \addtogroup CMD_REMOVE_PENDING_ENTRIES +//! @{ +#define CMD_REMOVE_PENDING_ENTRIES 0x0009 +struct __RFC_STRUCT rfc_CMD_REMOVE_PENDING_ENTRIES_s { + uint16_t commandNo; //!< The command ID number 0x0009 + uint16_t __dummy0; + dataQueue_t* pQueue; //!< Pointer to the queue structure to be flushed + uint8_t* pFirstEntry; //!< Pointer to the first entry that was removed +}; + +//! @} + +//! \addtogroup CMD_SET_RAT_CMP +//! @{ +#define CMD_SET_RAT_CMP 0x000A +struct __RFC_STRUCT rfc_CMD_SET_RAT_CMP_s { + uint16_t commandNo; //!< The command ID number 0x000A + uint8_t ratCh; //!< The radio timer channel number + uint8_t __dummy0; + ratmr_t compareTime; //!< The time at which the compare occurs +}; + +//! @} + +//! \addtogroup CMD_SET_RAT_CPT +//! @{ +#define CMD_SET_RAT_CPT 0x0603 +struct __RFC_STRUCT rfc_CMD_SET_RAT_CPT_s { + uint16_t commandNo; //!< The command ID number 0x0603 + struct { + uint16_t :3; + uint16_t inputSrc:5; //!< Input source indicator + uint16_t ratCh:4; //!< The radio timer channel number + uint16_t bRepeated:1; //!< \brief 0: Single capture mode
+ //!< 1: Repeated capture mode + uint16_t inputMode:2; //!< \brief Input mode:
+ //!< 0: Capture on rising edge
+ //!< 1: Capture on falling edge
+ //!< 2: Capture on both edges
+ //!< 3: Reserved + } config; +}; + +//! @} + +//! \addtogroup CMD_DISABLE_RAT_CH +//! @{ +#define CMD_DISABLE_RAT_CH 0x0408 +struct __RFC_STRUCT rfc_CMD_DISABLE_RAT_CH_s { + uint16_t commandNo; //!< The command ID number 0x0408 + uint8_t ratCh; //!< The radio timer channel number +}; + +//! @} + +//! \addtogroup CMD_SET_RAT_OUTPUT +//! @{ +#define CMD_SET_RAT_OUTPUT 0x0604 +struct __RFC_STRUCT rfc_CMD_SET_RAT_OUTPUT_s { + uint16_t commandNo; //!< The command ID number 0x0604 + struct { + uint16_t :2; + uint16_t outputSel:3; //!< Output event indicator + uint16_t outputMode:3; //!< \brief 0: Set output line low as default; and pulse on event. Duration of pulse is one RF Core clock period (ca. 41.67 ns).
+ //!< 1: Set output line high on event
+ //!< 2: Set output line low on event
+ //!< 3: Toggle (invert) output line state on event
+ //!< 4: Immediately set output line to low (does not change upon event)
+ //!< 5: Immediately set output line to high (does not change upon event)
+ //!< Others: Reserved + uint16_t ratCh:4; //!< The radio timer channel number + } config; +}; + +//! @} + +//! \addtogroup CMD_ARM_RAT_CH +//! @{ +#define CMD_ARM_RAT_CH 0x0409 +struct __RFC_STRUCT rfc_CMD_ARM_RAT_CH_s { + uint16_t commandNo; //!< The command ID number 0x0409 + uint8_t ratCh; //!< The radio timer channel number +}; + +//! @} + +//! \addtogroup CMD_DISARM_RAT_CH +//! @{ +#define CMD_DISARM_RAT_CH 0x040A +struct __RFC_STRUCT rfc_CMD_DISARM_RAT_CH_s { + uint16_t commandNo; //!< The command ID number 0x040A + uint8_t ratCh; //!< The radio timer channel number +}; + +//! @} + +//! \addtogroup CMD_SET_TX_POWER +//! @{ +#define CMD_SET_TX_POWER 0x0010 +struct __RFC_STRUCT rfc_CMD_SET_TX_POWER_s { + uint16_t commandNo; //!< The command ID number 0x0010 + struct { + uint16_t IB:6; //!< Value to write to the PA power control field at 25 °C + uint16_t GC:2; //!< Value to write to the gain control of the 1st stage of the PA + uint16_t boost:1; //!< Value of boost bit in synth + uint16_t tempCoeff:7; //!< Temperature coefficient for IB. 0: No temperature compensation + } txPower; //!< New Tx power setting +}; + +//! @} + +//! \addtogroup CMD_UPDATE_FS +//! @{ +#define CMD_UPDATE_FS 0x0011 +struct __RFC_STRUCT rfc_CMD_UPDATE_FS_s { + uint16_t commandNo; //!< The command ID number 0x0011 + uint16_t frequency; //!< The frequency in MHz to tune to + uint16_t fractFreq; //!< Fractional part of the frequency to tune to +}; + +//! @} + +//! \addtogroup CMD_BUS_REQUEST +//! @{ +#define CMD_BUS_REQUEST 0x040E +struct __RFC_STRUCT rfc_CMD_BUS_REQUEST_s { + uint16_t commandNo; //!< The command ID number 0x040E + uint8_t bSysBusNeeded; //!< \brief 0: System bus may sleep
+ //!< 1: System bus access needed +}; + +//! @} + +//! @} +//! @} +#endif /* COMMON_CMD_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/data_entry.h b/cpu/cc26xx-cc13xx/rf-core/api/data_entry.h new file mode 100644 index 000000000..c396a211f --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/data_entry.h @@ -0,0 +1,213 @@ +/****************************************************************************** +* Filename: data_entry.h +* Revised: 2015-08-04 11:44:20 +0200 (Tue, 04 Aug 2015) +* Revision: 44329 +* +* Description: Definition of API for data exchange +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3) Neither the name of the ORGANIZATION nor the names of its contributors may +* be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef DATA_ENTRY_H_ +#define DATA_ENTRY_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup data_entry +//! @{ + +#include +#include "mailbox.h" + +typedef struct __RFC_STRUCT rfc_dataEntry_s rfc_dataEntry_t; +typedef struct __RFC_STRUCT rfc_dataEntryGeneral_s rfc_dataEntryGeneral_t; +typedef struct __RFC_STRUCT rfc_dataEntryMulti_s rfc_dataEntryMulti_t; +typedef struct __RFC_STRUCT rfc_dataEntryPointer_s rfc_dataEntryPointer_t; +typedef struct __RFC_STRUCT rfc_dataEntryPartial_s rfc_dataEntryPartial_t; + +//! \addtogroup dataEntry +//! @{ +struct __RFC_STRUCT rfc_dataEntry_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
+ //!< 0: General data entry
+ //!< 1: Multi-element Rx entry
+ //!< 2: Pointer entry
+ //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
+ //!< 0: No length indicator
+ //!< 1: One byte length indicator
+ //!< 2: Two bytes length indicator
+ //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
+ //!< For other entries: Number of bytes following this length field +}; + +//! @} + +//! \addtogroup dataEntryGeneral +//! @{ +//! General data entry structure (type = 0) + +struct __RFC_STRUCT rfc_dataEntryGeneral_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
+ //!< 0: General data entry
+ //!< 1: Multi-element Rx entry
+ //!< 2: Pointer entry
+ //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
+ //!< 0: No length indicator
+ //!< 1: One byte length indicator
+ //!< 2: Two bytes length indicator
+ //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
+ //!< For other entries: Number of bytes following this length field + uint8_t data; //!< First byte of the data array to be received or transmitted +}; + +//! @} + +//! \addtogroup dataEntryMulti +//! @{ +//! Multi-element data entry structure (type = 1) + +struct __RFC_STRUCT rfc_dataEntryMulti_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
+ //!< 0: General data entry
+ //!< 1: Multi-element Rx entry
+ //!< 2: Pointer entry
+ //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
+ //!< 0: No length indicator
+ //!< 1: One byte length indicator
+ //!< 2: Two bytes length indicator
+ //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
+ //!< For other entries: Number of bytes following this length field + uint16_t numElements; //!< Number of entry elements committed in the entry + uint16_t nextIndex; //!< Index to the byte after the last byte of the last entry element committed by the radio CPU + uint8_t rxData; //!< First byte of the data array of received data entry elements +}; + +//! @} + +//! \addtogroup dataEntryPointer +//! @{ +//! Pointer data entry structure (type = 2) + +struct __RFC_STRUCT rfc_dataEntryPointer_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
+ //!< 0: General data entry
+ //!< 1: Multi-element Rx entry
+ //!< 2: Pointer entry
+ //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
+ //!< 0: No length indicator
+ //!< 1: One byte length indicator
+ //!< 2: Two bytes length indicator
+ //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
+ //!< For other entries: Number of bytes following this length field + uint8_t* pData; //!< Pointer to data buffer of data to be received ro transmitted +}; + +//! @} + +//! \addtogroup dataEntryPartial +//! @{ +//! Partial read data entry structure (type = 3) + +struct __RFC_STRUCT rfc_dataEntryPartial_s { + uint8_t* pNextEntry; //!< Pointer to next entry in the queue, NULL if this is the last entry + uint8_t status; //!< Indicates status of entry, including whether it is free for the system CPU to write to + struct { + uint8_t type:2; //!< \brief Type of data entry structure
+ //!< 0: General data entry
+ //!< 1: Multi-element Rx entry
+ //!< 2: Pointer entry
+ //!< 3: Partial read Rx entry + uint8_t lenSz:2; //!< \brief Size of length word in start of each Rx entry element
+ //!< 0: No length indicator
+ //!< 1: One byte length indicator
+ //!< 2: Two bytes length indicator
+ //!< 3: Reserved + uint8_t irqIntv:4; //!< \brief For partial read Rx entry only: The number of bytes between interrupt generated + //!< by the radio CPU (0: 16 bytes) + } config; + uint16_t length; //!< \brief For pointer entries: Number of bytes in the data buffer pointed to
+ //!< For other entries: Number of bytes following this length field + struct { + uint16_t numElements:13; //!< Number of entry elements committed in the entry + uint16_t bEntryOpen:1; //!< 1 if the entry contains an element that is still open for appending data + uint16_t bFirstCont:1; //!< 1 if the first element is a continuation of the last packet from the previous entry + uint16_t bLastCont:1; //!< 1 if the packet in the last element continues in the next entry + } pktStatus; + uint16_t nextIndex; //!< Index to the byte after the last byte of the last entry element committed by the radio CPU + uint8_t rxData; //!< First byte of the data array of received data entry elements +}; + +//! @} + +//! @} +//! @} +#endif /* DATA_ENTRY_H_ */ diff --git a/cpu/cc26xx/dev/rfc-api/ieee_cmd.h b/cpu/cc26xx-cc13xx/rf-core/api/ieee_cmd.h similarity index 97% rename from cpu/cc26xx/dev/rfc-api/ieee_cmd.h rename to cpu/cc26xx-cc13xx/rf-core/api/ieee_cmd.h index e06207053..62f9abd32 100644 --- a/cpu/cc26xx/dev/rfc-api/ieee_cmd.h +++ b/cpu/cc26xx-cc13xx/rf-core/api/ieee_cmd.h @@ -1,614 +1,611 @@ -/****************************************************************************** -* Filename: ieee_cmd.h -* Revised: $ $ -* Revision: $ $ -* -* Description: CC26xx/CC13xx API for IEEE 802.15.4 commands -* -* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -******************************************************************************/ - -#ifndef __IEEE_CMD_H -#define __IEEE_CMD_H - -#ifndef __RFC_STRUCT -#ifdef __GNUC__ -#define __RFC_STRUCT __attribute__ ((aligned (4))) -#else -#define __RFC_STRUCT -#endif -#endif - -//! \addtogroup rfc -//! @{ - -//! \addtogroup ieee_cmd -//! @{ - -#include -#include "mailbox.h" -#include "common_cmd.h" - -typedef struct __RFC_STRUCT rfc_CMD_IEEE_RX_s rfc_CMD_IEEE_RX_t; -typedef struct __RFC_STRUCT rfc_shortAddrEntry_s rfc_shortAddrEntry_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_CSMA_s rfc_CMD_IEEE_CSMA_t; -typedef struct __RFC_STRUCT rfc_ieeeAuxSecCtrl_s rfc_ieeeAuxSecCtrl_t; -typedef struct __RFC_STRUCT rfc_ieeeRxCorrCrc_s rfc_ieeeRxCorrCrc_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_RX_ACK_s rfc_CMD_IEEE_RX_ACK_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_BG_s rfc_CMD_IEEE_ABORT_BG_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_ED_SCAN_s rfc_CMD_IEEE_ED_SCAN_t; -typedef struct __RFC_STRUCT rfc_ieeeMacHdr_s rfc_ieeeMacHdr_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_FG_s rfc_CMD_IEEE_ABORT_FG_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_CCA_REQ_s rfc_CMD_IEEE_CCA_REQ_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_SETUP_s rfc_CMD_IEEE_SETUP_t; -typedef struct __RFC_STRUCT rfc_ieeeRxOutput_s rfc_ieeeRxOutput_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_MOD_SRC_MATCH_s rfc_CMD_IEEE_MOD_SRC_MATCH_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_STOP_FG_s rfc_CMD_IEEE_STOP_FG_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_TX_s rfc_CMD_IEEE_TX_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_MOD_FILT_s rfc_CMD_IEEE_MOD_FILT_t; -typedef struct __RFC_STRUCT rfc_CMD_IEEE_MOD_CCA_s rfc_CMD_IEEE_MOD_CCA_t; - -//! \addtogroup CMD_IEEE_RX -//! @{ -#define CMD_IEEE_RX 0x2801 -struct __RFC_STRUCT rfc_CMD_IEEE_RX_s { - uint16_t commandNo; //!< The command ID number 0x2801 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to tune to in the start of the operation
- //!< 0: Use existing channel
- //!< 11–26: Use as IEEE 802.15.4 channel, i.e. frequency is (2405 + 5 × (channel - 11)) MHz
- //!< 60–207: Frequency is (2300 + channel) MHz
- //!< Others: Reserved - struct { - uint8_t bAutoFlushCrc:1; //!< If 1, automatically remove packets with CRC error from Rx queue - uint8_t bAutoFlushIgn:1; //!< If 1, automatically remove packets that can be ignored according to frame filtering from Rx queue - uint8_t bIncludePhyHdr:1; //!< If 1, include the received PHY header field in the stored packet; otherwise discard it - uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it - uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue - uint8_t bAppendCorrCrc:1; //!< If 1, append a correlation value and CRC result byte to the packet in the Rx queue - uint8_t bAppendSrcInd:1; //!< If 1, append an index from the source matching algorithm - uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue - } rxConfig; - dataQueue_t* pRxQ; //!< Pointer to receive queue - rfc_ieeeRxOutput_t *pOutput; //!< Pointer to output structure (NULL: Do not store results) - struct { - uint16_t frameFiltEn:1; //!< \brief 0: Disable frame filtering
- //!< 1: Enable frame filtering - uint16_t frameFiltStop:1; //!< \brief 0: Receive all packets to the end
- //!< 1: Stop receiving frame once frame filtering has caused the frame to be rejected. - uint16_t autoAckEn:1; //!< \brief 0: Disable auto ACK
- //!< 1: Enable auto ACK. - uint16_t slottedAckEn:1; //!< \brief 0: Non-slotted ACK
- //!< 1: Slotted ACK. - uint16_t autoPendEn:1; //!< \brief 0: Auto-pend disabled
- //!< 1: Auto-pend enabled - uint16_t defaultPend:1; //!< The value of the pending data bit in auto ACK packets that are not subject to auto-pend - uint16_t bPendDataReqOnly:1; //!< \brief 0: Use auto-pend for any packet
- //!< 1: Use auto-pend for data request packets only - uint16_t bPanCoord:1; //!< \brief 0: Device is not PAN coordinator
- //!< 1: Device is PAN coordinator - uint16_t maxFrameVersion:2; //!< Reject frames where the frame version field in the FCF is greater than this value - uint16_t fcfReservedMask:3; //!< Value to be AND-ed with the reserved part of the FCF; frame rejected if result is non-zero - uint16_t modifyFtFilter:2; //!< \brief Treatment of MSB of frame type field before frame-type filtering:
- //!< 0: No modification
- //!< 1: Invert MSB
- //!< 2: Set MSB to 0
- //!< 3: Set MSB to 1 - uint16_t bStrictLenFilter:1; //!< \brief 0: Accept acknowledgement frames of any length >= 5
- //!< 1: Accept only acknowledgement frames of length 5 - } frameFiltOpt; //!< Frame filtering options - struct { - uint8_t bAcceptFt0Beacon:1; //!< \brief Treatment of frames with frame type 000 (beacon):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt1Data:1; //!< \brief Treatment of frames with frame type 001 (data):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt2Ack:1; //!< \brief Treatment of frames with frame type 010 (ACK):
- //!< 0: Reject, unless running ACK receive command
- //!< 1: Always accept - uint8_t bAcceptFt3MacCmd:1; //!< \brief Treatment of frames with frame type 011 (MAC command):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt4Reserved:1; //!< \brief Treatment of frames with frame type 100 (reserved):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt5Reserved:1; //!< \brief Treatment of frames with frame type 101 (reserved):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt6Reserved:1; //!< \brief Treatment of frames with frame type 110 (reserved):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt7Reserved:1; //!< \brief Treatment of frames with frame type 111 (reserved):
- //!< 0: Reject
- //!< 1: Accept - } frameTypes; //!< Frame types to receive in frame filtering - struct { - uint8_t ccaEnEnergy:1; //!< Enable energy scan as CCA source - uint8_t ccaEnCorr:1; //!< Enable correlator based carrier sense as CCA source - uint8_t ccaEnSync:1; //!< Enable sync found based carrier sense as CCA source - uint8_t ccaCorrOp:1; //!< \brief Operator to use between energy based and correlator based CCA
- //!< 0: Report busy channel if either ccaEnergy or ccaCorr are busy
- //!< 1: Report busy channel if both ccaEnergy and ccaCorr are busy - uint8_t ccaSyncOp:1; //!< \brief Operator to use between sync found based CCA and the others
- //!< 0: Always report busy channel if ccaSync is busy
- //!< 1: Always report idle channel if ccaSync is idle - uint8_t ccaCorrThr:2; //!< Threshold for number of correlation peaks in correlator based carrier sense - } ccaOpt; //!< CCA options - int8_t ccaRssiThr; //!< RSSI threshold for CCA - uint8_t __dummy0; - uint8_t numExtEntries; //!< Number of extended address entries - uint8_t numShortEntries; //!< Number of short address entries - uint32_t* pExtEntryList; //!< Pointer to list of extended address entries - rfc_shortAddrEntry_t *pShortEntryList;//!< Pointer to list of short address entries - uint64_t localExtAddr; //!< The extended address of the local device - uint16_t localShortAddr; //!< The short address of the local device - uint16_t localPanID; //!< The PAN ID of the local device - uint16_t __dummy1; - uint8_t __dummy2; - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to end the Rx operation - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the Rx - //!< operation -}; - -//! @} - -//! \addtogroup CMD_IEEE_ED_SCAN -//! @{ -#define CMD_IEEE_ED_SCAN 0x2802 -struct __RFC_STRUCT rfc_CMD_IEEE_ED_SCAN_s { - uint16_t commandNo; //!< The command ID number 0x2802 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t channel; //!< \brief Channel to tune to in the start of the operation
- //!< 0: Use existing channel
- //!< 11–26: Use as IEEE 802.15.4 channel, i.e. frequency is (2405 + 5 × (channel - 11)) MHz
- //!< 60–207: Frequency is (2300 + channel) MHz
- //!< Others: Reserved - struct { - uint8_t ccaEnEnergy:1; //!< Enable energy scan as CCA source - uint8_t ccaEnCorr:1; //!< Enable correlator based carrier sense as CCA source - uint8_t ccaEnSync:1; //!< Enable sync found based carrier sense as CCA source - uint8_t ccaCorrOp:1; //!< \brief Operator to use between energy based and correlator based CCA
- //!< 0: Report busy channel if either ccaEnergy or ccaCorr are busy
- //!< 1: Report busy channel if both ccaEnergy and ccaCorr are busy - uint8_t ccaSyncOp:1; //!< \brief Operator to use between sync found based CCA and the others
- //!< 0: Always report busy channel if ccaSync is busy
- //!< 1: Always report idle channel if ccaSync is idle - uint8_t ccaCorrThr:2; //!< Threshold for number of correlation peaks in correlator based carrier sense - } ccaOpt; //!< CCA options - int8_t ccaRssiThr; //!< RSSI threshold for CCA - uint8_t __dummy0; - int8_t maxRssi; //!< The maximum RSSI recorded during the ED scan - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to end the Rx operation - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the Rx - //!< operation -}; - -//! @} - -//! \addtogroup CMD_IEEE_TX -//! @{ -#define CMD_IEEE_TX 0x2C01 -struct __RFC_STRUCT rfc_CMD_IEEE_TX_s { - uint16_t commandNo; //!< The command ID number 0x2C01 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - struct { - uint8_t bIncludePhyHdr:1; //!< \brief 0: Find PHY header automatically
- //!< 1: Insert PHY header from the buffer - uint8_t bIncludeCrc:1; //!< \brief 0: Append automatically calculated CRC
- //!< 1: Insert FCS (CRC) from the buffer - uint8_t :1; - uint8_t payloadLenMsb:5; //!< \brief Most significant bits of payload length. Should only be non-zero to create long - //!< non-standard packets for test purposes - } txOpt; - uint8_t payloadLen; //!< Number of bytes in the payload - uint8_t* pPayload; //!< Pointer to payload buffer of size payloadLen - ratmr_t timeStamp; //!< Time stamp of transmitted frame -}; - -//! @} - -//! \addtogroup CMD_IEEE_CSMA -//! @{ -#define CMD_IEEE_CSMA 0x2C02 -struct __RFC_STRUCT rfc_CMD_IEEE_CSMA_s { - uint16_t commandNo; //!< The command ID number 0x2C02 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint16_t randomState; //!< The state of the pseudo-random generator - uint8_t macMaxBE; //!< The IEEE 802.15.4 MAC parameter macMaxBE - uint8_t macMaxCSMABackoffs; //!< The IEEE 802.15.4 MAC parameter macMaxCSMABackoffs - struct { - uint8_t initCW:5; //!< The initialization value for the CW parameter - uint8_t bSlotted:1; //!< \brief 0: non-slotted CSMA
- //!< 1: slotted CSMA - uint8_t rxOffMode:2; //!< \brief 0: RX stays on during CSMA backoffs
- //!< 1: The CSMA-CA algorithm will suspend the receiver if no frame is being received
- //!< 2: The CSMA-CA algorithm will suspend the receiver if no frame is being received, - //!< or after finishing it (including auto ACK) otherwise
- //!< 3: The CSMA-CA algorithm will suspend the receiver immediately during back-offs - } csmaConfig; - uint8_t NB; //!< The NB parameter from the IEEE 802.15.4 CSMA-CA algorithm - uint8_t BE; //!< The BE parameter from the IEEE 802.15.4 CSMA-CA algorithm - uint8_t remainingPeriods; //!< The number of remaining periods from a paused backoff countdown - int8_t lastRssi; //!< RSSI measured at the last CCA operation - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to end the CSMA-CA operation - ratmr_t lastTimeStamp; //!< Time of the last CCA operation - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the - //!< CSMA-CA operation -}; - -//! @} - -//! \addtogroup CMD_IEEE_RX_ACK -//! @{ -#define CMD_IEEE_RX_ACK 0x2C03 -struct __RFC_STRUCT rfc_CMD_IEEE_RX_ACK_s { - uint16_t commandNo; //!< The command ID number 0x2C03 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; - uint8_t seqNo; //!< Sequence number to expect - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } endTrigger; //!< Trigger that causes the device to give up acknowledgement reception - ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to give up - //!< acknowledgement reception -}; - -//! @} - -//! \addtogroup CMD_IEEE_ABORT_BG -//! @{ -#define CMD_IEEE_ABORT_BG 0x2C04 -struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_BG_s { - uint16_t commandNo; //!< The command ID number 0x2C04 - uint16_t status; //!< \brief An integer telling the status of the command. This value is - //!< updated by the radio CPU during operation and may be read by the - //!< system CPU at any time. - rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done - ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) - struct { - uint8_t triggerType:4; //!< The type of trigger - uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
- //!< 1: CMD_TRIGGER can be used as an alternative trigger - uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action - uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
- //!< 1: A trigger in the past is triggered as soon as possible - } startTrigger; //!< Identification of the trigger that starts the operation - struct { - uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed - uint8_t nSkip:4; //!< Number of skips if the rule involves skipping - } condition; -}; - -//! @} - -//! \addtogroup CMD_IEEE_MOD_CCA -//! @{ -#define CMD_IEEE_MOD_CCA 0x2001 -struct __RFC_STRUCT rfc_CMD_IEEE_MOD_CCA_s { - uint16_t commandNo; //!< The command ID number 0x2001 - struct { - uint8_t ccaEnEnergy:1; //!< Enable energy scan as CCA source - uint8_t ccaEnCorr:1; //!< Enable correlator based carrier sense as CCA source - uint8_t ccaEnSync:1; //!< Enable sync found based carrier sense as CCA source - uint8_t ccaCorrOp:1; //!< \brief Operator to use between energy based and correlator based CCA
- //!< 0: Report busy channel if either ccaEnergy or ccaCorr are busy
- //!< 1: Report busy channel if both ccaEnergy and ccaCorr are busy - uint8_t ccaSyncOp:1; //!< \brief Operator to use between sync found based CCA and the others
- //!< 0: Always report busy channel if ccaSync is busy
- //!< 1: Always report idle channel if ccaSync is idle - uint8_t ccaCorrThr:2; //!< Threshold for number of correlation peaks in correlator based carrier sense - } newCcaOpt; //!< New value of ccaOpt for the running background level operation - int8_t newCcaRssiThr; //!< New value of ccaRssiThr for the running background level operation -}; - -//! @} - -//! \addtogroup CMD_IEEE_MOD_FILT -//! @{ -#define CMD_IEEE_MOD_FILT 0x2002 -struct __RFC_STRUCT rfc_CMD_IEEE_MOD_FILT_s { - uint16_t commandNo; //!< The command ID number 0x2002 - struct { - uint16_t frameFiltEn:1; //!< \brief 0: Disable frame filtering
- //!< 1: Enable frame filtering - uint16_t frameFiltStop:1; //!< \brief 0: Receive all packets to the end
- //!< 1: Stop receiving frame once frame filtering has caused the frame to be rejected. - uint16_t autoAckEn:1; //!< \brief 0: Disable auto ACK
- //!< 1: Enable auto ACK. - uint16_t slottedAckEn:1; //!< \brief 0: Non-slotted ACK
- //!< 1: Slotted ACK. - uint16_t autoPendEn:1; //!< \brief 0: Auto-pend disabled
- //!< 1: Auto-pend enabled - uint16_t defaultPend:1; //!< The value of the pending data bit in auto ACK packets that are not subject to auto-pend - uint16_t bPendDataReqOnly:1; //!< \brief 0: Use auto-pend for any packet
- //!< 1: Use auto-pend for data request packets only - uint16_t bPanCoord:1; //!< \brief 0: Device is not PAN coordinator
- //!< 1: Device is PAN coordinator - uint16_t maxFrameVersion:2; //!< Reject frames where the frame version field in the FCF is greater than this value - uint16_t fcfReservedMask:3; //!< Value to be AND-ed with the reserved part of the FCF; frame rejected if result is non-zero - uint16_t modifyFtFilter:2; //!< \brief Treatment of MSB of frame type field before frame-type filtering:
- //!< 0: No modification
- //!< 1: Invert MSB
- //!< 2: Set MSB to 0
- //!< 3: Set MSB to 1 - uint16_t bStrictLenFilter:1; //!< \brief 0: Accept acknowledgement frames of any length >= 5
- //!< 1: Accept only acknowledgement frames of length 5 - } newFrameFiltOpt; //!< New value of frameFiltOpt for the running background level operation - struct { - uint8_t bAcceptFt0Beacon:1; //!< \brief Treatment of frames with frame type 000 (beacon):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt1Data:1; //!< \brief Treatment of frames with frame type 001 (data):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt2Ack:1; //!< \brief Treatment of frames with frame type 010 (ACK):
- //!< 0: Reject, unless running ACK receive command
- //!< 1: Always accept - uint8_t bAcceptFt3MacCmd:1; //!< \brief Treatment of frames with frame type 011 (MAC command):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt4Reserved:1; //!< \brief Treatment of frames with frame type 100 (reserved):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt5Reserved:1; //!< \brief Treatment of frames with frame type 101 (reserved):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt6Reserved:1; //!< \brief Treatment of frames with frame type 110 (reserved):
- //!< 0: Reject
- //!< 1: Accept - uint8_t bAcceptFt7Reserved:1; //!< \brief Treatment of frames with frame type 111 (reserved):
- //!< 0: Reject
- //!< 1: Accept - } newFrameTypes; //!< New value of frameTypes for the running background level operation -}; - -//! @} - -//! \addtogroup CMD_IEEE_MOD_SRC_MATCH -//! @{ -#define CMD_IEEE_MOD_SRC_MATCH 0x2003 -struct __RFC_STRUCT rfc_CMD_IEEE_MOD_SRC_MATCH_s { - uint16_t commandNo; //!< The command ID number 0x2003 - struct { - uint8_t bEnable:1; //!< \brief 0: Disable entry
- //!< 1: Enable entry - uint8_t srcPend:1; //!< New value of the pending bit for the entry - uint8_t entryType:1; //!< \brief 0: Extended address
- //!< 1: Short address - } options; - uint8_t entryNo; //!< Index of entry to enable or disable -}; - -//! @} - -//! \addtogroup CMD_IEEE_ABORT_FG -//! @{ -#define CMD_IEEE_ABORT_FG 0x2401 -struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_FG_s { - uint16_t commandNo; //!< The command ID number 0x2401 -}; - -//! @} - -//! \addtogroup CMD_IEEE_STOP_FG -//! @{ -#define CMD_IEEE_STOP_FG 0x2402 -struct __RFC_STRUCT rfc_CMD_IEEE_STOP_FG_s { - uint16_t commandNo; //!< The command ID number 0x2402 -}; - -//! @} - -//! \addtogroup CMD_IEEE_CCA_REQ -//! @{ -#define CMD_IEEE_CCA_REQ 0x2403 -struct __RFC_STRUCT rfc_CMD_IEEE_CCA_REQ_s { - uint16_t commandNo; //!< The command ID number 0x2403 - int8_t currentRssi; //!< The RSSI currently observed on the channel - int8_t maxRssi; //!< The maximum RSSI observed on the channel since Rx was started - struct { - uint8_t ccaState:2; //!< \brief Value of the current CCA state
- //!< 0: Idle
- //!< 1: Busy
- //!< 2: Invalid - uint8_t ccaEnergy:2; //!< \brief Value of the current energy detect CCA state
- //!< 0: Idle
- //!< 1: Busy
- //!< 2: Invalid - uint8_t ccaCorr:2; //!< \brief Value of the current correlator based carrier sense CCA state
- //!< 0: Idle
- //!< 1: Busy
- //!< 2: Invalid - uint8_t ccaSync:1; //!< \brief Value of the current sync found based carrier sense CCA state
- //!< 0: Idle
- //!< 1: Busy - } ccaInfo; -}; - -//! @} - -//! \addtogroup ieeeRxOutput -//! @{ -//! Output structure for CMD_IEEE_RX - -struct __RFC_STRUCT rfc_ieeeRxOutput_s { - uint8_t nTxAck; //!< Total number of transmitted ACK frames - uint8_t nRxBeacon; //!< Number of received beacon frames - uint8_t nRxData; //!< Number of received data frames - uint8_t nRxAck; //!< Number of received acknowledgement frames - uint8_t nRxMacCmd; //!< Number of received MAC command frames - uint8_t nRxReserved; //!< Number of received frames with reserved frame type - uint8_t nRxNok; //!< Number of received frames with CRC error - uint8_t nRxIgnored; //!< Number of frames received that are to be ignored - uint8_t nRxBufFull; //!< Number of received frames discarded because the Rx buffer was full - int8_t lastRssi; //!< RSSI of last received frame - int8_t maxRssi; //!< Highest RSSI observed in the operation - uint8_t __dummy0; - ratmr_t beaconTimeStamp; //!< Time stamp of last received beacon frame -}; - -//! @} - -//! \addtogroup shortAddrEntry -//! @{ -//! Structure for short address entries - -struct __RFC_STRUCT rfc_shortAddrEntry_s { - uint16_t shortAddr; //!< Short address - uint16_t panId; //!< PAN ID -}; - -//! @} - -//! \addtogroup ieeeRxCorrCrc -//! @{ -//! Receive status byte that may be appended to message in receive buffer - -struct __RFC_STRUCT rfc_ieeeRxCorrCrc_s { - struct { - uint8_t corr:6; //!< The correlation value - uint8_t bIgnore:1; //!< 1 if the packet should be rejected by frame filtering, 0 otherwise - uint8_t bCrcErr:1; //!< 1 if the packet was received with CRC error, 0 otherwise - } status; -}; - -//! @} - -//! @} -//! @} -#endif +/****************************************************************************** +* Filename: ieee_cmd.h +* Revised: $ $ +* Revision: $ $ +* +* Description: CC26xx/CC13xx API for IEEE 802.15.4 commands +* +* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef IEEE_CMD_H_ +#define IEEE_CMD_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup ieee_cmd +//! @{ + +#include +#include "mailbox.h" +#include "common_cmd.h" + +typedef struct __RFC_STRUCT rfc_CMD_IEEE_RX_s rfc_CMD_IEEE_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_ED_SCAN_s rfc_CMD_IEEE_ED_SCAN_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_TX_s rfc_CMD_IEEE_TX_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_CSMA_s rfc_CMD_IEEE_CSMA_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_RX_ACK_s rfc_CMD_IEEE_RX_ACK_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_BG_s rfc_CMD_IEEE_ABORT_BG_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_MOD_CCA_s rfc_CMD_IEEE_MOD_CCA_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_MOD_FILT_s rfc_CMD_IEEE_MOD_FILT_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_MOD_SRC_MATCH_s rfc_CMD_IEEE_MOD_SRC_MATCH_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_FG_s rfc_CMD_IEEE_ABORT_FG_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_STOP_FG_s rfc_CMD_IEEE_STOP_FG_t; +typedef struct __RFC_STRUCT rfc_CMD_IEEE_CCA_REQ_s rfc_CMD_IEEE_CCA_REQ_t; +typedef struct __RFC_STRUCT rfc_ieeeRxOutput_s rfc_ieeeRxOutput_t; +typedef struct __RFC_STRUCT rfc_shortAddrEntry_s rfc_shortAddrEntry_t; +typedef struct __RFC_STRUCT rfc_ieeeRxCorrCrc_s rfc_ieeeRxCorrCrc_t; + +//! \addtogroup CMD_IEEE_RX +//! @{ +#define CMD_IEEE_RX 0x2801 +struct __RFC_STRUCT rfc_CMD_IEEE_RX_s { + uint16_t commandNo; //!< The command ID number 0x2801 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to tune to in the start of the operation
+ //!< 0: Use existing channel
+ //!< 11–26: Use as IEEE 802.15.4 channel, i.e. frequency is (2405 + 5 × (channel - 11)) MHz
+ //!< 60–207: Frequency is (2300 + channel) MHz
+ //!< Others: Reserved + struct { + uint8_t bAutoFlushCrc:1; //!< If 1, automatically remove packets with CRC error from Rx queue + uint8_t bAutoFlushIgn:1; //!< If 1, automatically remove packets that can be ignored according to frame filtering from Rx queue + uint8_t bIncludePhyHdr:1; //!< If 1, include the received PHY header field in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendCorrCrc:1; //!< If 1, append a correlation value and CRC result byte to the packet in the Rx queue + uint8_t bAppendSrcInd:1; //!< If 1, append an index from the source matching algorithm + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + } rxConfig; + dataQueue_t* pRxQ; //!< Pointer to receive queue + rfc_ieeeRxOutput_t *pOutput; //!< Pointer to output structure (NULL: Do not store results) + struct { + uint16_t frameFiltEn:1; //!< \brief 0: Disable frame filtering
+ //!< 1: Enable frame filtering + uint16_t frameFiltStop:1; //!< \brief 0: Receive all packets to the end
+ //!< 1: Stop receiving frame once frame filtering has caused the frame to be rejected. + uint16_t autoAckEn:1; //!< \brief 0: Disable auto ACK
+ //!< 1: Enable auto ACK. + uint16_t slottedAckEn:1; //!< \brief 0: Non-slotted ACK
+ //!< 1: Slotted ACK. + uint16_t autoPendEn:1; //!< \brief 0: Auto-pend disabled
+ //!< 1: Auto-pend enabled + uint16_t defaultPend:1; //!< The value of the pending data bit in auto ACK packets that are not subject to auto-pend + uint16_t bPendDataReqOnly:1; //!< \brief 0: Use auto-pend for any packet
+ //!< 1: Use auto-pend for data request packets only + uint16_t bPanCoord:1; //!< \brief 0: Device is not PAN coordinator
+ //!< 1: Device is PAN coordinator + uint16_t maxFrameVersion:2; //!< Reject frames where the frame version field in the FCF is greater than this value + uint16_t fcfReservedMask:3; //!< Value to be AND-ed with the reserved part of the FCF; frame rejected if result is non-zero + uint16_t modifyFtFilter:2; //!< \brief Treatment of MSB of frame type field before frame-type filtering:
+ //!< 0: No modification
+ //!< 1: Invert MSB
+ //!< 2: Set MSB to 0
+ //!< 3: Set MSB to 1 + uint16_t bStrictLenFilter:1; //!< \brief 0: Accept acknowledgement frames of any length >= 5
+ //!< 1: Accept only acknowledgement frames of length 5 + } frameFiltOpt; //!< Frame filtering options + struct { + uint8_t bAcceptFt0Beacon:1; //!< \brief Treatment of frames with frame type 000 (beacon):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt1Data:1; //!< \brief Treatment of frames with frame type 001 (data):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt2Ack:1; //!< \brief Treatment of frames with frame type 010 (ACK):
+ //!< 0: Reject, unless running ACK receive command
+ //!< 1: Always accept + uint8_t bAcceptFt3MacCmd:1; //!< \brief Treatment of frames with frame type 011 (MAC command):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt4Reserved:1; //!< \brief Treatment of frames with frame type 100 (reserved):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt5Reserved:1; //!< \brief Treatment of frames with frame type 101 (reserved):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt6Reserved:1; //!< \brief Treatment of frames with frame type 110 (reserved):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt7Reserved:1; //!< \brief Treatment of frames with frame type 111 (reserved):
+ //!< 0: Reject
+ //!< 1: Accept + } frameTypes; //!< Frame types to receive in frame filtering + struct { + uint8_t ccaEnEnergy:1; //!< Enable energy scan as CCA source + uint8_t ccaEnCorr:1; //!< Enable correlator based carrier sense as CCA source + uint8_t ccaEnSync:1; //!< Enable sync found based carrier sense as CCA source + uint8_t ccaCorrOp:1; //!< \brief Operator to use between energy based and correlator based CCA
+ //!< 0: Report busy channel if either ccaEnergy or ccaCorr are busy
+ //!< 1: Report busy channel if both ccaEnergy and ccaCorr are busy + uint8_t ccaSyncOp:1; //!< \brief Operator to use between sync found based CCA and the others
+ //!< 0: Always report busy channel if ccaSync is busy
+ //!< 1: Always report idle channel if ccaSync is idle + uint8_t ccaCorrThr:2; //!< Threshold for number of correlation peaks in correlator based carrier sense + } ccaOpt; //!< CCA options + int8_t ccaRssiThr; //!< RSSI threshold for CCA + uint8_t __dummy0; + uint8_t numExtEntries; //!< Number of extended address entries + uint8_t numShortEntries; //!< Number of short address entries + uint32_t* pExtEntryList; //!< Pointer to list of extended address entries + rfc_shortAddrEntry_t *pShortEntryList;//!< Pointer to list of short address entries + uint64_t localExtAddr; //!< The extended address of the local device + uint16_t localShortAddr; //!< The short address of the local device + uint16_t localPanID; //!< The PAN ID of the local device + uint16_t __dummy1; + uint8_t __dummy2; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the Rx operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the Rx + //!< operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_ED_SCAN +//! @{ +#define CMD_IEEE_ED_SCAN 0x2802 +struct __RFC_STRUCT rfc_CMD_IEEE_ED_SCAN_s { + uint16_t commandNo; //!< The command ID number 0x2802 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t channel; //!< \brief Channel to tune to in the start of the operation
+ //!< 0: Use existing channel
+ //!< 11–26: Use as IEEE 802.15.4 channel, i.e. frequency is (2405 + 5 × (channel - 11)) MHz
+ //!< 60–207: Frequency is (2300 + channel) MHz
+ //!< Others: Reserved + struct { + uint8_t ccaEnEnergy:1; //!< Enable energy scan as CCA source + uint8_t ccaEnCorr:1; //!< Enable correlator based carrier sense as CCA source + uint8_t ccaEnSync:1; //!< Enable sync found based carrier sense as CCA source + uint8_t ccaCorrOp:1; //!< \brief Operator to use between energy based and correlator based CCA
+ //!< 0: Report busy channel if either ccaEnergy or ccaCorr are busy
+ //!< 1: Report busy channel if both ccaEnergy and ccaCorr are busy + uint8_t ccaSyncOp:1; //!< \brief Operator to use between sync found based CCA and the others
+ //!< 0: Always report busy channel if ccaSync is busy
+ //!< 1: Always report idle channel if ccaSync is idle + uint8_t ccaCorrThr:2; //!< Threshold for number of correlation peaks in correlator based carrier sense + } ccaOpt; //!< CCA options + int8_t ccaRssiThr; //!< RSSI threshold for CCA + uint8_t __dummy0; + int8_t maxRssi; //!< The maximum RSSI recorded during the ED scan + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the Rx operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the Rx + //!< operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_TX +//! @{ +#define CMD_IEEE_TX 0x2C01 +struct __RFC_STRUCT rfc_CMD_IEEE_TX_s { + uint16_t commandNo; //!< The command ID number 0x2C01 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bIncludePhyHdr:1; //!< \brief 0: Find PHY header automatically
+ //!< 1: Insert PHY header from the buffer + uint8_t bIncludeCrc:1; //!< \brief 0: Append automatically calculated CRC
+ //!< 1: Insert FCS (CRC) from the buffer + uint8_t :1; + uint8_t payloadLenMsb:5; //!< \brief Most significant bits of payload length. Should only be non-zero to create long + //!< non-standard packets for test purposes + } txOpt; + uint8_t payloadLen; //!< Number of bytes in the payload + uint8_t* pPayload; //!< Pointer to payload buffer of size payloadLen + ratmr_t timeStamp; //!< Time stamp of transmitted frame +}; + +//! @} + +//! \addtogroup CMD_IEEE_CSMA +//! @{ +#define CMD_IEEE_CSMA 0x2C02 +struct __RFC_STRUCT rfc_CMD_IEEE_CSMA_s { + uint16_t commandNo; //!< The command ID number 0x2C02 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint16_t randomState; //!< The state of the pseudo-random generator + uint8_t macMaxBE; //!< The IEEE 802.15.4 MAC parameter macMaxBE + uint8_t macMaxCSMABackoffs; //!< The IEEE 802.15.4 MAC parameter macMaxCSMABackoffs + struct { + uint8_t initCW:5; //!< The initialization value for the CW parameter + uint8_t bSlotted:1; //!< \brief 0: non-slotted CSMA
+ //!< 1: slotted CSMA + uint8_t rxOffMode:2; //!< \brief 0: RX stays on during CSMA backoffs
+ //!< 1: The CSMA-CA algorithm will suspend the receiver if no frame is being received
+ //!< 2: The CSMA-CA algorithm will suspend the receiver if no frame is being received, + //!< or after finishing it (including auto ACK) otherwise
+ //!< 3: The CSMA-CA algorithm will suspend the receiver immediately during back-offs + } csmaConfig; + uint8_t NB; //!< The NB parameter from the IEEE 802.15.4 CSMA-CA algorithm + uint8_t BE; //!< The BE parameter from the IEEE 802.15.4 CSMA-CA algorithm + uint8_t remainingPeriods; //!< The number of remaining periods from a paused backoff countdown + int8_t lastRssi; //!< RSSI measured at the last CCA operation + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to end the CSMA-CA operation + ratmr_t lastTimeStamp; //!< Time of the last CCA operation + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to end the + //!< CSMA-CA operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_RX_ACK +//! @{ +#define CMD_IEEE_RX_ACK 0x2C03 +struct __RFC_STRUCT rfc_CMD_IEEE_RX_ACK_s { + uint16_t commandNo; //!< The command ID number 0x2C03 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + uint8_t seqNo; //!< Sequence number to expect + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger that causes the device to give up acknowledgement reception + ratmr_t endTime; //!< \brief Time used together with endTrigger that causes the device to give up + //!< acknowledgement reception +}; + +//! @} + +//! \addtogroup CMD_IEEE_ABORT_BG +//! @{ +#define CMD_IEEE_ABORT_BG 0x2C04 +struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_BG_s { + uint16_t commandNo; //!< The command ID number 0x2C04 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; +}; + +//! @} + +//! \addtogroup CMD_IEEE_MOD_CCA +//! @{ +#define CMD_IEEE_MOD_CCA 0x2001 +struct __RFC_STRUCT rfc_CMD_IEEE_MOD_CCA_s { + uint16_t commandNo; //!< The command ID number 0x2001 + struct { + uint8_t ccaEnEnergy:1; //!< Enable energy scan as CCA source + uint8_t ccaEnCorr:1; //!< Enable correlator based carrier sense as CCA source + uint8_t ccaEnSync:1; //!< Enable sync found based carrier sense as CCA source + uint8_t ccaCorrOp:1; //!< \brief Operator to use between energy based and correlator based CCA
+ //!< 0: Report busy channel if either ccaEnergy or ccaCorr are busy
+ //!< 1: Report busy channel if both ccaEnergy and ccaCorr are busy + uint8_t ccaSyncOp:1; //!< \brief Operator to use between sync found based CCA and the others
+ //!< 0: Always report busy channel if ccaSync is busy
+ //!< 1: Always report idle channel if ccaSync is idle + uint8_t ccaCorrThr:2; //!< Threshold for number of correlation peaks in correlator based carrier sense + } newCcaOpt; //!< New value of ccaOpt for the running background level operation + int8_t newCcaRssiThr; //!< New value of ccaRssiThr for the running background level operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_MOD_FILT +//! @{ +#define CMD_IEEE_MOD_FILT 0x2002 +struct __RFC_STRUCT rfc_CMD_IEEE_MOD_FILT_s { + uint16_t commandNo; //!< The command ID number 0x2002 + struct { + uint16_t frameFiltEn:1; //!< \brief 0: Disable frame filtering
+ //!< 1: Enable frame filtering + uint16_t frameFiltStop:1; //!< \brief 0: Receive all packets to the end
+ //!< 1: Stop receiving frame once frame filtering has caused the frame to be rejected. + uint16_t autoAckEn:1; //!< \brief 0: Disable auto ACK
+ //!< 1: Enable auto ACK. + uint16_t slottedAckEn:1; //!< \brief 0: Non-slotted ACK
+ //!< 1: Slotted ACK. + uint16_t autoPendEn:1; //!< \brief 0: Auto-pend disabled
+ //!< 1: Auto-pend enabled + uint16_t defaultPend:1; //!< The value of the pending data bit in auto ACK packets that are not subject to auto-pend + uint16_t bPendDataReqOnly:1; //!< \brief 0: Use auto-pend for any packet
+ //!< 1: Use auto-pend for data request packets only + uint16_t bPanCoord:1; //!< \brief 0: Device is not PAN coordinator
+ //!< 1: Device is PAN coordinator + uint16_t maxFrameVersion:2; //!< Reject frames where the frame version field in the FCF is greater than this value + uint16_t fcfReservedMask:3; //!< Value to be AND-ed with the reserved part of the FCF; frame rejected if result is non-zero + uint16_t modifyFtFilter:2; //!< \brief Treatment of MSB of frame type field before frame-type filtering:
+ //!< 0: No modification
+ //!< 1: Invert MSB
+ //!< 2: Set MSB to 0
+ //!< 3: Set MSB to 1 + uint16_t bStrictLenFilter:1; //!< \brief 0: Accept acknowledgement frames of any length >= 5
+ //!< 1: Accept only acknowledgement frames of length 5 + } newFrameFiltOpt; //!< New value of frameFiltOpt for the running background level operation + struct { + uint8_t bAcceptFt0Beacon:1; //!< \brief Treatment of frames with frame type 000 (beacon):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt1Data:1; //!< \brief Treatment of frames with frame type 001 (data):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt2Ack:1; //!< \brief Treatment of frames with frame type 010 (ACK):
+ //!< 0: Reject, unless running ACK receive command
+ //!< 1: Always accept + uint8_t bAcceptFt3MacCmd:1; //!< \brief Treatment of frames with frame type 011 (MAC command):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt4Reserved:1; //!< \brief Treatment of frames with frame type 100 (reserved):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt5Reserved:1; //!< \brief Treatment of frames with frame type 101 (reserved):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt6Reserved:1; //!< \brief Treatment of frames with frame type 110 (reserved):
+ //!< 0: Reject
+ //!< 1: Accept + uint8_t bAcceptFt7Reserved:1; //!< \brief Treatment of frames with frame type 111 (reserved):
+ //!< 0: Reject
+ //!< 1: Accept + } newFrameTypes; //!< New value of frameTypes for the running background level operation +}; + +//! @} + +//! \addtogroup CMD_IEEE_MOD_SRC_MATCH +//! @{ +#define CMD_IEEE_MOD_SRC_MATCH 0x2003 +struct __RFC_STRUCT rfc_CMD_IEEE_MOD_SRC_MATCH_s { + uint16_t commandNo; //!< The command ID number 0x2003 + struct { + uint8_t bEnable:1; //!< \brief 0: Disable entry
+ //!< 1: Enable entry + uint8_t srcPend:1; //!< New value of the pending bit for the entry + uint8_t entryType:1; //!< \brief 0: Extended address
+ //!< 1: Short address + } options; + uint8_t entryNo; //!< Index of entry to enable or disable +}; + +//! @} + +//! \addtogroup CMD_IEEE_ABORT_FG +//! @{ +#define CMD_IEEE_ABORT_FG 0x2401 +struct __RFC_STRUCT rfc_CMD_IEEE_ABORT_FG_s { + uint16_t commandNo; //!< The command ID number 0x2401 +}; + +//! @} + +//! \addtogroup CMD_IEEE_STOP_FG +//! @{ +#define CMD_IEEE_STOP_FG 0x2402 +struct __RFC_STRUCT rfc_CMD_IEEE_STOP_FG_s { + uint16_t commandNo; //!< The command ID number 0x2402 +}; + +//! @} + +//! \addtogroup CMD_IEEE_CCA_REQ +//! @{ +#define CMD_IEEE_CCA_REQ 0x2403 +struct __RFC_STRUCT rfc_CMD_IEEE_CCA_REQ_s { + uint16_t commandNo; //!< The command ID number 0x2403 + int8_t currentRssi; //!< The RSSI currently observed on the channel + int8_t maxRssi; //!< The maximum RSSI observed on the channel since Rx was started + struct { + uint8_t ccaState:2; //!< \brief Value of the current CCA state
+ //!< 0: Idle
+ //!< 1: Busy
+ //!< 2: Invalid + uint8_t ccaEnergy:2; //!< \brief Value of the current energy detect CCA state
+ //!< 0: Idle
+ //!< 1: Busy
+ //!< 2: Invalid + uint8_t ccaCorr:2; //!< \brief Value of the current correlator based carrier sense CCA state
+ //!< 0: Idle
+ //!< 1: Busy
+ //!< 2: Invalid + uint8_t ccaSync:1; //!< \brief Value of the current sync found based carrier sense CCA state
+ //!< 0: Idle
+ //!< 1: Busy + } ccaInfo; +}; + +//! @} + +//! \addtogroup ieeeRxOutput +//! @{ +//! Output structure for CMD_IEEE_RX + +struct __RFC_STRUCT rfc_ieeeRxOutput_s { + uint8_t nTxAck; //!< Total number of transmitted ACK frames + uint8_t nRxBeacon; //!< Number of received beacon frames + uint8_t nRxData; //!< Number of received data frames + uint8_t nRxAck; //!< Number of received acknowledgement frames + uint8_t nRxMacCmd; //!< Number of received MAC command frames + uint8_t nRxReserved; //!< Number of received frames with reserved frame type + uint8_t nRxNok; //!< Number of received frames with CRC error + uint8_t nRxIgnored; //!< Number of frames received that are to be ignored + uint8_t nRxBufFull; //!< Number of received frames discarded because the Rx buffer was full + int8_t lastRssi; //!< RSSI of last received frame + int8_t maxRssi; //!< Highest RSSI observed in the operation + uint8_t __dummy0; + ratmr_t beaconTimeStamp; //!< Time stamp of last received beacon frame +}; + +//! @} + +//! \addtogroup shortAddrEntry +//! @{ +//! Structure for short address entries + +struct __RFC_STRUCT rfc_shortAddrEntry_s { + uint16_t shortAddr; //!< Short address + uint16_t panId; //!< PAN ID +}; + +//! @} + +//! \addtogroup ieeeRxCorrCrc +//! @{ +//! Receive status byte that may be appended to message in receive buffer + +struct __RFC_STRUCT rfc_ieeeRxCorrCrc_s { + struct { + uint8_t corr:6; //!< The correlation value + uint8_t bIgnore:1; //!< 1 if the packet should be rejected by frame filtering, 0 otherwise + uint8_t bCrcErr:1; //!< 1 if the packet was received with CRC error, 0 otherwise + } status; +}; + +//! @} + +//! @} +//! @} +#endif /* IEEE_CMD_H_ */ diff --git a/cpu/cc26xx/dev/rfc-api/ieee_mailbox.h b/cpu/cc26xx-cc13xx/rf-core/api/ieee_mailbox.h similarity index 66% rename from cpu/cc26xx/dev/rfc-api/ieee_mailbox.h rename to cpu/cc26xx-cc13xx/rf-core/api/ieee_mailbox.h index 772c4c219..c6784da09 100644 --- a/cpu/cc26xx/dev/rfc-api/ieee_mailbox.h +++ b/cpu/cc26xx-cc13xx/rf-core/api/ieee_mailbox.h @@ -1,107 +1,75 @@ -/****************************************************************************** -* Filename: ieee_mailbox.h -* Revised: $ $ -* Revision: $ $ -* -* Description: Definitions for IEEE 802.15.4 interface -* -* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -******************************************************************************/ - -#ifndef _IEEE_MAILBOX_H -#define _IEEE_MAILBOX_H - -#include "mailbox.h" - -/// \name CPE interrupt definitions for IEEE 802.15.4 -/// Interrupt masks for the CPE interrupt in RDBELL. These are new names for interrupts in mailbox.h, -/// used for compartibility with previous versions with separate interrupt numbers. -///@{ -#define IRQN_IEEE_BG_COMMAND_SUSPENDED IRQN_BG_COMMAND_SUSPENDED -#define IRQN_IEEE_TX_FRAME IRQN_TX_DONE -#define IRQN_IEEE_TX_ACK IRQN_TX_ACK - -#define IRQN_IEEE_RX_FRAME IRQN_RX_OK -#define IRQN_IEEE_RX_NOK IRQN_RX_NOK -#define IRQN_IEEE_RX_IGNORED IRQN_RX_IGNORED -#define IRQN_IEEE_RX_BUF_FULL IRQN_RX_BUF_FULL -#define IRQN_IEEE_RX_ENTRY_DONE IRQN_RX_ENTRY_DONE - -#define IRQ_IEEE_BG_COMMAND_SUSPENDED (1U << IRQN_IEEE_BG_COMMAND_SUSPENDED) -#define IRQ_IEEE_TX_FRAME (1U << IRQN_IEEE_TX_FRAME) -#define IRQ_IEEE_TX_ACK (1U << IRQN_IEEE_TX_ACK) -#define IRQ_IEEE_RX_FRAME (1U << IRQN_IEEE_RX_FRAME) -#define IRQ_IEEE_RX_NOK (1U << IRQN_IEEE_RX_NOK) -#define IRQ_IEEE_RX_IGNORED (1U << IRQN_IEEE_RX_IGNORED) -#define IRQ_IEEE_RX_BUF_FULL (1U << IRQN_IEEE_RX_BUF_FULL) -#define IRQ_IEEE_RX_ENTRY_DONE (1U << IRQN_IEEE_RX_ENTRY_DONE) -///@} - - - -/// \name Radio operation status -/// Radio operation status format: -/// Bits 15:12: Protocol -/// 0010: IEEE 802.15.4 -/// Bits 11:10: Type -/// 00: Not finished -/// 01: Done successfully -/// 10: Done with error -/// Bits 9:0: Identifier - -/// \name Operation not finished -///@{ -#define IEEE_SUSPENDED 0x2001 ///< Operation suspended -///@} -/// \name Operation finished normally -///@{ -#define IEEE_DONE_OK 0x2400 ///< Operation ended normally -#define IEEE_DONE_BUSY 0x2401 ///< CSMA-CA operation ended with failure -#define IEEE_DONE_STOPPED 0x2402 ///< Operation stopped after stop command -#define IEEE_DONE_ACK 0x2403 ///< ACK packet received with pending data bit cleared -#define IEEE_DONE_ACKPEND 0x2404 ///< ACK packet received with pending data bit set -#define IEEE_DONE_TIMEOUT 0x2405 ///< Operation ended due to timeout -#define IEEE_DONE_BGEND 0x2406 ///< FG operation ended because necessary background level - ///< operation ended -#define IEEE_DONE_ABORT 0x2407 ///< Operation aborted by command -///@} -/// \name Operation finished with error -///@{ -#define IEEE_ERROR_PAR 0x2800 ///< Illegal parameter -#define IEEE_ERROR_NO_SETUP 0x2801 ///< Operation using Rx or Tx attemted when not in 15.4 mode -#define IEEE_ERROR_NO_FS 0x2802 ///< Operation using Rx or Tx attemted without frequency synth configured -#define IEEE_ERROR_SYNTH_PROG 0x2803 ///< Synthesizer programming failed to complete on time -#define IEEE_ERROR_RXOVF 0x2804 ///< Receiver overflowed during operation -#define IEEE_ERROR_TXUNF 0x2805 ///< Transmitter underflowed during operation -///@} -///@} - -#endif +/****************************************************************************** +* Filename: ieee_mailbox.h +* Revised: $ $ +* Revision: $ $ +* +* Description: Definitions for IEEE 802.15.4 interface +* +* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ +* +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef IEEE_MAILBOX_H_ +#define IEEE_MAILBOX_H_ + +#include "mailbox.h" + + +/// \name Radio operation status +///@{ +/// \name Operation not finished +///@{ +#define IEEE_SUSPENDED 0x2001 ///< Operation suspended +///@} +/// \name Operation finished normally +///@{ +#define IEEE_DONE_OK 0x2400 ///< Operation ended normally +#define IEEE_DONE_BUSY 0x2401 ///< CSMA-CA operation ended with failure +#define IEEE_DONE_STOPPED 0x2402 ///< Operation stopped after stop command +#define IEEE_DONE_ACK 0x2403 ///< ACK packet received with pending data bit cleared +#define IEEE_DONE_ACKPEND 0x2404 ///< ACK packet received with pending data bit set +#define IEEE_DONE_TIMEOUT 0x2405 ///< Operation ended due to timeout +#define IEEE_DONE_BGEND 0x2406 ///< FG operation ended because necessary background level + ///< operation ended +#define IEEE_DONE_ABORT 0x2407 ///< Operation aborted by command +///@} +/// \name Operation finished with error +///@{ +#define IEEE_ERROR_PAR 0x2800 ///< Illegal parameter +#define IEEE_ERROR_NO_SETUP 0x2801 ///< Operation using Rx or Tx attemted when not in 15.4 mode +#define IEEE_ERROR_NO_FS 0x2802 ///< Operation using Rx or Tx attemted without frequency synth configured +#define IEEE_ERROR_SYNTH_PROG 0x2803 ///< Synthesizer programming failed to complete on time +#define IEEE_ERROR_RXOVF 0x2804 ///< Receiver overflowed during operation +#define IEEE_ERROR_TXUNF 0x2805 ///< Transmitter underflowed during operation +///@} +///@} + +#endif /* IEEE_MAILBOX_H_ */ diff --git a/cpu/cc26xx/dev/rfc-api/mailbox.h b/cpu/cc26xx-cc13xx/rf-core/api/mailbox.h similarity index 55% rename from cpu/cc26xx/dev/rfc-api/mailbox.h rename to cpu/cc26xx-cc13xx/rf-core/api/mailbox.h index b11d72f08..119565959 100644 --- a/cpu/cc26xx/dev/rfc-api/mailbox.h +++ b/cpu/cc26xx-cc13xx/rf-core/api/mailbox.h @@ -1,580 +1,328 @@ -/****************************************************************************** -* Filename: mailbox.h -* Revised: $ $ -* Revision: $ $ -* -* Description: Definitions for interface between system and radio CPU -* -* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -******************************************************************************/ - -#ifndef _MAILBOX_H -#define _MAILBOX_H - -#include -#include - -/// Type definition for RAT -typedef uint32_t ratmr_t; - - - -/// Type definition for a data queue -typedef struct { - uint8_t *pCurrEntry; ///< Pointer to the data queue entry to be used, NULL for an empty queue - uint8_t *pLastEntry; ///< Pointer to the last entry in the queue, NULL for a circular queue -} dataQueue_t; - - - -/// \name CPE interrupt definitions -/// Interrupt masks for the CPE interrupt in RDBELL. -///@{ -#define IRQN_COMMAND_DONE 0 ///< Radio operation command finished -#define IRQN_LAST_COMMAND_DONE 1 ///< Last radio operation command in a chain finished -#define IRQN_FG_COMMAND_DONE 2 ///< FG level Radio operation command finished -#define IRQN_LAST_FG_COMMAND_DONE 3 ///< Last FG level radio operation command in a chain finished -#define IRQN_TX_DONE 4 ///< Packet transmitted -#define IRQN_TX_ACK 5 ///< ACK packet transmitted -#define IRQN_TX_CTRL 6 ///< Control packet transmitted -#define IRQN_TX_CTRL_ACK 7 ///< Acknowledgement received on a transmitted control packet -#define IRQN_TX_CTRL_ACK_ACK 8 ///< Acknowledgement received on a transmitted control packet, and acknowledgement transmitted for that packet -#define IRQN_TX_RETRANS 9 ///< Packet retransmitted -#define IRQN_TX_ENTRY_DONE 10 ///< Tx queue data entry state changed to Finished -#define IRQN_TX_BUFFER_CHANGED 11 ///< A buffer change is complete -#define IRQN_BG_COMMAND_SUSPENDED 12 ///< A background level radio operation command has been suspended -#define IRQN_RX_OK 16 ///< Packet received with CRC OK, payload, and not to be ignored -#define IRQN_RX_NOK 17 ///< Packet received with CRC error -#define IRQN_RX_IGNORED 18 ///< Packet received with CRC OK, but to be ignored -#define IRQN_RX_EMPTY 19 ///< Packet received with CRC OK, not to be ignored, no payload -#define IRQN_RX_CTRL 20 ///< Control packet received with CRC OK, not to be ignored -#define IRQN_RX_CTRL_ACK 21 ///< Control packet received with CRC OK, not to be ignored, then ACK sent -#define IRQN_RX_BUF_FULL 22 ///< Packet received that did not fit in the Rx queue -#define IRQN_RX_ENTRY_DONE 23 ///< Rx queue data entry changing state to Finished -#define IRQN_RX_DATA_WRITTEN 24 ///< Data written to partial read Rx buffer -#define IRQN_RX_N_DATA_WRITTEN 25 ///< Specified number of bytes written to partial read Rx buffer -#define IRQN_RX_ABORTED 26 ///< Packet reception stopped before packet was done -#define IRQN_SYNTH_NO_LOCK 28 ///< The synth has gone out of lock after calibration -#define IRQN_MODULES_UNLOCKED 29 ///< As part of the boot process, the CM0 has opened access to RF core modules and memories -#define IRQN_BOOT_DONE 30 ///< The RF core CPU boot is finished - -#define IRQN_INTERNAL_ERROR 31 ///< Internal error observed - -#define IRQ_COMMAND_DONE (1U << IRQN_COMMAND_DONE) -#define IRQ_LAST_COMMAND_DONE (1U << IRQN_LAST_COMMAND_DONE) -#define IRQ_FG_COMMAND_DONE (1U << IRQN_FG_COMMAND_DONE) -#define IRQ_LAST_FG_COMMAND_DONE (1U << IRQN_LAST_FG_COMMAND_DONE) - -#define IRQ_TX_DONE (1U << IRQN_TX_DONE) -#define IRQ_TX_ACK (1U << IRQN_TX_ACK) -#define IRQ_TX_CTRL (1U << IRQN_TX_CTRL) -#define IRQ_TX_CTRL_ACK (1U << IRQN_TX_CTRL_ACK) -#define IRQ_TX_CTRL_ACK_ACK (1U << IRQN_TX_CTRL_ACK_ACK) -#define IRQ_TX_RETRANS (1U << IRQN_TX_RETRANS) - -#define IRQ_TX_ENTRY_DONE (1U << IRQN_TX_ENTRY_DONE) -#define IRQ_TX_BUFFER_CHANGED (1U << IRQN_TX_BUFFER_CHANGED) - -#define IRQ_BG_COMMAND_SUSPENDED (1U << IRQN_BG_COMMAND_SUSPENDED) - -#define IRQ_RX_OK (1U << IRQN_RX_OK) -#define IRQ_RX_NOK (1U << IRQN_RX_NOK) -#define IRQ_RX_IGNORED (1U << IRQN_RX_IGNORED) -#define IRQ_RX_EMPTY (1U << IRQN_RX_EMPTY) -#define IRQ_RX_CTRL (1U << IRQN_RX_CTRL) -#define IRQ_RX_CTRL_ACK (1U << IRQN_RX_CTRL_ACK) -#define IRQ_RX_BUF_FULL (1U << IRQN_RX_BUF_FULL) -#define IRQ_RX_ENTRY_DONE (1U << IRQN_RX_ENTRY_DONE) -#define IRQ_RX_DATA_WRITTEN (1U << IRQN_RX_DATA_WRITTEN) -#define IRQ_RX_N_DATA_WRITTEN (1U << IRQN_RX_N_DATA_WRITTEN) -#define IRQ_RX_ABORTED (1U << IRQN_RX_ABORTED) - -#define IRQ_SYNTH_NO_LOCK (1U << IRQN_SYNTH_NO_LOCK) -#define IRQ_MODULES_UNLOCKED (1U << IRQN_MODULES_UNLOCKED) -#define IRQ_BOOT_DONE (1U << IRQN_BOOT_DONE) -#define IRQ_INTERNAL_ERROR (1U << IRQN_INTERNAL_ERROR) -///@} - - - -/// \name CMDSTA values -/// Values returned in result byte of CMDSTA -///@{ -#define CMDSTA_Pending 0x00 ///< The command has not yet been parsed -#define CMDSTA_Done 0x01 ///< Command successfully parsed - -#define CMDSTA_IllegalPointer 0x81 ///< The pointer signaled in CMDR is not valid -#define CMDSTA_UnknownCommand 0x82 ///< The command number in the command structure is unknown -#define CMDSTA_UnknownDirCommand 0x83 ///< The command number for a direct command is unknown, or the - ///< command is not a direct command -#define CMDSTA_ContextError 0x85 ///< An immediate or direct command was issued in a context - ///< where it is not supported -#define CMDSTA_SchedulingError 0x86 ///< A radio operation command was attempted to be scheduled - ///< while another operation was already running in the RF core -#define CMDSTA_ParError 0x87 ///< There were errors in the command parameters that are parsed - ///< on submission. -#define CMDSTA_QueueError 0x88 ///< An operation on a data entry queue was attempted that was - ///< not supported by the queue in its current state -#define CMDSTA_QueueBusy 0x89 ///< An operation on a data entry was attempted while that entry - ///< was busy -///@} - -/// \name Macros for use with command definition files -/// The script create_command.pl generates header files from command and structure definitions in the -/// *_def.txt files. These are the macros to access the definitions -///@{ - -/// Get a field from a structure -// -/// Gets a field from a structure defined in a _def.txt file. This may be used both in assignments and -/// references (e.g. GET_FIELD(pCmd1, CMD_TEST, testParam) = GET_FIELD(pCmd2, CMD_DUMMY, dummyParam);) -/// \param[in] ptr -/// Pointer to the structure -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the accessed field as defined in the _def.txt file -/// -#define GET_FIELD(ptr, cmd, field) \ -(*((_TYPE_##cmd##_##field *) (((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field)))) - -/// Get a field from a structure, reading as volatile -// -/// Gets a field from a structure defined in a _def.txt file, reading it as a volatile parameter, which -/// takes into account that it may be changed by the other side. This may be used both in assignments and -/// references (e.g. GET_FIELD(pCmd1, CMD_TEST, testParam) = GET_FIELD(pCmd2, CMD_DUMMY, dummyParam);) -/// \param[in] ptr -/// Pointer to the structure -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the accessed field as defined in the _def.txt file -/// -#define GET_FIELD_V(ptr, cmd, field) \ -(*((volatile _TYPE_##cmd##_##field *) (((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field)))) - -/// Get the pointer to a field from a structure -// -/// Gets the pointer to a field from a structure defined in a _def.txt file. -/// \param[in] ptr -/// Pointer to the structure -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the accessed field as defined in the _def.txt file -/// -#define GET_FIELD_PTR(ptr, cmd, field) \ -((_TYPE_##cmd##_##field *) (((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field))) - -/// Get the volatile pointer to a field from a structure -// -/// Gets the volatile pointer to a field from a structure defined in a _def.txt file. -/// \param[in] ptr -/// Pointer to the structure -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the accessed field as defined in the _def.txt file -/// -#define GET_FIELD_VPTR(ptr, cmd, field) \ -((volatile _TYPE_##cmd##_##field *) (((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field))) - -/// Get bits from a bit field -// -/// Returns bits from a bit field defined in a _def.txt file. -/// \param[in] value -/// The value of the entire field that contains the bit field -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the field that contains the bit field definition as defined in the _def.txt file -/// \param[in] bitfield -/// Name of the bitfield as defined in the _def.txt file -/// -#define GET_BITS(value, cmd, field, bitfield) \ -(((value) >> (_BITPOS_##cmd##_##field##_##bitfield)) & \ - ((1U << (_NBITS_##cmd##_##field##_##bitfield)) - 1)) - -/// Get bits from a bit field as a signed value -// -/// Returns sign extended bits from a bit field defined in a _def.txt file. -/// \param[in] value -/// The value of the entire field that contains the bit field -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the field that contains the bit field definition as defined in the _def.txt file -/// \param[in] bitfield -/// Name of the bitfield as defined in the _def.txt file -/// -#define GET_BITS_S(value, cmd, field, bitfield) \ -(((int)(value) << (32 - ((_BITPOS_##cmd##_##field##_##bitfield) + (_NBITS_##cmd##_##field##_##bitfield)))) >> \ - (32 - (_NBITS_##cmd##_##field##_##bitfield))) - -/// Set bits in a bit field -// -/// Modifies a bit field defined in a _def.txt file. -/// \param[in,out] value -/// The value of the entire field that contains the bit field -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the field that contains the bit field definition as defined in the _def.txt file -/// \param[in] bitfield -/// Name of the bitfield as defined in the _def.txt file -/// \param[in] bvalue -/// The value to set in the bitfield -/// -#define SET_BITS(value, cmd, field, bitfield, bvalue) \ -(((value) = ((value) & \ - (~(((1U << (_NBITS_##cmd##_##field##_##bitfield)) - 1) << (_BITPOS_##cmd##_##field##_##bitfield))) | \ - ((bvalue) << (_BITPOS_##cmd##_##field##_##bitfield))))) - - -/// Get bits from a bit field in a structure -// -/// Returns bits from a bit field in a structure defined in a _def.txt file. -/// \param[in] ptr -/// Pointer to the structure -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the field that contains the bit field definition as defined in the _def.txt file -/// \param[in] bitfield -/// Name of the bitfield as defined in the _def.txt file -/// -#define GET_BITFIELD(ptr, cmd, field, bitfield) \ -((*((_TYPE_##cmd##_##field *) ((((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field)))) >> \ - ((_BITPOS_##cmd##_##field##_##bitfield))) & \ - ((1U << (_NBITS_##cmd##_##field##_##bitfield)) - 1)) - -/// Get bits from a bit field in a structure, reading as volatile -// -/// Returns bits from a bit field in a structure defined in a _def.txt file, reading it as a -/// volatile parameter. -/// \param[in] ptr -/// Pointer to the structure -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the field that contains the bit field definition as defined in the _def.txt file -/// \param[in] bitfield -/// Name of the bitfield as defined in the _def.txt file -/// -#define GET_BITFIELD_V(ptr, cmd, field, bitfield) \ -((*((volatile _TYPE_##cmd##_##field *) ((((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field)))) >> \ - ((_BITPOS_##cmd##_##field##_##bitfield))) & \ - ((1U << (_NBITS_##cmd##_##field##_##bitfield)) - 1)) - - -/// Set bits in a bit field in a structure -// -/// Modifies a bit field in a field in a structure defined in a _def.txt file. -/// \param[in] ptr -/// Pointer to the structure -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the field that contains the bit field definition as defined in the _def.txt file -/// \param[in] bitfield -/// Name of the bitfield as defined in the _def.txt file -/// \param[in] value -/// The value to set in the bitfield -/// -#define SET_BITFIELD(ptr, cmd, field, bitfield, value) \ -((*((_TYPE_##cmd##_##field *) (((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field)))) = \ - ((*((_TYPE_##cmd##_##field *) (((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field)))) & \ - (~(((1U << (_NBITS_##cmd##_##field##_##bitfield)) - 1) << (_BITPOS_##cmd##_##field##_##bitfield))) | \ - (((uint32_t)(value)) << (_BITPOS_##cmd##_##field##_##bitfield)))) - -/// Set bits in a bit field in a structure, reading and writing as volatile -// -/// Modifies a bit field in a field in a structure defined in a _def.txt file, accessing it as a volatile -/// parameter. -/// \param[in] ptr -/// Pointer to the structure -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the field that contains the bit field definition as defined in the _def.txt file -/// \param[in] bitfield -/// Name of the bitfield as defined in the _def.txt file -/// \param[in] value -/// The value to set in the bitfield -/// -#define SET_BITFIELD_V(ptr, cmd, field, bitfield, value) \ -((*((volatile _TYPE_##cmd##_##field *) (((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field)))) = \ - ((*((volatile _TYPE_##cmd##_##field *) (((uint8_t *)(ptr)) + (_POSITION_##cmd##_##field)))) & \ - (~(((1U << (_NBITS_##cmd##_##field##_##bitfield)) - 1) << (_BITPOS_##cmd##_##field##_##bitfield))) | \ - (((uint32_t)(value)) << (_BITPOS_##cmd##_##field##_##bitfield)))) - -/// Get the value of specific bifield in a field with the remaining bits set to 0 -// -/// Returns a bitfield so that the value of the full field can be obtained by bitwise -/// OR between these -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] field -/// Name of the field that contains the bit field definition as defined in the _def.txt file -/// \param[in] bitfield -/// Name of the bitfield as defined in the _def.txt file -/// \param[in] value -/// The value to use in the bitfield -/// -#define BITVALUE(cmd, field, bitfield, value) \ -((((uint32_t)(value)) & ((1U << (_NBITS_##cmd##_##field##_##bitfield)) - 1)) << \ - (_BITPOS_##cmd##_##field##_##bitfield)) - -/// Get the size of a structure -// -/// Gets the size of a structure defined in a _def.txt file. -/// -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// -#define SIZEOF_STRUCT(cmd) \ -(_SIZEOF_##cmd) - -/// Get the size of a radio operation command structure -// -/// Gets the size of a radio operation command structure defined in a _def.txt file. The difference from -/// SIZEOF_STRUCT is for legacy reasons only. -/// -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// -#define SIZEOF_RADIO_OP(cmd) \ -(_SIZEOF_##cmd) - -/// Initializes a structure to an initialization set -// -/// Sets the value of a structure to its given initialization values -/// \param[in] ptr -/// Pointer to the structure, must be word aligned -/// \param[in] cmd -/// Name of the command or structure as defined in the _def.txt file -/// \param[in] set -/// Index of the set of initializations to use -/// -#define INIT_STRUCT(ptr, cmd, set) \ -(memcpy(((uint32_t *)(ptr)) + (_START_INIT_WIDX_##cmd), (__init_##cmd[(set)]), \ - (_N_INIT_WORDS_##cmd) * sizeof(uint32_t))) - -///@} - - -/// \name Macros for sending direct commands -///@{ -/// Direct command with no parameter -#define CMDR_DIR_CMD(cmdId) (((cmdId) << 16) | 1) - -/// Direct command with 1-byte parameter -#define CMDR_DIR_CMD_1BYTE(cmdId, par) (((cmdId) << 16) | ((par) << 8) | 1) - -/// Direct command with 2-byte parameter -#define CMDR_DIR_CMD_2BYTE(cmdId, par) (((cmdId) << 16) | ((par) & 0xFFFC) | 1) - -///@} - - - -/// \name Definitions for trigger types -///@{ -#define TRIG_NOW 0 ///< Triggers immediately -#define TRIG_NEVER 1 ///< Never trigs -#define TRIG_ABSTIME 2 ///< Trigs at an absolute time -#define TRIG_REL_SUBMIT 3 ///< Trigs at a time relative to the command was submitted -#define TRIG_REL_START 4 ///< Trigs at a time relative to the command started -#define TRIG_REL_PREVSTART 5 ///< Trigs at a time relative to the previous command in the chain started -#define TRIG_REL_FIRSTSTART 6 ///< Trigs at a time relative to the first command in the chain started -#define TRIG_REL_PREVEND 7 ///< Trigs at a time relative to the previous command in the chain ended -#define TRIG_REL_EVT1 8 ///< Trigs at a time relative to the context defined "Event 1" -#define TRIG_REL_EVT2 9 ///< Trigs at a time relative to the context defined "Event 2" -#define TRIG_EXTERNAL 10 ///< Trigs at an external event to the radio timer -#define TRIG_PAST_BM 0x80 ///< Bitmask for setting pastTrig bit in order to trig immediately if - ///< trigger happened in the past -///@} - - -/// \name Definitions for conditional execution -///@{ -#define COND_ALWAYS 0 ///< Always run next command (except in case of Abort) -#define COND_NEVER 1 ///< Never run next command -#define COND_STOP_ON_FALSE 2 ///< Run next command if this command returned True, stop if it returned - ///< False -#define COND_STOP_ON_TRUE 3 ///< Stop if this command returned True, run next command if it returned - ///< False -#define COND_SKIP_ON_FALSE 4 ///< Run next command if this command returned True, skip a number of - ///< commands if it returned False -#define COND_SKIP_ON_TRUE 5 ///< Skip a number of commands if this command returned True, run next - ///< command if it returned False -///@} - - - -/// \name Radio operation status -/// Radio operation status format: -///@{ -/// \name Operation not finished -///@{ -#define IDLE 0x0000 ///< Operation not started -#define PENDING 0x0001 ///< Start of command is pending -#define ACTIVE 0x0002 ///< Running -#define SKIPPED 0x0003 ///< Operation skipped due to condition in another command -///@} -/// \name Operation finished normally -///@{ -#define DONE_OK 0x0400 ///< Operation ended normally -#define DONE_COUNTDOWN 0x0401 ///< Counter reached zero -#define DONE_RXERR 0x0402 ///< Operation ended with CRC error -#define DONE_TIMEOUT 0x0403 ///< Operation ended with timeout -#define DONE_STOPPED 0x0404 ///< Operation stopped after CMD_STOP command -#define DONE_ABORT 0x0405 ///< Operation aborted by CMD_ABORT command -#define DONE_FAILED 0x0406 ///< Scheduled immediate command failed -///@} -/// \name Operation finished with error -///@{ -#define ERROR_PAST_START 0x0800 ///< The start trigger occurred in the past -#define ERROR_START_TRIG 0x0801 ///< Illegal start trigger parameter -#define ERROR_CONDITION 0x0802 ///< Illegal condition for next operation -#define ERROR_PAR 0x0803 ///< Error in a command specific parameter -#define ERROR_POINTER 0x0804 ///< Invalid pointer to next operation -#define ERROR_CMDID 0x0805 ///< Next operation has a command ID that is undefined or not a radio - ///< operation command -#define ERROR_WRONG_BG 0x0806 ///< FG level command not compatible with running BG level command -#define ERROR_NO_SETUP 0x0807 ///< Operation using Rx or Tx attemted without CMD_RADIO_SETUP -#define ERROR_NO_FS 0x0808 ///< Operation using Rx or Tx attemted without frequency synth configured -#define ERROR_SYNTH_PROG 0x0809 ///< Synthesizer calibration failed -#define ERROR_TXUNF 0x080A ///< Tx underflow observed -#define ERROR_RXOVF 0x080B ///< Rx overflow observed -#define ERROR_NO_RX 0x080C ///< Attempted to access data from Rx when no such data was yet received -#define ERROR_PENDING 0x080D ///< Command submitted in the future with another command at different level pending -///@} -///@} - - -/// \name Data entry types -///@{ -#define DATA_ENTRY_TYPE_GEN 0 ///< General type: Tx entry or single element Rx entry -#define DATA_ENTRY_TYPE_MULTI 1 ///< Multi-element Rx entry type -#define DATA_ENTRY_TYPE_PTR 2 ///< Pointer entry type -#define DATA_ENTRY_TYPE_PARTIAL 3 ///< Partial read entry type -///@ - - -/// \name Data entry statuses -///@{ -#define DATA_ENTRY_PENDING 0 ///< Entry not yet used -#define DATA_ENTRY_ACTIVE 1 ///< Entry in use by radio CPU -#define DATA_ENTRY_BUSY 2 ///< Entry being updated -#define DATA_ENTRY_FINISHED 3 ///< Radio CPU is finished accessing the entry -#define DATA_ENTRY_UNFINISHED 4 ///< Radio CPU is finished accessing the entry, but packet could not be finished -///@} - -/// Difference between length and size of rxData field in multi-element Rx entry -#define DATA_ENTRY_MULTI_LEN_OFFSET (_POSITION_dataEntry_rxData - _POSITION_dataEntry_data) - - -/// \name Macros for RF register override -///@{ -/// Macro for ADI half-size value-mask combination -#define ADI_VAL_MASK(addr, mask, value) \ -(((addr) & 1) ? (((mask) & 0x0F) | (((value) & 0x0F) << 4)) : \ - ((((mask) & 0x0F) << 4) | ((value) & 0x0F))) -/// 32-bit write of 16-bit value -#define HW_REG_OVERRIDE(addr, val) ((((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(val) << 16)) -/// ADI register, full-size write -#define ADI_REG_OVERRIDE(adiNo, addr, val) (2 | ((uint32_t)(val) << 16) | \ -(((addr) & 0x3F) << 24) | (((adiNo) ? 1U : 0) << 31)) -/// 2 ADI registers, full-size write -#define ADI_2REG_OVERRIDE(adiNo, addr, val, addr2, val2) \ -(2 | ((uint32_t)(val2) << 2) | (((addr2) & 0x3F) << 10) | ((uint32_t)(val) << 16) | \ -(((addr) & 0x3F) << 24) | (((adiNo) ? 1U : 0) << 31)) -/// ADI register, half-size read-modify-write -#define ADI_HALFREG_OVERRIDE(adiNo, addr, mask, val) (2 | (ADI_VAL_MASK(addr, mask, val) << 16) | \ -(((addr) & 0x3F) << 24) | (1U << 30) | (((adiNo) ? 1U : 0) << 31)) -/// 2 ADI registers, half-size read-modify-write -#define ADI_2HALFREG_OVERRIDE(adiNo, addr, mask, val, addr2, mask2, val2) \ -(2 | (ADI_VAL_MASK(addr2, mask2, val2) << 2) | (((addr2) & 0x3F) << 10) | \ -(ADI_VAL_MASK(addr, mask, val) << 16) | (((addr) & 0x3F) << 24) | (1U << 30) | (((adiNo) ? 1U : 0) << 31)) - -/// 16-bit SW register as defined in radio_par_def.txt -#define SW_REG_OVERRIDE(cmd, field, val) (3 | ((_POSITION_##cmd##_##field) << 4) | ((uint32_t)(val) << 16)) -/// SW register as defined in radio_par_def.txt with added index (for use with registers > 16 bits). -#define SW_REG_IND_OVERRIDE(cmd, field, offset, val) (3 | \ -(((_POSITION_##cmd##_##field) + ((offset) << 1)) << 4) | ((uint32_t)(val) << 16)) -/// 8-bit SW register as defined in radio_par_def.txt -#define SW_REG_BYTE_OVERRIDE(cmd, field, val) (0x8003 | ((_POSITION_##cmd##_##field) << 4) | \ -((uint32_t)(val) << 16)) -/// Two 8-bit SW registers as defined in radio_par_def.txt; the one given by field and the next byte. -#define SW_REG_2BYTE_OVERRIDE(cmd, field, val0, val1) (3 | (((_POSITION_##cmd##_##field) & 0xFFFE) << 4) | \ - (((uint32_t)(val0) << 16) & 0x00FF0000) | ((uint32_t)(val1) << 24)) -#define HW16_ARRAY_OVERRIDE(addr, length) (1 | (((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(length) << 16)) -#define HW32_ARRAY_OVERRIDE(addr, length) (1 | (((uintptr_t) (addr)) & 0xFFFC) | \ -((uint32_t)(length) << 16) | (1U << 30)) -#define ADI_ARRAY_OVERRIDE(adiNo, addr, bHalfSize, length) (1 | ((((addr) & 0x3F) << 2)) | \ -((!!(bHalfSize)) << 8) | ((!!(adiNo)) << 9) | ((uint32_t)(length) << 16) | (2U << 30)) -#define SW_ARRAY_OVERRIDE(cmd, firstfield, length) (1 | (((_POSITION_##cmd##_##firstfield)) << 2) | \ -((uint32_t)(length) << 16) | (3U << 30)) -#define MCE_RFE_OVERRIDE(bMceRam, mceRomBank, mceMode, bRfeRam, rfeRomBank, rfeMode) \ - (7 | ((!!(bMceRam)) << 8) | (((mceRomBank) & 0x07) << 9) | ((!!(bRfeRam)) << 12) | (((rfeRomBank) & 0x07) << 13) | \ - (((mceMode) & 0x00FF) << 16) | (((rfeMode) & 0x00FF) << 24)) -#define BAW_OVERRIDE(freqOffset) (0x000B | ((freqOffset) << 16)) -#define NEW_OVERRIDE_SEGMENT(address) (((((uintptr_t)(address)) & 0x03FFFFFC) << 6) | 0x000F | \ - (((((uintptr_t)(address) >> 24) == 0x20) ? 0x01 : \ - (((uintptr_t)(address) >> 24) == 0x21) ? 0x02 : \ - (((uintptr_t)(address) >> 24) == 0xA0) ? 0x03 : \ - (((uintptr_t)(address) >> 24) == 0x00) ? 0x04 : \ - (((uintptr_t)(address) >> 24) == 0x10) ? 0x05 : \ - (((uintptr_t)(address) >> 24) == 0x11) ? 0x06 : \ - (((uintptr_t)(address) >> 24) == 0x40) ? 0x07 : \ - (((uintptr_t)(address) >> 24) == 0x50) ? 0x08 : \ - 0x09) << 4)) // Use illegal value for illegal address range -/// End of string for override register -#define END_OVERRIDE 0xFFFFFFFF - - -#define FWPAR_8BIT_ADDR(cmd, field) (0x1800 | (_POSITION_##cmd##_##field)) -#define FWPAR_16BIT_ADDR(cmd, field) (0x1000 | (_POSITION_##cmd##_##field)) -#define FWPAR_32BIT_ADDR(cmd, field) (0x0000 | (_POSITION_##cmd##_##field)) - -/// ADI address-value pair -#define ADI_ADDR_VAL(addr, value) ((((addr) & 0x7F) << 8) | ((value) & 0xFF)) -#define ADI_ADDR_VAL_MASK(addr, mask, value) ((((addr) & 0x7F) << 8) | ADI_VAL_MASK(addr, mask, value)) - -/// Low half-word -#define LOWORD(value) ((value) & 0xFFFF) -/// High half-word -#define HIWORD(value) ((value) >> 16) -///@} - - -#endif +/****************************************************************************** +* Filename: mailbox.h +* Revised: 2015-06-29 12:59:58 +0200 (Mon, 29 Jun 2015) +* Revision: 44063 +* +* Description: Definitions for interface between system and radio CPU +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3) Neither the name of the ORGANIZATION nor the names of its contributors may +* be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef MAILBOX_H_ +#define MAILBOX_H_ + +#include +#include + +/// Type definition for RAT +typedef uint32_t ratmr_t; + + + +/// Type definition for a data queue +typedef struct { + uint8_t *pCurrEntry; ///< Pointer to the data queue entry to be used, NULL for an empty queue + uint8_t *pLastEntry; ///< Pointer to the last entry in the queue, NULL for a circular queue +} dataQueue_t; + + + +/// \name CPE interrupt definitions +/// Interrupt masks for the CPE interrupt in RDBELL. +///@{ +#define IRQN_COMMAND_DONE 0 ///< Radio operation command finished +#define IRQN_LAST_COMMAND_DONE 1 ///< Last radio operation command in a chain finished +#define IRQN_FG_COMMAND_DONE 2 ///< FG level Radio operation command finished +#define IRQN_LAST_FG_COMMAND_DONE 3 ///< Last FG level radio operation command in a chain finished +#define IRQN_TX_DONE 4 ///< Packet transmitted +#define IRQN_TX_ACK 5 ///< ACK packet transmitted +#define IRQN_TX_CTRL 6 ///< Control packet transmitted +#define IRQN_TX_CTRL_ACK 7 ///< Acknowledgement received on a transmitted control packet +#define IRQN_TX_CTRL_ACK_ACK 8 ///< Acknowledgement received on a transmitted control packet, and acknowledgement transmitted for that packet +#define IRQN_TX_RETRANS 9 ///< Packet retransmitted +#define IRQN_TX_ENTRY_DONE 10 ///< Tx queue data entry state changed to Finished +#define IRQN_TX_BUFFER_CHANGED 11 ///< A buffer change is complete +#define IRQN_RX_OK 16 ///< Packet received with CRC OK, payload, and not to be ignored +#define IRQN_RX_NOK 17 ///< Packet received with CRC error +#define IRQN_RX_IGNORED 18 ///< Packet received with CRC OK, but to be ignored +#define IRQN_RX_EMPTY 19 ///< Packet received with CRC OK, not to be ignored, no payload +#define IRQN_RX_CTRL 20 ///< Control packet received with CRC OK, not to be ignored +#define IRQN_RX_CTRL_ACK 21 ///< Control packet received with CRC OK, not to be ignored, then ACK sent +#define IRQN_RX_BUF_FULL 22 ///< Packet received that did not fit in the Rx queue +#define IRQN_RX_ENTRY_DONE 23 ///< Rx queue data entry changing state to Finished +#define IRQN_RX_DATA_WRITTEN 24 ///< Data written to partial read Rx buffer +#define IRQN_RX_N_DATA_WRITTEN 25 ///< Specified number of bytes written to partial read Rx buffer +#define IRQN_RX_ABORTED 26 ///< Packet reception stopped before packet was done +#define IRQN_RX_COLLISION_DETECTED 27 ///< A collision was indicated during packet reception +#define IRQN_SYNTH_NO_LOCK 28 ///< The synth has gone out of lock after calibration +#define IRQN_MODULES_UNLOCKED 29 ///< As part of the boot process, the CM0 has opened access to RF core modules and memories +#define IRQN_BOOT_DONE 30 ///< The RF core CPU boot is finished + +#define IRQN_INTERNAL_ERROR 31 ///< Internal error observed + +#define IRQ_COMMAND_DONE (1U << IRQN_COMMAND_DONE) +#define IRQ_LAST_COMMAND_DONE (1U << IRQN_LAST_COMMAND_DONE) +#define IRQ_FG_COMMAND_DONE (1U << IRQN_FG_COMMAND_DONE) +#define IRQ_LAST_FG_COMMAND_DONE (1U << IRQN_LAST_FG_COMMAND_DONE) + +#define IRQ_TX_DONE (1U << IRQN_TX_DONE) +#define IRQ_TX_ACK (1U << IRQN_TX_ACK) +#define IRQ_TX_CTRL (1U << IRQN_TX_CTRL) +#define IRQ_TX_CTRL_ACK (1U << IRQN_TX_CTRL_ACK) +#define IRQ_TX_CTRL_ACK_ACK (1U << IRQN_TX_CTRL_ACK_ACK) +#define IRQ_TX_RETRANS (1U << IRQN_TX_RETRANS) + +#define IRQ_TX_ENTRY_DONE (1U << IRQN_TX_ENTRY_DONE) +#define IRQ_TX_BUFFER_CHANGED (1U << IRQN_TX_BUFFER_CHANGED) + +#define IRQ_RX_OK (1U << IRQN_RX_OK) +#define IRQ_RX_NOK (1U << IRQN_RX_NOK) +#define IRQ_RX_IGNORED (1U << IRQN_RX_IGNORED) +#define IRQ_RX_EMPTY (1U << IRQN_RX_EMPTY) +#define IRQ_RX_CTRL (1U << IRQN_RX_CTRL) +#define IRQ_RX_CTRL_ACK (1U << IRQN_RX_CTRL_ACK) +#define IRQ_RX_BUF_FULL (1U << IRQN_RX_BUF_FULL) +#define IRQ_RX_ENTRY_DONE (1U << IRQN_RX_ENTRY_DONE) +#define IRQ_RX_DATA_WRITTEN (1U << IRQN_RX_DATA_WRITTEN) +#define IRQ_RX_N_DATA_WRITTEN (1U << IRQN_RX_N_DATA_WRITTEN) +#define IRQ_RX_ABORTED (1U << IRQN_RX_ABORTED) +#define IRQ_RX_COLLISION_DETECTED (1U << IRQN_RX_COLLISION_DETECTED) +#define IRQ_SYNTH_NO_LOCK (1U << IRQN_SYNTH_NO_LOCK) +#define IRQ_MODULES_UNLOCKED (1U << IRQN_MODULES_UNLOCKED) +#define IRQ_BOOT_DONE (1U << IRQN_BOOT_DONE) +#define IRQ_INTERNAL_ERROR (1U << IRQN_INTERNAL_ERROR) +///@} + + + +/// \name CMDSTA values +/// Values returned in result byte of CMDSTA +///@{ +#define CMDSTA_Pending 0x00 ///< The command has not yet been parsed +#define CMDSTA_Done 0x01 ///< Command successfully parsed + +#define CMDSTA_IllegalPointer 0x81 ///< The pointer signalled in CMDR is not valid +#define CMDSTA_UnknownCommand 0x82 ///< The command number in the command structure is unknown +#define CMDSTA_UnknownDirCommand 0x83 ///< The command number for a direct command is unknown, or the + ///< command is not a direct command +#define CMDSTA_ContextError 0x85 ///< An immediate or direct command was issued in a context + ///< where it is not supported +#define CMDSTA_SchedulingError 0x86 ///< A radio operation command was attempted to be scheduled + ///< while another operation was already running in the RF core +#define CMDSTA_ParError 0x87 ///< There were errors in the command parameters that are parsed + ///< on submission. +#define CMDSTA_QueueError 0x88 ///< An operation on a data entry queue was attempted that was + ///< not supported by the queue in its current state +#define CMDSTA_QueueBusy 0x89 ///< An operation on a data entry was attempted while that entry + ///< was busy +///@} + + + +/// \name Macros for sending direct commands +///@{ +/// Direct command with no parameter +#define CMDR_DIR_CMD(cmdId) (((cmdId) << 16) | 1) + +/// Direct command with 1-byte parameter +#define CMDR_DIR_CMD_1BYTE(cmdId, par) (((cmdId) << 16) | ((par) << 8) | 1) + +/// Direct command with 2-byte parameter +#define CMDR_DIR_CMD_2BYTE(cmdId, par) (((cmdId) << 16) | ((par) & 0xFFFC) | 1) + +///@} + + + +/// \name Definitions for trigger types +///@{ +#define TRIG_NOW 0 ///< Triggers immediately +#define TRIG_NEVER 1 ///< Never trigs +#define TRIG_ABSTIME 2 ///< Trigs at an absolute time +#define TRIG_REL_SUBMIT 3 ///< Trigs at a time relative to the command was submitted +#define TRIG_REL_START 4 ///< Trigs at a time relative to the command started +#define TRIG_REL_PREVSTART 5 ///< Trigs at a time relative to the previous command in the chain started +#define TRIG_REL_FIRSTSTART 6 ///< Trigs at a time relative to the first command in the chain started +#define TRIG_REL_PREVEND 7 ///< Trigs at a time relative to the previous command in the chain ended +#define TRIG_REL_EVT1 8 ///< Trigs at a time relative to the context defined "Event 1" +#define TRIG_REL_EVT2 9 ///< Trigs at a time relative to the context defined "Event 2" +#define TRIG_EXTERNAL 10 ///< Trigs at an external event to the radio timer +#define TRIG_PAST_BM 0x80 ///< Bitmask for setting pastTrig bit in order to trig immediately if + ///< trigger happened in the past +///@} + + +/// \name Definitions for conditional execution +///@{ +#define COND_ALWAYS 0 ///< Always run next command (except in case of Abort) +#define COND_NEVER 1 ///< Never run next command +#define COND_STOP_ON_FALSE 2 ///< Run next command if this command returned True, stop if it returned + ///< False +#define COND_STOP_ON_TRUE 3 ///< Stop if this command returned True, run next command if it returned + ///< False +#define COND_SKIP_ON_FALSE 4 ///< Run next command if this command returned True, skip a number of + ///< commands if it returned False +#define COND_SKIP_ON_TRUE 5 ///< Skip a number of commands if this command returned True, run next + ///< command if it returned False +///@} + + + +/// \name Radio operation status +///@{ +/// \name Operation not finished +///@{ +#define IDLE 0x0000 ///< Operation not started +#define PENDING 0x0001 ///< Start of command is pending +#define ACTIVE 0x0002 ///< Running +#define SKIPPED 0x0003 ///< Operation skipped due to condition in another command +///@} +/// \name Operation finished normally +///@{ +#define DONE_OK 0x0400 ///< Operation ended normally +#define DONE_COUNTDOWN 0x0401 ///< Counter reached zero +#define DONE_RXERR 0x0402 ///< Operation ended with CRC error +#define DONE_TIMEOUT 0x0403 ///< Operation ended with timeout +#define DONE_STOPPED 0x0404 ///< Operation stopped after CMD_STOP command +#define DONE_ABORT 0x0405 ///< Operation aborted by CMD_ABORT command +#define DONE_FAILED 0x0406 ///< Scheduled immediate command failed +///@} +/// \name Operation finished with error +///@{ +#define ERROR_PAST_START 0x0800 ///< The start trigger occurred in the past +#define ERROR_START_TRIG 0x0801 ///< Illegal start trigger parameter +#define ERROR_CONDITION 0x0802 ///< Illegal condition for next operation +#define ERROR_PAR 0x0803 ///< Error in a command specific parameter +#define ERROR_POINTER 0x0804 ///< Invalid pointer to next operation +#define ERROR_CMDID 0x0805 ///< Next operation has a command ID that is undefined or not a radio + ///< operation command +#define ERROR_WRONG_BG 0x0806 ///< FG level command not compatible with running BG level command +#define ERROR_NO_SETUP 0x0807 ///< Operation using Rx or Tx attempted without CMD_RADIO_SETUP +#define ERROR_NO_FS 0x0808 ///< Operation using Rx or Tx attempted without frequency synth configured +#define ERROR_SYNTH_PROG 0x0809 ///< Synthesizer calibration failed +#define ERROR_TXUNF 0x080A ///< Tx underflow observed +#define ERROR_RXOVF 0x080B ///< Rx overflow observed +#define ERROR_NO_RX 0x080C ///< Attempted to access data from Rx when no such data was yet received +#define ERROR_PENDING 0x080D ///< Command submitted in the future with another command at different level pending +///@} +///@} + + +/// \name Data entry types +///@{ +#define DATA_ENTRY_TYPE_GEN 0 ///< General type: Tx entry or single element Rx entry +#define DATA_ENTRY_TYPE_MULTI 1 ///< Multi-element Rx entry type +#define DATA_ENTRY_TYPE_PTR 2 ///< Pointer entry type +#define DATA_ENTRY_TYPE_PARTIAL 3 ///< Partial read entry type +///@ + + +/// \name Data entry statuses +///@{ +#define DATA_ENTRY_PENDING 0 ///< Entry not yet used +#define DATA_ENTRY_ACTIVE 1 ///< Entry in use by radio CPU +#define DATA_ENTRY_BUSY 2 ///< Entry being updated +#define DATA_ENTRY_FINISHED 3 ///< Radio CPU is finished accessing the entry +#define DATA_ENTRY_UNFINISHED 4 ///< Radio CPU is finished accessing the entry, but packet could not be finished +///@} + + + +/// \name Macros for RF register override +///@{ +/// Macro for ADI half-size value-mask combination +#define ADI_VAL_MASK(addr, mask, value) \ +(((addr) & 1) ? (((mask) & 0x0F) | (((value) & 0x0F) << 4)) : \ + ((((mask) & 0x0F) << 4) | ((value) & 0x0F))) +/// 32-bit write of 16-bit value +#define HW_REG_OVERRIDE(addr, val) ((((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(val) << 16)) +/// ADI register, full-size write +#define ADI_REG_OVERRIDE(adiNo, addr, val) (2 | ((uint32_t)(val) << 16) | \ +(((addr) & 0x3F) << 24) | (((adiNo) ? 1U : 0) << 31)) +/// 2 ADI registers, full-size write +#define ADI_2REG_OVERRIDE(adiNo, addr, val, addr2, val2) \ +(2 | ((uint32_t)(val2) << 2) | (((addr2) & 0x3F) << 10) | ((uint32_t)(val) << 16) | \ +(((addr) & 0x3F) << 24) | (((adiNo) ? 1U : 0) << 31)) +/// ADI register, half-size read-modify-write +#define ADI_HALFREG_OVERRIDE(adiNo, addr, mask, val) (2 | (ADI_VAL_MASK(addr, mask, val) << 16) | \ +(((addr) & 0x3F) << 24) | (1U << 30) | (((adiNo) ? 1U : 0) << 31)) +/// 2 ADI registers, half-size read-modify-write +#define ADI_2HALFREG_OVERRIDE(adiNo, addr, mask, val, addr2, mask2, val2) \ +(2 | (ADI_VAL_MASK(addr2, mask2, val2) << 2) | (((addr2) & 0x3F) << 10) | \ +(ADI_VAL_MASK(addr, mask, val) << 16) | (((addr) & 0x3F) << 24) | (1U << 30) | (((adiNo) ? 1U : 0) << 31)) + +/// 16-bit SW register as defined in radio_par_def.txt +#define SW_REG_OVERRIDE(cmd, field, val) (3 | ((_POSITION_##cmd##_##field) << 4) | ((uint32_t)(val) << 16)) +/// SW register as defined in radio_par_def.txt with added index (for use with registers > 16 bits). +#define SW_REG_IND_OVERRIDE(cmd, field, offset, val) (3 | \ +(((_POSITION_##cmd##_##field) + ((offset) << 1)) << 4) | ((uint32_t)(val) << 16)) +/// 8-bit SW register as defined in radio_par_def.txt +#define SW_REG_BYTE_OVERRIDE(cmd, field, val) (0x8003 | ((_POSITION_##cmd##_##field) << 4) | \ +((uint32_t)(val) << 16)) +/// Two 8-bit SW registers as defined in radio_par_def.txt; the one given by field and the next byte. +#define SW_REG_2BYTE_OVERRIDE(cmd, field, val0, val1) (3 | (((_POSITION_##cmd##_##field) & 0xFFFE) << 4) | \ + (((uint32_t)(val0) << 16) & 0x00FF0000) | ((uint32_t)(val1) << 24)) +#define HW16_ARRAY_OVERRIDE(addr, length) (1 | (((uintptr_t) (addr)) & 0xFFFC) | ((uint32_t)(length) << 16)) +#define HW32_ARRAY_OVERRIDE(addr, length) (1 | (((uintptr_t) (addr)) & 0xFFFC) | \ +((uint32_t)(length) << 16) | (1U << 30)) +#define ADI_ARRAY_OVERRIDE(adiNo, addr, bHalfSize, length) (1 | ((((addr) & 0x3F) << 2)) | \ +((!!(bHalfSize)) << 8) | ((!!(adiNo)) << 9) | ((uint32_t)(length) << 16) | (2U << 30)) +#define SW_ARRAY_OVERRIDE(cmd, firstfield, length) (1 | (((_POSITION_##cmd##_##firstfield)) << 2) | \ +((uint32_t)(length) << 16) | (3U << 30)) +#define MCE_RFE_OVERRIDE(bMceRam, mceRomBank, mceMode, bRfeRam, rfeRomBank, rfeMode) \ + (7 | ((!!(bMceRam)) << 8) | (((mceRomBank) & 0x07) << 9) | ((!!(bRfeRam)) << 12) | (((rfeRomBank) & 0x07) << 13) | \ + (((mceMode) & 0x00FF) << 16) | (((rfeMode) & 0x00FF) << 24)) +#define NEW_OVERRIDE_SEGMENT(address) (((((uintptr_t)(address)) & 0x03FFFFFC) << 6) | 0x000F | \ + (((((uintptr_t)(address) >> 24) == 0x20) ? 0x01 : \ + (((uintptr_t)(address) >> 24) == 0x21) ? 0x02 : \ + (((uintptr_t)(address) >> 24) == 0xA0) ? 0x03 : \ + (((uintptr_t)(address) >> 24) == 0x00) ? 0x04 : \ + (((uintptr_t)(address) >> 24) == 0x10) ? 0x05 : \ + (((uintptr_t)(address) >> 24) == 0x11) ? 0x06 : \ + (((uintptr_t)(address) >> 24) == 0x40) ? 0x07 : \ + (((uintptr_t)(address) >> 24) == 0x50) ? 0x08 : \ + 0x09) << 4)) // Use illegal value for illegal address range +/// End of string for override register +#define END_OVERRIDE 0xFFFFFFFF + + +/// ADI address-value pair +#define ADI_ADDR_VAL(addr, value) ((((addr) & 0x7F) << 8) | ((value) & 0xFF)) +#define ADI_ADDR_VAL_MASK(addr, mask, value) ((((addr) & 0x7F) << 8) | ADI_VAL_MASK(addr, mask, value)) + +/// Low half-word +#define LOWORD(value) ((value) & 0xFFFF) +/// High half-word +#define HIWORD(value) ((value) >> 16) +///@} + + +#endif /* MAILBOX_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/prop_cmd.h b/cpu/cc26xx-cc13xx/rf-core/api/prop_cmd.h new file mode 100644 index 000000000..e0d0a0c35 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/prop_cmd.h @@ -0,0 +1,596 @@ +/****************************************************************************** +* Filename: prop_cmd.h +* Revised: 2015-08-04 10:40:45 +0200 (Tue, 04 Aug 2015) +* Revision: 44326 +* +* Description: CC13xx API for Proprietary mode commands +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3) Neither the name of the ORGANIZATION nor the names of its contributors may +* be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef PROP_CMD_H_ +#define PROP_CMD_H_ + +#ifndef __RFC_STRUCT +#ifdef __GNUC__ +#define __RFC_STRUCT __attribute__ ((aligned (4))) +#else +#define __RFC_STRUCT +#endif +#endif + +//! \addtogroup rfc +//! @{ + +//! \addtogroup prop_cmd +//! @{ + +#include +#include "mailbox.h" +#include "common_cmd.h" + +typedef struct __RFC_STRUCT rfc_carrierSense_s rfc_carrierSense_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_TX_s rfc_CMD_PROP_TX_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RX_s rfc_CMD_PROP_RX_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_TX_ADV_s rfc_CMD_PROP_TX_ADV_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RX_ADV_s rfc_CMD_PROP_RX_ADV_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RADIO_SETUP_s rfc_CMD_PROP_RADIO_SETUP_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RADIO_DIV_SETUP_s rfc_CMD_PROP_RADIO_DIV_SETUP_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_SET_LEN_s rfc_CMD_PROP_SET_LEN_t; +typedef struct __RFC_STRUCT rfc_CMD_PROP_RESTART_RX_s rfc_CMD_PROP_RESTART_RX_t; +typedef struct __RFC_STRUCT rfc_propRxOutput_s rfc_propRxOutput_t; +typedef struct __RFC_STRUCT rfc_propRxStatus_s rfc_propRxStatus_t; + +//! \addtogroup carrierSense +//! @{ +struct __RFC_STRUCT rfc_carrierSense_s { + struct { + uint8_t bEnaRssi:1; //!< If 1, enable RSSI as a criterion + uint8_t bEnaCorr:1; //!< If 1, enable correlation as a criterion + uint8_t operation:1; //!< \brief 0: Busy if either RSSI or correlation indicates Busy
+ //!< 1: Busy if both RSSI and correlation indicates Busy + uint8_t busyOp:1; //!< \brief 0: Continue carrier sense on channel Busy
+ //!< 1: End carrier sense on channel Busy
+ //!< For an Rx command, the receiver will continue when carrier sense ends, but it will then not end if channel goes Idle + uint8_t idleOp:1; //!< \brief 0: Continue on channel Idle
+ //!< 1: End on channel Idle + uint8_t timeoutRes:1; //!< \brief 0: Timeout with channel state Invalid treated as Busy
+ //!< 1: Timeout with channel state Invalid treated as Idle + } csConf; + int8_t rssiThr; //!< RSSI threshold + uint8_t numRssiIdle; //!< \brief Number of consecutive RSSI measurements below the threshold needed before the channel is + //!< declared Idle + uint8_t numRssiBusy; //!< \brief Number of consecutive RSSI measurements above the threshold needed before the channel is + //!< declared Busy + uint16_t corrPeriod; //!< Number of RAT ticks for a correlation observation periods + struct { + uint8_t numCorrInv:4; //!< \brief Number of subsequent correlation tops with maximum corrPeriod RAT + //!< ticks between them needed to go from Idle to Invalid + uint8_t numCorrBusy:4; //!< \brief Number of subsequent correlation tops with maximum corrPeriod RAT + //!< ticks between them needed to go from Invalid to Busy + } corrConfig; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } csEndTrigger; //!< Trigger classifier for ending the carrier sense + ratmr_t csEndTime; //!< Time used together with csEndTrigger for ending the operation +}; + +//! @} + +//! \addtogroup CMD_PROP_TX +//! @{ +#define CMD_PROP_TX 0x3801 +struct __RFC_STRUCT rfc_CMD_PROP_TX_s { + uint16_t commandNo; //!< The command ID number 0x3801 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
+ //!< 1: Turn frequency synth off after command + uint8_t :2; + uint8_t bUseCrc:1; //!< \brief 0: Do not append CRC
+ //!< 1: Append CRC + uint8_t bVarLen:1; //!< \brief 0: Fixed length
+ //!< 1: Transmit length as first byte + } pktConf; + uint8_t pktLen; //!< Packet length + uint32_t syncWord; //!< Sync word to transmit + uint8_t* pPkt; //!< Pointer to packet +}; + +//! @} + +//! \addtogroup CMD_PROP_RX +//! @{ +#define CMD_PROP_RX 0x3802 +struct __RFC_STRUCT rfc_CMD_PROP_RX_s { + uint16_t commandNo; //!< The command ID number 0x3802 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
+ //!< 1: Turn frequency synth off after command + uint8_t bRepeatOk:1; //!< \brief 0: End operation after receiving a packet correctly
+ //!< 1: Go back to sync search after receiving a packet correctly + uint8_t bRepeatNok:1; //!< \brief 0: End operation after receiving a packet with CRC error
+ //!< 1: Go back to sync search after receiving a packet with CRC error + uint8_t bUseCrc:1; //!< \brief 0: Do not check CRC
+ //!< 1: Check CRC + uint8_t bVarLen:1; //!< \brief 0: Fixed length
+ //!< 1: Receive length as first byte + uint8_t bChkAddress:1; //!< \brief 0: No address check
+ //!< 1: Check address + uint8_t endType:1; //!< \brief 0: Packet is received to the end if end trigger happens after sync is obtained
+ //!< 1: Packet reception is stopped if end trigger happens + uint8_t filterOp:1; //!< \brief 0: Stop receiver and restart sync search on address mismatch
+ //!< 1: Receive packet and mark it as ignored on address mismatch + } pktConf; + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically discard ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically discard packets with CRC error from Rx queue + uint8_t :1; + uint8_t bIncludeHdr:1; //!< If 1, include the received header or length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + } rxConf; //!< Rx configuration + uint32_t syncWord; //!< Sync word to listen for + uint8_t maxPktLen; //!< \brief Packet length for fixed length, maximum packet length for variable length
+ //!< 0: Unlimited or unknown length + uint8_t address0; //!< Address + uint8_t address1; //!< \brief Address (set equal to address0 to accept only one address. If 0xFF, accept + //!< 0x00 as well) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + ratmr_t endTime; //!< Time used together with endTrigger for ending the operation + dataQueue_t* pQueue; //!< Pointer to receive queue + uint8_t* pOutput; //!< Pointer to output structure +}; + +//! @} + +//! \addtogroup CMD_PROP_TX_ADV +//! @{ +#define CMD_PROP_TX_ADV 0x3803 +struct __RFC_STRUCT rfc_CMD_PROP_TX_ADV_s { + uint16_t commandNo; //!< The command ID number 0x3803 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
+ //!< 1: Turn frequency synth off after command + uint8_t :2; + uint8_t bUseCrc:1; //!< \brief 0: Do not append CRC
+ //!< 1: Append CRC + uint8_t bCrcIncSw:1; //!< \brief 0:Do not include sync word in CRC calculation
+ //!< 1: Include sync word in CRC calculation + uint8_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
+ //!< 1: Include header in CRC calculation + } pktConf; + uint8_t numHdrBits; //!< Number of bits in header (0–32) + uint16_t pktLen; //!< Packet length. 0: Unlimited + struct { + uint8_t bExtTxTrig:1; //!< \brief 0: Start packet on a fixed time from the command start trigger
+ //!< 1: Start packet on an external trigger (input event to RAT) + uint8_t inputMode:2; //!< \brief Input mode if external trigger is used for Tx start
+ //!< 0: Rising edge
+ //!< 1: Falling edge
+ //!< 2: Both edges
+ //!< 3: Reserved + uint8_t source:5; //!< RAT input event number used for capture if external trigger is used for Tx start + } startConf; + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } preTrigger; //!< Trigger for transition from preamble to sync word + ratmr_t preTime; //!< \brief Time used together with preTrigger for transition from preamble to sync + //!< word. If preTrigger.triggerType is set to "now", one preamble as + //!< configured in the setup will be sent. Otherwise, the preamble will be repeated until + //!< this trigger is observed. + uint32_t syncWord; //!< Sync word to transmit + uint8_t* pPkt; //!< Pointer to packet, or Tx queue for unlimited length +}; + +//! @} + +//! \addtogroup CMD_PROP_RX_ADV +//! @{ +#define CMD_PROP_RX_ADV 0x3804 +struct __RFC_STRUCT rfc_CMD_PROP_RX_ADV_s { + uint16_t commandNo; //!< The command ID number 0x3804 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint8_t bFsOff:1; //!< \brief 0: Keep frequency synth on after command
+ //!< 1: Turn frequency synth off after command + uint8_t bRepeatOk:1; //!< \brief 0: End operation after receiving a packet correctly
+ //!< 1: Go back to sync search after receiving a packet correctly + uint8_t bRepeatNok:1; //!< \brief 0: End operation after receiving a packet with CRC error
+ //!< 1: Go back to sync search after receiving a packet with CRC error + uint8_t bUseCrc:1; //!< \brief 0: Do not check CRC
+ //!< 1: Check CRC + uint8_t bCrcIncSw:1; //!< \brief 0: Do not include sync word in CRC calculation
+ //!< 1: Include sync word in CRC calculation + uint8_t bCrcIncHdr:1; //!< \brief 0: Do not include header in CRC calculation
+ //!< 1: Include header in CRC calculation + uint8_t endType:1; //!< \brief 0: Packet is received to the end if end trigger happens after sync is obtained
+ //!< 1: Packet reception is stopped if end trigger happens + uint8_t filterOp:1; //!< \brief 0: Stop receiver and restart sync search on address mismatch
+ //!< 1: Receive packet and mark it as ignored on address mismatch + } pktConf; + struct { + uint8_t bAutoFlushIgnored:1; //!< If 1, automatically discard ignored packets from Rx queue + uint8_t bAutoFlushCrcErr:1; //!< If 1, automatically discard packets with CRC error from Rx queue + uint8_t :1; + uint8_t bIncludeHdr:1; //!< If 1, include the received header or length byte in the stored packet; otherwise discard it + uint8_t bIncludeCrc:1; //!< If 1, include the received CRC field in the stored packet; otherwise discard it + uint8_t bAppendRssi:1; //!< If 1, append an RSSI byte to the packet in the Rx queue + uint8_t bAppendTimestamp:1; //!< If 1, append a timestamp to the packet in the Rx queue + uint8_t bAppendStatus:1; //!< If 1, append a status byte to the packet in the Rx queue + } rxConf; //!< Rx configuration + uint32_t syncWord0; //!< Sync word to listen for + uint32_t syncWord1; //!< Alternative sync word if non-zero + uint16_t maxPktLen; //!< \brief Packet length for fixed length, maximum packet length for variable length
+ //!< 0: Unlimited or unknown length + struct { + uint16_t numHdrBits:6; //!< Number of bits in header (0–32) + uint16_t lenPos:5; //!< Position of length field in header (0–31) + uint16_t numLenBits:5; //!< Number of bits in length field (0–16) + } hdrConf; + struct { + uint16_t addrType:1; //!< \brief 0: Address after header
+ //!< 1: Address in header + uint16_t addrSize:5; //!< \brief If addrType = 0: Address size in bytes
+ //!< If addrType = 1: Address size in bits + uint16_t addrPos:5; //!< \brief If addrType = 1: Bit position of address in header
+ //!< If addrType = 0: Non-zero to extend address with sync word identifier + uint16_t numAddr:5; //!< Number of addresses in address list + } addrConf; + int8_t lenOffset; //!< Signed value to add to length field + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } endTrigger; //!< Trigger classifier for ending the operation + ratmr_t endTime; //!< Time used together with endTrigger for ending the operation + uint8_t* pAddr; //!< Pointer to address list + dataQueue_t* pQueue; //!< Pointer to receive queue + uint8_t* pOutput; //!< Pointer to output structure +}; + +//! @} + +//! \addtogroup CMD_PROP_RADIO_SETUP +//! @{ +#define CMD_PROP_RADIO_SETUP 0x3806 +struct __RFC_STRUCT rfc_CMD_PROP_RADIO_SETUP_s { + uint16_t commandNo; //!< The command ID number 0x3806 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t modType:3; //!< \brief 0: FSK
+ //!< 1: GFSK
+ //!< Others: Reserved + uint16_t deviation:13; //!< Deviation (250 Hz steps) + } modulation; + struct { + uint32_t preScale:4; //!< Prescaler value + uint32_t :4; + uint32_t rateWord:21; //!< Rate word + } symbolRate; + uint8_t rxBw; //!< Receiver bandwidth + struct { + uint8_t nPreamBytes:6; //!< \brief 0–30: Number of preamble bytes
+ //!< 31: 4 preamble bits + uint8_t preamMode:2; //!< \brief 0: Send 0 as the first preamble bit
+ //!< 1: Send 1 as the first preamble bit
+ //!< 2: Send same first bit in preamble and sync word
+ //!< 3: Send different first bit in preamble and sync word + } preamConf; + struct { + uint16_t nSwBits:6; //!< Number of sync word bits (up to 32) + uint16_t bBitReversal:1; //!< \brief 0: Use positive deviation for 1
+ //!< 1: Use positive deviation for 0 + uint16_t bMsbFirst:1; //!< \brief 0: Least significant bit transmitted first
+ //!< 1: Most significant bit transmitted first + uint16_t fecMode:4; //!< \brief Select coding
+ //!< 0: Uncoded binary modulation
+ //!< 10: Manchester coded binary modulation
+ //!< Others: Reserved + uint16_t :1; + uint16_t whitenMode:3; //!< \brief 0: No whitening
+ //!< 1: CC1101/CC2500 compatible whitening
+ //!< 2: PN9 whitening without byte reversal
+ //!< 3: Reserved
+ //!< 4: No whitener, 32-bit IEEE 802.15.4g compatible CRC
+ //!< 5: IEEE 802.15.4g compatible whitener and 32-bit CRC
+ //!< 6: No whitener, dynamically IEEE 802.15.4g compatible 16-bit or 32-bit CRC
+ //!< 7: Dynamically IEEE 802.15.4g compatible whitener and 16-bit or 32-bit CRC + } formatConf; + struct { + uint16_t frontEndMode:3; //!< \brief 0x00: Differential mode
+ //!< 0x01: Single-ended mode RFP
+ //!< 0x02: Single-ended mode RFN
+ //!< 0x05 Single-ended mode RFP with external frontend control on RF pins (RFN and RXTX)
+ //!< 0x06 Single-ended mode RFN with external frontend control on RF pins (RFP and RXTX)
+ //!< Others: Reserved + uint16_t biasMode:1; //!< \brief 0: Internal bias
+ //!< 1: External bias + uint16_t :6; + uint16_t bNoFsPowerUp:1; //!< \brief 0: Power up frequency synth
+ //!< 1: Do not power up frequency synth + } config; //!< Configuration options + uint16_t txPower; //!< Transmit power + uint32_t* pRegOverride; //!< \brief Pointer to a list of hardware and configuration registers to override. If NULL, no + //!< override is used. +}; + +//! @} + +//! \addtogroup CMD_PROP_RADIO_DIV_SETUP +//! @{ +#define CMD_PROP_RADIO_DIV_SETUP 0x3807 +struct __RFC_STRUCT rfc_CMD_PROP_RADIO_DIV_SETUP_s { + uint16_t commandNo; //!< The command ID number 0x3807 + uint16_t status; //!< \brief An integer telling the status of the command. This value is + //!< updated by the radio CPU during operation and may be read by the + //!< system CPU at any time. + rfc_radioOp_t *pNextOp; //!< Pointer to the next operation to run after this operation is done + ratmr_t startTime; //!< Absolute or relative start time (depending on the value of startTrigger) + struct { + uint8_t triggerType:4; //!< The type of trigger + uint8_t bEnaCmd:1; //!< \brief 0: No alternative trigger command
+ //!< 1: CMD_TRIGGER can be used as an alternative trigger + uint8_t triggerNo:2; //!< The trigger number of the CMD_TRIGGER command that triggers this action + uint8_t pastTrig:1; //!< \brief 0: A trigger in the past is never triggered, or for start of commands, give an error
+ //!< 1: A trigger in the past is triggered as soon as possible + } startTrigger; //!< Identification of the trigger that starts the operation + struct { + uint8_t rule:4; //!< Condition for running next command: Rule for how to proceed + uint8_t nSkip:4; //!< Number of skips if the rule involves skipping + } condition; + struct { + uint16_t modType:3; //!< \brief 0: FSK
+ //!< 1: GFSK
+ //!< Others: Reserved + uint16_t deviation:13; //!< Deviation (250 Hz steps) + } modulation; + struct { + uint32_t preScale:4; //!< Prescaler value + uint32_t :4; + uint32_t rateWord:21; //!< Rate word + } symbolRate; + uint8_t rxBw; //!< Receiver bandwidth + struct { + uint8_t nPreamBytes:6; //!< \brief 0–30: Number of preamble bytes
+ //!< 31: 4 preamble bits + uint8_t preamMode:2; //!< \brief 0: Send 0 as the first preamble bit
+ //!< 1: Send 1 as the first preamble bit
+ //!< 2: Send same first bit in preamble and sync word
+ //!< 3: Send different first bit in preamble and sync word + } preamConf; + struct { + uint16_t nSwBits:6; //!< Number of sync word bits (up to 32) + uint16_t bBitReversal:1; //!< \brief 0: Use positive deviation for 1
+ //!< 1: Use positive deviation for 0 + uint16_t bMsbFirst:1; //!< \brief 0: Least significant bit transmitted first
+ //!< 1: Most significant bit transmitted first + uint16_t fecMode:4; //!< \brief Select coding
+ //!< 0: Uncoded binary modulation
+ //!< 10: Manchester coded binary modulation
+ //!< Others: Reserved + uint16_t :1; + uint16_t whitenMode:3; //!< \brief 0: No whitening
+ //!< 1: CC1101/CC2500 compatible whitening
+ //!< 2: PN9 whitening without byte reversal
+ //!< 3: Reserved
+ //!< 4: No whitener, 32-bit IEEE 802.15.4g compatible CRC
+ //!< 5: IEEE 802.15.4g compatible whitener and 32-bit CRC
+ //!< 6: No whitener, dynamically IEEE 802.15.4g compatible 16-bit or 32-bit CRC
+ //!< 7: Dynamically IEEE 802.15.4g compatible whitener and 16-bit or 32-bit CRC + } formatConf; + struct { + uint16_t frontEndMode:3; //!< \brief 0x00: Differential mode
+ //!< 0x01: Single-ended mode RFP
+ //!< 0x02: Single-ended mode RFN
+ //!< 0x05 Single-ended mode RFP with external frontend control on RF pins (RFN and RXTX)
+ //!< 0x06 Single-ended mode RFN with external frontend control on RF pins (RFP and RXTX)
+ //!< Others: Reserved + uint16_t biasMode:1; //!< \brief 0: Internal bias
+ //!< 1: External bias + uint16_t :6; + uint16_t bNoFsPowerUp:1; //!< \brief 0: Power up frequency synth
+ //!< 1: Do not power up frequency synth + } config; //!< Configuration options + uint16_t txPower; //!< Transmit power + uint32_t* pRegOverride; //!< \brief Pointer to a list of hardware and configuration registers to override. If NULL, no + //!< override is used. + uint16_t centerFreq; //!< \brief Center frequency of the frequency band used, in MHz; used for calculating some internal Tx and Rx parameters. + //!< For a single channel RF system, this should be set equal to the RF frequency used. + //!< For a multi channel RF system (e.g. frequency hopping spread spectrum), this should be set equal + //!< to the center frequency of the frequency band used. + int16_t intFreq; //!< \brief Intermediate frequency to use for Rx, in MHz on 4.12 signed format. Tx will use same + //!< intermediate frequency if supported, otherwise 0.
+ //!< 0x8000: Use default. + uint8_t loDivider; //!< LO frequency divider setting to use. Supported values: 2, 5, 6, 10, 12, 15, and 30 +}; + +//! @} + +//! \addtogroup CMD_PROP_SET_LEN +//! @{ +#define CMD_PROP_SET_LEN 0x3401 +struct __RFC_STRUCT rfc_CMD_PROP_SET_LEN_s { + uint16_t commandNo; //!< The command ID number 0x3401 + uint16_t rxLen; //!< Payload length to use +}; + +//! @} + +//! \addtogroup CMD_PROP_RESTART_RX +//! @{ +#define CMD_PROP_RESTART_RX 0x3402 +struct __RFC_STRUCT rfc_CMD_PROP_RESTART_RX_s { + uint16_t commandNo; //!< The command ID number 0x3402 +}; + +//! @} + +//! \addtogroup propRxOutput +//! @{ +//! Output structure for Rx operations + +struct __RFC_STRUCT rfc_propRxOutput_s { + uint16_t nRxOk; //!< Number of packets that have been received with payload, CRC OK and not ignored + uint16_t nRxNok; //!< Number of packets that have been received with CRC error + uint8_t nRxIgnored; //!< Number of packets that have been received with CRC OK and ignored due to address mismatch + uint8_t nRxStopped; //!< Number of packets not received due to illegal length or address mismatch with pktConf.filterOp = 1 + uint8_t nRxBufFull; //!< Number of packets that have been received and discarded due to lack of buffer space + int8_t lastRssi; //!< RSSI of last received packet + ratmr_t timeStamp; //!< Time stamp of last received packet +}; + +//! @} + +//! \addtogroup propRxStatus +//! @{ +//! Receive status byte that may be appended to message in receive buffer + +struct __RFC_STRUCT rfc_propRxStatus_s { + struct { + uint8_t addressInd:5; //!< Index of address found (0 if not applicable) + uint8_t syncWordId:1; //!< 0 for primary sync word, 1 for alternate sync word + uint8_t result:2; //!< \brief 0: Packet received correctly, not ignored
+ //!< 1: Packet received with CRC error
+ //!< 2: Packet received correctly, but can be ignored
+ //!< 3: Packet reception was aborted + } status; +}; + +//! @} + +//! @} +//! @} +#endif /* PROP_CMD_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/api/prop_mailbox.h b/cpu/cc26xx-cc13xx/rf-core/api/prop_mailbox.h new file mode 100644 index 000000000..ff7b6c25b --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/api/prop_mailbox.h @@ -0,0 +1,71 @@ +/****************************************************************************** +* Filename: prop_mailbox.h +* Revised: 2015-06-29 12:59:58 +0200 (Mon, 29 Jun 2015) +* Revision: 44063 +* +* Description: Definitions for proprietary mode radio interface +* +* Copyright (c) 2015, Texas Instruments Incorporated +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* +* 1) Redistributions of source code must retain the above copyright notice, +* this list of conditions and the following disclaimer. +* +* 2) Redistributions in binary form must reproduce the above copyright notice, +* this list of conditions and the following disclaimer in the documentation +* and/or other materials provided with the distribution. +* +* 3) Neither the name of the ORGANIZATION nor the names of its contributors may +* be used to endorse or promote products derived from this software without +* specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +* +******************************************************************************/ + +#ifndef PROP_MAILBOX_H_ +#define PROP_MAILBOX_H_ + +/// \name Radio operation status +///@{ +/// \name Operation finished normally +///@{ +#define PROP_DONE_OK 0x3400 ///< Operation ended normally +#define PROP_DONE_RXTIMEOUT 0x3401 ///< Operation stopped after end trigger while waiting for sync +#define PROP_DONE_BREAK 0x3402 ///< Rx stopped due to time out in the middle of a packet +#define PROP_DONE_ENDED 0x3403 ///< Operation stopped after end trigger during reception +#define PROP_DONE_STOPPED 0x3404 ///< Operation stopped after stop command +#define PROP_DONE_ABORT 0x3405 ///< Operation aborted by abort command +#define PROP_DONE_RXERR 0x3406 ///< Operation ended after receiving packet with CRC error +#define PROP_DONE_IDLE 0x3407 ///< Carrier sense operation ended because of idle channel +#define PROP_DONE_BUSY 0x3408 ///< Carrier sense operation ended because of busy channel +#define PROP_DONE_IDLETIMEOUT 0x3409 ///< Carrier sense operation ended because of time out with csConf.timeoutRes = 1 +#define PROP_DONE_BUSYTIMEOUT 0x340A ///< Carrier sense operation ended because of time out with csConf.timeoutRes = 0 + +///@} +/// \name Operation finished with error +///@{ +#define PROP_ERROR_PAR 0x3800 ///< Illegal parameter +#define PROP_ERROR_RXBUF 0x3801 ///< No available Rx buffer at the start of a packet +#define PROP_ERROR_RXFULL 0x3802 ///< Out of Rx buffer during reception in a partial read buffer +#define PROP_ERROR_NO_SETUP 0x3803 ///< Radio was not set up in proprietary mode +#define PROP_ERROR_NO_FS 0x3804 ///< Synth was not programmed when running Rx or Tx +#define PROP_ERROR_RXOVF 0x3805 ///< Rx overflow observed during operation +#define PROP_ERROR_TXUNF 0x3806 ///< Tx underflow observed during operation +///@} +///@} + +#endif /* PROP_MAILBOX_H_ */ diff --git a/cpu/cc26xx-cc13xx/rf-core/dot-15-4g.h b/cpu/cc26xx-cc13xx/rf-core/dot-15-4g.h new file mode 100644 index 000000000..30dc63367 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/dot-15-4g.h @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core + * @{ + * + * \defgroup rf-core-15-4g-modes IEEE 802.15.4g Frequency Bands and Modes + * + * @{ + * + * \file + * Header file with descriptors for the various modes of operation defined in + * IEEE 802.15.4g + */ +/*---------------------------------------------------------------------------*/ +#ifndef DOT_15_4G_H_ +#define DOT_15_4G_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +/*---------------------------------------------------------------------------*/ +/* IEEE 802.15.4g frequency band identifiers (Table 68f) */ +#define DOT_15_4G_FREQUENCY_BAND_169 0 /* 169.400–169.475 (Europe) - 169 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_450 1 /* 450–470 (US FCC Part 22/90) - 450 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_470 2 /* 470–510 (China) - 470 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_780 3 /* 779–787 (China) - 780 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_863 4 /* 863–870 (Europe) - 863 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_896 5 /* 896–901 (US FCC Part 90) - 896 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_901 6 /* 901–902 (US FCC Part 24) - 901 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_915 7 /* 902–928 (US) - 915 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_917 8 /* 917–923.5 (Korea) - 917 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_920 9 /* 920–928 (Japan) - 920 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_928 10 /* 928–960 (US, non-contiguous) - 928 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_950 11 /* 950–958 (Japan) - 950 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_1427 12 /* 1427–1518 (US and Canada, non-contiguous) - 1427 MHz band */ +#define DOT_15_4G_FREQUENCY_BAND_2450 13 /* 2400–2483.5 2450 MHz band */ +/*---------------------------------------------------------------------------*/ +/* Default band selection to band 4 - 863MHz */ +#ifdef DOT_15_4G_CONF_FREQUENCY_BAND_ID +#define DOT_15_4G_FREQUENCY_BAND_ID DOT_15_4G_CONF_FREQUENCY_BAND_ID +#else +#define DOT_15_4G_FREQUENCY_BAND_ID DOT_15_4G_FREQUENCY_BAND_863 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Channel count, spacing and other params relating to the selected band. We + * currently only support some of the bands defined in .15.4g and for those + * bands we only support operating mode #1 (Table 134). + * + * DOT_15_4G_CHAN0_FREQUENCY is specified here in KHz + */ +#if DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_470 +#define DOT_15_4G_CHANNEL_MAX 198 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 470200 +#define PROP_MODE_CONF_LO_DIVIDER 0x0A + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_780 +#define DOT_15_4G_CHANNEL_MAX 38 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 779200 +#define PROP_MODE_CONF_LO_DIVIDER 0x06 + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_863 +#define DOT_15_4G_CHANNEL_MAX 33 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 863125 +#define PROP_MODE_CONF_LO_DIVIDER 0x05 + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_915 +#define DOT_15_4G_CHANNEL_MAX 128 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 902200 +#define PROP_MODE_CONF_LO_DIVIDER 0x05 + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_920 +#define DOT_15_4G_CHANNEL_MAX 37 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 920600 +#define PROP_MODE_CONF_LO_DIVIDER 0x05 + +#elif DOT_15_4G_FREQUENCY_BAND_ID==DOT_15_4G_FREQUENCY_BAND_950 +#define DOT_15_4G_CHANNEL_MAX 32 +#define DOT_15_4G_CHANNEL_SPACING 200 +#define DOT_15_4G_CHAN0_FREQUENCY 951000 +#define PROP_MODE_CONF_LO_DIVIDER 0x05 + +#else +#error The selected frequency band is not supported +#endif +/*---------------------------------------------------------------------------*/ +#endif /* DOT_15_4G_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c new file mode 100644 index 000000000..b997043ab --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/ieee-mode.c @@ -0,0 +1,1376 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core + * @{ + * + * \defgroup rf-core-ieee CC13xx/CC26xx IEEE mode driver + * + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx IEEE mode NETSTACK_RADIO driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/radio.h" +#include "dev/cc26xx-uart.h" +#include "dev/oscillators.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "net/linkaddr.h" +#include "net/netstack.h" +#include "sys/energest.h" +#include "sys/clock.h" +#include "sys/rtimer.h" +#include "sys/cc.h" +#include "lpm.h" +#include "ti-lib.h" +#include "rf-core/rf-core.h" +#include "rf-core/rf-ble.h" +/*---------------------------------------------------------------------------*/ +/* RF core and RF HAL API */ +#include "hw_rfc_dbell.h" +#include "hw_rfc_pwr.h" +/*---------------------------------------------------------------------------*/ +/* RF Core Mailbox API */ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/ieee_cmd.h" +#include "rf-core/api/data_entry.h" +#include "rf-core/api/ieee_mailbox.h" +/*---------------------------------------------------------------------------*/ +#include "smartrf-settings.h" +/*---------------------------------------------------------------------------*/ +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#ifdef __GNUC__ +#define CC_ALIGN_ATTR(n) __attribute__ ((aligned(n))) +#else +#define CC_ALIGN_ATTR(n) +#endif +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +/* Configuration to enable/disable auto ACKs in IEEE mode */ +#ifdef IEEE_MODE_CONF_AUTOACK +#define IEEE_MODE_AUTOACK IEEE_MODE_CONF_AUTOACK +#else +#define IEEE_MODE_AUTOACK 1 +#endif /* IEEE_MODE_CONF_AUTOACK */ + +/* Configuration to enable/disable frame filtering in IEEE mode */ +#ifdef IEEE_MODE_CONF_PROMISCOUS +#define IEEE_MODE_PROMISCOUS IEEE_MODE_CONF_PROMISCOUS +#else +#define IEEE_MODE_PROMISCOUS 0 +#endif /* IEEE_MODE_CONF_PROMISCOUS */ + +#ifdef IEEE_MODE_CONF_RSSI_THRESHOLD +#define IEEE_MODE_RSSI_THRESHOLD IEEE_MODE_CONF_RSSI_THRESHOLD +#else +#define IEEE_MODE_RSSI_THRESHOLD 0xA6 +#endif /* IEEE_MODE_CONF_RSSI_THRESHOLD */ +/*---------------------------------------------------------------------------*/ +/* Data entry status field constants */ +#define DATA_ENTRY_STATUS_PENDING 0x00 /* Not in use by the Radio CPU */ +#define DATA_ENTRY_STATUS_ACTIVE 0x01 /* Open for r/w by the radio CPU */ +#define DATA_ENTRY_STATUS_BUSY 0x02 /* Ongoing r/w */ +#define DATA_ENTRY_STATUS_FINISHED 0x03 /* Free to use and to free */ +#define DATA_ENTRY_STATUS_UNFINISHED 0x04 /* Partial RX entry */ +/*---------------------------------------------------------------------------*/ +/* RF stats data structure */ +static uint8_t rf_stats[16] = { 0 }; +/*---------------------------------------------------------------------------*/ +/* The size of the RF commands buffer */ +#define RF_CMD_BUFFER_SIZE 128 +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the current status of a running Radio Op command + * \param a A pointer with the buffer used to initiate the command + * \return The value of the Radio Op buffer's status field + * + * This macro can be used to e.g. return the status of a previously + * initiated background operation, or of an immediate command + */ +#define RF_RADIO_OP_GET_STATUS(a) (((rfc_radioOp_t *)a)->status) +/*---------------------------------------------------------------------------*/ +/* Special value returned by CMD_IEEE_CCA_REQ when an RSSI is not available */ +#define RF_CMD_CCA_REQ_RSSI_UNKNOWN -128 + +/* Used for the return value of channel_clear */ +#define RF_CCA_CLEAR 1 +#define RF_CCA_BUSY 0 + +/* Used as an error return value for get_cca_info */ +#define RF_GET_CCA_INFO_ERROR 0xFF + +/* + * Values of the individual bits of the ccaInfo field in CMD_IEEE_CCA_REQ's + * status struct + */ +#define RF_CMD_CCA_REQ_CCA_STATE_IDLE 0 /* 00 */ +#define RF_CMD_CCA_REQ_CCA_STATE_BUSY 1 /* 01 */ +#define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2 /* 10 */ +/*---------------------------------------------------------------------------*/ +#define IEEE_MODE_CHANNEL_MIN 11 +#define IEEE_MODE_CHANNEL_MAX 26 +/*---------------------------------------------------------------------------*/ +/* How long to wait for an ongoing ACK TX to finish before starting frame TX */ +#define TX_WAIT_TIMEOUT (RTIMER_SECOND >> 11) + +/* How long to wait for the RF to enter RX in rf_cmd_ieee_rx */ +#define ENTER_RX_WAIT_TIMEOUT (RTIMER_SECOND >> 10) +/*---------------------------------------------------------------------------*/ +/* TX Power dBm lookup table - values from SmartRF Studio */ +typedef struct output_config { + radio_value_t dbm; + uint8_t register_ib; + uint8_t register_gc; + uint8_t temp_coeff; +} output_config_t; + +static const output_config_t output_power[] = { + { 5, 0x30, 0x00, 0x93 }, + { 4, 0x24, 0x00, 0x93 }, + { 3, 0x1c, 0x00, 0x5a }, + { 2, 0x18, 0x00, 0x4e }, + { 1, 0x14, 0x00, 0x42 }, + { 0, 0x21, 0x01, 0x31 }, + { -3, 0x18, 0x01, 0x25 }, + { -6, 0x11, 0x01, 0x1d }, + { -9, 0x0e, 0x01, 0x19 }, + {-12, 0x0b, 0x01, 0x14 }, + {-15, 0x0b, 0x03, 0x0c }, + {-18, 0x09, 0x03, 0x0c }, + {-21, 0x07, 0x03, 0x0c }, +}; + +#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) + +/* Max and Min Output Power in dBm */ +#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm) +#define OUTPUT_POWER_MAX (output_power[0].dbm) +#define OUTPUT_POWER_UNKNOWN 0xFFFF + +/* Default TX Power - position in output_power[] */ +const output_config_t *tx_power_current = &output_power[0]; +/*---------------------------------------------------------------------------*/ +/* + * Buffers used to send commands to the RF core (generic and IEEE commands). + * Some of those buffers are re-usable, some are not. + * + * If you are uncertain, declare a new buffer. + */ +/* + * A buffer to send a CMD_IEEE_RX and to subsequently monitor its status + * Do not use this buffer for any commands other than CMD_IEEE_RX + */ +static uint8_t cmd_ieee_rx_buf[RF_CMD_BUFFER_SIZE] CC_ALIGN_ATTR(4); +/*---------------------------------------------------------------------------*/ +#define DATA_ENTRY_LENSZ_NONE 0 +#define DATA_ENTRY_LENSZ_BYTE 1 +#define DATA_ENTRY_LENSZ_WORD 2 /* 2 bytes */ + +#define RX_BUF_SIZE 140 +/* Four receive buffers entries with room for 1 IEEE802.15.4 frame in each */ +static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN_ATTR(4); +static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN_ATTR(4); +static uint8_t rx_buf_2[RX_BUF_SIZE] CC_ALIGN_ATTR(4); +static uint8_t rx_buf_3[RX_BUF_SIZE] CC_ALIGN_ATTR(4); + +/* The RX Data Queue */ +static dataQueue_t rx_data_queue = { 0 }; + +/* Receive entry pointer to keep track of read items */ +volatile static uint8_t *rx_read_entry; +/*---------------------------------------------------------------------------*/ +/* The outgoing frame buffer */ +#define TX_BUF_PAYLOAD_LEN 180 +#define TX_BUF_HDR_LEN 2 + +static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN_ATTR(4); +/*---------------------------------------------------------------------------*/ +/* Overrides for IEEE 802.15.4, differential mode */ +static uint32_t ieee_overrides[] = { + 0x00354038, /* Synth: Set RTRIM (POTAILRESTRIM) to 5 */ + 0x4001402D, /* Synth: Correct CKVD latency setting (address) */ + 0x00608402, /* Synth: Correct CKVD latency setting (value) */ +// 0x4001405D, /* Synth: Set ANADIV DIV_BIAS_MODE to PG1 (address) */ +// 0x1801F800, /* Synth: Set ANADIV DIV_BIAS_MODE to PG1 (value) */ + 0x000784A3, /* Synth: Set FREF = 3.43 MHz (24 MHz / 7) */ + 0xA47E0583, /* Synth: Set loop bandwidth after lock to 80 kHz (K2) */ + 0xEAE00603, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, LSB) */ + 0x00010623, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, MSB) */ + 0x002B50DC, /* Adjust AGC DC filter */ + 0x05000243, /* Increase synth programming timeout */ + 0x002082C3, /* Increase synth programming timeout */ + 0xFFFFFFFF, /* End of override list */ +}; +/*---------------------------------------------------------------------------*/ +static int on(void); +static int off(void); +/*---------------------------------------------------------------------------*/ +/** + * \brief Checks whether the RFC domain is accessible and the RFC is in IEEE RX + * \return 1: RFC in RX mode (and therefore accessible too). 0 otherwise + */ +static uint8_t +rf_is_on(void) +{ + if(!rf_core_is_accessible()) { + return 0; + } + + return RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == RF_CORE_RADIO_OP_STATUS_ACTIVE; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Check the RF's TX status + * \return 1 RF is transmitting + * \return 0 RF is not transmitting + * + * TX mode may be triggered either by a CMD_IEEE_TX or by the automatic + * transmission of an ACK frame. + */ +static uint8_t +transmitting(void) +{ + uint32_t cmd_status; + rfc_CMD_IEEE_CCA_REQ_t cmd; + + /* If we are off, we are not in TX */ + if(!rf_core_is_accessible()) { + return 0; + } + + memset(&cmd, 0x00, sizeof(cmd)); + + cmd.commandNo = CMD_IEEE_CCA_REQ; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("transmitting: CMDSTA=0x%08lx\n", cmd_status); + return 0; + } + + if((cmd.currentRssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN) && + (cmd.ccaInfo.ccaEnergy == RF_CMD_CCA_REQ_CCA_STATE_BUSY)) { + return 1; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns CCA information + * \return RF_GET_CCA_INFO_ERROR if the RF was not on + * \return On success, the return value is formatted as per the ccaInfo field + * of CMD_IEEE_CCA_REQ + * + * It is the caller's responsibility to make sure the RF is on. This function + * will return RF_GET_CCA_INFO_ERROR if the RF is off + * + * This function will in fact wait for a valid RSSI signal + */ +static uint8_t +get_cca_info(void) +{ + uint32_t cmd_status; + int8_t rssi; + rfc_CMD_IEEE_CCA_REQ_t cmd; + + if(!rf_is_on()) { + PRINTF("get_cca_info: Not on\n"); + return RF_GET_CCA_INFO_ERROR; + } + + rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; + + while(rssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) { + memset(&cmd, 0x00, sizeof(cmd)); + cmd.commandNo = CMD_IEEE_CCA_REQ; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("get_cca_info: CMDSTA=0x%08lx\n", cmd_status); + + return RF_GET_CCA_INFO_ERROR; + } + + rssi = cmd.currentRssi; + } + + /* We have a valid RSSI signal. Return the CCA Info */ + return *((uint8_t *)&cmd.ccaInfo); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Reads the current signal strength (RSSI) + * \return The current RSSI in dBm or CMD_GET_RSSI_UNKNOWN + * + * This function reads the current RSSI on the currently configured + * channel. + */ +static radio_value_t +get_rssi(void) +{ + uint32_t cmd_status; + int8_t rssi; + uint8_t was_off = 0; + rfc_CMD_GET_RSSI_t cmd; + + /* If we are off, turn on first */ + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("get_rssi: on() failed\n"); + return RF_CMD_CCA_REQ_RSSI_UNKNOWN; + } + } + + memset(&cmd, 0x00, sizeof(cmd)); + cmd.commandNo = CMD_GET_RSSI; + + rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_OK) { + /* Current RSSI in bits 23:16 of cmd_status */ + rssi = (cmd_status >> 16) & 0xFF; + } + + /* If we were off, turn back off */ + if(was_off) { + off(); + } + + return rssi; +} +/*---------------------------------------------------------------------------*/ +/* Returns the current TX power in dBm */ +static radio_value_t +get_tx_power(void) +{ + return tx_power_current->dbm; +} +/*---------------------------------------------------------------------------*/ +/* + * Set TX power to 'at least' power dBm + * This works with a lookup table. If the value of 'power' does not exist in + * the lookup table, TXPOWER will be set to the immediately higher available + * value + */ +static void +set_tx_power(radio_value_t power) +{ + uint32_t cmd_status; + int i; + rfc_CMD_SET_TX_POWER_t cmd; + + /* Send a CMD_SET_TX_POWER command to the RF */ + memset(&cmd, 0x00, sizeof(cmd)); + + cmd.commandNo = CMD_SET_TX_POWER; + + for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) { + if(power <= output_power[i].dbm) { + cmd.txPower.IB = output_power[i].register_ib; + cmd.txPower.GC = output_power[i].register_gc; + cmd.txPower.tempCoeff = output_power[i].temp_coeff; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_OK) { + /* Success: Remember the new setting */ + tx_power_current = &output_power[i]; + } else { + PRINTF("set_tx_power: CMDSTA=0x%08lx\n", cmd_status); + } + return; + } + } +} +/*---------------------------------------------------------------------------*/ +static uint8_t +rf_radio_setup() +{ + uint32_t cmd_status; + rfc_CMD_RADIO_SETUP_t cmd; + + /* Create radio setup command */ + rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_RADIO_SETUP); + + cmd.txPower.IB = tx_power_current->register_ib; + cmd.txPower.GC = tx_power_current->register_gc; + cmd.txPower.tempCoeff = tx_power_current->temp_coeff; + cmd.pRegOverride = ieee_overrides; + cmd.mode = 1; + + /* Send Radio setup to RF Core */ + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rf_radio_setup: CMD_RADIO_SETUP, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until radio setup is done */ + if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) { + PRINTF("rf_radio_setup: CMD_RADIO_SETUP wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Set up radio in IEEE802.15.4 RX mode + * + * \return RF_CORE_CMD_OK Succeeded + * \return RF_CORE_CMD_ERROR Failed + * + * This function assumes that cmd_ieee_rx_buf has been previously populated + * with correct values. This can be done through init_rf_params (sets defaults) + * or through Contiki's extended RF API (set_value, set_object) + */ +static uint8_t +rf_cmd_ieee_rx() +{ + uint32_t cmd_status; + rtimer_clock_t t0; + int ret; + + ret = rf_core_send_cmd((uint32_t)cmd_ieee_rx_buf, &cmd_status); + + if(ret != RF_CORE_CMD_OK) { + PRINTF("rf_cmd_ieee_rx: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", + ret, cmd_status, RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + return RF_CORE_CMD_ERROR; + } + + t0 = RTIMER_NOW(); + + while(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) != RF_CORE_RADIO_OP_STATUS_ACTIVE && + (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ENTER_RX_WAIT_TIMEOUT))); + + /* Wait to enter RX */ + if(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) != RF_CORE_RADIO_OP_STATUS_ACTIVE) { + PRINTF("rf_cmd_ieee_rx: CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + return RF_CORE_CMD_ERROR; + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static void +init_rx_buffers(void) +{ + rfc_dataEntry_t *entry; + + entry = (rfc_dataEntry_t *)rx_buf_0; + entry->pNextEntry = rx_buf_1; + entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE; + entry->length = sizeof(rx_buf_0) - 8; + + entry = (rfc_dataEntry_t *)rx_buf_1; + entry->pNextEntry = rx_buf_2; + entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE; + entry->length = sizeof(rx_buf_0) - 8; + + entry = (rfc_dataEntry_t *)rx_buf_2; + entry->pNextEntry = rx_buf_3; + entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE; + entry->length = sizeof(rx_buf_0) - 8; + + entry = (rfc_dataEntry_t *)rx_buf_3; + entry->pNextEntry = rx_buf_0; + entry->config.lenSz = DATA_ENTRY_LENSZ_BYTE; + entry->length = sizeof(rx_buf_0) - 8; +} +/*---------------------------------------------------------------------------*/ +static void +init_rf_params(void) +{ + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + + memset(cmd_ieee_rx_buf, 0x00, RF_CMD_BUFFER_SIZE); + + cmd->commandNo = CMD_IEEE_RX; + cmd->status = RF_CORE_RADIO_OP_STATUS_IDLE; + cmd->pNextOp = NULL; + cmd->startTime = 0x00000000; + cmd->startTrigger.triggerType = TRIG_NOW; + cmd->condition.rule = COND_NEVER; + cmd->channel = RF_CORE_CHANNEL; + + cmd->rxConfig.bAutoFlushCrc = 1; + cmd->rxConfig.bAutoFlushIgn = 0; + cmd->rxConfig.bIncludePhyHdr = 0; + cmd->rxConfig.bIncludeCrc = 1; + cmd->rxConfig.bAppendRssi = 1; + cmd->rxConfig.bAppendCorrCrc = 1; + cmd->rxConfig.bAppendSrcInd = 0; + cmd->rxConfig.bAppendTimestamp = 0; + + cmd->pRxQ = &rx_data_queue; + cmd->pOutput = (rfc_ieeeRxOutput_t *)rf_stats; + +#if IEEE_MODE_PROMISCOUS + cmd->frameFiltOpt.frameFiltEn = 0; +#else + cmd->frameFiltOpt.frameFiltEn = 1; +#endif + + cmd->frameFiltOpt.frameFiltStop = 1; + +#if IEEE_MODE_AUTOACK + cmd->frameFiltOpt.autoAckEn = 1; +#else + cmd->frameFiltOpt.autoAckEn = 0; +#endif + + cmd->frameFiltOpt.slottedAckEn = 0; + cmd->frameFiltOpt.autoPendEn = 0; + cmd->frameFiltOpt.defaultPend = 0; + cmd->frameFiltOpt.bPendDataReqOnly = 0; + cmd->frameFiltOpt.bPanCoord = 0; + cmd->frameFiltOpt.maxFrameVersion = 1; + cmd->frameFiltOpt.bStrictLenFilter = 0; + + /* Receive all frame types */ + cmd->frameTypes.bAcceptFt0Beacon = 1; + cmd->frameTypes.bAcceptFt1Data = 1; + cmd->frameTypes.bAcceptFt2Ack = 1; + cmd->frameTypes.bAcceptFt3MacCmd = 1; + cmd->frameTypes.bAcceptFt4Reserved = 1; + cmd->frameTypes.bAcceptFt5Reserved = 1; + cmd->frameTypes.bAcceptFt6Reserved = 1; + cmd->frameTypes.bAcceptFt7Reserved = 1; + + /* Configure CCA settings */ + cmd->ccaOpt.ccaEnEnergy = 1; + cmd->ccaOpt.ccaEnCorr = 1; + cmd->ccaOpt.ccaEnSync = 0; + cmd->ccaOpt.ccaCorrOp = 1; + cmd->ccaOpt.ccaSyncOp = 1; + cmd->ccaOpt.ccaCorrThr = 3; + + cmd->ccaRssiThr = IEEE_MODE_RSSI_THRESHOLD; + + cmd->numExtEntries = 0x00; + cmd->numShortEntries = 0x00; + cmd->pExtEntryList = 0; + cmd->pShortEntryList = 0; + + cmd->endTrigger.triggerType = TRIG_NEVER; + cmd->endTime = 0x00000000; +} +/*---------------------------------------------------------------------------*/ +static int +rx_on(void) +{ + int ret; + + /* Get status of running IEEE_RX (if any) */ + if(rf_is_on()) { + PRINTF("rx_on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), + RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + return RF_CORE_CMD_OK; + } + + /* Put CPE in RX using the currently configured parameters */ + ret = rf_cmd_ieee_rx(); + + if(ret) { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +rx_off(void) +{ + uint32_t cmd_status; + int ret; + + /* If we are off, do nothing */ + if(!rf_is_on()) { + return RF_CORE_CMD_OK; + } + + /* Wait for ongoing ACK TX to finish */ + while(transmitting()); + + /* Send a CMD_ABORT command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("RX off: CMD_ABORT status=0x%08lx\n", cmd_status); + /* Continue nonetheless */ + } + + while(rf_is_on()); + + if(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_STOPPED || + RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_ABORT) { + /* Stopped gracefully */ + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ret = RF_CORE_CMD_OK; + } else { + PRINTF("RX off: BG status=0x%04x\n", RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + ret = RF_CORE_CMD_ERROR; + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +request(void) +{ + /* + * We rely on the RDC layer to turn us on and off. Thus, if we are on we + * will only allow sleep, standby otherwise + */ + if(rf_is_on()) { + return LPM_MODE_SLEEP; + } + + return LPM_MODE_MAX_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE); +/*---------------------------------------------------------------------------*/ +static void +soft_off(void) +{ + uint32_t cmd_status; + volatile rfc_radioOp_t *cmd = rf_core_get_last_radio_op(); + + if(!rf_core_is_accessible()) { + return; + } + + PRINTF("soft_off: Aborting 0x%04x, Status=0x%04x\n", cmd->commandNo, + cmd->status); + + /* Send a CMD_ABORT command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("soft_off: CMD_ABORT status=0x%08lx\n", cmd_status); + return; + } + + while((cmd->status & RF_CORE_RADIO_OP_MASKED_STATUS) == + RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +soft_on(void) +{ + if(rf_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("on: radio_setup() failed\n"); + return RF_CORE_CMD_ERROR; + } + + return rx_on(); +} +/*---------------------------------------------------------------------------*/ +static const rf_core_primary_mode_t mode_ieee = { + soft_off, + soft_on, +}; +/*---------------------------------------------------------------------------*/ +static int +init(void) +{ + lpm_register_module(&cc26xx_rf_lpm_module); + + rf_core_set_modesel(); + + /* Initialise RX buffers */ + memset(rx_buf_0, 0, RX_BUF_SIZE); + memset(rx_buf_1, 0, RX_BUF_SIZE); + memset(rx_buf_2, 0, RX_BUF_SIZE); + memset(rx_buf_3, 0, RX_BUF_SIZE); + + /* Set of RF Core data queue. Circular buffer, no last entry */ + rx_data_queue.pCurrEntry = rx_buf_0; + + rx_data_queue.pLastEntry = NULL; + + /* Initialize current read pointer to first element (used in ISR) */ + rx_read_entry = rx_buf_0; + + /* Populate the RF parameters data structure with default values */ + init_rf_params(); + + if(on() != RF_CORE_CMD_OK) { + PRINTF("init: on() failed\n"); + return RF_CORE_CMD_ERROR; + } + + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + rf_core_primary_mode_register(&mode_ieee); + + process_start(&rf_core_process, NULL); + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +prepare(const void *payload, unsigned short payload_len) +{ + int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN); + + memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len); + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +static int +transmit(unsigned short transmit_len) +{ + int ret; + uint8_t was_off = 0; + uint32_t cmd_status; + uint16_t stat; + uint8_t tx_active = 0; + rtimer_clock_t t0; + rfc_CMD_IEEE_TX_t cmd; + + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("transmit: on() failed\n"); + return RADIO_TX_ERR; + } + } + + /* + * We are certainly not TXing a frame as a result of CMD_IEEE_TX, but we may + * be in the process of TXing an ACK. In that case, wait for the TX to finish + * or return after approx TX_WAIT_TIMEOUT + */ + t0 = RTIMER_NOW(); + + do { + tx_active = transmitting(); + } while(tx_active == 1 && + (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + TX_WAIT_TIMEOUT))); + + if(tx_active) { + PRINTF("transmit: Already TXing and wait timed out\n"); + + if(was_off) { + off(); + } + + return RADIO_TX_COLLISION; + } + + /* Send the CMD_IEEE_TX command */ + rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_IEEE_TX); + + cmd.payloadLen = transmit_len; + cmd.pPayload = &tx_buf[TX_BUF_HDR_LEN]; + + /* Enable the LAST_FG_COMMAND_DONE interrupt, which will wake us up */ + rf_core_cmd_done_en(); + + ret = rf_core_send_cmd((uint32_t)&cmd, &cmd_status); + + if(ret) { + /* If we enter here, TX actually started */ + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + /* Idle away while the command is running */ + while((cmd.status & RF_CORE_RADIO_OP_MASKED_STATUS) + == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) { + lpm_sleep(); + } + + stat = cmd.status; + + if(stat == RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK) { + /* Sent OK */ + RIMESTATS_ADD(lltx); + ret = RADIO_TX_OK; + } else { + /* Operation completed, but frame was not sent */ + PRINTF("transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", ret, + cmd_status, stat); + ret = RADIO_TX_ERR; + } + } else { + /* Failure sending the CMD_IEEE_TX command */ + PRINTF("transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", + ret, cmd_status, cmd.status); + + ret = RADIO_TX_ERR; + } + + /* + * Update ENERGEST state here, before a potential call to off(), which + * will correctly update it if required. + */ + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + /* + * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it + * except when we are transmitting + */ + rf_core_cmd_done_dis(); + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +send(const void *payload, unsigned short payload_len) +{ + prepare(payload, payload_len); + return transmit(payload_len); +} +/*---------------------------------------------------------------------------*/ +static void +release_data_entry(void) +{ + rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry; + + /* Clear the length byte */ + rx_read_entry[8] = 0; + + /* Set status to 0 "Pending" in element */ + entry->status = DATA_ENTRY_STATUS_PENDING; + rx_read_entry = entry->pNextEntry; +}/*---------------------------------------------------------------------------*/ +static int +read_frame(void *buf, unsigned short buf_len) +{ + int8_t rssi; + int len = 0; + rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry; + + if(entry->status != DATA_ENTRY_STATUS_FINISHED) { + /* No available data */ + return 0; + } + + if(rx_read_entry[8] < 4) { + PRINTF("RF: too short\n"); + RIMESTATS_ADD(tooshort); + + release_data_entry(); + return 0; + } + + len = rx_read_entry[8] - 4; + + if(len > buf_len) { + PRINTF("RF: too long\n"); + RIMESTATS_ADD(toolong); + + release_data_entry(); + return 0; + } + + memcpy(buf, (char *)&rx_read_entry[9], len); + + rssi = (int8_t)rx_read_entry[9 + len + 2]; + + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); + RIMESTATS_ADD(llrx); + + release_data_entry(); + + return len; +} +/*---------------------------------------------------------------------------*/ +static int +channel_clear(void) +{ + uint8_t was_off = 0; + uint8_t cca_info; + int ret = RF_CCA_CLEAR; + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Indicate a clear channel + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + PRINTF("channel_clear: Interrupt context but BLE in progress\n"); + return RF_CCA_CLEAR; + } + + if(rf_is_on()) { + /* + * Wait for potential leftover ACK still being sent. + * Strictly speaking, if we are TXing an ACK then the channel is not clear. + * However, channel_clear is only ever called to determine whether there is + * someone else's packet in the air, not ours. + * + * We could probably even simply return that the channel is clear + */ + while(transmitting()); + } else { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("channel_clear: on() failed\n"); + if(was_off) { + off(); + } + return RF_CCA_CLEAR; + } + } + + cca_info = get_cca_info(); + + if(cca_info == RF_GET_CCA_INFO_ERROR) { + PRINTF("channel_clear: CCA error\n"); + ret = RF_CCA_CLEAR; + } else { + /* + * cca_info bits 1:0 - ccaStatus + * Return 1 (clear) if idle or invalid. + */ + ret = (cca_info & 0x03) != RF_CMD_CCA_REQ_CCA_STATE_BUSY; + } + + if(was_off) { + off(); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +receiving_packet(void) +{ + int ret = 0; + uint8_t cca_info; + uint8_t was_off = 0; + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. We are not receiving + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + PRINTF("receiving_packet: Interrupt context but BLE in progress\n"); + return 0; + } + + /* If we are off, we are not receiving */ + if(!rf_is_on()) { + PRINTF("receiving_packet: We were off\n"); + return 0; + } + + /* If we are transmitting (can only be an ACK here), we are not receiving */ + if(transmitting()) { + PRINTF("receiving_packet: We were TXing\n"); + return 0; + } + + cca_info = get_cca_info(); + + if(cca_info == RF_GET_CCA_INFO_ERROR) { + /* If we can't read CCA info, return "not receiving" */ + ret = 0; + } else { + /* Return 1 (receiving) if ccaState is busy */ + ret = (cca_info & 0x03) == RF_CMD_CCA_REQ_CCA_STATE_BUSY; + } + + if(was_off) { + off(); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +pending_packet(void) +{ + volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry; + int rv = 0; + + /* Go through all RX buffers and check their status */ + do { + if(entry->status == DATA_ENTRY_STATUS_FINISHED) { + rv = 1; + process_poll(&rf_core_process); + } + + entry = (rfc_dataEntry_t *)entry->pNextEntry; + } while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry); + + /* If we didn't find an entry at status finished, no frames are pending */ + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + /* + * Request the HF XOSC as the source for the HF clock. Needed before we can + * use the FS. This will only request, it will _not_ perform the switch. + */ + oscillators_request_hf_xosc(); + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Abort, but pretend everything is OK. + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + PRINTF("on: Interrupt context but BLE in progress\n"); + return RF_CORE_CMD_OK; + } + + if(rf_is_on()) { + PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), + RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); + return RF_CORE_CMD_OK; + } + + if(rf_core_boot() != RF_CORE_CMD_OK) { + PRINTF("on: rf_core_boot() failed\n"); + return RF_CORE_CMD_ERROR; + } + + init_rx_buffers(); + + rf_core_setup_interrupts(); + + /* + * Trigger a switch to the XOSC, so that we can subsequently use the RF FS + * This will block until the XOSC is actually ready, but give how we + * requested it early on, this won't be too long a wait/ + */ + oscillators_switch_to_hf_xosc(); + + if(rf_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("on: radio_setup() failed\n"); + return RF_CORE_CMD_ERROR; + } + + return rx_on(); +} +/*---------------------------------------------------------------------------*/ +static int +off(void) +{ + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Abort, but pretend everything is OK. + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + PRINTF("off: Interrupt context but BLE in progress\n"); + return RF_CORE_CMD_OK; + } + + while(transmitting()); + + rf_core_power_down(); + + /* Switch HF clock source to the RCOSC to preserve power */ + oscillators_switch_to_hf_rc(); + + /* We pulled the plug, so we need to restore the status manually */ + ((rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf)->status = RF_CORE_RADIO_OP_STATUS_IDLE; + + /* + * Just in case there was an ongoing RX (which started after we begun the + * shutdown sequence), we don't want to leave the buffer in state == ongoing + */ + ((rfc_dataEntry_t *)rx_buf_0)->status = DATA_ENTRY_STATUS_PENDING; + ((rfc_dataEntry_t *)rx_buf_1)->status = DATA_ENTRY_STATUS_PENDING; + ((rfc_dataEntry_t *)rx_buf_2)->status = DATA_ENTRY_STATUS_PENDING; + ((rfc_dataEntry_t *)rx_buf_3)->status = DATA_ENTRY_STATUS_PENDING; + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + + switch(param) { + case RADIO_PARAM_POWER_MODE: + /* On / off */ + *value = rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = (radio_value_t)cmd->channel; + return RADIO_RESULT_OK; + case RADIO_PARAM_PAN_ID: + *value = (radio_value_t)cmd->localPanID; + return RADIO_RESULT_OK; + case RADIO_PARAM_16BIT_ADDR: + *value = (radio_value_t)cmd->localShortAddr; + return RADIO_RESULT_OK; + case RADIO_PARAM_RX_MODE: + *value = 0; + if(cmd->frameFiltOpt.frameFiltEn) { + *value |= RADIO_RX_MODE_ADDRESS_FILTER; + } + if(cmd->frameFiltOpt.autoAckEn) { + *value |= RADIO_RX_MODE_AUTOACK; + } + + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + *value = get_tx_power(); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = cmd->ccaRssiThr; + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + *value = get_rssi(); + + if(*value == RF_CMD_CCA_REQ_RSSI_UNKNOWN) { + return RADIO_RESULT_ERROR; + } else { + return RADIO_RESULT_OK; + } + case RADIO_CONST_CHANNEL_MIN: + *value = IEEE_MODE_CHANNEL_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = IEEE_MODE_CHANNEL_MAX; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = OUTPUT_POWER_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = OUTPUT_POWER_MAX; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + uint8_t was_off = 0; + radio_result_t rv = RADIO_RESULT_OK; + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + if(on() != RF_CORE_CMD_OK) { + PRINTF("set_value: on() failed (1)\n"); + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < IEEE_MODE_CHANNEL_MIN || + value > IEEE_MODE_CHANNEL_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + cmd->channel = (uint8_t)value; + break; + case RADIO_PARAM_PAN_ID: + cmd->localPanID = (uint16_t)value; + break; + case RADIO_PARAM_16BIT_ADDR: + cmd->localShortAddr = (uint16_t)value; + break; + case RADIO_PARAM_RX_MODE: + { + if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | + RADIO_RX_MODE_AUTOACK)) { + return RADIO_RESULT_INVALID_VALUE; + } + + cmd->frameFiltOpt.frameFiltEn = (value & RADIO_RX_MODE_ADDRESS_FILTER) != 0; + cmd->frameFiltOpt.frameFiltStop = 1; + cmd->frameFiltOpt.autoAckEn = (value & RADIO_RX_MODE_AUTOACK) != 0; + cmd->frameFiltOpt.slottedAckEn = 0; + cmd->frameFiltOpt.autoPendEn = 0; + cmd->frameFiltOpt.defaultPend = 0; + cmd->frameFiltOpt.bPendDataReqOnly = 0; + cmd->frameFiltOpt.bPanCoord = 0; + cmd->frameFiltOpt.bStrictLenFilter = 0; + break; + } + case RADIO_PARAM_TXPOWER: + if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + set_tx_power(value); + + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + cmd->ccaRssiThr = (int8_t)value; + break; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } + + /* If we reach here we had no errors. Apply new settings */ + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("set_value: on() failed (2)\n"); + return RADIO_RESULT_ERROR; + } + } + + if(rx_off() != RF_CORE_CMD_OK) { + PRINTF("set_value: rx_off() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + if(rx_on() != RF_CORE_CMD_OK) { + PRINTF("set_value: rx_on() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + /* If we were off, turn back off */ + if(was_off) { + off(); + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + uint8_t *target; + uint8_t *src; + int i; + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + + if(param == RADIO_PARAM_64BIT_ADDR) { + if(size != 8 || !dest) { + return RADIO_RESULT_INVALID_VALUE; + } + + target = dest; + src = (uint8_t *)(&cmd->localExtAddr); + + for(i = 0; i < 8; i++) { + target[i] = src[7 - i]; + } + + return RADIO_RESULT_OK; + } + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + uint8_t was_off = 0; + radio_result_t rv; + int i; + uint8_t *dst; + rfc_CMD_IEEE_RX_t *cmd = (rfc_CMD_IEEE_RX_t *)cmd_ieee_rx_buf; + + if(param == RADIO_PARAM_64BIT_ADDR) { + if(size != 8 || !src) { + return RADIO_RESULT_INVALID_VALUE; + } + + dst = (uint8_t *)(&cmd->localExtAddr); + + for(i = 0; i < 8; i++) { + dst[i] = ((uint8_t *)src)[7 - i]; + } + + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("set_object: on() failed\n"); + return RADIO_RESULT_ERROR; + } + } + + if(rx_off() != RF_CORE_CMD_OK) { + PRINTF("set_object: rx_off() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + if(rx_on() != RF_CORE_CMD_OK) { + PRINTF("set_object: rx_on() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + /* If we were off, turn back off */ + if(was_off) { + off(); + } + + return rv; + } + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +const struct radio_driver ieee_mode_driver = { + init, + prepare, + transmit, + send, + read_frame, + channel_clear, + receiving_packet, + pending_packet, + on, + off, + get_value, + set_value, + get_object, + set_object, +}; +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/prop-mode.c b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c new file mode 100644 index 000000000..c4aa341d0 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/prop-mode.c @@ -0,0 +1,1143 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core + * @{ + * + * \defgroup rf-core-prop CC13xx Prop mode driver + * + * @{ + * + * \file + * Implementation of the CC13xx prop mode NETSTACK_RADIO driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/radio.h" +#include "dev/cc26xx-uart.h" +#include "dev/oscillators.h" +#include "dev/watchdog.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "net/linkaddr.h" +#include "net/netstack.h" +#include "sys/energest.h" +#include "sys/clock.h" +#include "sys/rtimer.h" +#include "sys/cc.h" +#include "lpm.h" +#include "ti-lib.h" +#include "rf-core/rf-core.h" +#include "rf-core/rf-ble.h" +#include "rf-core/dot-15-4g.h" +/*---------------------------------------------------------------------------*/ +/* RF core and RF HAL API */ +#include "hw_rfc_dbell.h" +#include "hw_rfc_pwr.h" +/*---------------------------------------------------------------------------*/ +/* RF Core Mailbox API */ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/data_entry.h" +#include "rf-core/api/prop_mailbox.h" +#include "rf-core/api/prop_cmd.h" +/*---------------------------------------------------------------------------*/ +/* CC13xxware patches */ +#include "rf_patches/rf_patch_cpe_genfsk.h" +/*---------------------------------------------------------------------------*/ +#include "rf-core/smartrf-settings.h" +/*---------------------------------------------------------------------------*/ +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#ifdef __GNUC__ +#define CC_ALIGN_ATTR(n) __attribute__ ((aligned(n))) +#else +#define CC_ALIGN_ATTR(n) +#endif +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* Data entry status field constants */ +#define DATA_ENTRY_STATUS_PENDING 0x00 /* Not in use by the Radio CPU */ +#define DATA_ENTRY_STATUS_ACTIVE 0x01 /* Open for r/w by the radio CPU */ +#define DATA_ENTRY_STATUS_BUSY 0x02 /* Ongoing r/w */ +#define DATA_ENTRY_STATUS_FINISHED 0x03 /* Free to use and to free */ +#define DATA_ENTRY_STATUS_UNFINISHED 0x04 /* Partial RX entry */ +/*---------------------------------------------------------------------------*/ +/* Data whitener. 1: Whitener, 0: No whitener */ +#ifdef PROP_MODE_CONF_DW +#define PROP_MODE_DW PROP_MODE_CONF_DW +#else +#define PROP_MODE_DW 0 +#endif + +#ifdef PROP_MODE_CONF_USE_CRC16 +#define PROP_MODE_USE_CRC16 PROP_MODE_CONF_USE_CRC16 +#else +#define PROP_MODE_USE_CRC16 0 +#endif +/*---------------------------------------------------------------------------*/ +#ifdef PROP_MODE_CONF_SNIFFER +#define PROP_MODE_SNIFFER PROP_MODE_CONF_SNIFFER +#else +#define PROP_MODE_SNIFFER 0 +#endif + +#if PROP_MODE_SNIFFER +static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; +#endif +/*---------------------------------------------------------------------------*/ +/** + * \brief Returns the current status of a running Radio Op command + * \param a A pointer with the buffer used to initiate the command + * \return The value of the Radio Op buffer's status field + * + * This macro can be used to e.g. return the status of a previously + * initiated background operation, or of an immediate command + */ +#define RF_RADIO_OP_GET_STATUS(a) GET_FIELD_V(a, radioOp, status) +/*---------------------------------------------------------------------------*/ +/* Special value returned by CMD_IEEE_CCA_REQ when an RSSI is not available */ +#define RF_CMD_CCA_REQ_RSSI_UNKNOWN -128 + +/* Used for the return value of channel_clear */ +#define RF_CCA_CLEAR 1 +#define RF_CCA_BUSY 0 + +/* Used as an error return value for get_cca_info */ +#define RF_GET_CCA_INFO_ERROR 0xFF + +/* + * Values of the individual bits of the ccaInfo field in CMD_IEEE_CCA_REQ's + * status struct + */ +#define RF_CMD_CCA_REQ_CCA_STATE_IDLE 0 /* 00 */ +#define RF_CMD_CCA_REQ_CCA_STATE_BUSY 1 /* 01 */ +#define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2 /* 10 */ + +#ifdef PROP_MODE_CONF_RSSI_THRESHOLD +#define PROP_MODE_RSSI_THRESHOLD PROP_MODE_CONF_RSSI_THRESHOLD +#else +#define PROP_MODE_RSSI_THRESHOLD 0xA6 +#endif + +static int8_t rssi_threshold = PROP_MODE_RSSI_THRESHOLD; +/*---------------------------------------------------------------------------*/ +static int on(void); +static int off(void); + +static rfc_propRxOutput_t rx_stats; +/*---------------------------------------------------------------------------*/ +/* Defines and variables related to the .15.4g PHY HDR */ +#define DOT_4G_MAX_FRAME_LEN 2047 +#define DOT_4G_PHR_LEN 2 + +/* PHY HDR bits */ +#define DOT_4G_PHR_CRC16 0x10 +#define DOT_4G_PHR_DW 0x08 + +#if PROP_MODE_USE_CRC16 +/* CRC16 */ +#define DOT_4G_PHR_CRC_BIT DOT_4G_PHR_CRC16 +#define CRC_LEN 2 +#else +/* CRC32 */ +#define DOT_4G_PHR_CRC_BIT 0 +#define CRC_LEN 4 +#endif + +#if PROP_MODE_DW +#define DOT_4G_PHR_DW_BIT DOT_4G_PHR_DW +#else +#define DOT_4G_PHR_DW_BIT 0 +#endif +/*---------------------------------------------------------------------------*/ +/* How long to wait for an ongoing ACK TX to finish before starting frame TX */ +#define TX_WAIT_TIMEOUT (RTIMER_SECOND >> 11) + +/* How long to wait for the RF to enter RX in rf_cmd_ieee_rx */ +#define ENTER_RX_WAIT_TIMEOUT (RTIMER_SECOND >> 10) +/*---------------------------------------------------------------------------*/ +/* TX Power dBm lookup table - values from SmartRF Studio */ +typedef struct output_config { + radio_value_t dbm; + uint16_t tx_power; /* Value for the PROP_DIV_RADIO_SETUP.txPower field */ +} output_config_t; + +static const output_config_t output_power[] = { + { 14, 0xa73f }, + { 13, 0xa73f }, /* 12.5 */ + { 12, 0xb818 }, + { 11, 0x50da }, + { 10, 0x38d3 }, + { 9, 0x2ccd }, + { 8, 0x24cb }, + { 7, 0x20c9 }, + { 6, 0x1cc7 }, + { 5, 0x18c6 }, + { 4, 0x18c5 }, + { 3, 0x14c4 }, + { 2, 0x1042 }, + { 1, 0x10c3 }, + { 0, 0x0041 }, + {-10, 0x08c0 }, +}; + +#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) + +/* Max and Min Output Power in dBm */ +#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm) +#define OUTPUT_POWER_MAX (output_power[0].dbm) +#define OUTPUT_POWER_UNKNOWN 0xFFFF + +/* Default TX Power - position in output_power[] */ +const output_config_t *tx_power_current = &output_power[1]; +/*---------------------------------------------------------------------------*/ +#ifdef PROP_MODE_CONF_LO_DIVIDER +#define PROP_MODE_LO_DIVIDER PROP_MODE_CONF_LO_DIVIDER +#else +#define PROP_MODE_LO_DIVIDER 0x05 +#endif +/*---------------------------------------------------------------------------*/ +#define DATA_ENTRY_LENSZ_NONE 0 +#define DATA_ENTRY_LENSZ_BYTE 1 +#define DATA_ENTRY_LENSZ_WORD 2 /* 2 bytes */ + +#define RX_BUF_SIZE 140 +/* Receive buffers: 1 frame in each */ +static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN_ATTR(4); +static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN_ATTR(4); + +/* The RX Data Queue */ +static dataQueue_t rx_data_queue = { 0 }; + +/* Receive entry pointer to keep track of read items */ +volatile static uint8_t *rx_read_entry; +/*---------------------------------------------------------------------------*/ +/* The outgoing frame buffer */ +#define TX_BUF_PAYLOAD_LEN 180 +#define TX_BUF_HDR_LEN 2 + +static uint8_t tx_buf[TX_BUF_HDR_LEN + TX_BUF_PAYLOAD_LEN] CC_ALIGN_ATTR(4); +/*---------------------------------------------------------------------------*/ +static uint8_t +rf_is_on(void) +{ + if(!rf_core_is_accessible()) { + return 0; + } + + return smartrf_settings_cmd_prop_rx_adv.status == RF_CORE_RADIO_OP_STATUS_ACTIVE; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +transmitting(void) +{ + return smartrf_settings_cmd_prop_tx_adv.status == RF_CORE_RADIO_OP_STATUS_ACTIVE; +} +/*---------------------------------------------------------------------------*/ +static radio_value_t +get_rssi(void) +{ + uint32_t cmd_status; + int8_t rssi; + uint8_t was_off = 0; + rfc_CMD_GET_RSSI_t cmd; + + /* If we are off, turn on first */ + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("get_rssi: on() failed\n"); + return RF_CMD_CCA_REQ_RSSI_UNKNOWN; + } + } + + memset(&cmd, 0x00, sizeof(cmd)); + cmd.commandNo = CMD_GET_RSSI; + + rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_OK) { + /* Current RSSI in bits 23:16 of cmd_status */ + rssi = (cmd_status >> 16) & 0xFF; + } + + /* If we were off, turn back off */ + if(was_off) { + off(); + } + + return rssi; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +get_channel(void) +{ + uint32_t freq_khz; + + freq_khz = smartrf_settings_cmd_fs.frequency * 1000; + + /* + * For some channels, fractFreq * 1000 / 65536 will return 324.99xx. + * Casting the result to uint32_t will truncate decimals resulting in the + * function returning channel - 1 instead of channel. Thus, we do a quick + * positive integer round up. + */ + freq_khz += (((smartrf_settings_cmd_fs.fractFreq * 1000) + 65535) / 65536); + + return (freq_khz - DOT_15_4G_CHAN0_FREQUENCY) / DOT_15_4G_CHANNEL_SPACING; +} +/*---------------------------------------------------------------------------*/ +static void +set_channel(uint8_t channel) +{ + uint32_t new_freq; + uint16_t freq, frac; + + new_freq = DOT_15_4G_CHAN0_FREQUENCY + (channel * DOT_15_4G_CHANNEL_SPACING); + + freq = (uint16_t)(new_freq / 1000); + frac = (new_freq - (freq * 1000)) * 65536 / 1000; + + PRINTF("set_channel: %u = 0x%04x.0x%04x (%lu)\n", channel, freq, frac, + new_freq); + + smartrf_settings_cmd_prop_radio_div_setup.centerFreq = freq; + smartrf_settings_cmd_fs.frequency = freq; + smartrf_settings_cmd_fs.fractFreq = frac; +} +/*---------------------------------------------------------------------------*/ +/* Returns the current TX power in dBm */ +static radio_value_t +get_tx_power(void) +{ + return tx_power_current->dbm; +} +/*---------------------------------------------------------------------------*/ +/* + * The caller must make sure to send a new CMD_PROP_RADIO_DIV_SETP to the + * radio after calling this function. + */ +static void +set_tx_power(radio_value_t power) +{ + int i; + + for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) { + if(power <= output_power[i].dbm) { + /* + * Merely save the value. It will be used in all subsequent usages of + * CMD_PROP_RADIO_DIV_SETP, including one immediately after this function + * has returned + */ + tx_power_current = &output_power[i]; + + return; + } + } +} +/*---------------------------------------------------------------------------*/ +static int +prop_div_radio_setup(void) +{ + uint32_t cmd_status; + rfc_radioOp_t *cmd = (rfc_radioOp_t *)&smartrf_settings_cmd_prop_radio_div_setup; + + /* Adjust loDivider depending on the selected band */ + smartrf_settings_cmd_prop_radio_div_setup.loDivider = PROP_MODE_LO_DIVIDER; + + /* Update to the correct TX power setting */ + smartrf_settings_cmd_prop_radio_div_setup.txPower = tx_power_current->tx_power; + + /* Send Radio setup to RF Core */ + if(rf_core_send_cmd((uint32_t)cmd, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("prop_div_radio_setup: DIV_SETUP, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd->status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until radio setup is done */ + if(rf_core_wait_cmd_done(cmd) != RF_CORE_CMD_OK) { + PRINTF("prop_div_radio_setup: DIV_SETUP wait, CMDSTA=0x%08lx," + "status=0x%04x\n", cmd_status, cmd->status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +rf_cmd_prop_rx() +{ + uint32_t cmd_status; + rtimer_clock_t t0; + volatile rfc_CMD_PROP_RX_ADV_t *cmd_rx_adv; + int ret; + + cmd_rx_adv = (rfc_CMD_PROP_RX_ADV_t *)&smartrf_settings_cmd_prop_rx_adv; + cmd_rx_adv->status = RF_CORE_RADIO_OP_STATUS_IDLE; + + /* + * Set the max Packet length. This is for the payload only, therefore + * 2047 - length offset + */ + cmd_rx_adv->maxPktLen = DOT_4G_MAX_FRAME_LEN - cmd_rx_adv->lenOffset; + + ret = rf_core_send_cmd((uint32_t)cmd_rx_adv, &cmd_status); + + if(ret != RF_CORE_CMD_OK) { + PRINTF("rf_cmd_prop_rx: send_cmd ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", + ret, cmd_status, cmd_rx_adv->status); + return RF_CORE_CMD_ERROR; + } + + t0 = RTIMER_NOW(); + + while(cmd_rx_adv->status != RF_CORE_RADIO_OP_STATUS_ACTIVE && + (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ENTER_RX_WAIT_TIMEOUT))); + + /* Wait to enter RX */ + if(cmd_rx_adv->status != RF_CORE_RADIO_OP_STATUS_ACTIVE) { + PRINTF("rf_cmd_prop_rx: CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd_rx_adv->status); + return RF_CORE_CMD_ERROR; + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +rx_on_prop(void) +{ + int ret; + + if(rf_is_on()) { + PRINTF("rx_on_prop: We were on. PD=%u, RX=0x%04x\n", + rf_core_is_accessible(), smartrf_settings_cmd_prop_rx_adv.status); + return RF_CORE_CMD_OK; + } + + /* Put CPE in RX using the currently configured parameters */ + ret = rf_cmd_prop_rx(); + + if(ret) { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +rx_off_prop(void) +{ + uint32_t cmd_status; + int ret; + + /* If we are off, do nothing */ + if(!rf_is_on()) { + return RF_CORE_CMD_OK; + } + + /* Send a CMD_ABORT command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rx_off_prop: CMD_ABORT status=0x%08lx\n", cmd_status); + /* Continue nonetheless */ + } + + while(rf_is_on()); + + if(smartrf_settings_cmd_prop_rx_adv.status == PROP_DONE_STOPPED || + smartrf_settings_cmd_prop_rx_adv.status == PROP_DONE_ABORT) { + /* Stopped gracefully */ + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ret = RF_CORE_CMD_OK; + } else { + PRINTF("rx_off_prop: status=0x%04x\n", + smartrf_settings_cmd_prop_rx_adv.status); + ret = RF_CORE_CMD_ERROR; + } + + return ret; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +request(void) +{ + /* + * We rely on the RDC layer to turn us on and off. Thus, if we are on we + * will only allow sleep, standby otherwise + */ + if(rf_is_on()) { + return LPM_MODE_SLEEP; + } + + return LPM_MODE_MAX_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +LPM_MODULE(prop_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE); +/*---------------------------------------------------------------------------*/ +static int +prop_fs(void) +{ + uint32_t cmd_status; + rfc_radioOp_t *cmd = (rfc_radioOp_t *)&smartrf_settings_cmd_fs; + + /* Send the command to the RF Core */ + if(rf_core_send_cmd((uint32_t)cmd, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("prop_fs: CMD_FS, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd->status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until the command is done */ + if(rf_core_wait_cmd_done(cmd) != RF_CORE_CMD_OK) { + PRINTF("prop_fs: CMD_FS wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd->status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +static void +soft_off_prop(void) +{ + uint32_t cmd_status; + volatile rfc_radioOp_t *cmd = rf_core_get_last_radio_op(); + + if(!rf_core_is_accessible()) { + return; + } + + /* Send a CMD_ABORT command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("soft_off_prop: CMD_ABORT status=0x%08lx\n", cmd_status); + return; + } + + while((cmd->status & RF_CORE_RADIO_OP_MASKED_STATUS) == + RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +soft_on_prop(void) +{ + if(prop_div_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("soft_on_prop: prop_div_radio_setup() failed\n"); + return RF_CORE_CMD_ERROR; + } + + if(prop_fs() != RF_CORE_CMD_OK) { + PRINTF("soft_on_prop: prop_fs() failed\n"); + return RF_CORE_CMD_ERROR; + } + + return rx_on_prop(); +} +/*---------------------------------------------------------------------------*/ +static const rf_core_primary_mode_t mode_prop = { + soft_off_prop, + soft_on_prop, +}; +/*---------------------------------------------------------------------------*/ +static int +init(void) +{ + rfc_dataEntry_t *entry; + + lpm_register_module(&prop_lpm_module); + + if(ti_lib_chipinfo_chip_family_is_cc13xx() == false) { + return RF_CORE_CMD_ERROR; + } + + rf_core_set_modesel(); + + /* Initialise RX buffers */ + memset(rx_buf_0, 0, RX_BUF_SIZE); + memset(rx_buf_1, 0, RX_BUF_SIZE); + + entry = (rfc_dataEntry_t *)rx_buf_0; + entry->status = DATA_ENTRY_STATUS_PENDING; + entry->config.type = DATA_ENTRY_TYPE_GEN; + entry->config.lenSz = DATA_ENTRY_LENSZ_WORD; + entry->length = RX_BUF_SIZE - 8; + entry->pNextEntry = rx_buf_1; + + entry = (rfc_dataEntry_t *)rx_buf_1; + entry->status = DATA_ENTRY_STATUS_PENDING; + entry->config.type = DATA_ENTRY_TYPE_GEN; + entry->config.lenSz = DATA_ENTRY_LENSZ_WORD; + entry->length = RX_BUF_SIZE - 8; + entry->pNextEntry = rx_buf_0; + + /* Set of RF Core data queue. Circular buffer, no last entry */ + rx_data_queue.pCurrEntry = rx_buf_0; + rx_data_queue.pLastEntry = NULL; + + /* Initialize current read pointer to first element (used in ISR) */ + rx_read_entry = rx_buf_0; + + smartrf_settings_cmd_prop_rx_adv.pQueue = &rx_data_queue; + smartrf_settings_cmd_prop_rx_adv.pOutput = (uint8_t *)&rx_stats; + + set_channel(RF_CORE_CHANNEL); + + if(on() != RF_CORE_CMD_OK) { + PRINTF("init: on() failed\n"); + return RF_CORE_CMD_ERROR; + } + + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + rf_core_primary_mode_register(&mode_prop); + + process_start(&rf_core_process, NULL); + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +prepare(const void *payload, unsigned short payload_len) +{ + int len = MIN(payload_len, TX_BUF_PAYLOAD_LEN); + + memcpy(&tx_buf[TX_BUF_HDR_LEN], payload, len); + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +static int +transmit(unsigned short transmit_len) +{ + int ret; + uint32_t cmd_status; + volatile rfc_CMD_PROP_TX_ADV_t *cmd_tx_adv; + + /* Length in .15.4g PHY HDR. Includes the CRC but not the HDR itself */ + uint16_t total_length; + + if(!rf_is_on()) { + if(on() != RF_CORE_CMD_OK) { + PRINTF("transmit: on() failed\n"); + return RADIO_TX_ERR; + } + } + + /* + * Prepare the .15.4g PHY header + * MS=0, Length MSBits=0, DW and CRC configurable + * Total length = transmit_len (payload) + CRC length + * + * The Radio will flip the bits around, so tx_buf[0] must have the length + * LSBs (PHR[15:8] and tx_buf[1] will have PHR[7:0] + */ + total_length = transmit_len + CRC_LEN; + + tx_buf[0] = total_length & 0xFF; + tx_buf[1] = (total_length >> 8) + DOT_4G_PHR_DW_BIT + DOT_4G_PHR_CRC_BIT; + + /* Prepare the CMD_PROP_TX_ADV command */ + cmd_tx_adv = (rfc_CMD_PROP_TX_ADV_t *)&smartrf_settings_cmd_prop_tx_adv; + + /* + * pktLen: Total number of bytes in the TX buffer, including the header if + * one exists, but not including the CRC (which is not present in the buffer) + */ + cmd_tx_adv->pktLen = transmit_len + DOT_4G_PHR_LEN; + cmd_tx_adv->pPkt = tx_buf; + + /* Abort RX */ + rx_off_prop(); + + /* Enable the LAST_COMMAND_DONE interrupt to wake us up */ + rf_core_cmd_done_en(); + + ret = rf_core_send_cmd((uint32_t)cmd_tx_adv, &cmd_status); + + if(ret) { + /* If we enter here, TX actually started */ + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + watchdog_periodic(); + + /* Idle away while the command is running */ + while((cmd_tx_adv->status & RF_CORE_RADIO_OP_MASKED_STATUS) + == RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING) { + lpm_sleep(); + } + + if(cmd_tx_adv->status == RF_CORE_RADIO_OP_STATUS_PROP_DONE_OK) { + /* Sent OK */ + RIMESTATS_ADD(lltx); + ret = RADIO_TX_OK; + } else { + /* Operation completed, but frame was not sent */ + PRINTF("transmit: Not Sent OK status=0x%04x\n", + cmd_tx_adv->status); + ret = RADIO_TX_ERR; + } + } else { + /* Failure sending the CMD_PROP_TX command */ + PRINTF("transmit: PROP_TX_ERR ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", + ret, cmd_status, cmd_tx_adv->status); + ret = RADIO_TX_ERR; + } + + /* + * Update ENERGEST state here, before a potential call to off(), which + * will correctly update it if required. + */ + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + /* + * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it + * except when we are transmitting + */ + rf_core_cmd_done_dis(); + + /* Workaround. Set status to IDLE */ + cmd_tx_adv->status = RF_CORE_RADIO_OP_STATUS_IDLE; + + rx_on_prop(); + + return ret; +} +/*---------------------------------------------------------------------------*/ +static int +send(const void *payload, unsigned short payload_len) +{ + prepare(payload, payload_len); + return transmit(payload_len); +} +/*---------------------------------------------------------------------------*/ +static int +read_frame(void *buf, unsigned short buf_len) +{ + rfc_dataEntryGeneral_t *entry = (rfc_dataEntryGeneral_t *)rx_read_entry; + uint8_t *data_ptr = &entry->data; + int len = 0; + + if(entry->status == DATA_ENTRY_STATUS_FINISHED) { + + /* + * First 2 bytes in the data entry are the length. + * Our data entry consists of: Payload + RSSI (1 byte) + Status (1 byte) + * This length includes all of those. + */ + len = (*(uint16_t *)data_ptr); + data_ptr += 2; + len -= 2; + + if(len > 0) { + if(len <= buf_len) { + memcpy(buf, data_ptr, len); + } + + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, (int8_t)data_ptr[len]); + +#if PROP_MODE_SNIFFER + { + int i; + + cc26xx_uart_write_byte(magic[0]); + cc26xx_uart_write_byte(magic[1]); + cc26xx_uart_write_byte(magic[2]); + cc26xx_uart_write_byte(magic[3]); + + cc26xx_uart_write_byte(len + 2); + + for(i = 0; i < len; ++i) { + cc26xx_uart_write_byte(((uint8_t *)(buf))[i]); + } + + cc26xx_uart_write_byte((uint8_t)rx_stats.lastRssi); + cc26xx_uart_write_byte(0x80); + + while(cc26xx_uart_busy() == UART_BUSY); + } +#endif + } + + /* Move read entry pointer to next entry */ + rx_read_entry = entry->pNextEntry; + entry->status = DATA_ENTRY_STATUS_PENDING; + } + + return len; +} +/*---------------------------------------------------------------------------*/ +static int +channel_clear(void) +{ + uint8_t was_off = 0; + uint32_t cmd_status; + int8_t rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Indicate a clear channel + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + return RF_CCA_CLEAR; + } + + if(!rf_core_is_accessible()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("channel_clear: on() failed\n"); + if(was_off) { + off(); + } + return RF_CCA_CLEAR; + } + } else { + if(transmitting()) { + PRINTF("channel_clear: called while in TX\n"); + return RF_CCA_CLEAR; + } + } + + while(rssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) { + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_GET_RSSI), &cmd_status) + != RF_CORE_CMD_OK) { + break; + } + /* Current RSSI in bits 23:16 of cmd_status */ + rssi = (cmd_status >> 16) & 0xFF; + } + + if(was_off) { + off(); + } + + if(rssi >= rssi_threshold) { + return RF_CCA_BUSY; + } + + return RF_CCA_CLEAR; +} +/*---------------------------------------------------------------------------*/ +static int +receiving_packet(void) +{ + if(!rf_is_on()) { + return 0; + } + + if(channel_clear() == RF_CCA_CLEAR) { + return 0; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +pending_packet(void) +{ + int rv = 0; + volatile rfc_dataEntry_t *entry = (rfc_dataEntry_t *)rx_data_queue.pCurrEntry; + + /* Go through all RX buffers and check their status */ + do { + if(entry->status == DATA_ENTRY_STATUS_FINISHED) { + rv += 1; + process_poll(&rf_core_process); + } + + entry = (rfc_dataEntry_t *)entry->pNextEntry; + } while(entry != (rfc_dataEntry_t *)rx_data_queue.pCurrEntry); + + /* If we didn't find an entry at status finished, no frames are pending */ + return rv; +} +/*---------------------------------------------------------------------------*/ +static int +on(void) +{ + /* + * Request the HF XOSC as the source for the HF clock. Needed before we can + * use the FS. This will only request, it will _not_ perform the switch. + */ + oscillators_request_hf_xosc(); + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Abort, but pretend everything is OK. + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + return RF_CORE_CMD_OK; + } + + if(rf_is_on()) { + PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_core_is_accessible(), + smartrf_settings_cmd_prop_rx_adv.status); + return RF_CORE_CMD_OK; + } + + if(!rf_core_is_accessible()) { + if(rf_core_power_up() != RF_CORE_CMD_OK) { + PRINTF("on: rf_core_power_up() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + + rf_patch_cpe_genfsk(); + + if(rf_core_start_rat() != RF_CORE_CMD_OK) { + PRINTF("on: rf_core_start_rat() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + } + + rf_core_setup_interrupts(); + + /* + * Trigger a switch to the XOSC, so that we can subsequently use the RF FS + * This will block until the XOSC is actually ready, but give how we + * requested it early on, this won't be too long a wait/ + */ + oscillators_switch_to_hf_xosc(); + + if(prop_div_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("on: prop_div_radio_setup() failed\n"); + return RF_CORE_CMD_ERROR; + } + + if(prop_fs() != RF_CORE_CMD_OK) { + PRINTF("on: prop_fs() failed\n"); + return RF_CORE_CMD_ERROR; + } + + return rx_on_prop(); +} +/*---------------------------------------------------------------------------*/ +static int +off(void) +{ + rfc_dataEntry_t *entry; + + /* + * If we are in the middle of a BLE operation, we got called by ContikiMAC + * from within an interrupt context. Abort, but pretend everything is OK. + */ + if(rf_ble_is_active() == RF_BLE_ACTIVE) { + return RF_CORE_CMD_OK; + } + + rf_core_power_down(); + + /* Switch HF clock source to the RCOSC to preserve power */ + oscillators_switch_to_hf_rc(); + + /* We pulled the plug, so we need to restore the status manually */ + smartrf_settings_cmd_prop_rx_adv.status = RF_CORE_RADIO_OP_STATUS_IDLE; + + entry = (rfc_dataEntry_t *)rx_buf_0; + entry->status = DATA_ENTRY_STATUS_PENDING; + + entry = (rfc_dataEntry_t *)rx_buf_1; + entry->status = DATA_ENTRY_STATUS_PENDING; + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + + switch(param) { + case RADIO_PARAM_POWER_MODE: + /* On / off */ + *value = rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; + return RADIO_RESULT_OK; + case RADIO_PARAM_CHANNEL: + *value = (radio_value_t)get_channel(); + return RADIO_RESULT_OK; + case RADIO_PARAM_TXPOWER: + *value = get_tx_power(); + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + *value = rssi_threshold; + return RADIO_RESULT_OK; + case RADIO_PARAM_RSSI: + *value = get_rssi(); + + if(*value == RF_CMD_CCA_REQ_RSSI_UNKNOWN) { + return RADIO_RESULT_ERROR; + } else { + return RADIO_RESULT_OK; + } + case RADIO_CONST_CHANNEL_MIN: + *value = 0; + return RADIO_RESULT_OK; + case RADIO_CONST_CHANNEL_MAX: + *value = DOT_15_4G_CHANNEL_MAX; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MIN: + *value = OUTPUT_POWER_MIN; + return RADIO_RESULT_OK; + case RADIO_CONST_TXPOWER_MAX: + *value = OUTPUT_POWER_MAX; + return RADIO_RESULT_OK; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + uint8_t was_off = 0; + radio_result_t rv = RADIO_RESULT_OK; + + switch(param) { + case RADIO_PARAM_POWER_MODE: + if(value == RADIO_POWER_MODE_ON) { + if(on() != RF_CORE_CMD_OK) { + PRINTF("set_value: on() failed (1)\n"); + return RADIO_RESULT_ERROR; + } + return RADIO_RESULT_OK; + } + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + return RADIO_RESULT_INVALID_VALUE; + case RADIO_PARAM_CHANNEL: + if(value < 0 || + value > DOT_15_4G_CHANNEL_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + set_channel((uint8_t)value); + break; + case RADIO_PARAM_TXPOWER: + if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { + return RADIO_RESULT_INVALID_VALUE; + } + + soft_off_prop(); + + set_tx_power(value); + + if(soft_on_prop() != RF_CORE_CMD_OK) { + PRINTF("set_value: soft_on_prop() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + return RADIO_RESULT_OK; + case RADIO_PARAM_CCA_THRESHOLD: + rssi_threshold = (int8_t)value; + break; + default: + return RADIO_RESULT_NOT_SUPPORTED; + } + + /* If we reach here we had no errors. Apply new settings */ + if(!rf_is_on()) { + was_off = 1; + if(on() != RF_CORE_CMD_OK) { + PRINTF("set_value: on() failed (2)\n"); + return RADIO_RESULT_ERROR; + } + } + + if(rx_off_prop() != RF_CORE_CMD_OK) { + PRINTF("set_value: rx_off_prop() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + if(rx_on_prop() != RF_CORE_CMD_OK) { + PRINTF("set_value: rx_on_prop() failed\n"); + rv = RADIO_RESULT_ERROR; + } + + /* If we were off, turn back off */ + if(was_off) { + off(); + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + return RADIO_RESULT_NOT_SUPPORTED; +} +/*---------------------------------------------------------------------------*/ +const struct radio_driver prop_mode_driver = { + init, + prepare, + transmit, + send, + read_frame, + channel_clear, + receiving_packet, + pending_packet, + on, + off, + get_value, + set_value, + get_object, + set_object, +}; +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-ble.c b/cpu/cc26xx-cc13xx/rf-core/rf-ble.c new file mode 100644 index 000000000..1db80569f --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/rf-ble.c @@ -0,0 +1,400 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core-ble + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx RF BLE driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "sys/process.h" +#include "sys/clock.h" +#include "sys/etimer.h" +#include "net/netstack.h" +#include "net/linkaddr.h" +#include "dev/oscillators.h" +#include "rf-core/rf-core.h" +#include "rf-core/rf-ble.h" +#include "rf-core/api/ble_cmd.h" +#include "rf-core/api/common_cmd.h" +#include "ti-lib.h" +/*---------------------------------------------------------------------------*/ +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#ifdef __GNUC__ +#define CC_ALIGN_ATTR(n) __attribute__ ((aligned(n))) +#else +#define CC_ALIGN_ATTR(n) +#endif +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +/* BLE Intervals: Send a burst of advertisements every BLE_ADV_INTERVAL secs */ +#define BLE_ADV_INTERVAL (CLOCK_SECOND * 5) +#define BLE_ADV_DUTY_CYCLE (CLOCK_SECOND / 10) +#define BLE_ADV_MESSAGES 10 + +/* BLE Advertisement-related macros */ +#define BLE_ADV_TYPE_DEVINFO 0x01 +#define BLE_ADV_TYPE_NAME 0x09 +#define BLE_ADV_TYPE_MANUFACTURER 0xFF +#define BLE_ADV_NAME_BUF_LEN 32 +#define BLE_ADV_PAYLOAD_BUF_LEN 64 +#define BLE_UUID_SIZE 16 +/*---------------------------------------------------------------------------*/ +static unsigned char ble_params_buf[32] CC_ALIGN_ATTR(4); +static uint8_t ble_mode_on = RF_BLE_IDLE; +static struct etimer ble_adv_et; +static uint8_t payload[BLE_ADV_PAYLOAD_BUF_LEN]; +static int p = 0; +static int i; +/*---------------------------------------------------------------------------*/ +typedef struct default_ble_tx_power_s { + uint16_t ib:6; + uint16_t gc:2; + uint16_t boost:1; + uint16_t temp_coeff:7; +} default_ble_tx_power_t; + +static default_ble_tx_power_t tx_power = { 0x29, 0x00, 0x00, 0x00 }; +/*---------------------------------------------------------------------------*/ +/* BLE beacond config */ +static struct ble_beacond_config { + clock_time_t interval; + char adv_name[BLE_ADV_NAME_BUF_LEN]; +} beacond_config = { .interval = BLE_ADV_INTERVAL }; +/*---------------------------------------------------------------------------*/ +/* BLE overrides */ +static uint32_t ble_overrides[] = { + 0x00364038, /* Synth: Set RTRIM (POTAILRESTRIM) to 6 */ + 0x000784A3, /* Synth: Set FREF = 3.43 MHz (24 MHz / 7) */ + 0xA47E0583, /* Synth: Set loop bandwidth after lock to 80 kHz (K2) */ + 0xEAE00603, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, LSB) */ + 0x00010623, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, MSB) */ + 0x00456088, /* Adjust AGC reference level */ + 0xFFFFFFFF, /* End of override list */ +}; +/*---------------------------------------------------------------------------*/ +PROCESS(rf_ble_beacon_process, "CC13xx / CC26xx RF BLE Beacon Process"); +/*---------------------------------------------------------------------------*/ +static int +send_ble_adv_nc(int channel, uint8_t *adv_payload, int adv_payload_len) +{ + uint32_t cmd_status; + rfc_CMD_BLE_ADV_NC_t cmd; + rfc_bleAdvPar_t *params; + + params = (rfc_bleAdvPar_t *)ble_params_buf; + + /* Clear both buffers */ + memset(&cmd, 0x00, sizeof(cmd)); + memset(ble_params_buf, 0x00, sizeof(ble_params_buf)); + + /* Adv NC */ + cmd.commandNo = CMD_BLE_ADV_NC; + cmd.condition.rule = COND_NEVER; + cmd.whitening.bOverride = 0; + cmd.whitening.init = 0; + cmd.pParams = params; + cmd.channel = channel; + + /* Set up BLE Advertisement parameters */ + params->pDeviceAddress = (uint16_t *)&linkaddr_node_addr.u8[LINKADDR_SIZE - 2]; + params->endTrigger.triggerType = TRIG_NEVER; + params->endTime = TRIG_NEVER; + + /* Set up BLE Advertisement parameters */ + params = (rfc_bleAdvPar_t *)ble_params_buf; + params->advLen = adv_payload_len; + params->pAdvData = adv_payload; + + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) == RF_CORE_CMD_ERROR) { + PRINTF("send_ble_adv_nc: Chan=%d CMDSTA=0x%08lx, status=0x%04x\n", + channel, cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until the command is done */ + if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) { + PRINTF("send_ble_adv_nc: Chan=%d CMDSTA=0x%08lx, status=0x%04x\n", + channel, cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +void +rf_ble_beacond_config(clock_time_t interval, const char *name) +{ + if(RF_BLE_ENABLED == 0) { + return; + } + + if(name != NULL) { + if(strlen(name) == 0 || strlen(name) >= BLE_ADV_NAME_BUF_LEN) { + return; + } + + memset(beacond_config.adv_name, 0, BLE_ADV_NAME_BUF_LEN); + memcpy(beacond_config.adv_name, name, strlen(name)); + } + + if(interval != 0) { + beacond_config.interval = interval; + } +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_ble_beacond_start() +{ + if(RF_BLE_ENABLED == 0) { + return RF_CORE_CMD_ERROR; + } + + if(ti_lib_chipinfo_supports_ble() == false) { + return RF_CORE_CMD_ERROR; + } + + if(beacond_config.adv_name[0] == 0) { + return RF_CORE_CMD_ERROR; + } + + ble_mode_on = RF_BLE_IDLE; + + process_start(&rf_ble_beacon_process, NULL); + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_ble_is_active() +{ + return ble_mode_on; +} +/*---------------------------------------------------------------------------*/ +void +rf_ble_beacond_stop() +{ + process_exit(&rf_ble_beacon_process); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +rf_radio_setup() +{ + uint32_t cmd_status; + rfc_CMD_RADIO_SETUP_t cmd; + + /* Create radio setup command */ + rf_core_init_radio_op((rfc_radioOp_t *)&cmd, sizeof(cmd), CMD_RADIO_SETUP); + + cmd.txPower.IB = tx_power.ib; + cmd.txPower.GC = tx_power.gc; + cmd.txPower.tempCoeff = tx_power.temp_coeff; + cmd.txPower.boost = tx_power.boost; + cmd.pRegOverride = ble_overrides; + cmd.mode = 0; + + /* Send Radio setup to RF Core */ + if(rf_core_send_cmd((uint32_t)&cmd, &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rf_radio_setup: CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + /* Wait until radio setup is done */ + if(rf_core_wait_cmd_done(&cmd) != RF_CORE_CMD_OK) { + PRINTF("rf_radio_setup: wait, CMDSTA=0x%08lx, status=0x%04x\n", + cmd_status, cmd.status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(rf_ble_beacon_process, ev, data) +{ + uint8_t was_on; + int j; + uint32_t cmd_status; + bool interrupts_disabled; + + PROCESS_BEGIN(); + + while(1) { + etimer_set(&ble_adv_et, beacond_config.interval); + + PROCESS_WAIT_EVENT(); + + if(ev == PROCESS_EVENT_EXIT) { + PROCESS_EXIT(); + } + + /* Set the adv payload each pass: The device name may have changed */ + p = 0; + + /* device info */ + memset(payload, 0, BLE_ADV_PAYLOAD_BUF_LEN); + payload[p++] = 0x02; /* 2 bytes */ + payload[p++] = BLE_ADV_TYPE_DEVINFO; + payload[p++] = 0x1a; /* LE general discoverable + BR/EDR */ + payload[p++] = 1 + strlen(beacond_config.adv_name); + payload[p++] = BLE_ADV_TYPE_NAME; + memcpy(&payload[p], beacond_config.adv_name, + strlen(beacond_config.adv_name)); + p += strlen(beacond_config.adv_name); + + for(i = 0; i < BLE_ADV_MESSAGES; i++) { + /* + * Under ContikiMAC, some IEEE-related operations will be called from an + * interrupt context. We need those to see that we are in BLE mode. + */ + interrupts_disabled = ti_lib_int_master_disable(); + ble_mode_on = RF_BLE_ACTIVE; + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + /* + * Send BLE_ADV_MESSAGES beacon bursts. Each burst on all three + * channels, with a BLE_ADV_DUTY_CYCLE interval between bursts + * + * First, determine our state: + * + * If we are running NullRDC, we are likely in IEEE RX mode. We need to + * abort the IEEE BG Op before entering BLE mode. + * If we are ContikiMAC, we are likely off, in which case we need to + * boot the CPE before entering BLE mode + */ + was_on = rf_core_is_accessible(); + + if(was_on) { + /* + * We were on: If we are in the process of receiving a frame, abort the + * BLE beacon burst. Otherwise, terminate the primary radio Op so we + * can switch to BLE mode + */ + if(NETSTACK_RADIO.receiving_packet()) { + PRINTF("rf_ble_beacon_process: We were receiving\n"); + + /* Abort this pass */ + break; + } + + rf_core_primary_mode_abort(); + } else { + /* Request the HF XOSC to source the HF clock. */ + oscillators_request_hf_xosc(); + + /* We were off: Boot the CPE */ + if(rf_core_boot() != RF_CORE_CMD_OK) { + PRINTF("rf_ble_beacon_process: rf_core_boot() failed\n"); + + /* Abort this pass */ + break; + } + + /* Trigger a switch to the XOSC, so that we can use the FS */ + oscillators_switch_to_hf_xosc(); + } + + /* Enter BLE mode */ + if(rf_radio_setup() != RF_CORE_CMD_OK) { + PRINTF("cc26xx_rf_ble_beacon_process: Error entering BLE mode\n"); + /* Continue so we can at least try to restore our previous state */ + } else { + /* Send advertising packets on all 3 advertising channels */ + for(j = 37; j <= 39; j++) { + if(send_ble_adv_nc(j, payload, p) != RF_CORE_CMD_OK) { + PRINTF("cc26xx_rf_ble_beacon_process: Channel=%d, " + "Error advertising\n", j); + /* Break the loop, but don't return just yet */ + break; + } + } + } + + /* Send a CMD_STOP command to RF Core */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_STOP), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("cc26xx_rf_ble_beacon_process: status=0x%08lx\n", cmd_status); + /* Continue... */ + } + + if(was_on) { + /* We were on, go back to previous primary mode */ + rf_core_primary_mode_restore(); + } else { + /* We were off. Shut back off */ + rf_core_power_down(); + + /* Switch HF clock source to the RCOSC to preserve power */ + oscillators_switch_to_hf_rc(); + } + etimer_set(&ble_adv_et, BLE_ADV_DUTY_CYCLE); + + interrupts_disabled = ti_lib_int_master_disable(); + + ble_mode_on = RF_BLE_IDLE; + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + /* Wait unless this is the last burst */ + if(i < BLE_ADV_MESSAGES - 1) { + PROCESS_WAIT_EVENT(); + } + } + + interrupts_disabled = ti_lib_int_master_disable(); + + ble_mode_on = RF_BLE_IDLE; + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx/dev/cc26xx-rf.h b/cpu/cc26xx-cc13xx/rf-core/rf-ble.h similarity index 62% rename from cpu/cc26xx/dev/cc26xx-rf.h rename to cpu/cc26xx-cc13xx/rf-core/rf-ble.h index a278e085d..f26bd383e 100644 --- a/cpu/cc26xx/dev/cc26xx-rf.h +++ b/cpu/cc26xx-cc13xx/rf-core/rf-ble.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -10,7 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -28,59 +27,35 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */ +/*---------------------------------------------------------------------------*/ /** - * \addtogroup cc26xx + * \addtogroup rf-core * @{ * - * \defgroup cc26xx-rf CC26xx RF driver - * - * The CC26xx RF has dual capability: It can operate in IEEE 802.15.4 mode at - * 2.4GHz, but it can also operate in BLE mode. This driver provides a fully - * contiki-compliant .15.4 functionality, but it also provides some very basic - * BLE capability. + * \defgroup rf-core-ble CC13xx/CC26xx BLE driver * * @{ - */ -/** + * * \file - * Header file for the CC26xx RF driver + * Header file for the CC13xx/CC26xx BLE driver */ -#ifndef CC26XX_RF_H_ -#define CC26XX_RF_H_ /*---------------------------------------------------------------------------*/ -#include "contiki.h" -#include "cc26xx-model.h" -#include "dev/radio.h" +#ifndef RF_BLE_H_ +#define RF_BLE_H_ /*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "rf-core/rf-core.h" + #include /*---------------------------------------------------------------------------*/ -#ifdef CC26XX_RF_CONF_CHANNEL -#define CC26XX_RF_CHANNEL CC26XX_RF_CONF_CHANNEL +#ifdef RF_BLE_CONF_ENABLED +#define RF_BLE_ENABLED RF_BLE_CONF_ENABLED #else -#define CC26XX_RF_CHANNEL 18 -#endif /* CC26XX_RF_CONF_CHANNEL */ - -#ifdef CC26XX_RF_CONF_AUTOACK -#define CC26XX_RF_AUTOACK CC26XX_RF_CONF_AUTOACK -#else -#define CC26XX_RF_AUTOACK 1 -#endif /* CC26XX_RF_CONF_AUTOACK */ - -#if (CC26XX_RF_CONF_BLE_SUPPORT) && (CC26XX_MODEL_CPU_VARIANT == 2650) -#define CC26XX_RF_BLE_SUPPORT CC26XX_RF_CONF_BLE_SUPPORT -#else -#define CC26XX_RF_BLE_SUPPORT 0 +#define RF_BLE_ENABLED 1 #endif -/*--------------------------------------------------------------------------- - * RF Config - *---------------------------------------------------------------------------*/ -/* Constants */ -#define CC26XX_RF_CHANNEL_MIN 11 -#define CC26XX_RF_CHANNEL_MAX 26 -#define CC26XX_RF_CHANNEL_SPACING 5 -#define CC26XX_RF_CHANNEL_SET_ERROR -1 -#define CC26XX_RF_MAX_PACKET_LEN 127 -#define CC26XX_RF_MIN_PACKET_LEN 4 +/*---------------------------------------------------------------------------*/ +#define RF_BLE_IDLE 0 +#define RF_BLE_ACTIVE 1 /*---------------------------------------------------------------------------*/ /** * \brief Set the device name to use with the BLE advertisement/beacon daemon @@ -91,24 +66,31 @@ * this function can be used to configure a single parameter at a time if so * desired. */ -void cc26xx_rf_ble_beacond_config(clock_time_t interval, const char *name); +void rf_ble_beacond_config(clock_time_t interval, const char *name); /** * \brief Start the BLE advertisement/beacon daemon - * \return 1: Success, 0: Failure + * \return RF_CORE_CMD_OK: Success, RF_CORE_CMD_ERROR: Failure * * Before calling this function, the name to advertise must first be set by - * calling cc26xx_rf_ble_beacond_set_adv_name(). Otherwise, this function will - * return an error. + * calling rf_ble_beacond_config(). Otherwise, this function will return an + * error. */ -uint8_t cc26xx_rf_ble_beacond_start(void); +uint8_t rf_ble_beacond_start(void); /** * \brief Stop the BLE advertisement/beacon daemon */ -void cc26xx_rf_ble_beacond_stop(void); +void rf_ble_beacond_stop(void); + +/** + * \brief Check whether the BLE beacond is currently active + * \retval 1 The radio is in BLE mode + * \retval 0 The BLE daemon is not active, or disabled + */ +uint8_t rf_ble_is_active(void); /*---------------------------------------------------------------------------*/ -#endif /* CC26XX_RF_H_ */ +#endif /* RF_BLE_H_ */ /*---------------------------------------------------------------------------*/ /** * @} diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.c b/cpu/cc26xx-cc13xx/rf-core/rf-core.c new file mode 100644 index 000000000..7528a6f77 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.c @@ -0,0 +1,518 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup rf-core + * @{ + * + * \file + * Implementation of the CC13xx/CC26xx RF core driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "dev/watchdog.h" +#include "sys/process.h" +#include "sys/energest.h" +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "rf-core/rf-core.h" +#include "ti-lib.h" +/*---------------------------------------------------------------------------*/ +/* RF core and RF HAL API */ +#include "hw_rfc_dbell.h" +#include "hw_rfc_pwr.h" +/*---------------------------------------------------------------------------*/ +/* RF Core Mailbox API */ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/ble_cmd.h" +#include "rf-core/api/ieee_cmd.h" +#include "rf-core/api/data_entry.h" +#include "rf-core/api/ble_mailbox.h" +#include "rf-core/api/ieee_mailbox.h" +#include "rf-core/api/prop_mailbox.h" +#include "rf-core/api/prop_cmd.h" +/*---------------------------------------------------------------------------*/ +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif +/*---------------------------------------------------------------------------*/ +#ifdef __GNUC__ +#define CC_ALIGN_ATTR(n) __attribute__ ((aligned(n))) +#else +#define CC_ALIGN_ATTR(n) +#endif +/*---------------------------------------------------------------------------*/ +#ifdef RF_CORE_CONF_DEBUG_CRC +#define RF_CORE_DEBUG_CRC RF_CORE_CONF_DEBUG_CRC +#else +#define RF_CORE_DEBUG_CRC DEBUG +#endif +/*---------------------------------------------------------------------------*/ +/* RF interrupts */ +#define RX_FRAME_IRQ IRQ_RX_ENTRY_DONE +#define ERROR_IRQ IRQ_INTERNAL_ERROR +#define RX_NOK_IRQ IRQ_RX_NOK + +/* Those IRQs are enabled all the time */ +#if RF_CORE_DEBUG_CRC +#define ENABLED_IRQS (RX_FRAME_IRQ | ERROR_IRQ | RX_NOK_IRQ) +#else +#define ENABLED_IRQS (RX_FRAME_IRQ | ERROR_IRQ) +#endif + +#define cc26xx_rf_cpe0_isr RFCCPE0IntHandler +#define cc26xx_rf_cpe1_isr RFCCPE1IntHandler +/*---------------------------------------------------------------------------*/ +/* Remember the last Radio Op issued to the radio */ +static rfc_radioOp_t *last_radio_op = NULL; +/*---------------------------------------------------------------------------*/ +/* A struct holding pointers to the primary mode's abort() and restore() */ +static const rf_core_primary_mode_t *primary_mode = NULL; +/*---------------------------------------------------------------------------*/ +PROCESS(rf_core_process, "CC13xx / CC26xx RF driver"); +/*---------------------------------------------------------------------------*/ +#define RF_CORE_CLOCKS_MASK (RFC_PWR_PWMCLKEN_RFC_M | RFC_PWR_PWMCLKEN_CPE_M \ + | RFC_PWR_PWMCLKEN_CPERAM_M) +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_is_accessible() +{ + if(ti_lib_prcm_rf_ready() && + ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) == + PRCM_DOMAIN_POWER_ON) { + return RF_CORE_ACCESSIBLE; + } + return RF_CORE_NOT_ACCESSIBLE; +} +/*---------------------------------------------------------------------------*/ +uint_fast8_t +rf_core_send_cmd(uint32_t cmd, uint32_t *status) +{ + uint32_t timeout_count = 0; + bool interrupts_disabled; + bool is_radio_op = false; + + /* If cmd is 4-byte aligned, then it's a radio OP. Clear the status field */ + if((cmd & 0x03) == 0) { + is_radio_op = true; + ((rfc_radioOp_t *)cmd)->status = RF_CORE_RADIO_OP_STATUS_IDLE; + } + + /* + * Make sure ContikiMAC doesn't turn us off from within an interrupt while + * we are accessing RF Core registers + */ + interrupts_disabled = ti_lib_int_master_disable(); + + if(!rf_core_is_accessible()) { + PRINTF("rf_core_send_cmd: RF was off\n"); + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + return RF_CORE_CMD_ERROR; + } + + if(is_radio_op) { + uint16_t command_no = ((rfc_radioOp_t *)cmd)->commandNo; + if((command_no & RF_CORE_COMMAND_PROTOCOL_MASK) != RF_CORE_COMMAND_PROTOCOL_COMMON && + (command_no & RF_CORE_COMMAND_TYPE_MASK) == RF_CORE_COMMAND_TYPE_RADIO_OP) { + last_radio_op = (rfc_radioOp_t *)cmd; + } + } + + HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = cmd; + do { + *status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA); + if(++timeout_count > 50000) { + PRINTF("rf_core_send_cmd: 0x%08lx Timeout\n", cmd); + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + return RF_CORE_CMD_ERROR; + } + } while(*status == RF_CORE_CMDSTA_PENDING); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + /* + * If we reach here the command is no longer pending. It is either completed + * successfully or with error + */ + return (*status & RF_CORE_CMDSTA_RESULT_MASK) == RF_CORE_CMDSTA_DONE; +} +/*---------------------------------------------------------------------------*/ +uint_fast8_t +rf_core_wait_cmd_done(void *cmd) +{ + volatile rfc_radioOp_t *command = (rfc_radioOp_t *)cmd; + uint32_t timeout_cnt = 0; + + /* + * 0xn4nn=DONE, 0x0400=DONE_OK while all other "DONE" values means done + * but with some kind of error (ref. "Common radio operation status codes") + */ + do { + if(++timeout_cnt > 500000) { + return RF_CORE_CMD_ERROR; + } + } while((command->status & RF_CORE_RADIO_OP_MASKED_STATUS) + != RF_CORE_RADIO_OP_MASKED_STATUS_DONE); + + return (command->status & RF_CORE_RADIO_OP_MASKED_STATUS) + == RF_CORE_RADIO_OP_STATUS_DONE_OK; +} +/*---------------------------------------------------------------------------*/ +int +rf_core_power_up() +{ + uint32_t cmd_status; + bool interrupts_disabled = ti_lib_int_master_disable(); + + ti_lib_int_pend_clear(INT_RF_CPE0); + ti_lib_int_pend_clear(INT_RF_CPE1); + ti_lib_int_disable(INT_RF_CPE0); + ti_lib_int_disable(INT_RF_CPE1); + + /* Enable RF Core power domain */ + ti_lib_prcm_power_domain_on(PRCM_DOMAIN_RFCORE); + while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) + != PRCM_DOMAIN_POWER_ON); + + ti_lib_prcm_domain_enable(PRCM_DOMAIN_RFCORE); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + while(!rf_core_is_accessible()) { + PRINTF("rf_core_power_up: Not ready\n"); + } + + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0; + ti_lib_int_enable(INT_RF_CPE0); + ti_lib_int_enable(INT_RF_CPE1); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } + + /* Let CPE boot */ + HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = RF_CORE_CLOCKS_MASK; + + /* Send ping (to verify RFCore is ready and alive) */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_PING), &cmd_status) != RF_CORE_CMD_OK) { + PRINTF("rf_core_power_up: CMD_PING fail, CMDSTA=0x%08lx\n", cmd_status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_power_down() +{ + bool interrupts_disabled = ti_lib_int_master_disable(); + ti_lib_int_disable(INT_RF_CPE0); + ti_lib_int_disable(INT_RF_CPE1); + + if(rf_core_is_accessible()) { + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0; + } + + /* Shut down the RFCORE clock domain in the MCU VD */ + ti_lib_prcm_domain_disable(PRCM_DOMAIN_RFCORE); + ti_lib_prcm_load_set(); + while(!ti_lib_prcm_load_get()); + + /* Turn off RFCORE PD */ + ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE); + while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) + != PRCM_DOMAIN_POWER_OFF); + + ti_lib_int_pend_clear(INT_RF_CPE0); + ti_lib_int_pend_clear(INT_RF_CPE1); + ti_lib_int_enable(INT_RF_CPE0); + ti_lib_int_enable(INT_RF_CPE1); + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_set_modesel() +{ + uint8_t rv = RF_CORE_CMD_ERROR; + + if(ti_lib_chipinfo_chip_family_is_cc26xx()) { + if(ti_lib_chipinfo_supports_ble() == true && + ti_lib_chipinfo_supports_ieee_802_15_4() == true) { + /* CC2650 */ + HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5; + rv = RF_CORE_CMD_OK; + } else if(ti_lib_chipinfo_supports_ble() == false && + ti_lib_chipinfo_supports_ieee_802_15_4() == true) { + /* CC2630 */ + HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE2; + rv = RF_CORE_CMD_OK; + } + } else if(ti_lib_chipinfo_chip_family_is_cc13xx()) { + if(ti_lib_chipinfo_supports_ble() == false && + ti_lib_chipinfo_supports_ieee_802_15_4() == false) { + /* CC1310 */ + HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE3; + rv = RF_CORE_CMD_OK; + } + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_start_rat() +{ + uint32_t cmd_status; + + /* Start radio timer (RAT) */ + if(rf_core_send_cmd(CMDR_DIR_CMD(CMD_START_RAT), &cmd_status) + != RF_CORE_CMD_OK) { + PRINTF("rf_core_apply_patches: START_RAT fail, CMDSTA=0x%08lx\n", + cmd_status); + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_boot() +{ + if(rf_core_power_up() != RF_CORE_CMD_OK) { + PRINTF("rf_core_boot: rf_core_power_up() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + + if(rf_core_start_rat() != RF_CORE_CMD_OK) { + PRINTF("rf_core_boot: rf_core_start_rat() failed\n"); + + rf_core_power_down(); + + return RF_CORE_CMD_ERROR; + } + + return RF_CORE_CMD_OK; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_setup_interrupts() +{ + bool interrupts_disabled; + + /* We are already turned on by the caller, so this should not happen */ + if(!rf_core_is_accessible()) { + PRINTF("setup_interrupts: No access\n"); + return; + } + + /* Disable interrupts */ + interrupts_disabled = ti_lib_int_master_disable(); + + /* Set all interrupt channels to CPE0 channel, error to CPE1 */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEISL) = ERROR_IRQ; + + /* Acknowledge configured interrupts */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS; + + /* Clear interrupt flags, active low clear(?) */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + + ti_lib_int_pend_clear(INT_RF_CPE0); + ti_lib_int_pend_clear(INT_RF_CPE1); + ti_lib_int_enable(INT_RF_CPE0); + ti_lib_int_enable(INT_RF_CPE1); + + if(!interrupts_disabled) { + ti_lib_int_master_enable(); + } +} +/*---------------------------------------------------------------------------*/ +void +rf_core_cmd_done_en() +{ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = ENABLED_IRQS; + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS + + IRQ_LAST_COMMAND_DONE; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_cmd_done_dis() +{ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS; +} +/*---------------------------------------------------------------------------*/ +rfc_radioOp_t * +rf_core_get_last_radio_op() +{ + return last_radio_op; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_init_radio_op(rfc_radioOp_t *op, uint16_t len, uint16_t command) +{ + memset(op, 0, len); + + op->commandNo = command; + op->condition.rule = COND_NEVER; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_primary_mode_register(const rf_core_primary_mode_t *mode) +{ + primary_mode = mode; +} +/*---------------------------------------------------------------------------*/ +void +rf_core_primary_mode_abort() +{ + if(primary_mode) { + if(primary_mode->abort) { + primary_mode->abort(); + } + } +} +/*---------------------------------------------------------------------------*/ +uint8_t +rf_core_primary_mode_restore() +{ + if(primary_mode) { + if(primary_mode->restore) { + return primary_mode->restore(); + } + } + + return RF_CORE_CMD_ERROR; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(rf_core_process, ev, data) +{ + int len; + + PROCESS_BEGIN(); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); + do { + watchdog_periodic(); + packetbuf_clear(); + len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE); + + if(len > 0) { + packetbuf_set_datalen(len); + + NETSTACK_RDC.input(); + } + } while(len > 0); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static void +rx_nok_isr(void) +{ + RIMESTATS_ADD(badcrc); + PRINTF("RF: Bad CRC\n"); +} +/*---------------------------------------------------------------------------*/ +void +cc26xx_rf_cpe1_isr(void) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + PRINTF("RF Error\n"); + + if(!rf_core_is_accessible()) { + if(rf_core_power_up() != RF_CORE_CMD_OK) { + return; + } + } + + /* Clear interrupt flags */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +cc26xx_rf_cpe0_isr(void) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if(!rf_core_is_accessible()) { + printf("RF ISR called but RF not ready... PANIC!!\n"); + if(rf_core_power_up() != RF_CORE_CMD_OK) { + PRINTF("rf_core_power_up() failed\n"); + return; + } + } + + ti_lib_int_master_disable(); + + if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_FRAME_IRQ) { + process_poll(&rf_core_process); + } + + if(RF_CORE_DEBUG_CRC) { + if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_NOK_IRQ) { + rx_nok_isr(); + } + } + + /* Clear interrupt flags */ + HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; + ti_lib_int_master_enable(); + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/cpu/cc26xx-cc13xx/rf-core/rf-core.h b/cpu/cc26xx-cc13xx/rf-core/rf-core.h new file mode 100644 index 000000000..bc389257c --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/rf-core.h @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx + * @{ + * + * \defgroup rf-core CC13xx/CC26xx RF core + * + * Different flavours of chips of the CC13xx/CC26xx family have different + * radio capability. For example, the CC2650 can operate in IEEE 802.15.4 mode + * at 2.4GHz, but it can also operate in BLE mode. The CC1310 only supports + * sub-ghz mode. + * + * However, there are many radio functionalities that are identical across + * all chips. The rf-core driver provides support for this common functionality + * + * @{ + * + * \file + * Header file for the CC13xx/CC26xx RF core driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef RF_CORE_H_ +#define RF_CORE_H_ +/*---------------------------------------------------------------------------*/ +#include "contiki-conf.h" +#include "rf-core/api/common_cmd.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/* The channel to use in IEEE or prop mode. */ +#ifdef RF_CORE_CONF_CHANNEL +#define RF_CORE_CHANNEL RF_CORE_CONF_CHANNEL +#else +#define RF_CORE_CHANNEL 25 +#endif /* RF_CORE_CONF_IEEE_MODE_CHANNEL */ +/*---------------------------------------------------------------------------*/ +#define RF_CORE_CMD_ERROR 0 +#define RF_CORE_CMD_OK 1 +/*---------------------------------------------------------------------------*/ +/** + * \brief A data strcuture representing the radio's primary mode of operation + * + * The CC13xx / CC26xx radio supports up to potentially 3 modes: IEEE, Prop and + * BLE. Within Contiki, we assume that the radio is by default in one of IEEE + * or Prop in order to support standard 6LoWPAN / .15.4 operation. The BLE + * mode interrupts this so called "primary" mode in order to send BLE adv + * messages. Once BLE is done advertising, we need to be able to restore the + * previous .15.4 mode. Unfortunately, the only way this can be done with + * NETSTACK_RADIO API is by fully power-cycling the radio, which is something + * we do not want to do. + * + * Thus, we declare a secondary data structure for primary mode drivers (IEEE + * or Prop). We use this data structure to issue "soft off" and "back on" + * commands. Soft off in this context means stopping RX (e.g. the respective + * IEEE RX operation), but without shutting down the RF core (which is what + * NETSTACK_RADIO.off() would have done). We then remember what mode we were + * using in order to be able to re-enter RX mode for this mode. + * + * A NETSTACK_RADIO driver will declare those two functions somewhere within + * its module of implementation. During its init() routine, it will notify + * the RF core module so that the latter can abort and restore operations. + */ +typedef struct rf_core_primary_mode_s { + /** + * \brief A pointer to a function used to abort the current radio op + */ + void (*abort)(void); + + /** + * \brief A pointer to a function that will restore the previous radio op + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + */ + uint8_t (*restore)(void); +} rf_core_primary_mode_t; +/*---------------------------------------------------------------------------*/ +/* RF Command status constants - Correspond to values in the CMDSTA register */ +#define RF_CORE_CMDSTA_PENDING 0x00 +#define RF_CORE_CMDSTA_DONE 0x01 +#define RF_CORE_CMDSTA_ILLEGAL_PTR 0x81 +#define RF_CORE_CMDSTA_UNKNOWN_CMD 0x82 +#define RF_CORE_CMDSTA_UNKNOWN_DIR_CMD 0x83 +#define RF_CORE_CMDSTA_CONTEXT_ERR 0x85 +#define RF_CORE_CMDSTA_SCHEDULING_ERR 0x86 +#define RF_CORE_CMDSTA_PAR_ERR 0x87 +#define RF_CORE_CMDSTA_QUEUE_ERR 0x88 +#define RF_CORE_CMDSTA_QUEUE_BUSY 0x89 + +/* Status values starting with 0x8 correspond to errors */ +#define RF_CORE_CMDSTA_ERR_MASK 0x80 + +/* CMDSTA is 32-bits. Return value in bits 7:0 */ +#define RF_CORE_CMDSTA_RESULT_MASK 0xFF + +#define RF_CORE_RADIO_OP_STATUS_IDLE 0x0000 +/*---------------------------------------------------------------------------*/ +#define RF_CORE_NOT_ACCESSIBLE 0x00 +#define RF_CORE_ACCESSIBLE 0x01 +/*---------------------------------------------------------------------------*/ +/* RF Radio Op status constants. Field 'status' in Radio Op command struct */ +#define RF_CORE_RADIO_OP_STATUS_IDLE 0x0000 +#define RF_CORE_RADIO_OP_STATUS_PENDING 0x0001 +#define RF_CORE_RADIO_OP_STATUS_ACTIVE 0x0002 +#define RF_CORE_RADIO_OP_STATUS_SKIPPED 0x0003 +#define RF_CORE_RADIO_OP_STATUS_DONE_OK 0x0400 +#define RF_CORE_RADIO_OP_STATUS_DONE_COUNTDOWN 0x0401 +#define RF_CORE_RADIO_OP_STATUS_DONE_RXERR 0x0402 +#define RF_CORE_RADIO_OP_STATUS_DONE_TIMEOUT 0x0403 +#define RF_CORE_RADIO_OP_STATUS_DONE_STOPPED 0x0404 +#define RF_CORE_RADIO_OP_STATUS_DONE_ABORT 0x0405 +#define RF_CORE_RADIO_OP_STATUS_ERROR_PAST_START 0x0800 +#define RF_CORE_RADIO_OP_STATUS_ERROR_START_TRIG 0x0801 +#define RF_CORE_RADIO_OP_STATUS_ERROR_CONDITION 0x0802 +#define RF_CORE_RADIO_OP_STATUS_ERROR_PAR 0x0803 +#define RF_CORE_RADIO_OP_STATUS_ERROR_POINTER 0x0804 +#define RF_CORE_RADIO_OP_STATUS_ERROR_CMDID 0x0805 +#define RF_CORE_RADIO_OP_STATUS_ERROR_NO_SETUP 0x0807 +#define RF_CORE_RADIO_OP_STATUS_ERROR_NO_FS 0x0808 +#define RF_CORE_RADIO_OP_STATUS_ERROR_SYNTH_PROG 0x0809 + +/* Additional Op status values for IEEE mode */ +#define RF_CORE_RADIO_OP_STATUS_IEEE_SUSPENDED 0x2001 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_OK 0x2400 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_BUSY 0x2401 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_STOPPED 0x2402 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_ACK 0x2403 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_ACKPEND 0x2404 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_TIMEOUT 0x2405 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_BGEND 0x2406 +#define RF_CORE_RADIO_OP_STATUS_IEEE_DONE_ABORT 0x2407 +#define RF_CORE_RADIO_OP_STATUS_ERROR_WRONG_BG 0x0806 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_PAR 0x2800 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_NO_SETUP 0x2801 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_NO_FS 0x2802 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_SYNTH_PROG 0x2803 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_RXOVF 0x2804 +#define RF_CORE_RADIO_OP_STATUS_IEEE_ERROR_TXUNF 0x2805 + +/* Op status values for BLE mode */ +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_OK 0x1400 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_RXTIMEOUT 0x1401 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_NOSYNC 0x1402 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_RXERR 0x1403 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_CONNECT 0x1404 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_MAXNACK 0x1405 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_ENDED 0x1406 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_ABORT 0x1407 +#define RF_CORE_RADIO_OP_STATUS_BLE_DONE_STOPPED 0x1408 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_PAR 0x1800 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_RXBUF 0x1801 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_NO_SETUP 0x1802 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_NO_FS 0x1803 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_SYNTH_PROG 0x1804 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_RXOVF 0x1805 +#define RF_CORE_RADIO_OP_STATUS_BLE_ERROR_TXUNF 0x1806 + +/* Op status values for proprietary mode */ +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_OK 0x3400 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_RXTIMEOUT 0x3401 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_BREAK 0x3402 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_ENDED 0x3403 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_STOPPED 0x3404 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_ABORT 0x3405 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_RXERR 0x3406 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_IDLE 0x3407 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_BUSY 0x3408 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_IDLETIMEOUT 0x3409 +#define RF_CORE_RADIO_OP_STATUS_PROP_DONE_BUSYTIMEOUT 0x340A +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_PAR 0x3800 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_RXBUF 0x3801 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_RXFULL 0x3802 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_NO_SETUP 0x3803 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_NO_FS 0x3804 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_RXOVF 0x3805 +#define RF_CORE_RADIO_OP_STATUS_PROP_ERROR_TXUNF 0x3806 + +/* Bits 15:12 signify the protocol */ +#define RF_CORE_RADIO_OP_STATUS_PROTO_MASK 0xF000 +#define RF_CORE_RADIO_OP_STATUS_PROTO_GENERIC 0x0000 +#define RF_CORE_RADIO_OP_STATUS_PROTO_BLE 0x1000 +#define RF_CORE_RADIO_OP_STATUS_PROTO_IEEE 0x2000 +#define RF_CORE_RADIO_OP_STATUS_PROTO_PROP 0x3000 + +/* Bits 11:10 signify Running / Done OK / Done with error */ +#define RF_CORE_RADIO_OP_MASKED_STATUS 0x0C00 +#define RF_CORE_RADIO_OP_MASKED_STATUS_RUNNING 0x0000 +#define RF_CORE_RADIO_OP_MASKED_STATUS_DONE 0x0400 +#define RF_CORE_RADIO_OP_MASKED_STATUS_ERROR 0x0800 +/*---------------------------------------------------------------------------*/ +/* Command Types */ +#define RF_CORE_COMMAND_TYPE_MASK 0x0C00 +#define RF_CORE_COMMAND_TYPE_IMMEDIATE 0x0000 +#define RF_CORE_COMMAND_TYPE_RADIO_OP 0x0800 +#define RF_CORE_COMMAND_TYPE_IEEE_BG_RADIO_OP 0x0800 +#define RF_CORE_COMMAND_TYPE_IEEE_FG_RADIO_OP 0x0C00 + +#define RF_CORE_COMMAND_PROTOCOL_MASK 0x3000 +#define RF_CORE_COMMAND_PROTOCOL_COMMON 0x0000 +#define RF_CORE_COMMAND_PROTOCOL_BLE 0x1000 +#define RF_CORE_COMMAND_PROTOCOL_IEEE 0x2000 +#define RF_CORE_COMMAND_PROTOCOL_PROP 0x3000 +/*---------------------------------------------------------------------------*/ +/* Make the main driver process visible to mode drivers */ +PROCESS_NAME(rf_core_process); +/*---------------------------------------------------------------------------*/ +/** + * \brief Check whether the RF core is accessible + * \retval RF_CORE_ACCESSIBLE The core is powered and ready for access + * \retval RF_CORE_NOT_ACCESSIBLE The core is not ready + * + * If this function returns RF_CORE_NOT_ACCESSIBLE, rf_core_power_up() must be + * called before any attempt to access the core. + */ +uint8_t rf_core_is_accessible(void); + +/** + * \brief Sends a command to the RF core. + * + * \param cmd The command value or a pointer to a command buffer + * \param status A pointer to a variable which will hold the status + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function supports all three types of command (Radio OP, immediate and + * direct) + * + * For immediate and Radio OPs, cmd is a pointer to the data structure + * containing the command and its parameters. This data structure must be + * 4-byte aligned. + * + * For direct commands, cmd contains the value of the command alongside its + * parameters. This value will be written to CMDSTA verbatim, so the command + * ID must be in the 16 high bits, and the 2 LS bits must be set to 01 by the + * caller. + * + * The caller is responsible of allocating and populating cmd for Radio OP and + * immediate commands + * + * The caller is responsible for allocating status + * + * For immediate commands and radio Ops, this function will set the command's + * status field to RF_CORE_RADIO_OP_STATUS_IDLE before sending it to the RF + */ +uint_fast8_t rf_core_send_cmd(uint32_t cmd, uint32_t *status); + +/** + * \brief Block and wait for a Radio op to complete + * \param cmd A pointer to any command's structure + * \retval RF_CORE_CMD_OK the command completed with status _DONE_OK + * \retval RF_CORE_CMD_ERROR Timeout exceeded or the command completed with + * status _DONE_xxx (e.g. RF_CORE_RADIO_OP_STATUS_DONE_TIMEOUT) + */ +uint_fast8_t rf_core_wait_cmd_done(void *cmd); + +/** + * \brief Turn on power to the RFC and boot it. + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + */ +int rf_core_power_up(void); + +/** + * \brief Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD + */ +void rf_core_power_down(void); + +/** + * \brief Initialise RF APIs in the RF core + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * Depending on chip family and capability, this function will set the correct + * value to PRCM.RFCMODESEL + */ +uint8_t rf_core_set_modesel(void); + +/** + * \brief Start the CM0 RAT + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function must be called each time the CM0 boots. The boot sequence + * can be performed automatically by calling rf_core_boot() if patches are not + * required. If patches are required then the patches must be applied after + * power up and before calling this function. + */ +uint8_t rf_core_start_rat(void); + +/** + * \brief Boot the RF Core + * \return RF_CORE_CMD_OK or RF_CORE_CMD_ERROR + * + * This function will perform the CM0 boot sequence. It will first power it up + * and then start the RAT. If a patch is required, then the mode driver must + * not call this function and perform the sequence manually, applying patches + * after boot and before calling rf_core_start_rat(). + * + * The function will return RF_CORE_CMD_ERROR if any of those steps fails. If + * the boot sequence fails to complete, the RF Core will be powered down. + */ +uint8_t rf_core_boot(void); + +/** + * \brief Setup RF core interrupts + */ +void rf_core_setup_interrupts(void); + +/** + * \brief Enable the LAST_CMD_DONE interrupt. + * + * This is used within TX routines in order to be able to sleep the CM3 and + * wake up after TX has finished + * + * \sa rf_core_cmd_done_dis() + */ +void rf_core_cmd_done_en(void); + +/** + * \brief Disable the LAST_CMD_DONE interrupt. + * + * This is used within TX routines after TX has completed + * + * \sa rf_core_cmd_done_en() + */ +void rf_core_cmd_done_dis(void); + +/** + * \brief Returns a pointer to the most recent proto-dependent Radio Op + * \return The pointer + * + * The RF Core driver will remember the most recent proto-dependent Radio OP + * issued, so that other modules can inspect its type and state at a subsequent + * stage. The assumption is that those commands will be issued by a function + * that will then return. The following commands will be "remembered" + * + * - All BLE Radio Ops (0x18nn) + * - All Prop Radio Ops (0x38nn) + * - IEEE BG Radio Ops (0x28nn) + * + * The following commands are assumed to be executed synchronously and will + * thus not be remembered by the core and not returned by this function: + * + * - Direct commands + * - Proto-independent commands (including Radio Ops and Immediate ones) + * - IEEE FG Radio Ops (0x2Cxx) + * + * This assumes that all commands will be sent to the radio using + * rf_core_send_cmd() + */ +rfc_radioOp_t *rf_core_get_last_radio_op(void); + +/** + * \brief Prepare a buffer to host a Radio Op + * \param buf A pointer to the buffer that will host the Radio Op + * \param len The buffer's length + * \param command The command ID + * + * The caller is responsible to allocate the buffer + * + * This function will not check whether the buffer is large enough to hold the + * command. This is the caller's responsibility + * + * This function will wipe out the buffer's contents. + */ +void rf_core_init_radio_op(rfc_radioOp_t *buf, uint16_t len, uint16_t command); + +/** + * \brief Register a primary mode for radio operation + * \param mode A pointer to the struct representing the mode + * + * A normal NESTACK_RADIO driver will normally register itself by calling + * this function during its own init(). + * + * \sa rf_core_primary_mode_t + */ +void rf_core_primary_mode_register(const rf_core_primary_mode_t *mode); + +/** + * \brief Abort the currently running primary radio op + */ +void rf_core_primary_mode_abort(void); + +/** + * \brief Abort the currently running primary radio op + */ +uint8_t rf_core_primary_mode_restore(void); +/*---------------------------------------------------------------------------*/ +#endif /* RF_CORE_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.c b/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.c new file mode 100644 index 000000000..8eedf23cb --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/prop_cmd.h" +/*---------------------------------------------------------------------------*/ +/* Overrides for CMD_PROP_RADIO_DIV_SETUP */ +uint32_t overrides[] = +{ + /* override_synth.xml */ + HW32_ARRAY_OVERRIDE(0x6088, 1), + (uint32_t)0x0000001A, + ADI_HALFREG_OVERRIDE(0, 61, 0xF, 0xD), + HW32_ARRAY_OVERRIDE(0x4038, 1), + (uint32_t)0x0000003A, + HW_REG_OVERRIDE(0x4020, 0x7F00), + HW_REG_OVERRIDE(0x4064, 0x0040), + (uint32_t)0x684A3, + (uint32_t)0xC0040141, + (uint32_t)0x0533B107, + (uint32_t)0xA480583, + (uint32_t)0x7AB80603, + ADI_REG_OVERRIDE(1, 4, 0x1F), + ADI_HALFREG_OVERRIDE(1, 7, 0x4, 0x4), + HW_REG_OVERRIDE(0x6084, 0x35F1), + (uint32_t)0x00038883, + (uint32_t)0x00FB88A3, + /* TX power override */ + ADI_REG_OVERRIDE(0, 12, 0xF9), + + /* Overrides for CRC16 functionality */ + (uint32_t)0x943, + (uint32_t)0x963, + + (uint32_t)0xFFFFFFFF, +}; +/*---------------------------------------------------------------------------*/ +/* CMD_PROP_RADIO_DIV_SETUP */ +rfc_CMD_PROP_RADIO_DIV_SETUP_t smartrf_settings_cmd_prop_radio_div_setup = +{ + .commandNo = 0x3807, + .status = 0x0000, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = 0x0, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = 0x1, + .condition.nSkip = 0x0, + .modulation.modType = 0x1, + .modulation.deviation = 0x64, + .symbolRate.preScale = 0xf, + .symbolRate.rateWord = 0x8000, + .rxBw = 0x24, + .preamConf.nPreamBytes = 0x3, + .preamConf.preamMode = 0x0, + .formatConf.nSwBits = 0x18, + .formatConf.bBitReversal = 0x0, + .formatConf.bMsbFirst = 0x1, + .formatConf.fecMode = 0x0, + + /* 7: .4g mode with dynamic whitening and CRC choice */ + .formatConf.whitenMode = 0x7, + .config.frontEndMode = 0x0, /* Differential mode */ + .config.biasMode = 0x1, /* External bias*/ + .config.bNoFsPowerUp = 0x0, + .txPower = 0x00, /* Driver sets correct value */ + .pRegOverride = overrides, + .intFreq = 0x8000, + .centerFreq = 868, + .loDivider = 0x05, +}; +/*---------------------------------------------------------------------------*/ +/* CMD_FS */ +rfc_CMD_FS_t smartrf_settings_cmd_fs = +{ + .commandNo = 0x0803, + .status = 0x0000, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = 0x0, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = 0x1, + .condition.nSkip = 0x0, + .frequency = 868, + .fractFreq = 0x0000, + .synthConf.bTxMode = 0x0, + .synthConf.refFreq = 0x0, + .__dummy0 = 0x00, + .midPrecal = 0x00, + .ktPrecal = 0x00, + .tdcPrecal = 0x0000, +}; +/*---------------------------------------------------------------------------*/ +/* CMD_PROP_TX_ADV */ +rfc_CMD_PROP_TX_ADV_t smartrf_settings_cmd_prop_tx_adv = +{ + .commandNo = 0x3803, + .status = 0x0000, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = 0x0, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = 0x1, + .condition.nSkip = 0x0, + .pktConf.bFsOff = 0x0, + .pktConf.bUseCrc = 0x1, + .pktConf.bCrcIncSw = 0x0, /* .4g mode */ + .pktConf.bCrcIncHdr = 0x0, /* .4g mode */ + .numHdrBits = 0x10 /* 16: .4g mode */, + .pktLen = 0x0000, + .startConf.bExtTxTrig = 0x0, + .startConf.inputMode = 0x0, + .startConf.source = 0x0, + .preTrigger.triggerType = TRIG_REL_START, + .preTrigger.bEnaCmd = 0x0, + .preTrigger.triggerNo = 0x0, + .preTrigger.pastTrig = 0x1, + .preTime = 0x00000000, + .syncWord = 0x0055904e, + .pPkt = 0, +}; +/*---------------------------------------------------------------------------*/ +/* CMD_PROP_RX_ADV */ +rfc_CMD_PROP_RX_ADV_t smartrf_settings_cmd_prop_rx_adv = +{ + .commandNo = 0x3804, + .status = 0x0000, + .pNextOp = 0, + .startTime = 0x00000000, + .startTrigger.triggerType = 0x0, + .startTrigger.bEnaCmd = 0x0, + .startTrigger.triggerNo = 0x0, + .startTrigger.pastTrig = 0x0, + .condition.rule = 0x1, + .condition.nSkip = 0x0, + .pktConf.bFsOff = 0x0, + .pktConf.bRepeatOk = 0x1, + .pktConf.bRepeatNok = 0x1, + .pktConf.bUseCrc = 0x1, + .pktConf.bCrcIncSw = 0x0, /* .4g mode */ + .pktConf.bCrcIncHdr = 0x0, /* .4g mode */ + .pktConf.endType = 0x0, + .pktConf.filterOp = 0x1, + .rxConf.bAutoFlushIgnored = 0x1, + .rxConf.bAutoFlushCrcErr = 0x1, + .rxConf.bIncludeHdr = 0x0, + .rxConf.bIncludeCrc = 0x0, + .rxConf.bAppendRssi = 0x1, + .rxConf.bAppendTimestamp = 0x0, + .rxConf.bAppendStatus = 0x1, + .syncWord0 = 0x0055904e, + .syncWord1 = 0x00000000, + .maxPktLen = 0x0000, /* To be populated by the driver. */ + .hdrConf.numHdrBits = 0x10, /* 16: .4g mode */ + .hdrConf.lenPos = 0x0, /* .4g mode */ + .hdrConf.numLenBits = 0x0B, /* 11 = 0x0B .4g mode */ + .addrConf.addrType = 0x0, + .addrConf.addrSize = 0x0, + .addrConf.addrPos = 0x0, + .addrConf.numAddr = 0x0, + .lenOffset = -4, /* .4g mode */ + .endTrigger.triggerType = TRIG_NEVER, + .endTrigger.bEnaCmd = 0x0, + .endTrigger.triggerNo = 0x0, + .endTrigger.pastTrig = 0x0, + .endTime = 0x00000000, + .pAddr = 0, + .pQueue = 0, + .pOutput = 0, +}; +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.h b/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.h new file mode 100644 index 000000000..bd36ed6d0 --- /dev/null +++ b/cpu/cc26xx-cc13xx/rf-core/smartrf-settings.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#ifndef SMARTRF_SETTINGS_H_ +#define SMARTRF_SETTINGS_H_ +/*---------------------------------------------------------------------------*/ +#include "rf-core/api/mailbox.h" +#include "rf-core/api/common_cmd.h" +#include "rf-core/api/prop_cmd.h" +/*---------------------------------------------------------------------------*/ +extern rfc_CMD_PROP_RADIO_DIV_SETUP_t smartrf_settings_cmd_prop_radio_div_setup; +extern rfc_CMD_FS_t smartrf_settings_cmd_fs; +extern rfc_CMD_PROP_TX_ADV_t smartrf_settings_cmd_prop_tx_adv; +extern rfc_CMD_PROP_RX_ADV_t smartrf_settings_cmd_prop_rx_adv; +/*---------------------------------------------------------------------------*/ +#endif // SMARTRF_SETTINGS_H_ +/*---------------------------------------------------------------------------*/ diff --git a/cpu/cc26xx/rtimer-arch.c b/cpu/cc26xx-cc13xx/rtimer-arch.c similarity index 97% rename from cpu/cc26xx/rtimer-arch.c rename to cpu/cc26xx-cc13xx/rtimer-arch.c index 37077f1b3..6d0505f47 100644 --- a/cpu/cc26xx/rtimer-arch.c +++ b/cpu/cc26xx-cc13xx/rtimer-arch.c @@ -33,15 +33,14 @@ * @{ * * \file - * Implementation of the arch-specific rtimer functions for the cc26xx - * + * Implementation of the arch-specific rtimer functions for the CC13xx/CC26xx */ /*---------------------------------------------------------------------------*/ #include "contiki.h" #include "sys/energest.h" #include "sys/rtimer.h" #include "cpu.h" -#include "dev/cc26xx-rtc.h" +#include "dev/soc-rtc.h" #include "ti-lib.h" @@ -72,7 +71,7 @@ void rtimer_arch_schedule(rtimer_clock_t t) { /* Convert the rtimer tick value to a value suitable for the AON RTC */ - cc26xx_rtc_schedule_one_shot(t); + soc_rtc_schedule_one_shot(AON_RTC_CH0, t); } /*---------------------------------------------------------------------------*/ /** diff --git a/cpu/cc26xx/rtimer-arch.h b/cpu/cc26xx-cc13xx/rtimer-arch.h similarity index 85% rename from cpu/cc26xx/rtimer-arch.h rename to cpu/cc26xx-cc13xx/rtimer-arch.h index 1a4a50c09..0d54d227c 100644 --- a/cpu/cc26xx/rtimer-arch.h +++ b/cpu/cc26xx-cc13xx/rtimer-arch.h @@ -32,20 +32,14 @@ * \addtogroup cc26xx-clocks * @{ * - * \defgroup cc26xx-rtimer CC26xx rtimer + * \defgroup cc26xx-rtimer CC13xx/CC26xx rtimer * - * Implementation of the rtimer module for the CC26xx - * - * The rtimer runs on the AON RTC. We set the RTC's channel 2 to continuous - * compare mode, instead of scheduling the next tick interrupt by software. - * This gives us completely equidistant events. - * - * The RTC runs in all power modes (except shutdown) + * Implementation of the rtimer module for the CC13xx/CC26xx * @{ */ /** * \file - * Header file for the CC26xx rtimer driver + * Header file for the CC13xx/CC26xx rtimer driver */ /*---------------------------------------------------------------------------*/ #ifndef RTIMER_ARCH_H_ diff --git a/cpu/cc26xx/slip-arch.c b/cpu/cc26xx-cc13xx/slip-arch.c similarity index 97% rename from cpu/cc26xx/slip-arch.c rename to cpu/cc26xx-cc13xx/slip-arch.c index ebd6f91c8..c1be6849f 100644 --- a/cpu/cc26xx/slip-arch.c +++ b/cpu/cc26xx-cc13xx/slip-arch.c @@ -34,7 +34,7 @@ * @{ * * \file - * Arch-specific SLIP functions for the cc26xx + * Arch-specific SLIP functions for the CC13xx/CC26xx */ /*---------------------------------------------------------------------------*/ #include "contiki-conf.h" diff --git a/cpu/cc26xx/ti-lib.h b/cpu/cc26xx-cc13xx/ti-lib.h similarity index 94% rename from cpu/cc26xx/ti-lib.h rename to cpu/cc26xx-cc13xx/ti-lib.h index ff707cfae..cbf9a8e61 100644 --- a/cpu/cc26xx/ti-lib.h +++ b/cpu/cc26xx-cc13xx/ti-lib.h @@ -31,7 +31,7 @@ * \addtogroup cc26xx * @{ * - * \defgroup cc26xx-ti-lib TI CC26xxware Glue + * \defgroup cc26xx-ti-lib TI CC26xxware/CC13xxware Glue * * Glue file which renames TI CC26xxware functions. Thus, for example, * PowerCtrlIOFreezeDisable() becomes power_ctrl_io_freeze_disable() @@ -89,7 +89,8 @@ #define ti_lib_aon_rtc_enable(...) AONRTCEnable(__VA_ARGS__) #define ti_lib_aon_rtc_disable(...) AONRTCDisable(__VA_ARGS__) -#define ti_lib_aon_rtc_status(...) AONRTCStatus(__VA_ARGS__) +#define ti_lib_aon_rtc_active(...) AONRTCActive(__VA_ARGS__) +#define ti_lib_aon_rtc_channel_active(...) AONRTCChannelActive(__VA_ARGS__) #define ti_lib_aon_rtc_reset(...) AONRTCReset(__VA_ARGS__) #define ti_lib_aon_rtc_delay_config(...) AONRTCDelayConfig(__VA_ARGS__) #define ti_lib_aon_rtc_combined_event_config(...) AONRTCCombinedEventConfig(__VA_ARGS__) @@ -107,6 +108,7 @@ #define ti_lib_aon_rtc_compare_value_set(...) AONRTCCompareValueSet(__VA_ARGS__) #define ti_lib_aon_rtc_compare_value_get(...) AONRTCCompareValueGet(__VA_ARGS__) #define ti_lib_aon_rtc_current_compare_value_get(...) AONRTCCurrentCompareValueGet(__VA_ARGS__) +#define ti_lib_aon_rtc_current_64_bit_value_get(...) AONRTCCurrent64BitValueGet(__VA_ARGS__) #define ti_lib_aon_rtc_inc_value_ch2_set(...) AONRTCIncValueCh2Set(__VA_ARGS__) #define ti_lib_aon_rtc_inc_value_ch2_get(...) AONRTCIncValueCh2Get(__VA_ARGS__) #define ti_lib_aon_rtc_capture_value_ch1_get(...) AONRTCCaptureValueCh1Get(__VA_ARGS__) @@ -161,6 +163,29 @@ #define ti_lib_cpu_base_pri_set(...) CPUbasepriSet(__VA_ARGS__) #define ti_lib_cpu_delay(...) CPUdelay(__VA_ARGS__) /*---------------------------------------------------------------------------*/ +/* chipinfo.h */ +#include "driverlib/chipinfo.h" + +#define ti_lib_chipinfo_get_supported_protocol_bv(...) ChipInfo_GetSupportedProtocol_BV(__VA_ARGS__) +#define ti_lib_chipinfo_supports_ble(...) ChipInfo_SupportsBLE(__VA_ARGS__) +#define ti_lib_chipinfo_supports_ieee_802_15_4(...) ChipInfo_SupportsIEEE_802_15_4(__VA_ARGS__) +#define ti_lib_chipinfo_supports_proprietary(...) ChipInfo_SupportsPROPRIETARY(__VA_ARGS__) +#define ti_lib_chipinfo_get_package_type(...) ChipInfo_GetPackageType(__VA_ARGS__) +#define ti_lib_chipinfo_package_type_is_4x4(...) ChipInfo_PackageTypeIs4x4(__VA_ARGS__) +#define ti_lib_chipinfo_package_type_is_5x5(...) ChipInfo_PackageTypeIs5x5(__VA_ARGS__) +#define ti_lib_chipinfo_package_type_is_7x7(...) ChipInfo_PackageTypeIs7x7(__VA_ARGS__) +#define ti_lib_chipinfo_get_device_id_hw_rev_code(...) ChipInfo_GetDeviceIdHwRevCode(__VA_ARGS__) +#define ti_lib_chipinfo_get_chip_family(...) ChipInfo_GetChipFamily(__VA_ARGS__) +#define ti_lib_chipinfo_chip_family_is_cc26xx(...) ChipInfo_ChipFamilyIsCC26xx(__VA_ARGS__) +#define ti_lib_chipinfo_chip_family_is_cc13xx(...) ChipInfo_ChipFamilyIsCC13xx(__VA_ARGS__) +#define ti_lib_chipinfo_get_hw_revision(...) ChipInfo_GetHwRevision(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_1_0(...) ChipInfo_HwRevisionIs_1_0(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_gteq_2_0(...) ChipInfo_HwRevisionIs_GTEQ_2_0(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_2_0(...) ChipInfo_HwRevisionIs_2_0(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_2_1(...) ChipInfo_HwRevisionIs_2_1(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_2_2(...) ChipInfo_HwRevisionIs_2_2(__VA_ARGS__) +#define ti_lib_chipinfo_hw_revision_is_gteq_2_2(...) ChipInfo_HwRevisionIs_GTEQ_2_2( __VA_ARGS__ ) +/*---------------------------------------------------------------------------*/ /* ddi.h */ #include "driverlib/ddi.h" @@ -309,7 +334,6 @@ #define ti_lib_prcm_peripheral_deep_sleep_disable(...) PRCMPeripheralDeepSleepDisable(__VA_ARGS__) #define ti_lib_prcm_power_domain_status(...) PRCMPowerDomainStatus(__VA_ARGS__) #define ti_lib_prcm_rf_ready(...) PRCMRfReady(__VA_ARGS__) -#define ti_lib_prcm_wdt_reset_status(...) PRCMWdtResetStatus(__VA_ARGS__) #define ti_lib_prcm_sleep(...) PRCMSleep(__VA_ARGS__) #define ti_lib_prcm_deep_sleep(...) PRCMDeepSleep(__VA_ARGS__) #define ti_lib_prcm_cache_retention_enable(...) PRCMCacheRetentionEnable(__VA_ARGS__) @@ -384,10 +408,6 @@ #define ti_lib_rom_flash_protection_set ROM_FlashProtectionSet #define ti_lib_rom_flash_protection_get ROM_FlashProtectionGet #define ti_lib_rom_flash_protection_save ROM_FlashProtectionSave -#define ti_lib_rom_flash_sector_erase ROM_FlashSectorErase -#define ti_lib_rom_flash_program ROM_FlashProgram -#define ti_lib_rom_flash_program_nowait ROM_FlashProgramNowait - #define ti_lib_rom_flash_efuse_read_row ROM_FlashEfuseReadRow #define ti_lib_rom_flash_disable_sectors_for_write ROM_FlashDisableSectorsForWrite @@ -507,8 +527,6 @@ #define ti_lib_hapi_max_value(a, b) HapiMaxValue(a,b) #define ti_lib_hapi_mean_value(a, b) HapiMeanValue(a,b) #define ti_lib_hapi_stand_deviation_value(a, b) HapiStandDeviationValue(a,b) -#define ti_lib_hapi_reset_peripheral(a) HapiResetPeripheral(a) -#define ti_lib_hapi_reset_domain(a) HapiResetDomain(a) #define ti_lib_hapi_hf_source_safe_switch() HapiHFSourceSafeSwitch() #define ti_lib_hapi_select_comp_a_input(a) HapiSelectCompAInput(a) #define ti_lib_hapi_select_comp_a_ref(a) HapiSelectCompARef(a) @@ -517,9 +535,6 @@ #define ti_lib_hapi_get_flash_size() HapiGetFlashSize() #define ti_lib_hapi_sector_erase(a) HapiSectorErase(a) #define ti_lib_hapi_program_flash(a, b, c) HapiProgramFlash(a, b, c) -#define ti_lib_hapi_get_flash_size() HapiGetFlashSize() -#define ti_lib_hapi_sector_erase(a) HapiSectorErase(a) -#define ti_lib_hapi_program_flash(a, b, c) HapiProgramFlash(a, b, c) /*---------------------------------------------------------------------------*/ /* sys_ctrl.h */ #include "driverlib/sys_ctrl.h" @@ -578,7 +593,6 @@ #define ti_lib_timer_disable(...) TimerDisable(__VA_ARGS__) #define ti_lib_timer_configure(...) TimerConfigure(__VA_ARGS__) #define ti_lib_timer_level_control(...) TimerLevelControl(__VA_ARGS__) -#define ti_lib_timer_trigger_control(...) TimerTriggerControl(__VA_ARGS__) #define ti_lib_timer_event_control(...) TimerEventControl(__VA_ARGS__) #define ti_lib_timer_stall_control(...) TimerStallControl(__VA_ARGS__) #define ti_lib_timer_wait_on_trigger_control(...) TimerWaitOnTriggerControl(__VA_ARGS__) diff --git a/cpu/cc26xx/dev/cc26xx-rf.c b/cpu/cc26xx/dev/cc26xx-rf.c deleted file mode 100644 index ade53ed19..000000000 --- a/cpu/cc26xx/dev/cc26xx-rf.c +++ /dev/null @@ -1,2148 +0,0 @@ -/* - * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/*---------------------------------------------------------------------------*/ -/** - * \addtogroup cc26xx-rf - * @{ - * - * \file - * Implementation of the CC26xx RF driver - */ -/*---------------------------------------------------------------------------*/ -#include "contiki.h" -#include "dev/radio.h" -#include "dev/cc26xx-rf.h" -#include "dev/oscillators.h" -#include "net/packetbuf.h" -#include "net/rime/rimestats.h" -#include "net/linkaddr.h" -#include "net/netstack.h" -#include "sys/energest.h" -#include "sys/clock.h" -#include "sys/rtimer.h" -#include "sys/cc.h" -#include "lpm.h" -#include "ti-lib.h" -/*---------------------------------------------------------------------------*/ -/* RF core and RF HAL API */ -#include "hw_rfc_dbell.h" -#include "hw_rfc_pwr.h" -/*---------------------------------------------------------------------------*/ -/* RF Core Mailbox API */ -#include "mailbox.h" -#include "common_cmd.h" -#include "common_cmd_field.h" -#include "ble_cmd.h" -#include "ble_cmd_field.h" -#include "ieee_cmd.h" -#include "ieee_cmd_field.h" -#include "data_entry.h" -#include "ble_mailbox.h" -#include "ieee_mailbox.h" -/*---------------------------------------------------------------------------*/ -#include -#include -#include -#include -/*---------------------------------------------------------------------------*/ -#define BUSYWAIT_UNTIL(cond, max_time) \ - do { \ - rtimer_clock_t t0; \ - t0 = RTIMER_NOW(); \ - while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \ - } while(0) -/*---------------------------------------------------------------------------*/ -#ifdef __GNUC__ -#define CC_ALIGN_ATTR(n) __attribute__ ((aligned(n))) -#else -#define CC_ALIGN_ATTR(n) -#endif -/*---------------------------------------------------------------------------*/ -#define DEBUG 0 -#if DEBUG -#define PRINTF(...) printf(__VA_ARGS__) -#else -#define PRINTF(...) -#endif -/*---------------------------------------------------------------------------*/ -/* Data entry status field constants */ -#define DATA_ENTRY_STATUS_PENDING 0x00 /* Not in use by the Radio CPU */ -#define DATA_ENTRY_STATUS_ACTIVE 0x01 /* Open for r/w by the radio CPU */ -#define DATA_ENTRY_STATUS_BUSY 0x02 /* Ongoing r/w */ -#define DATA_ENTRY_STATUS_FINISHED 0x03 /* Free to use and to free */ -#define DATA_ENTRY_STATUS_UNFINISHED 0x04 /* Partial RX entry */ -/*---------------------------------------------------------------------------*/ -/* RF stats data structure */ -static uint8_t rf_stats[16] = { 0 }; -/*---------------------------------------------------------------------------*/ -/* RF Command status constants - Correspond to values in the CMDSTA register */ -#define RF_CMD_STATUS_PENDING 0x00 -#define RF_CMD_STATUS_DONE 0x01 -#define RF_CMD_STATUS_ILLEGAL_PTR 0x81 -#define RF_CMD_STATUS_UNKNOWN_CMD 0x82 -#define RF_CMD_STATUS_UNKNOWN_DIR_CMD 0x83 -#define RF_CMD_STATUS_CONTEXT_ERR 0x85 -#define RF_CMD_STATUS_SCHEDULING_ERR 0x86 -#define RF_CMD_STATUS_PAR_ERR 0x87 -#define RF_CMD_STATUS_QUEUE_ERR 0x88 -#define RF_CMD_STATUS_QUEUE_BUSY 0x89 - -/* Status values starting with 0x8 correspond to errors */ -#define RF_CMD_STATUS_ERR_MASK 0x80 - -/* Return values for rf_send_cmd_ok */ -#define RF_CMD_ERROR 0 -#define RF_CMD_OK 1 - -/* The size of the RF commands buffer */ -#define RF_CMD_BUFFER_SIZE 128 -/*---------------------------------------------------------------------------*/ -/* RF Radio Op status constants. Field 'status' in Radio Op command struct */ -#define RF_RADIO_OP_STATUS_IDLE 0x0000 -#define RF_RADIO_OP_STATUS_PENDING 0x0001 -#define RF_RADIO_OP_STATUS_ACTIVE 0x0002 -#define RF_RADIO_OP_STATUS_SKIPPED 0x0003 -#define RF_RADIO_OP_STATUS_DONE_OK 0x0400 -#define RF_RADIO_OP_STATUS_DONE_COUNTDOWN 0x0401 -#define RF_RADIO_OP_STATUS_DONE_RXERR 0x0402 -#define RF_RADIO_OP_STATUS_DONE_TIMEOUT 0x0403 -#define RF_RADIO_OP_STATUS_DONE_STOPPED 0x0404 -#define RF_RADIO_OP_STATUS_DONE_ABORT 0x0405 -#define RF_RADIO_OP_STATUS_ERROR_PAST_START 0x0800 -#define RF_RADIO_OP_STATUS_ERROR_START_TRIG 0x0801 -#define RF_RADIO_OP_STATUS_ERROR_CONDITION 0x0802 -#define RF_RADIO_OP_STATUS_ERROR_PAR 0x0803 -#define RF_RADIO_OP_STATUS_ERROR_POINTER 0x0804 -#define RF_RADIO_OP_STATUS_ERROR_CMDID 0x0805 -#define RF_RADIO_OP_STATUS_ERROR_NO_SETUP 0x0807 -#define RF_RADIO_OP_STATUS_ERROR_NO_FS 0x0808 -#define RF_RADIO_OP_STATUS_ERROR_SYNTH_PROG 0x0809 - -/* Additional Op status values for IEEE mode */ -#define RF_RADIO_OP_STATUS_IEEE_SUSPENDED 0x2001 -#define RF_RADIO_OP_STATUS_IEEE_DONE_OK 0x2400 -#define RF_RADIO_OP_STATUS_IEEE_DONE_BUSY 0x2401 -#define RF_RADIO_OP_STATUS_IEEE_DONE_STOPPED 0x2402 -#define RF_RADIO_OP_STATUS_IEEE_DONE_ACK 0x2403 -#define RF_RADIO_OP_STATUS_IEEE_DONE_ACKPEND 0x2404 -#define RF_RADIO_OP_STATUS_IEEE_DONE_TIMEOUT 0x2405 -#define RF_RADIO_OP_STATUS_IEEE_DONE_BGEND 0x2406 -#define RF_RADIO_OP_STATUS_IEEE_DONE_ABORT 0x2407 -#define RF_RADIO_OP_STATUS_ERROR_WRONG_BG 0x0806 -#define RF_RADIO_OP_STATUS_IEEE_ERROR_PAR 0x2800 -#define RF_RADIO_OP_STATUS_IEEE_ERROR_NO_SETUP 0x2801 -#define RF_RADIO_OP_STATUS_IEEE_ERROR_NO_FS 0x2802 -#define RF_RADIO_OP_STATUS_IEEE_ERROR_SYNTH_PROG 0x2803 -#define RF_RADIO_OP_STATUS_IEEE_ERROR_RXOVF 0x2804 -#define RF_RADIO_OP_STATUS_IEEE_ERROR_TXUNF 0x2805 - -/* Op status values for BLE mode */ -#define RF_RADIO_OP_STATUS_BLE_DONE_OK 0x1400 -#define RF_RADIO_OP_STATUS_BLE_DONE_RXTIMEOUT 0x1401 -#define RF_RADIO_OP_STATUS_BLE_DONE_NOSYNC 0x1402 -#define RF_RADIO_OP_STATUS_BLE_DONE_RXERR 0x1403 -#define RF_RADIO_OP_STATUS_BLE_DONE_CONNECT 0x1404 -#define RF_RADIO_OP_STATUS_BLE_DONE_MAXNACK 0x1405 -#define RF_RADIO_OP_STATUS_BLE_DONE_ENDED 0x1406 -#define RF_RADIO_OP_STATUS_BLE_DONE_ABORT 0x1407 -#define RF_RADIO_OP_STATUS_BLE_DONE_STOPPED 0x1408 -#define RF_RADIO_OP_STATUS_BLE_ERROR_PAR 0x1800 -#define RF_RADIO_OP_STATUS_BLE_ERROR_RXBUF 0x1801 -#define RF_RADIO_OP_STATUS_BLE_ERROR_NO_SETUP 0x1802 -#define RF_RADIO_OP_STATUS_BLE_ERROR_NO_FS 0x1803 -#define RF_RADIO_OP_STATUS_BLE_ERROR_SYNTH_PROG 0x1804 -#define RF_RADIO_OP_STATUS_BLE_ERROR_RXOVF 0x1805 -#define RF_RADIO_OP_STATUS_BLE_ERROR_TXUNF 0x1806 - -/* Bits 15:12 signify the protocol */ -#define RF_RADIO_OP_STATUS_PROTO_MASK 0xF000 -#define RF_RADIO_OP_STATUS_PROTO_GENERIC 0x0000 -#define RF_RADIO_OP_STATUS_PROTO_BLE 0x1000 -#define RF_RADIO_OP_STATUS_PROTO_IEEE 0x2000 -#define RF_RADIO_OP_STATUS_PROTO_PROP 0x3000 - -/* Bits 11:10 signify Running / Done OK / Done with error */ -#define RF_RADIO_OP_MASKED_STATUS 0x0C00 -#define RF_RADIO_OP_MASKED_STATUS_RUNNING 0x0000 -#define RF_RADIO_OP_MASKED_STATUS_DONE 0x0400 -#define RF_RADIO_OP_MASKED_STATUS_ERROR 0x0800 -/*---------------------------------------------------------------------------*/ -/** - * \brief Returns the current status of a running Radio Op command - * \param a A pointer with the buffer used to initiate the command - * \return The value of the Radio Op buffer's status field - * - * This macro can be used to e.g. return the status of a previously - * initiated background operation, or of an immediate command - */ -#define RF_RADIO_OP_GET_STATUS(a) GET_FIELD_V(a, radioOp, status) -/*---------------------------------------------------------------------------*/ -/* Special value returned by CMD_IEEE_CCA_REQ when an RSSI is not available */ -#define RF_CMD_CCA_REQ_RSSI_UNKNOWN -128 - -/* Used for the return value of channel_clear */ -#define RF_CCA_CLEAR 1 -#define RF_CCA_BUSY 0 - -/* Used as an error return value for get_cca_info */ -#define RF_GET_CCA_INFO_ERROR 0xFF - -/* - * Values of the individual bits of the ccaInfo field in CMD_IEEE_CCA_REQ's - * status struct - */ -#define RF_CMD_CCA_REQ_CCA_STATE_IDLE 0 /* 00 */ -#define RF_CMD_CCA_REQ_CCA_STATE_BUSY 1 /* 01 */ -#define RF_CMD_CCA_REQ_CCA_STATE_INVALID 2 /* 10 */ -/*---------------------------------------------------------------------------*/ -#define RF_MODE_BLE 0 -#define RF_MODE_IEEE 1 -/*---------------------------------------------------------------------------*/ -/* How long to wait for an ongoing ACK TX to finish before starting frame TX */ -#define TX_WAIT_TIMEOUT (RTIMER_SECOND >> 11) - -/* How long to wait for the RF to enter RX in rf_cmd_ieee_rx */ -#define ENTER_RX_WAIT_TIMEOUT (RTIMER_SECOND >> 10) -/*---------------------------------------------------------------------------*/ -/* TX Power dBm lookup table - values from SmartRF Studio */ -typedef struct output_config { - radio_value_t dbm; - uint8_t register_ib; - uint8_t register_gc; -} output_config_t; - -static const output_config_t output_power[] = { - { 5, 0x29, 0x00 }, - { 4, 0x20, 0x00 }, - { 3, 0x19, 0x00 }, - { 2, 0x25, 0x01 }, - { 1, 0x21, 0x01 }, - { 0, 0x1D, 0x01 }, - { -3, 0x19, 0x03 }, - { -6, 0x13, 0x03 }, - { -9, 0x0F, 0x03 }, -}; - -#define OUTPUT_CONFIG_COUNT (sizeof(output_power) / sizeof(output_config_t)) - -/* Max and Min Output Power in dBm */ -#define OUTPUT_POWER_MIN (output_power[OUTPUT_CONFIG_COUNT - 1].dbm) -#define OUTPUT_POWER_MAX (output_power[0].dbm) -#define OUTPUT_POWER_UNKNOWN 0xFFFF - -/* Default TX Power - position in output_power[] */ -#define CC26XX_RF_TX_POWER 0 -const output_config_t *tx_power_current = &output_power[0]; -/*---------------------------------------------------------------------------*/ -#define RF_CORE_CLOCKS_MASK (RFC_PWR_PWMCLKEN_RFC_M | RFC_PWR_PWMCLKEN_CPE_M \ - | RFC_PWR_PWMCLKEN_CPERAM_M) -/*---------------------------------------------------------------------------*/ -/* RF interrupts */ -#define RX_IRQ IRQ_IEEE_RX_ENTRY_DONE -#define TX_ACK_IRQ IRQ_IEEE_TX_ACK -#define ERROR_IRQ IRQ_INTERNAL_ERROR - -/* Those IRQs are enabled all the time */ -#define ENABLED_IRQS (RX_IRQ + ERROR_IRQ) - -/* - * We only enable this right before starting frame TX, so we can sleep while - * the TX is ongoing - */ -#define LAST_FG_CMD_DONE IRQ_LAST_FG_COMMAND_DONE - -#define cc26xx_rf_cpe0_isr RFCCPE0IntHandler -#define cc26xx_rf_cpe1_isr RFCCPE1IntHandler -/*---------------------------------------------------------------------------*/ -/* - * Buffers used to send commands to the RF core (generic and IEEE commands). - * Some of those buffers are re-usable, some are not. - * - * If you are uncertain, declare a new buffer. - */ -/* - * A buffer to send a CMD_IEEE_RX and to subsequently monitor its status - * Do not use this buffer for any commands other than CMD_IEEE_RX - */ -static uint8_t cmd_ieee_rx_buf[RF_CMD_BUFFER_SIZE] CC_ALIGN_ATTR(4); - -/* - * A buffer used to send immediate and foreground Radio Op (e.g. CMD_IEEE_TX) - * commands. - * - * Do not re-use this buffer to send a command before the previous command - * has been completed. - * - * Do not intermingle preparation of this buffer to send a command with calls - * that might lead to a different command, since the latter will overwrite what - * you have written in preparation for the former. - */ -static uint8_t cmd_immediate_buf[RF_CMD_BUFFER_SIZE] CC_ALIGN_ATTR(4); -/*---------------------------------------------------------------------------*/ -/* BLE macros, variables and buffers */ - -/* BLE Intervals: Send a burst of advertisements every BLE_ADV_INTERVAL secs */ -#define BLE_ADV_INTERVAL (CLOCK_SECOND * 5) -#define BLE_ADV_DUTY_CYCLE (CLOCK_SECOND / 10) -#define BLE_ADV_MESSAGES 10 - -/* BLE Advertisement-related macros */ -#define BLE_ADV_TYPE_DEVINFO 0x01 -#define BLE_ADV_TYPE_NAME 0x09 -#define BLE_ADV_TYPE_MANUFACTURER 0xFF -#define BLE_ADV_NAME_BUF_LEN 32 -#define BLE_ADV_PAYLOAD_BUF_LEN 64 -#define BLE_UUID_SIZE 16 - -#if CC26XX_RF_BLE_SUPPORT -/* BLE buffers / variables */ -static unsigned char ble_cmd_buf[32] CC_ALIGN_ATTR(4) = { 0 }; -static unsigned char ble_tx_rx_buf[128] CC_ALIGN_ATTR(4); -static uint8_t ble_mode_on; - -/* BLE beacond config */ -static struct ble_beacond_config { - clock_time_t interval; - char adv_name[BLE_ADV_NAME_BUF_LEN]; -} beacond_config; - -/* BLE overrides */ -static uint32_t ble_overrides[] = { - 0x00364038, /* Synth: Set RTRIM (POTAILRESTRIM) to 6 */ - 0x000784A3, /* Synth: Set FREF = 3.43 MHz (24 MHz / 7) */ - 0xA47E0583, /* Synth: Set loop bandwidth after lock to 80 kHz (K2) */ - 0xEAE00603, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, LSB) */ - 0x00010623, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, MSB) */ - 0x00456088, /* Adjust AGC reference level */ - 0xFFFFFFFF, /* End of override list */ -}; - -PROCESS(cc26xx_rf_ble_beacon_process, "CC26xx RF BLE Beacon Process"); - -static void init_ble(void); -#else -#define init_ble(...) -#endif /* CC26XX_RF_BLE_SUPPORT */ -/*---------------------------------------------------------------------------*/ -#define RX_BUF_SIZE 140 -/* Four receive buffers entries with room for 1 IEEE802.15.4 frame in each */ -static uint8_t rx_buf_0[RX_BUF_SIZE] CC_ALIGN_ATTR(4); -static uint8_t rx_buf_1[RX_BUF_SIZE] CC_ALIGN_ATTR(4); -static uint8_t rx_buf_2[RX_BUF_SIZE] CC_ALIGN_ATTR(4); -static uint8_t rx_buf_3[RX_BUF_SIZE] CC_ALIGN_ATTR(4); - -/* The RX Data Queue */ -static dataQueue_t rx_data_queue = { 0 }; - -/* Receive entry pointer to keep track of read items */ -volatile static uint8_t *rx_read_entry; -/*---------------------------------------------------------------------------*/ -/* The outgoing frame buffer */ -#define TX_BUF_SIZE 180 - -static uint8_t tx_buf[TX_BUF_SIZE]; -/*---------------------------------------------------------------------------*/ -/* Overrides for IEEE 802.15.4, differential mode */ -static uint32_t ieee_overrides[] = { - 0x00354038, /* Synth: Set RTRIM (POTAILRESTRIM) to 5 */ - 0x4001402D, /* Synth: Correct CKVD latency setting (address) */ - 0x00608402, /* Synth: Correct CKVD latency setting (value) */ - 0x4001405D, /* Synth: Set ANADIV DIV_BIAS_MODE to PG1 (address) */ - 0x1801F800, /* Synth: Set ANADIV DIV_BIAS_MODE to PG1 (value) */ - 0x000784A3, /* Synth: Set FREF = 3.43 MHz (24 MHz / 7) */ - 0xA47E0583, /* Synth: Set loop bandwidth after lock to 80 kHz (K2) */ - 0xEAE00603, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, LSB) */ - 0x00010623, /* Synth: Set loop bandwidth after lock to 80 kHz (K3, MSB) */ - 0x002B50DC, /* Adjust AGC DC filter */ - 0x05000243, /* Increase synth programming timeout */ - 0x002082C3, /* Increase synth programming timeout */ - 0xFFFFFFFF, /* End of override list */ -}; -/*---------------------------------------------------------------------------*/ -PROCESS(cc26xx_rf_process, "CC26xx RF driver"); -/*---------------------------------------------------------------------------*/ -static int on(void); -static int off(void); -static void setup_interrupts(void); -/*---------------------------------------------------------------------------*/ -static uint8_t -rf_is_accessible(void) -{ - if(ti_lib_prcm_rf_ready() && - ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) == - PRCM_DOMAIN_POWER_ON) { - return 1; - } - return 0; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Sends a command to the RF core. - * - * \param cmd The command value or a pointer to a command buffer - * \param status A pointer to a variable which will hold the status - * \return RF_CMD_OK or RF_CMD_ERROR - * - * This function supports all three types of command (Radio OP, immediate and - * direct) - * - * For immediate and Radio OPs, cmd is a pointer to the data structure - * containing the command and its parameters. This data structure must be - * 4-byte aligned. - * - * For direct commands, cmd contains the value of the command alongside its - * parameters - * - * The caller is responsible of allocating and populating cmd for Radio OP and - * immediate commands - * - * The caller is responsible for allocating status - */ -static uint_fast8_t -rf_send_cmd(uint32_t cmd, uint32_t *status) -{ - uint32_t timeout_count = 0; - bool interrupts_disabled; - - /* - * Make sure ContikiMAC doesn't turn us off from within an interrupt while - * we are accessing RF Core registers - */ - interrupts_disabled = ti_lib_int_master_disable(); - - if(!rf_is_accessible()) { - PRINTF("rf_send_cmd: RF was off\n"); - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } - return RF_CMD_ERROR; - } - - HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDR) = cmd; - do { - *status = HWREG(RFC_DBELL_BASE + RFC_DBELL_O_CMDSTA); - if(++timeout_count > 50000) { - PRINTF("rf_send_cmd: Timeout\n"); - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } - return RF_CMD_ERROR; - } - } while(*status == RF_CMD_STATUS_PENDING); - - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } - - /* - * If we reach here the command is no longer pending. It is either completed - * successfully or with error - */ - return *status == RF_CMD_STATUS_DONE; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Checks whether the RFC domain is accessible and the RFC is in IEEE RX - * \return 1: RFC in RX mode (and therefore accessible too). 0 otherwise - */ -static uint8_t -rf_is_on(void) -{ - if(!rf_is_accessible()) { - return 0; - } - - return RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == RF_RADIO_OP_STATUS_ACTIVE; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Check the RF's TX status - * \return 1 RF is transmitting - * \return 0 RF is not transmitting - * - * TX mode may be triggered either by a CMD_IEEE_TX or by the automatic - * transmission of an ACK frame. - */ -static uint8_t -transmitting(void) -{ - uint32_t cmd_status; - - /* If we are off, we are not in TX */ - if(!rf_is_accessible()) { - return 0; - } - - memset(cmd_immediate_buf, 0x00, SIZEOF_STRUCT(CMD_IEEE_CCA_REQ)); - GET_FIELD(cmd_immediate_buf, command, commandNo) = CMD_IEEE_CCA_REQ; - - if(rf_send_cmd((uint32_t)cmd_immediate_buf, &cmd_status) == RF_CMD_ERROR) { - PRINTF("transmitting: CMDSTA=0x%08lx, status=0x%04x\n", - cmd_status, RF_RADIO_OP_GET_STATUS(cmd_immediate_buf)); - return 0; - } - - if((GET_FIELD(cmd_immediate_buf, CMD_IEEE_CCA_REQ, currentRssi) - == RF_CMD_CCA_REQ_RSSI_UNKNOWN) && - (GET_BITFIELD(cmd_immediate_buf, CMD_IEEE_CCA_REQ, ccaInfo, ccaEnergy) - == RF_CMD_CCA_REQ_CCA_STATE_BUSY)) { - return 1; - } - - return 0; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Returns CCA information - * \return RF_GET_CCA_INFO_ERROR if the RF was not on - * \return On success, the return value is formatted as per the ccaInfo field - * of CMD_IEEE_CCA_REQ - * - * It is the caller's responsibility to make sure the RF is on. This function - * will return RF_GET_CCA_INFO_ERROR if the RF is off - * - * This function will in fact wait for a valid RSSI signal - */ -static uint8_t -get_cca_info(void) -{ - uint32_t cmd_status; - int8_t rssi; - - if(!rf_is_on()) { - PRINTF("get_cca_info: Not on\n"); - return RF_GET_CCA_INFO_ERROR; - } - - rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; - - while(rssi == RF_CMD_CCA_REQ_RSSI_UNKNOWN || rssi == 0) { - memset(cmd_immediate_buf, 0x00, SIZEOF_STRUCT(CMD_IEEE_CCA_REQ)); - GET_FIELD(cmd_immediate_buf, command, commandNo) = CMD_IEEE_CCA_REQ; - - if(rf_send_cmd((uint32_t)cmd_immediate_buf, &cmd_status) == RF_CMD_ERROR) { - PRINTF("get_cca_info: CMDSTA=0x%08lx, status=0x%04x\n", - cmd_status, RF_RADIO_OP_GET_STATUS(cmd_immediate_buf)); - - return RF_GET_CCA_INFO_ERROR; - } - - rssi = GET_FIELD(cmd_immediate_buf, CMD_IEEE_CCA_REQ, currentRssi); - } - - /* We have a valid RSSI signal. Return the CCA Info */ - return GET_FIELD(cmd_immediate_buf, CMD_IEEE_CCA_REQ, ccaInfo); -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Reads the current signal strength (RSSI) - * \return The current RSSI in dBm or CMD_GET_RSSI_UNKNOWN - * - * This function reads the current RSSI on the currently configured - * channel. - */ -static radio_value_t -get_rssi(void) -{ - uint32_t cmd_status; - int8_t rssi; - uint8_t was_off = 0; - - /* If we are off, turn on first */ - if(!rf_is_on()) { - was_off = 1; - if(on() != RF_CMD_OK) { - PRINTF("get_rssi: on() failed\n"); - return RF_CMD_CCA_REQ_RSSI_UNKNOWN; - } - } - - memset(cmd_immediate_buf, 0x00, SIZEOF_STRUCT(CMD_GET_RSSI)); - GET_FIELD(cmd_immediate_buf, command, commandNo) = CMD_GET_RSSI; - - if(rf_send_cmd((uint32_t)cmd_immediate_buf, &cmd_status) == RF_CMD_ERROR) { - rssi = RF_CMD_CCA_REQ_RSSI_UNKNOWN; - } - - /* Current RSSI in bits 23:16 of cmd_status */ - rssi = (cmd_status >> 16) & 0xFF; - - /* If we were off, turn back off */ - if(was_off) { - off(); - } - - return rssi; -} -/*---------------------------------------------------------------------------*/ -/* Returns the current TX power in dBm */ -static radio_value_t -get_tx_power(void) -{ - return tx_power_current->dbm; -} -/*---------------------------------------------------------------------------*/ -/* - * Set TX power to 'at least' power dBm - * This works with a lookup table. If the value of 'power' does not exist in - * the lookup table, TXPOWER will be set to the immediately higher available - * value - */ -static void -set_tx_power(radio_value_t power) -{ - uint32_t cmd_status; - int i; - - /* Send a CMD_SET_TX_POWER command to the RF */ - memset(cmd_immediate_buf, 0x00, SIZEOF_STRUCT(CMD_SET_TX_POWER)); - - GET_FIELD(cmd_immediate_buf, command, commandNo) = CMD_SET_TX_POWER; - - for(i = OUTPUT_CONFIG_COUNT - 1; i >= 0; --i) { - if(power <= output_power[i].dbm) { - GET_FIELD(cmd_immediate_buf, CMD_SET_TX_POWER, txPower) = - BITVALUE(CMD_SET_TX_POWER, txPower, IB, output_power[i].register_ib) | - BITVALUE(CMD_SET_TX_POWER, txPower, GC, output_power[i].register_gc) | - BITVALUE(CMD_SET_TX_POWER, txPower, tempCoeff, 0); - - if(rf_send_cmd((uint32_t)cmd_immediate_buf, &cmd_status) == RF_CMD_OK) { - /* Success: Remember the new setting */ - tx_power_current = &output_power[i]; - } else { - PRINTF("set_tx_power: CMDSTA=0x%08lx\n", cmd_status); - } - return; - } - } -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Wait till running radio Op command completes - * - * \return RF_CMD_ERROR or RF_CMD_OK - * - * RF_CMD_OK will be returned if the Radio Op returned with - * RF_RADIO_OP_STATUS_DONE_OK - * - * RF_CMD_ERROR will be returned in the radio op returned with any other - * RF_RADIO_OP_STATUS_DONE_xyz - */ -static uint_fast8_t -rf_wait_cmd_completed_ok(uint8_t *cmd) -{ - _TYPE_radioOp_status tmp_status; - uint32_t timeoutCount = 0; - - /* - * 0x04XX=DONE, 0x0400=DONE_OK while all other "DONE" values means done - * but with some kind of error (ref. "Common radio operation status codes") - */ - do { - tmp_status = GET_FIELD_V(cmd, radioOp, status); - if(++timeoutCount > 500000) { - return RF_CMD_ERROR; - } - } while((tmp_status & RF_RADIO_OP_MASKED_STATUS) != RF_RADIO_OP_MASKED_STATUS_DONE); - - return tmp_status == RF_RADIO_OP_STATUS_DONE_OK; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Builds common radio parameters for radio operations - * - * \param *cmd Pointer to buffer to add parameters to - * \param command Radio command number (e.g. COMMAND_RADIO_SETUP) - * - * \note The buffer must be emptied with memset() before calling this function - * - * \return None - */ -static void -rf_build_radio_op_cmd(uint8_t *cmd, uint16_t command) -{ - GET_FIELD(cmd, radioOp, commandNo) = command; - GET_FIELD(cmd, radioOp, status) = IDLE; - GET_FIELD(cmd, radioOp, pNextOp) = NULL; - GET_FIELD(cmd, radioOp, startTime) = 0; - GET_FIELD(cmd, radioOp, startTrigger) = TRIG_NOW; - GET_FIELD(cmd, radioOp, condition) = COND_NEVER; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Sends a CMD_RADIO_SETUP for the selected mode (IEEE or BLE) - * \param mode RF_MODE_BLE or RF_MODE_IEEE - * \return RF_CMD_OK or RF_CMD_ERROR - * - * ToDo: Likely to need one more argument to set bNoAdi on first startup - * vs when coming back from sleep - */ -static uint8_t -rf_radio_setup(uint8_t mode) -{ - uint32_t cmd_status; - - /* Create radio setup command */ - memset(cmd_immediate_buf, 0x00, SIZEOF_RADIO_OP(CMD_RADIO_SETUP)); - rf_build_radio_op_cmd(cmd_immediate_buf, CMD_RADIO_SETUP); - - /* Set output power to the current (or default) value */ - GET_FIELD(cmd_immediate_buf, CMD_RADIO_SETUP, txPower) = - BITVALUE(CMD_RADIO_SETUP, txPower, IB, tx_power_current->register_ib) | - BITVALUE(CMD_RADIO_SETUP, txPower, GC, tx_power_current->register_gc) | - BITVALUE(CMD_RADIO_SETUP, txPower, tempCoeff, 0); - - /* Do mode-dependent things (e.g. apply overrides) */ - if(mode == RF_MODE_IEEE) { - /* Add override control pointer */ - GET_FIELD(cmd_immediate_buf, CMD_RADIO_SETUP, pRegOverride) = ieee_overrides; -#if CC26XX_RF_BLE_SUPPORT - } else if(mode == RF_MODE_BLE) { - /* Add override control pointer */ - GET_FIELD(cmd_immediate_buf, CMD_RADIO_SETUP, pRegOverride) = ble_overrides; -#endif - } else { - PRINTF("rf_radio_setup: Unknown mode %u\n", mode); - return RF_CMD_ERROR; - } - - /* Lastly, set the mode */ - GET_FIELD(cmd_immediate_buf, CMD_RADIO_SETUP, mode) = mode; - - /* Send Radio setup to RF Core */ - if(rf_send_cmd((uint32_t)cmd_immediate_buf, &cmd_status) != RF_CMD_OK) { - PRINTF("rf_radio_setup: CMD_RADIO_SETUP, CMDSTA=0x%08lx, status=0x%04x\n", - cmd_status, RF_RADIO_OP_GET_STATUS(cmd_immediate_buf)); - return RF_CMD_ERROR; - } - - /* Wait until radio setup is done */ - if(rf_wait_cmd_completed_ok(cmd_immediate_buf) != RF_CMD_OK) { - PRINTF("rf_radio_setup: CMD_RADIO_SETUP wait, CMDSTA=0x%08lx, status=0x%04x\n", - cmd_status, RF_RADIO_OP_GET_STATUS(cmd_immediate_buf)); - return RF_CMD_ERROR; - } - - return RF_CMD_OK; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Applies patches (if any) - * \return RF_CMD_OK or RF_CMD_ERROR - * - * Currently patches are not required. - */ -static uint8_t -apply_patches() -{ - uint32_t cmd_status; - - /* Patch of uninitialized pointer */ - *((uint32_t *)0x21000028) = 0x00000000; - - /* Start radio timer (RAT) */ - if(rf_send_cmd(CMDR_DIR_CMD(CMD_START_RAT), &cmd_status) != RF_CMD_OK) { - PRINTF("apply_patches: START_RAT fail, CMDSTA=0x%08lx\n", cmd_status); - return RF_CMD_ERROR; - } - - return RF_CMD_OK; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Set up radio in IEEE802.15.4 RX mode - * - * \return RF_CMD_OK Succeeded - * \return RF_CMD_ERROR Failed - * - * This function assumes that cmd_ieee_rx_buf has been previously populated - * with correct values. This can be done through init_rf_params (sets defaults) - * or through Contiki's extended RF API (set_value, set_object) - */ -static uint8_t -rf_cmd_ieee_rx() -{ - uint32_t cmd_status; - rtimer_clock_t t0; - int ret; - - ret = rf_send_cmd((uint32_t)cmd_ieee_rx_buf, &cmd_status); - - if(ret != RF_CMD_OK) { - PRINTF("rf_cmd_ieee_rx: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", - ret, cmd_status, RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); - } - - t0 = RTIMER_NOW(); - - while(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) != RF_RADIO_OP_STATUS_ACTIVE && - (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ENTER_RX_WAIT_TIMEOUT))); - - /* Wait to enter RX */ - if(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) != RF_RADIO_OP_STATUS_ACTIVE) { - PRINTF("rf_cmd_ieee_rx: CMDSTA=0x%08lx, status=0x%04x\n", - cmd_status, RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); - return RF_CMD_ERROR; - } - - return ret; -} -/*---------------------------------------------------------------------------*/ -static void -init_rx_buffers(void) -{ - /* Two-element circular buffer, hardcoded for now.. */ - GET_FIELD(rx_buf_0, dataEntry, pNextEntry) = rx_buf_1; - GET_FIELD(rx_buf_0, dataEntry, config) = 0x04; - GET_FIELD(rx_buf_0, dataEntry, length) = sizeof(rx_buf_0) - 8; - - GET_FIELD(rx_buf_1, dataEntry, pNextEntry) = rx_buf_2; - GET_FIELD(rx_buf_1, dataEntry, config) = 0x04; - GET_FIELD(rx_buf_1, dataEntry, length) = sizeof(rx_buf_1) - 8; - - GET_FIELD(rx_buf_2, dataEntry, pNextEntry) = rx_buf_3; - GET_FIELD(rx_buf_2, dataEntry, config) = 0x04; - GET_FIELD(rx_buf_2, dataEntry, length) = sizeof(rx_buf_2) - 8; - - /* Point to first element again */ - GET_FIELD(rx_buf_3, dataEntry, pNextEntry) = rx_buf_0; - GET_FIELD(rx_buf_3, dataEntry, config) = 0x04; - GET_FIELD(rx_buf_3, dataEntry, length) = sizeof(rx_buf_3) - 8; -} -/*---------------------------------------------------------------------------*/ -static void -init_rf_params(void) -{ - memset(cmd_ieee_rx_buf, 0x00, SIZEOF_RADIO_OP(CMD_IEEE_RX)); - - GET_FIELD(cmd_ieee_rx_buf, radioOp, commandNo) = CMD_IEEE_RX; - GET_FIELD(cmd_ieee_rx_buf, radioOp, status) = IDLE; - GET_FIELD(cmd_ieee_rx_buf, radioOp, pNextOp) = NULL; - GET_FIELD(cmd_ieee_rx_buf, radioOp, startTime) = 0x00000000; - GET_FIELD(cmd_ieee_rx_buf, radioOp, startTrigger) = TRIG_NOW; - GET_FIELD(cmd_ieee_rx_buf, radioOp, condition) = COND_NEVER; - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, channel) = CC26XX_RF_CHANNEL; - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, rxConfig) = - BITVALUE(CMD_IEEE_RX, rxConfig, bAutoFlushCrc, 1) | - BITVALUE(CMD_IEEE_RX, rxConfig, bAutoFlushIgn, 0) | - BITVALUE(CMD_IEEE_RX, rxConfig, bIncludePhyHdr, 0) | - BITVALUE(CMD_IEEE_RX, rxConfig, bIncludeCrc, 1) | - BITVALUE(CMD_IEEE_RX, rxConfig, bAppendRssi, 1) | - BITVALUE(CMD_IEEE_RX, rxConfig, bAppendCorrCrc, 1) | - BITVALUE(CMD_IEEE_RX, rxConfig, bAppendSrcInd, 0) | - BITVALUE(CMD_IEEE_RX, rxConfig, bAppendTimestamp, 0); - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, pRxQ) = &rx_data_queue; - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, pOutput) = rf_stats; - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, frameFiltOpt) = -#if CC26XX_RF_CONF_PROMISCOUS - BITVALUE(CMD_IEEE_RX, frameFiltOpt, frameFiltEn, 0) | -#else - BITVALUE(CMD_IEEE_RX, frameFiltOpt, frameFiltEn, 1) | -#endif - BITVALUE(CMD_IEEE_RX, frameFiltOpt, frameFiltStop, 1) | -#if CC26XX_RF_CONF_AUTOACK - BITVALUE(CMD_IEEE_RX, frameFiltOpt, autoAckEn, 1) | -#else - BITVALUE(CMD_IEEE_RX, frameFiltOpt, autoAckEn, 0) | -#endif - BITVALUE(CMD_IEEE_RX, frameFiltOpt, slottedAckEn, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, autoPendEn, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, defaultPend, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, bPendDataReqOnly, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, bPanCoord, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, maxFrameVersion, 1) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, bStrictLenFilter, 0); - /* Receive all frame types */ - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, frameTypes) = - BITVALUE(CMD_IEEE_RX, frameTypes, bAcceptFt0Beacon, 1) | - BITVALUE(CMD_IEEE_RX, frameTypes, bAcceptFt1Data, 1) | - BITVALUE(CMD_IEEE_RX, frameTypes, bAcceptFt2Ack, 1) | - BITVALUE(CMD_IEEE_RX, frameTypes, bAcceptFt3MacCmd, 1) | - BITVALUE(CMD_IEEE_RX, frameTypes, bAcceptFt4Reserved, 1) | - BITVALUE(CMD_IEEE_RX, frameTypes, bAcceptFt5Reserved, 1) | - BITVALUE(CMD_IEEE_RX, frameTypes, bAcceptFt6Reserved, 1) | - BITVALUE(CMD_IEEE_RX, frameTypes, bAcceptFt7Reserved, 1); - /* Configure CCA settings */ - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, ccaOpt) = - BITVALUE(CMD_IEEE_RX, ccaOpt, ccaEnEnergy, 1) | - BITVALUE(CMD_IEEE_RX, ccaOpt, ccaEnCorr, 1) | - BITVALUE(CMD_IEEE_RX, ccaOpt, ccaEnSync, 0) | - BITVALUE(CMD_IEEE_RX, ccaOpt, ccaCorrOp, 1) | - BITVALUE(CMD_IEEE_RX, ccaOpt, ccaSyncOp, 1) | - BITVALUE(CMD_IEEE_RX, ccaOpt, ccaCorrThr, 3); - /* Set CCA RSSI Threshold, 0xA6 corresponds to -90dBm (two's comp.)*/ - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, ccaRssiThr) = 0xA6; - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, numExtEntries) = 0x00; - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, numShortEntries) = 0x00; - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, pExtEntryList) = 0; - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, pShortEntryList) = 0; - - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, endTrigger) = TRIG_NEVER; - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, endTime) = 0x00000000; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Turn on power to the RFC and boot it. - * - * \return RF_CMD_OK or RF_CMD_ERROR - */ -static int -power_up(void) -{ - uint32_t cmd_status; - bool interrupts_disabled = ti_lib_int_master_disable(); - - ti_lib_int_pend_clear(INT_RF_CPE0); - ti_lib_int_pend_clear(INT_RF_CPE1); - ti_lib_int_disable(INT_RF_CPE0); - ti_lib_int_disable(INT_RF_CPE1); - - /* Enable RF Core power domain */ - ti_lib_prcm_power_domain_on(PRCM_DOMAIN_RFCORE); - while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) - != PRCM_DOMAIN_POWER_ON); - - ti_lib_prcm_domain_enable(PRCM_DOMAIN_RFCORE); - ti_lib_prcm_load_set(); - while(!ti_lib_prcm_load_get()); - - while(!rf_is_accessible()) { - PRINTF("power_up: Not ready\n"); - } - - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0; - ti_lib_int_enable(INT_RF_CPE0); - ti_lib_int_enable(INT_RF_CPE1); - - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } - - /* Let CPE boot */ - HWREG(RFC_PWR_NONBUF_BASE + RFC_PWR_O_PWMCLKEN) = RF_CORE_CLOCKS_MASK; - - /* Send ping (to verify RFCore is ready and alive) */ - if(rf_send_cmd(CMDR_DIR_CMD(CMD_PING), &cmd_status) != RF_CMD_OK) { - PRINTF("power_up: CMD_PING fail, CMDSTA=0x%08lx\n", cmd_status); - return RF_CMD_ERROR; - } - - return RF_CMD_OK; -} -/*---------------------------------------------------------------------------*/ -/** - * \brief Disable RFCORE clock domain in the MCU VD and turn off the RFCORE PD - */ -static void -power_down(void) -{ - bool interrupts_disabled = ti_lib_int_master_disable(); - ti_lib_int_disable(INT_RF_CPE0); - ti_lib_int_disable(INT_RF_CPE1); - - if(rf_is_accessible()) { - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = 0x0; - } - - /* Shut down the RFCORE clock domain in the MCU VD */ - ti_lib_prcm_domain_disable(PRCM_DOMAIN_RFCORE); - ti_lib_prcm_load_set(); - while(!ti_lib_prcm_load_get()); - - /* Turn off RFCORE PD */ - ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE); - while(ti_lib_prcm_power_domain_status(PRCM_DOMAIN_RFCORE) - != PRCM_DOMAIN_POWER_OFF); - - ti_lib_int_pend_clear(INT_RF_CPE0); - ti_lib_int_pend_clear(INT_RF_CPE1); - ti_lib_int_enable(INT_RF_CPE0); - ti_lib_int_enable(INT_RF_CPE1); - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } -} -/*---------------------------------------------------------------------------*/ -static int -rx_on(void) -{ - int ret; - - /* Get status of running IEEE_RX (if any) */ - if(rf_is_on()) { - PRINTF("rx_on: We were on. PD=%u, RX=0x%04x \n", rf_is_accessible(), - RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); - return RF_CMD_OK; - } - - /* Put CPE in RX using the currently configured parameters */ - ret = rf_cmd_ieee_rx(); - - if(ret) { - ENERGEST_ON(ENERGEST_TYPE_LISTEN); - } - - return ret; -} -/*---------------------------------------------------------------------------*/ -static int -rx_off(void) -{ - uint32_t cmd_status; - int ret; - - /* If we are off, do nothing */ - if(!rf_is_on()) { - return RF_CMD_OK; - } - - /* Wait for ongoing ACK TX to finish */ - while(transmitting()); - - /* Send a CMD_STOP command to RF Core */ - if(rf_send_cmd(CMDR_DIR_CMD(CMD_ABORT), &cmd_status) != RF_CMD_OK) { - PRINTF("RX off: CMD_ABORT status=0x%08lx\n", cmd_status); - /* Continue nonetheless */ - } - - while(rf_is_on()); - - if(RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_STOPPED || - RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf) == IEEE_DONE_ABORT) { - /* Stopped gracefully */ - ENERGEST_OFF(ENERGEST_TYPE_LISTEN); - ret = RF_CMD_OK; - } else { - PRINTF("RX off: BG status=0x%04x\n", RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); - ret = RF_CMD_ERROR; - } - - return ret; -} -/*---------------------------------------------------------------------------*/ -static void -rx_isr(void) -{ - process_poll(&cc26xx_rf_process); -} -/*---------------------------------------------------------------------------*/ -void -cc26xx_rf_cpe1_isr(void) -{ - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - ti_lib_int_master_disable(); - PRINTF("RF Error\n"); - - if(!rf_is_accessible()) { - if(power_up() != RF_CMD_OK) { - return; - } - } - - /* Clear interrupt flags */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; - ti_lib_int_master_enable(); - - ENERGEST_OFF(ENERGEST_TYPE_IRQ); -} -/*---------------------------------------------------------------------------*/ -void -cc26xx_rf_cpe0_isr(void) -{ - ENERGEST_ON(ENERGEST_TYPE_IRQ); - - if(!rf_is_accessible()) { - printf("RF ISR called but RF not ready... PANIC!!\n"); - if(power_up() != RF_CMD_OK) { - PRINTF("power_up() failed\n"); - return; - } - } - - ti_lib_int_master_disable(); - if(HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) & RX_IRQ) { - rx_isr(); - } - - /* Clear interrupt flags */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; - ti_lib_int_master_enable(); - - ENERGEST_OFF(ENERGEST_TYPE_IRQ); -} -/*---------------------------------------------------------------------------*/ -static void -setup_interrupts(void) -{ - bool interrupts_disabled; - - /* We are already turned on by the caller, so this should not happen */ - if(!rf_is_accessible()) { - PRINTF("setup_interrupts: No access\n"); - return; - } - - /* Disable interrupts */ - interrupts_disabled = ti_lib_int_master_disable(); - - /* Set all interrupt channels to CPE0 channel, error to CPE1 */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEISL) = ERROR_IRQ; - - /* Acknowledge TX_Frame, Rx_Entry_Done and ERROR */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS; - - /* Clear interrupt flags, active low clear(?) */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIFG) = 0x0; - - ti_lib_int_pend_clear(INT_RF_CPE0); - ti_lib_int_pend_clear(INT_RF_CPE1); - ti_lib_int_enable(INT_RF_CPE0); - ti_lib_int_enable(INT_RF_CPE1); - - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } -} -/*---------------------------------------------------------------------------*/ -static uint8_t -request(void) -{ - /* - * We rely on the RDC layer to turn us on and off. Thus, if we are on we - * will only allow sleep, standby otherwise - */ - if(rf_is_on()) { - return LPM_MODE_SLEEP; - } - - return LPM_MODE_MAX_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE); -/*---------------------------------------------------------------------------*/ -static int -init(void) -{ - lpm_register_module(&cc26xx_rf_lpm_module); - - /* Enable IEEE, BLE and Common-CMD APIs */ - HWREG(PRCM_BASE + PRCM_O_RFCMODESEL) = PRCM_RFCMODESEL_CURR_MODE5; - - /* Wipe out the BLE adv buffer */ - init_ble(); - - /* Initialise RX buffers */ - memset(rx_buf_0, 0, RX_BUF_SIZE); - memset(rx_buf_1, 0, RX_BUF_SIZE); - memset(rx_buf_2, 0, RX_BUF_SIZE); - memset(rx_buf_3, 0, RX_BUF_SIZE); - - /* Set of RF Core data queue. Circular buffer, no last entry */ - rx_data_queue.pCurrEntry = rx_buf_0; - - rx_data_queue.pLastEntry = NULL; - - /* Initialize current read pointer to first element (used in ISR) */ - rx_read_entry = rx_buf_0; - - /* Populate the RF parameters data structure with default values */ - init_rf_params(); - - if(on() != RF_CMD_OK) { - PRINTF("init: on() failed\n"); - return RF_CMD_ERROR; - } - - ENERGEST_ON(ENERGEST_TYPE_LISTEN); - - process_start(&cc26xx_rf_process, NULL); - return 1; -} -/*---------------------------------------------------------------------------*/ -static int -prepare(const void *payload, unsigned short payload_len) -{ - int len = MIN(payload_len, sizeof(tx_buf)); - - memcpy(tx_buf, payload, len); - return RF_CMD_OK; -} -/*---------------------------------------------------------------------------*/ -static int -transmit(unsigned short transmit_len) -{ - int ret; - uint8_t was_off = 0; - uint32_t cmd_status; - uint16_t stat; - uint8_t tx_active = 0; - rtimer_clock_t t0; - - if(!rf_is_on()) { - was_off = 1; - if(on() != RF_CMD_OK) { - PRINTF("transmit: on() failed\n"); - return RF_CMD_ERROR; - } - } - - /* - * We are certainly not TXing a frame as a result of CMD_IEEE_TX, but we may - * be in the process of TXing an ACK. In that case, wait for the TX to finish - * or return after approx TX_WAIT_TIMEOUT - */ - t0 = RTIMER_NOW(); - - do { - tx_active = transmitting(); - } while(tx_active == 1 && - (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + TX_WAIT_TIMEOUT))); - - if(tx_active) { - PRINTF("transmit: Already TXing and wait timed out\n"); - - if(was_off) { - off(); - } - - return RADIO_TX_COLLISION; - } - - /* Send the CMD_IEEE_TX command */ - memset(cmd_immediate_buf, 0, SIZEOF_RADIO_OP(CMD_IEEE_TX)); - - rf_build_radio_op_cmd(cmd_immediate_buf, CMD_IEEE_TX); - - GET_FIELD(cmd_immediate_buf, CMD_IEEE_TX, payloadLen) = transmit_len; - GET_FIELD(cmd_immediate_buf, CMD_IEEE_TX, pPayload) = tx_buf; - - /* Enable the LAST_FG_COMMAND_DONE interrupt, which will wake us up */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS + - LAST_FG_CMD_DONE; - - ret = rf_send_cmd((uint32_t)cmd_immediate_buf, &cmd_status); - - if(ret) { - /* If we enter here, TX actually started */ - ENERGEST_OFF(ENERGEST_TYPE_LISTEN); - ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); - - /* Idle away while the command is running */ - while((RF_RADIO_OP_GET_STATUS(cmd_immediate_buf) & RF_RADIO_OP_MASKED_STATUS) - == RF_RADIO_OP_MASKED_STATUS_RUNNING) { - lpm_sleep(); - } - - stat = RF_RADIO_OP_GET_STATUS(cmd_immediate_buf); - - if(stat == RF_RADIO_OP_STATUS_IEEE_DONE_OK) { - /* Sent OK */ - RIMESTATS_ADD(lltx); - ret = RADIO_TX_OK; - } else { - /* Operation completed, but frame was not sent */ - PRINTF("transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", ret, - cmd_status, stat); - ret = RADIO_TX_ERR; - } - } else { - /* Failure sending the CMD_IEEE_TX command */ - PRINTF("transmit: ret=%d, CMDSTA=0x%08lx, status=0x%04x\n", - ret, cmd_status, RF_RADIO_OP_GET_STATUS(cmd_immediate_buf)); - - ret = RADIO_TX_ERR; - } - - /* - * Update ENERGEST state here, before a potential call to off(), which - * will correctly update it if required. - */ - ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); - ENERGEST_ON(ENERGEST_TYPE_LISTEN); - - /* - * Disable LAST_FG_COMMAND_DONE interrupt. We don't really care about it - * except when we are transmitting - */ - HWREG(RFC_DBELL_NONBUF_BASE + RFC_DBELL_O_RFCPEIEN) = ENABLED_IRQS; - - return ret; -} -/*---------------------------------------------------------------------------*/ -static int -send(const void *payload, unsigned short payload_len) -{ - prepare(payload, payload_len); - return transmit(payload_len); -} -/*---------------------------------------------------------------------------*/ -static int -read_frame(void *buf, unsigned short buf_len) -{ - int len = 0; - - if(GET_FIELD_V(rx_read_entry, dataEntry, status) == DATA_ENTRY_STATUS_FINISHED) { - /* Set status to 0 "Pending" in element */ - GET_FIELD_V(rx_read_entry, dataEntry, status) = DATA_ENTRY_STATUS_PENDING; - - if(rx_read_entry[8] > 0) { - memcpy(buf, (char *)&rx_read_entry[9], buf_len); - - /* Remove the footer */ - len = MIN(buf_len, rx_read_entry[8] - 4); - - int rssi = (int8_t)rx_read_entry[9 + len + 2]; - - packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); - RIMESTATS_ADD(llrx); - - /* Clear the length byte */ - rx_read_entry[8] = 0; - } - - /* Move read entry pointer to next entry */ - rx_read_entry = GET_FIELD_V(rx_read_entry, dataEntry, pNextEntry); - } - - return len; -} -/*---------------------------------------------------------------------------*/ -static int -channel_clear(void) -{ - uint8_t was_off = 0; - uint8_t cca_info; - int ret = RF_CCA_CLEAR; - - /* - * If we are in the middle of a BLE operation, we got called by ContikiMAC - * from within an interrupt context. Indicate a clear channel - */ -#if CC26XX_RF_BLE_SUPPORT - if(ble_mode_on) { - PRINTF("channel_clear: Interrupt context but BLE in progress\n"); - return RF_CCA_CLEAR; - } -#endif - - if(rf_is_on()) { - /* - * Wait for potential leftover ACK still being sent. - * Strictly speaking, if we are TXing an ACK then the channel is not clear. - * However, channel_clear is only ever called to determine whether there is - * someone else's packet in the air, not ours. - * - * We could probably even simply return that the channel is clear - */ - while(transmitting()); - } else { - was_off = 1; - if(on() != RF_CMD_OK) { - PRINTF("channel_clear: on() failed\n"); - if(was_off) { - off(); - } - return RF_CCA_CLEAR; - } - } - - cca_info = get_cca_info(); - - if(cca_info == RF_GET_CCA_INFO_ERROR) { - PRINTF("channel_clear: CCA error\n"); - ret = RF_CCA_CLEAR; - } else { - /* - * cca_info bits 1:0 - ccaStatus - * Return 1 (clear) if idle or invalid. - */ - ret = (cca_info & 0x03) != RF_CMD_CCA_REQ_CCA_STATE_BUSY; - } - - if(was_off) { - off(); - } - - return ret; -} -/*---------------------------------------------------------------------------*/ -static int -receiving_packet(void) -{ - int ret = 0; - uint8_t cca_info; - uint8_t was_off = 0; - - if(!rf_is_on()) { - was_off = 1; - if(on() != RF_CMD_OK) { - PRINTF("receiving_packet: on() failed\n"); - return RF_CMD_ERROR; - } - } - - /* - * If we are in the middle of a BLE operation, we got called by ContikiMAC - * from within an interrupt context. We are not receiving - */ -#if CC26XX_RF_BLE_SUPPORT - if(ble_mode_on) { - PRINTF("receiving_packet: Interrupt context but BLE in progress\n"); - return 0; - } -#endif - - /* If we are off, we are not receiving */ - if(!rf_is_on()) { - PRINTF("receiving_packet: We were off\n"); - return 0; - } - - /* If we are transmitting (can only be an ACK here), we are not receiving */ - if(transmitting()) { - PRINTF("receiving_packet: We were TXing\n"); - return 0; - } - - cca_info = get_cca_info(); - - if(cca_info == RF_GET_CCA_INFO_ERROR) { - /* If we can't read CCA info, return "not receiving" */ - ret = 0; - } else { - /* Return 1 (receiving) if ccaState is busy */ - ret = (cca_info & 0x03) == RF_CMD_CCA_REQ_CCA_STATE_BUSY; - } - - if(was_off) { - off(); - } - - return ret; -} -/*---------------------------------------------------------------------------*/ -static int -pending_packet(void) -{ - volatile uint8_t *current = rx_data_queue.pCurrEntry; - int rv = 0; - - /* Go through all RX buffers and check their status */ - do { - if(GET_FIELD_V(current, dataEntry, status) == - DATA_ENTRY_STATUS_FINISHED) { - rv = 1; - process_poll(&cc26xx_rf_process); - } - - current = GET_FIELD_V(current, dataEntry, pNextEntry); - } while(current != rx_data_queue.pCurrEntry); - - /* If we didn't find an entry at status finished, no frames are pending */ - return rv; -} -/*---------------------------------------------------------------------------*/ -static int -on(void) -{ - /* - * Request the HF XOSC as the source for the HF clock. Needed before we can - * use the FS. This will only request, it will _not_ perform the switch. - */ - oscillators_request_hf_xosc(); - - /* - * If we are in the middle of a BLE operation, we got called by ContikiMAC - * from within an interrupt context. Abort, but pretend everything is OK. - */ -#if CC26XX_RF_BLE_SUPPORT - if(ble_mode_on) { - PRINTF("on: Interrupt context but BLE in progress\n"); - return RF_CMD_OK; - } -#endif - - if(rf_is_on()) { - PRINTF("on: We were on. PD=%u, RX=0x%04x \n", rf_is_accessible(), - RF_RADIO_OP_GET_STATUS(cmd_ieee_rx_buf)); - return RF_CMD_OK; - } - - if(power_up() != RF_CMD_OK) { - PRINTF("on: power_up() failed\n"); - return RF_CMD_ERROR; - } - - if(apply_patches() != RF_CMD_OK) { - PRINTF("on: apply_patches() failed\n"); - return RF_CMD_ERROR; - } - - init_rx_buffers(); - - setup_interrupts(); - - /* - * Trigger a switch to the XOSC, so that we can subsequently use the RF FS - * This will block until the XOSC is actually ready, but give how we - * requested it early on, this won't be too long a wait/ - */ - oscillators_switch_to_hf_xosc(); - - if(rf_radio_setup(RF_MODE_IEEE) != RF_CMD_OK) { - PRINTF("on: radio_setup() failed\n"); - return RF_CMD_ERROR; - } - - return rx_on(); -} -/*---------------------------------------------------------------------------*/ -static int -off(void) -{ - /* - * If we are in the middle of a BLE operation, we got called by ContikiMAC - * from within an interrupt context. Abort, but pretend everything is OK. - */ -#if CC26XX_RF_BLE_SUPPORT - if(ble_mode_on) { - PRINTF("off: Interrupt context but BLE in progress\n"); - return RF_CMD_OK; - } -#endif - - while(transmitting()); - - power_down(); - - /* Switch HF clock source to the RCOSC to preserve power */ - oscillators_switch_to_hf_rc(); - - /* We pulled the plug, so we need to restore the status manually */ - GET_FIELD(cmd_ieee_rx_buf, radioOp, status) = IDLE; - - /* - * Just in case there was an ongoing RX (which started after we begun the - * shutdown sequence), we don't want to leave the buffer in state == ongoing - */ - GET_FIELD_V(rx_buf_0, dataEntry, status) = DATA_ENTRY_STATUS_PENDING; - GET_FIELD_V(rx_buf_1, dataEntry, status) = DATA_ENTRY_STATUS_PENDING; - GET_FIELD_V(rx_buf_2, dataEntry, status) = DATA_ENTRY_STATUS_PENDING; - GET_FIELD_V(rx_buf_3, dataEntry, status) = DATA_ENTRY_STATUS_PENDING; - - return RF_CMD_OK; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -get_value(radio_param_t param, radio_value_t *value) -{ - if(!value) { - return RADIO_RESULT_INVALID_VALUE; - } - - switch(param) { - case RADIO_PARAM_POWER_MODE: - /* On / off */ - *value = rf_is_on() ? RADIO_POWER_MODE_ON : RADIO_POWER_MODE_OFF; - return RADIO_RESULT_OK; - case RADIO_PARAM_CHANNEL: - *value = (radio_value_t)GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, channel); - return RADIO_RESULT_OK; - case RADIO_PARAM_PAN_ID: - *value = (radio_value_t)GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, localPanID); - return RADIO_RESULT_OK; - case RADIO_PARAM_16BIT_ADDR: - *value = (radio_value_t)GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, localShortAddr); - return RADIO_RESULT_OK; - case RADIO_PARAM_RX_MODE: - *value = 0; - if(GET_BITFIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, frameFiltOpt, frameFiltEn)) { - *value |= RADIO_RX_MODE_ADDRESS_FILTER; - } - if(GET_BITFIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, frameFiltOpt, autoAckEn)) { - *value |= RADIO_RX_MODE_AUTOACK; - } - - return RADIO_RESULT_OK; - case RADIO_PARAM_TXPOWER: - *value = get_tx_power(); - return RADIO_RESULT_OK; - case RADIO_PARAM_CCA_THRESHOLD: - *value = GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, ccaRssiThr); - return RADIO_RESULT_OK; - case RADIO_PARAM_RSSI: - *value = get_rssi(); - - if(*value == RF_CMD_CCA_REQ_RSSI_UNKNOWN) { - return RADIO_RESULT_ERROR; - } else { - return RADIO_RESULT_OK; - } - case RADIO_CONST_CHANNEL_MIN: - *value = CC26XX_RF_CHANNEL_MIN; - return RADIO_RESULT_OK; - case RADIO_CONST_CHANNEL_MAX: - *value = CC26XX_RF_CHANNEL_MAX; - return RADIO_RESULT_OK; - case RADIO_CONST_TXPOWER_MIN: - *value = OUTPUT_POWER_MIN; - return RADIO_RESULT_OK; - case RADIO_CONST_TXPOWER_MAX: - *value = OUTPUT_POWER_MAX; - return RADIO_RESULT_OK; - default: - return RADIO_RESULT_NOT_SUPPORTED; - } -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -set_value(radio_param_t param, radio_value_t value) -{ - uint8_t was_off = 0; - radio_result_t rv; - - switch(param) { - case RADIO_PARAM_POWER_MODE: - if(value == RADIO_POWER_MODE_ON) { - if(on() != RF_CMD_OK) { - PRINTF("set_value: on() failed (1)\n"); - return RADIO_RESULT_ERROR; - } - return RADIO_RESULT_OK; - } - if(value == RADIO_POWER_MODE_OFF) { - off(); - return RADIO_RESULT_OK; - } - return RADIO_RESULT_INVALID_VALUE; - case RADIO_PARAM_CHANNEL: - if(value < CC26XX_RF_CHANNEL_MIN || - value > CC26XX_RF_CHANNEL_MAX) { - return RADIO_RESULT_INVALID_VALUE; - } - - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, channel) = (uint8_t)value; - break; - case RADIO_PARAM_PAN_ID: - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, localPanID) = (uint16_t)value; - break; - case RADIO_PARAM_16BIT_ADDR: - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, localShortAddr) = (uint16_t)value; - break; - case RADIO_PARAM_RX_MODE: - { - if(value & ~(RADIO_RX_MODE_ADDRESS_FILTER | - RADIO_RX_MODE_AUTOACK)) { - return RADIO_RESULT_INVALID_VALUE; - } - - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, frameFiltOpt) = - BITVALUE(CMD_IEEE_RX, frameFiltOpt, frameFiltEn, - (value & RADIO_RX_MODE_ADDRESS_FILTER) != 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, frameFiltStop, 1) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, autoAckEn, - (value & RADIO_RX_MODE_AUTOACK) != 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, slottedAckEn, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, autoPendEn, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, defaultPend, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, bPendDataReqOnly, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, bPanCoord, 0) | - BITVALUE(CMD_IEEE_RX, frameFiltOpt, bStrictLenFilter, 0); - - break; - } - case RADIO_PARAM_TXPOWER: - if(value < OUTPUT_POWER_MIN || value > OUTPUT_POWER_MAX) { - return RADIO_RESULT_INVALID_VALUE; - } - - set_tx_power(value); - - return RADIO_RESULT_OK; - case RADIO_PARAM_CCA_THRESHOLD: - GET_FIELD(cmd_ieee_rx_buf, CMD_IEEE_RX, ccaRssiThr) = (int8_t)value; - break; - default: - return RADIO_RESULT_NOT_SUPPORTED; - } - - /* If we reach here we had no errors. Apply new settings */ - if(!rf_is_on()) { - was_off = 1; - if(on() != RF_CMD_OK) { - PRINTF("set_value: on() failed (2)\n"); - return RADIO_RESULT_ERROR; - } - } - - if(rx_off() != RF_CMD_OK) { - PRINTF("set_value: rx_off() failed\n"); - rv = RADIO_RESULT_ERROR; - } - - if(rx_on() != RF_CMD_OK) { - PRINTF("set_value: rx_on() failed\n"); - rv = RADIO_RESULT_ERROR; - } - - /* If we were off, turn back off */ - if(was_off) { - off(); - } - - return rv; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -get_object(radio_param_t param, void *dest, size_t size) -{ - uint8_t *target; - uint8_t *src; - int i; - - if(param == RADIO_PARAM_64BIT_ADDR) { - if(size != 8 || !dest) { - return RADIO_RESULT_INVALID_VALUE; - } - - target = dest; - src = (uint8_t *)(GET_FIELD_PTR(cmd_ieee_rx_buf, CMD_IEEE_RX, localExtAddr)); - - for(i = 0; i < 8; i++) { - target[i] = src[7 - i]; - } - - return RADIO_RESULT_OK; - } - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -static radio_result_t -set_object(radio_param_t param, const void *src, size_t size) -{ - uint8_t was_off = 0; - radio_result_t rv; - int i; - uint8_t *dst; - - if(param == RADIO_PARAM_64BIT_ADDR) { - if(size != 8 || !src) { - return RADIO_RESULT_INVALID_VALUE; - } - - dst = (uint8_t *)(GET_FIELD_PTR(cmd_ieee_rx_buf, CMD_IEEE_RX, - localExtAddr)); - - for(i = 0; i < 8; i++) { - dst[i] = ((uint8_t *)src)[7 - i]; - } - - if(!rf_is_on()) { - was_off = 1; - if(on() != RF_CMD_OK) { - PRINTF("set_object: on() failed\n"); - return RADIO_RESULT_ERROR; - } - } - - if(rx_off() != RF_CMD_OK) { - PRINTF("set_object: rx_off() failed\n"); - rv = RADIO_RESULT_ERROR; - } - - if(rx_on() != RF_CMD_OK) { - PRINTF("set_object: rx_on() failed\n"); - rv = RADIO_RESULT_ERROR; - } - - /* If we were off, turn back off */ - if(was_off) { - off(); - } - - return rv; - } - return RADIO_RESULT_NOT_SUPPORTED; -} -/*---------------------------------------------------------------------------*/ -const struct radio_driver cc26xx_rf_driver = { - init, - prepare, - transmit, - send, - read_frame, - channel_clear, - receiving_packet, - pending_packet, - on, - off, - get_value, - set_value, - get_object, - set_object, -}; -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(cc26xx_rf_process, ev, data) -{ - int len; - - PROCESS_BEGIN(); - - while(1) { - PROCESS_WAIT_EVENT(); - do { - packetbuf_clear(); - len = read_frame(packetbuf_dataptr(), PACKETBUF_SIZE); - - if(len > 0) { - packetbuf_set_datalen(len); - - NETSTACK_RDC.input(); - } - } while(len > 0); - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -#if CC26XX_RF_BLE_SUPPORT -/*---------------------------------------------------------------------------*/ -/** - * \brief Builds common radio parameters for radio operations - * - * \param *cmd Pointer to buffer to add parameters to - * \param command Radio command number (e.g. COMMAND_RADIO_SETUP) - * - * \note The buffer must be emptied with memset() before calling this function - * - * \return None - */ -static void -rf_build_ble_radio_op_cmd(uint8_t *cmd, uint16_t command) -{ - GET_FIELD(cmd, radioOp, commandNo) = command; - GET_FIELD(cmd, radioOp, status) = IDLE; - GET_FIELD(cmd, radioOp, pNextOp) = NULL; - GET_FIELD(cmd, radioOp, startTime) = 0; - GET_FIELD(cmd, radioOp, startTrigger) = TRIG_NOW; - GET_FIELD(cmd, radioOp, condition) = COND_NEVER; -} -/*---------------------------------------------------------------------------*/ -static void -init_ble() -{ - ble_mode_on = 0; - - memset(beacond_config.adv_name, 0, BLE_ADV_NAME_BUF_LEN); - beacond_config.interval = BLE_ADV_INTERVAL; -} -/*---------------------------------------------------------------------------*/ -static int -send_ble_adv_nc(int channel, uint8_t *output, uint8_t *adv_payload, - int adv_payload_len, uint16_t *dev_address) -{ - uint32_t cmd_status; - int ret; - - /* Erase ble_tx_rx_buf array */ - memset(ble_tx_rx_buf, 0x00, SIZEOF_RADIO_OP(CMD_BLE_ADV_NC)); - rf_build_ble_radio_op_cmd(ble_tx_rx_buf, CMD_BLE_ADV_NC); - - GET_FIELD(ble_tx_rx_buf, bleRadioOp, channel) = channel; - GET_FIELD(ble_tx_rx_buf, bleRadioOp, whitening) = 0; - - memset(ble_cmd_buf, 0x00, SIZEOF_STRUCT(bleAdvPar)); - GET_FIELD(ble_tx_rx_buf, bleRadioOp, pParams) = (uint8_t *)ble_cmd_buf; - GET_FIELD(ble_tx_rx_buf, bleRadioOp, pOutput) = output; - - /* Set up BLE Advertisement parameters */ - GET_FIELD(ble_cmd_buf, bleAdvPar, pRxQ) = NULL; - GET_FIELD(ble_cmd_buf, bleAdvPar, rxConfig) = 0; - GET_FIELD(ble_cmd_buf, bleAdvPar, advConfig) = 0; - GET_FIELD(ble_cmd_buf, bleAdvPar, advLen) = adv_payload_len; - GET_FIELD(ble_cmd_buf, bleAdvPar, scanRspLen) = 0; - GET_FIELD(ble_cmd_buf, bleAdvPar, pAdvData) = adv_payload; - GET_FIELD(ble_cmd_buf, bleAdvPar, pScanRspData) = NULL; - GET_FIELD(ble_cmd_buf, bleAdvPar, pDeviceAddress) = dev_address; - GET_FIELD(ble_cmd_buf, bleAdvPar, pWhiteList) = NULL; - GET_FIELD(ble_cmd_buf, bleAdvPar, endTrigger) = TRIG_NEVER; - GET_FIELD(ble_cmd_buf, bleAdvPar, endTime) = TRIG_NEVER; - - if(rf_send_cmd((uint32_t)ble_tx_rx_buf, &cmd_status) == RF_CMD_ERROR) { - PRINTF("send_ble_adv_nc: Chan=%d CMDSTA=0x%08lx, status=0x%04x\n", - channel, cmd_status, RF_RADIO_OP_GET_STATUS(ble_tx_rx_buf)); - return RF_CMD_ERROR; - } - - /* Wait for the ADV_NC to go out */ - while((RF_RADIO_OP_GET_STATUS(ble_tx_rx_buf) & RF_RADIO_OP_MASKED_STATUS) - == RF_RADIO_OP_MASKED_STATUS_RUNNING); - - if(RF_RADIO_OP_GET_STATUS(ble_tx_rx_buf) == RF_RADIO_OP_STATUS_BLE_DONE_OK) { - /* Sent OK */ - ret = RF_CMD_OK; - } else { - /* Radio Op completed, but ADV NC was not sent */ - PRINTF("send_ble_adv_nc: Chan=%d CMDSTA=0x%08lx, status=0x%04x\n", - channel, cmd_status, RF_RADIO_OP_GET_STATUS(ble_tx_rx_buf)); - ret = RF_CMD_ERROR; - } - - return ret; -} -/*---------------------------------------------------------------------------*/ -static int -send_ble_adv(int channel, uint8_t *adv_payload, int adv_payload_len) -{ - if(send_ble_adv_nc(channel, rf_stats, adv_payload, adv_payload_len, - (uint16_t *)&linkaddr_node_addr.u8[2]) != RF_CMD_OK) { - PRINTF("send_ble_adv: Channel=%d, Error advertising\n", channel); - /* Break the loop, but don't return just yet */ - return RF_CMD_ERROR; - } - - return RF_CMD_OK; -} -/*---------------------------------------------------------------------------*/ -PROCESS_THREAD(cc26xx_rf_ble_beacon_process, ev, data) -{ - static struct etimer ble_adv_et; - static uint8_t payload[BLE_ADV_PAYLOAD_BUF_LEN]; - static int p = 0; - static int i; - uint8_t was_on; - int j; - uint32_t cmd_status; - bool interrupts_disabled; - - PROCESS_BEGIN(); - - while(1) { - etimer_set(&ble_adv_et, beacond_config.interval); - - PROCESS_WAIT_EVENT(); - - if(ev == PROCESS_EVENT_EXIT) { - PROCESS_EXIT(); - } - - /* Set the adv payload each pass: The device name may have changed */ - p = 0; - - /* device info */ - payload[p++] = 0x02; /* 2 bytes */ - payload[p++] = BLE_ADV_TYPE_DEVINFO; - payload[p++] = 0x1a; /* LE general discoverable + BR/EDR */ - payload[p++] = 1 + strlen(beacond_config.adv_name); - payload[p++] = BLE_ADV_TYPE_NAME; - memcpy(&payload[p], beacond_config.adv_name, - strlen(beacond_config.adv_name)); - p += strlen(beacond_config.adv_name); - - for(i = 0; i < BLE_ADV_MESSAGES; i++) { - /* - * Under ContikiMAC, some IEEE-related operations will be called from an - * interrupt context. We need those to see that we are in BLE mode. - */ - interrupts_disabled = ti_lib_int_master_disable(); - ble_mode_on = 1; - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } - - /* - * Send BLE_ADV_MESSAGES beacon bursts. Each burst on all three - * channels, with a BLE_ADV_DUTY_CYCLE interval between bursts - * - * First, determine our state: - * - * If we are running NullRDC, we are likely in IEEE RX mode. We need to - * abort the IEEE BG Op before entering BLE mode. - * If we are ContikiMAC, we are likely off, in which case we need to - * boot the CPE before entering BLE mode - */ - was_on = rf_is_accessible(); - - if(was_on) { - /* - * We were on: If we are in the process of receiving an IEEE frame, - * abort the BLE beacon burst. Otherwise, terminate the IEEE BG Op - * so we can switch to BLE mode - */ - if(receiving_packet()) { - PRINTF("cc26xx_rf_ble_beacon_process: We were receiving\n"); - - /* Abort this pass */ - break; - } - - if(rx_off() != RF_CMD_OK) { - PRINTF("cc26xx_rf_ble_beacon_process: rx_off() failed\n"); - - /* Abort this pass */ - break; - } - } else { - /* Request the HF XOSC to source the HF clock. */ - oscillators_request_hf_xosc(); - - /* We were off: Boot the CPE */ - if(power_up() != RF_CMD_OK) { - PRINTF("cc26xx_rf_ble_beacon_process: power_up() failed\n"); - - /* Abort this pass */ - break; - } - - if(apply_patches() != RF_CMD_OK) { - PRINTF("cc26xx_rf_ble_beacon_process: apply_patches() failed\n"); - - /* Abort this pass */ - break; - } - - /* Trigger a switch to the XOSC, so that we can use the FS */ - oscillators_switch_to_hf_xosc(); - } - - /* Enter BLE mode */ - if(rf_radio_setup(RF_MODE_BLE) != RF_CMD_OK) { - PRINTF("cc26xx_rf_ble_beacon_process: Error entering BLE mode\n"); - /* Continue so we can at least try to restore our previous state */ - } else { - /* Send advertising packets on all 3 advertising channels */ - for(j = 37; j <= 39; j++) { - if(send_ble_adv(j, payload, p) != RF_CMD_OK) { - PRINTF("cc26xx_rf_ble_beacon_process: Channel=%d," - "Error advertising\n", j); - /* Break the loop, but don't return just yet */ - break; - } - } - } - - /* Send a CMD_STOP command to RF Core */ - if(rf_send_cmd(CMDR_DIR_CMD(CMD_STOP), &cmd_status) != RF_CMD_OK) { - PRINTF("cc26xx_rf_ble_beacon_process: status=0x%08lx\n", cmd_status); - /* Continue... */ - } - - if(was_on) { - /* We were on, go back to IEEE mode */ - if(rf_radio_setup(RF_MODE_IEEE) != RF_CMD_OK) { - PRINTF("cc26xx_rf_ble_beacon_process: radio_setup() failed\n"); - } - - /* Enter IEEE RX mode */ - if(rx_on() != RF_CMD_OK) { - PRINTF("cc26xx_rf_ble_beacon_process: rx_on() failed\n"); - } - } else { - power_down(); - - /* Switch HF clock source to the RCOSC to preserve power */ - oscillators_switch_to_hf_rc(); - } - etimer_set(&ble_adv_et, BLE_ADV_DUTY_CYCLE); - - interrupts_disabled = ti_lib_int_master_disable(); - - ble_mode_on = 0; - - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } - - /* Wait unless this is the last burst */ - if(i < BLE_ADV_MESSAGES - 1) { - PROCESS_WAIT_EVENT(); - } - } - - interrupts_disabled = ti_lib_int_master_disable(); - - ble_mode_on = 0; - - if(!interrupts_disabled) { - ti_lib_int_master_enable(); - } - } - PROCESS_END(); -} -/*---------------------------------------------------------------------------*/ -#endif /* CC26XX_RF_BLE_SUPPORT */ -/*---------------------------------------------------------------------------*/ -void -cc26xx_rf_ble_beacond_config(clock_time_t interval, const char *name) -{ -#if CC26XX_RF_BLE_SUPPORT - if(name != NULL) { - memset(beacond_config.adv_name, 0, BLE_ADV_NAME_BUF_LEN); - - if(strlen(name) == 0 || strlen(name) >= BLE_ADV_NAME_BUF_LEN) { - return; - } - - memcpy(beacond_config.adv_name, name, strlen(name)); - } - - if(interval != 0) { - beacond_config.interval = interval; - } -#endif -} -/*---------------------------------------------------------------------------*/ -uint8_t -cc26xx_rf_ble_beacond_start() -{ -#if CC26XX_RF_BLE_SUPPORT - if(beacond_config.adv_name[0] == 0) { - return RF_CMD_ERROR; - } - - process_start(&cc26xx_rf_ble_beacon_process, NULL); - - return RF_CMD_OK; -#else - return RF_CMD_ERROR; -#endif -} -/*---------------------------------------------------------------------------*/ -void -cc26xx_rf_ble_beacond_stop() -{ -#if CC26XX_RF_BLE_SUPPORT - process_exit(&cc26xx_rf_ble_beacon_process); -#endif -} -/*---------------------------------------------------------------------------*/ -/** @} */ diff --git a/cpu/cc26xx/dev/rfc-api/ble_cmd_field.h b/cpu/cc26xx/dev/rfc-api/ble_cmd_field.h deleted file mode 100755 index 307e67dc6..000000000 --- a/cpu/cc26xx/dev/rfc-api/ble_cmd_field.h +++ /dev/null @@ -1,623 +0,0 @@ -/****************************************************************************** -* Filename: ble_cmd_field.h -* Revised: $ $ -* Revision: $ $ -* -* Description: CC26xx/CC13xx API for Bluetooth Low Energy commands -* -* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -******************************************************************************/ - -#ifndef __BLE_CMD_FIELD_H -#define __BLE_CMD_FIELD_H - -#include -#include "mailbox.h" -#include "common_cmd.h" - -#define _POSITION_bleRadioOp_channel 14 -#define _TYPE_bleRadioOp_channel uint8_t -#define _POSITION_bleRadioOp_whitening 15 -#define _TYPE_bleRadioOp_whitening uint8_t -#define _BITPOS_bleRadioOp_whitening_init 0 -#define _NBITS_bleRadioOp_whitening_init 7 -#define _BITPOS_bleRadioOp_whitening_bOverride 7 -#define _NBITS_bleRadioOp_whitening_bOverride 1 -#define _POSITION_bleRadioOp_pParams 16 -#define _TYPE_bleRadioOp_pParams uint8_t* -#define _POSITION_bleRadioOp_pOutput 20 -#define _TYPE_bleRadioOp_pOutput uint8_t* -#define _SIZEOF_bleRadioOp 24 - -#define _SIZEOF_CMD_BLE_SLAVE 24 - -#define _SIZEOF_CMD_BLE_MASTER 24 - -#define _SIZEOF_CMD_BLE_ADV 24 - -#define _SIZEOF_CMD_BLE_ADV_DIR 24 - -#define _SIZEOF_CMD_BLE_ADV_NC 24 - -#define _SIZEOF_CMD_BLE_ADV_SCAN 24 - -#define _SIZEOF_CMD_BLE_SCANNER 24 - -#define _SIZEOF_CMD_BLE_INITIATOR 24 - -#define _SIZEOF_CMD_BLE_GENERIC_RX 24 - -#define _SIZEOF_CMD_BLE_TX_TEST 24 - -#define _POSITION_CMD_BLE_ADV_PAYLOAD_payloadType 2 -#define _TYPE_CMD_BLE_ADV_PAYLOAD_payloadType uint8_t -#define _POSITION_CMD_BLE_ADV_PAYLOAD_newLen 3 -#define _TYPE_CMD_BLE_ADV_PAYLOAD_newLen uint8_t -#define _POSITION_CMD_BLE_ADV_PAYLOAD_pNewData 4 -#define _TYPE_CMD_BLE_ADV_PAYLOAD_pNewData uint8_t* -#define _POSITION_CMD_BLE_ADV_PAYLOAD_pParams 8 -#define _TYPE_CMD_BLE_ADV_PAYLOAD_pParams uint8_t* -#define _SIZEOF_CMD_BLE_ADV_PAYLOAD 12 - -#define _POSITION_bleMasterSlavePar_pRxQ 0 -#define _TYPE_bleMasterSlavePar_pRxQ dataQueue_t* -#define _POSITION_bleMasterSlavePar_pTxQ 4 -#define _TYPE_bleMasterSlavePar_pTxQ dataQueue_t* -#define _POSITION_bleMasterSlavePar_rxConfig 8 -#define _TYPE_bleMasterSlavePar_rxConfig uint8_t -#define _BITPOS_bleMasterSlavePar_rxConfig_bAutoFlushIgnored 0 -#define _NBITS_bleMasterSlavePar_rxConfig_bAutoFlushIgnored 1 -#define _BITPOS_bleMasterSlavePar_rxConfig_bAutoFlushCrcErr 1 -#define _NBITS_bleMasterSlavePar_rxConfig_bAutoFlushCrcErr 1 -#define _BITPOS_bleMasterSlavePar_rxConfig_bAutoFlushEmpty 2 -#define _NBITS_bleMasterSlavePar_rxConfig_bAutoFlushEmpty 1 -#define _BITPOS_bleMasterSlavePar_rxConfig_bIncludeLenByte 3 -#define _NBITS_bleMasterSlavePar_rxConfig_bIncludeLenByte 1 -#define _BITPOS_bleMasterSlavePar_rxConfig_bIncludeCrc 4 -#define _NBITS_bleMasterSlavePar_rxConfig_bIncludeCrc 1 -#define _BITPOS_bleMasterSlavePar_rxConfig_bAppendRssi 5 -#define _NBITS_bleMasterSlavePar_rxConfig_bAppendRssi 1 -#define _BITPOS_bleMasterSlavePar_rxConfig_bAppendStatus 6 -#define _NBITS_bleMasterSlavePar_rxConfig_bAppendStatus 1 -#define _BITPOS_bleMasterSlavePar_rxConfig_bAppendTimestamp 7 -#define _NBITS_bleMasterSlavePar_rxConfig_bAppendTimestamp 1 -#define _POSITION_bleMasterSlavePar_seqStat 9 -#define _TYPE_bleMasterSlavePar_seqStat uint8_t -#define _BITPOS_bleMasterSlavePar_seqStat_lastRxSn 0 -#define _NBITS_bleMasterSlavePar_seqStat_lastRxSn 1 -#define _BITPOS_bleMasterSlavePar_seqStat_lastTxSn 1 -#define _NBITS_bleMasterSlavePar_seqStat_lastTxSn 1 -#define _BITPOS_bleMasterSlavePar_seqStat_nextTxSn 2 -#define _NBITS_bleMasterSlavePar_seqStat_nextTxSn 1 -#define _BITPOS_bleMasterSlavePar_seqStat_bFirstPkt 3 -#define _NBITS_bleMasterSlavePar_seqStat_bFirstPkt 1 -#define _BITPOS_bleMasterSlavePar_seqStat_bAutoEmpty 4 -#define _NBITS_bleMasterSlavePar_seqStat_bAutoEmpty 1 -#define _BITPOS_bleMasterSlavePar_seqStat_bLlCtrlTx 5 -#define _NBITS_bleMasterSlavePar_seqStat_bLlCtrlTx 1 -#define _BITPOS_bleMasterSlavePar_seqStat_bLlCtrlAckRx 6 -#define _NBITS_bleMasterSlavePar_seqStat_bLlCtrlAckRx 1 -#define _BITPOS_bleMasterSlavePar_seqStat_bLlCtrlAckPending 7 -#define _NBITS_bleMasterSlavePar_seqStat_bLlCtrlAckPending 1 -#define _POSITION_bleMasterSlavePar_maxNack 10 -#define _TYPE_bleMasterSlavePar_maxNack uint8_t -#define _POSITION_bleMasterSlavePar_maxPkt 11 -#define _TYPE_bleMasterSlavePar_maxPkt uint8_t -#define _POSITION_bleMasterSlavePar_accessAddress 12 -#define _TYPE_bleMasterSlavePar_accessAddress uint32_t -#define _POSITION_bleMasterSlavePar_crcInit0 16 -#define _TYPE_bleMasterSlavePar_crcInit0 uint8_t -#define _POSITION_bleMasterSlavePar_crcInit1 17 -#define _TYPE_bleMasterSlavePar_crcInit1 uint8_t -#define _POSITION_bleMasterSlavePar_crcInit2 18 -#define _TYPE_bleMasterSlavePar_crcInit2 uint8_t -#define _POSITION_bleMasterSlavePar_crcInit 16 -#define _TYPE_bleMasterSlavePar_crcInit uint32_t -#define _SIZEOF_bleMasterSlavePar 20 - -#define _POSITION_bleMasterPar_endTrigger 19 -#define _TYPE_bleMasterPar_endTrigger uint8_t -#define _BITPOS_bleMasterPar_endTrigger_triggerType 0 -#define _NBITS_bleMasterPar_endTrigger_triggerType 4 -#define _BITPOS_bleMasterPar_endTrigger_bEnaCmd 4 -#define _NBITS_bleMasterPar_endTrigger_bEnaCmd 1 -#define _BITPOS_bleMasterPar_endTrigger_triggerNo 5 -#define _NBITS_bleMasterPar_endTrigger_triggerNo 2 -#define _BITPOS_bleMasterPar_endTrigger_pastTrig 7 -#define _NBITS_bleMasterPar_endTrigger_pastTrig 1 -#define _POSITION_bleMasterPar_endTime 20 -#define _TYPE_bleMasterPar_endTime ratmr_t -#define _SIZEOF_bleMasterPar 24 - -#define _POSITION_bleSlavePar_timeoutTrigger 19 -#define _TYPE_bleSlavePar_timeoutTrigger uint8_t -#define _BITPOS_bleSlavePar_timeoutTrigger_triggerType 0 -#define _NBITS_bleSlavePar_timeoutTrigger_triggerType 4 -#define _BITPOS_bleSlavePar_timeoutTrigger_bEnaCmd 4 -#define _NBITS_bleSlavePar_timeoutTrigger_bEnaCmd 1 -#define _BITPOS_bleSlavePar_timeoutTrigger_triggerNo 5 -#define _NBITS_bleSlavePar_timeoutTrigger_triggerNo 2 -#define _BITPOS_bleSlavePar_timeoutTrigger_pastTrig 7 -#define _NBITS_bleSlavePar_timeoutTrigger_pastTrig 1 -#define _POSITION_bleSlavePar_timeoutTime 20 -#define _TYPE_bleSlavePar_timeoutTime ratmr_t -#define _POSITION_bleSlavePar_endTrigger 27 -#define _TYPE_bleSlavePar_endTrigger uint8_t -#define _BITPOS_bleSlavePar_endTrigger_triggerType 0 -#define _NBITS_bleSlavePar_endTrigger_triggerType 4 -#define _BITPOS_bleSlavePar_endTrigger_bEnaCmd 4 -#define _NBITS_bleSlavePar_endTrigger_bEnaCmd 1 -#define _BITPOS_bleSlavePar_endTrigger_triggerNo 5 -#define _NBITS_bleSlavePar_endTrigger_triggerNo 2 -#define _BITPOS_bleSlavePar_endTrigger_pastTrig 7 -#define _NBITS_bleSlavePar_endTrigger_pastTrig 1 -#define _POSITION_bleSlavePar_endTime 28 -#define _TYPE_bleSlavePar_endTime ratmr_t -#define _SIZEOF_bleSlavePar 32 - -#define _POSITION_bleAdvPar_pRxQ 0 -#define _TYPE_bleAdvPar_pRxQ dataQueue_t* -#define _POSITION_bleAdvPar_rxConfig 4 -#define _TYPE_bleAdvPar_rxConfig uint8_t -#define _BITPOS_bleAdvPar_rxConfig_bAutoFlushIgnored 0 -#define _NBITS_bleAdvPar_rxConfig_bAutoFlushIgnored 1 -#define _BITPOS_bleAdvPar_rxConfig_bAutoFlushCrcErr 1 -#define _NBITS_bleAdvPar_rxConfig_bAutoFlushCrcErr 1 -#define _BITPOS_bleAdvPar_rxConfig_bAutoFlushEmpty 2 -#define _NBITS_bleAdvPar_rxConfig_bAutoFlushEmpty 1 -#define _BITPOS_bleAdvPar_rxConfig_bIncludeLenByte 3 -#define _NBITS_bleAdvPar_rxConfig_bIncludeLenByte 1 -#define _BITPOS_bleAdvPar_rxConfig_bIncludeCrc 4 -#define _NBITS_bleAdvPar_rxConfig_bIncludeCrc 1 -#define _BITPOS_bleAdvPar_rxConfig_bAppendRssi 5 -#define _NBITS_bleAdvPar_rxConfig_bAppendRssi 1 -#define _BITPOS_bleAdvPar_rxConfig_bAppendStatus 6 -#define _NBITS_bleAdvPar_rxConfig_bAppendStatus 1 -#define _BITPOS_bleAdvPar_rxConfig_bAppendTimestamp 7 -#define _NBITS_bleAdvPar_rxConfig_bAppendTimestamp 1 -#define _POSITION_bleAdvPar_advConfig 5 -#define _TYPE_bleAdvPar_advConfig uint8_t -#define _BITPOS_bleAdvPar_advConfig_advFilterPolicy 0 -#define _NBITS_bleAdvPar_advConfig_advFilterPolicy 2 -#define _BITPOS_bleAdvPar_advConfig_deviceAddrType 2 -#define _NBITS_bleAdvPar_advConfig_deviceAddrType 1 -#define _BITPOS_bleAdvPar_advConfig_peerAddrType 3 -#define _NBITS_bleAdvPar_advConfig_peerAddrType 1 -#define _BITPOS_bleAdvPar_advConfig_bStrictLenFilter 4 -#define _NBITS_bleAdvPar_advConfig_bStrictLenFilter 1 -#define _POSITION_bleAdvPar_advLen 6 -#define _TYPE_bleAdvPar_advLen uint8_t -#define _POSITION_bleAdvPar_scanRspLen 7 -#define _TYPE_bleAdvPar_scanRspLen uint8_t -#define _POSITION_bleAdvPar_pAdvData 8 -#define _TYPE_bleAdvPar_pAdvData uint8_t* -#define _POSITION_bleAdvPar_pScanRspData 12 -#define _TYPE_bleAdvPar_pScanRspData uint8_t* -#define _POSITION_bleAdvPar_pDeviceAddress 16 -#define _TYPE_bleAdvPar_pDeviceAddress uint16_t* -#define _POSITION_bleAdvPar_pWhiteList 20 -#define _TYPE_bleAdvPar_pWhiteList uint32_t* -#define _POSITION_bleAdvPar_endTrigger 27 -#define _TYPE_bleAdvPar_endTrigger uint8_t -#define _BITPOS_bleAdvPar_endTrigger_triggerType 0 -#define _NBITS_bleAdvPar_endTrigger_triggerType 4 -#define _BITPOS_bleAdvPar_endTrigger_bEnaCmd 4 -#define _NBITS_bleAdvPar_endTrigger_bEnaCmd 1 -#define _BITPOS_bleAdvPar_endTrigger_triggerNo 5 -#define _NBITS_bleAdvPar_endTrigger_triggerNo 2 -#define _BITPOS_bleAdvPar_endTrigger_pastTrig 7 -#define _NBITS_bleAdvPar_endTrigger_pastTrig 1 -#define _POSITION_bleAdvPar_endTime 28 -#define _TYPE_bleAdvPar_endTime ratmr_t -#define _SIZEOF_bleAdvPar 32 - -#define _POSITION_bleScannerPar_pRxQ 0 -#define _TYPE_bleScannerPar_pRxQ dataQueue_t* -#define _POSITION_bleScannerPar_rxConfig 4 -#define _TYPE_bleScannerPar_rxConfig uint8_t -#define _BITPOS_bleScannerPar_rxConfig_bAutoFlushIgnored 0 -#define _NBITS_bleScannerPar_rxConfig_bAutoFlushIgnored 1 -#define _BITPOS_bleScannerPar_rxConfig_bAutoFlushCrcErr 1 -#define _NBITS_bleScannerPar_rxConfig_bAutoFlushCrcErr 1 -#define _BITPOS_bleScannerPar_rxConfig_bAutoFlushEmpty 2 -#define _NBITS_bleScannerPar_rxConfig_bAutoFlushEmpty 1 -#define _BITPOS_bleScannerPar_rxConfig_bIncludeLenByte 3 -#define _NBITS_bleScannerPar_rxConfig_bIncludeLenByte 1 -#define _BITPOS_bleScannerPar_rxConfig_bIncludeCrc 4 -#define _NBITS_bleScannerPar_rxConfig_bIncludeCrc 1 -#define _BITPOS_bleScannerPar_rxConfig_bAppendRssi 5 -#define _NBITS_bleScannerPar_rxConfig_bAppendRssi 1 -#define _BITPOS_bleScannerPar_rxConfig_bAppendStatus 6 -#define _NBITS_bleScannerPar_rxConfig_bAppendStatus 1 -#define _BITPOS_bleScannerPar_rxConfig_bAppendTimestamp 7 -#define _NBITS_bleScannerPar_rxConfig_bAppendTimestamp 1 -#define _POSITION_bleScannerPar_scanConfig 5 -#define _TYPE_bleScannerPar_scanConfig uint8_t -#define _BITPOS_bleScannerPar_scanConfig_scanFilterPolicy 0 -#define _NBITS_bleScannerPar_scanConfig_scanFilterPolicy 1 -#define _BITPOS_bleScannerPar_scanConfig_bActiveScan 1 -#define _NBITS_bleScannerPar_scanConfig_bActiveScan 1 -#define _BITPOS_bleScannerPar_scanConfig_deviceAddrType 2 -#define _NBITS_bleScannerPar_scanConfig_deviceAddrType 1 -#define _BITPOS_bleScannerPar_scanConfig_bStrictLenFilter 4 -#define _NBITS_bleScannerPar_scanConfig_bStrictLenFilter 1 -#define _BITPOS_bleScannerPar_scanConfig_bAutoWlIgnore 5 -#define _NBITS_bleScannerPar_scanConfig_bAutoWlIgnore 1 -#define _BITPOS_bleScannerPar_scanConfig_bEndOnRpt 6 -#define _NBITS_bleScannerPar_scanConfig_bEndOnRpt 1 -#define _POSITION_bleScannerPar_randomState 6 -#define _TYPE_bleScannerPar_randomState uint16_t -#define _POSITION_bleScannerPar_backoffCount 8 -#define _TYPE_bleScannerPar_backoffCount uint16_t -#define _POSITION_bleScannerPar_backoffPar 10 -#define _TYPE_bleScannerPar_backoffPar uint8_t -#define _BITPOS_bleScannerPar_backoffPar_logUpperLimit 0 -#define _NBITS_bleScannerPar_backoffPar_logUpperLimit 4 -#define _BITPOS_bleScannerPar_backoffPar_bLastSucceeded 4 -#define _NBITS_bleScannerPar_backoffPar_bLastSucceeded 1 -#define _BITPOS_bleScannerPar_backoffPar_bLastFailed 5 -#define _NBITS_bleScannerPar_backoffPar_bLastFailed 1 -#define _POSITION_bleScannerPar_scanReqLen 11 -#define _TYPE_bleScannerPar_scanReqLen uint8_t -#define _POSITION_bleScannerPar_pScanReqData 12 -#define _TYPE_bleScannerPar_pScanReqData uint8_t* -#define _POSITION_bleScannerPar_pDeviceAddress 16 -#define _TYPE_bleScannerPar_pDeviceAddress uint16_t* -#define _POSITION_bleScannerPar_pWhiteList 20 -#define _TYPE_bleScannerPar_pWhiteList uint32_t* -#define _POSITION_bleScannerPar_timeoutTrigger 26 -#define _TYPE_bleScannerPar_timeoutTrigger uint8_t -#define _BITPOS_bleScannerPar_timeoutTrigger_triggerType 0 -#define _NBITS_bleScannerPar_timeoutTrigger_triggerType 4 -#define _BITPOS_bleScannerPar_timeoutTrigger_bEnaCmd 4 -#define _NBITS_bleScannerPar_timeoutTrigger_bEnaCmd 1 -#define _BITPOS_bleScannerPar_timeoutTrigger_triggerNo 5 -#define _NBITS_bleScannerPar_timeoutTrigger_triggerNo 2 -#define _BITPOS_bleScannerPar_timeoutTrigger_pastTrig 7 -#define _NBITS_bleScannerPar_timeoutTrigger_pastTrig 1 -#define _POSITION_bleScannerPar_endTrigger 27 -#define _TYPE_bleScannerPar_endTrigger uint8_t -#define _BITPOS_bleScannerPar_endTrigger_triggerType 0 -#define _NBITS_bleScannerPar_endTrigger_triggerType 4 -#define _BITPOS_bleScannerPar_endTrigger_bEnaCmd 4 -#define _NBITS_bleScannerPar_endTrigger_bEnaCmd 1 -#define _BITPOS_bleScannerPar_endTrigger_triggerNo 5 -#define _NBITS_bleScannerPar_endTrigger_triggerNo 2 -#define _BITPOS_bleScannerPar_endTrigger_pastTrig 7 -#define _NBITS_bleScannerPar_endTrigger_pastTrig 1 -#define _POSITION_bleScannerPar_timeoutTime 28 -#define _TYPE_bleScannerPar_timeoutTime ratmr_t -#define _POSITION_bleScannerPar_endTime 32 -#define _TYPE_bleScannerPar_endTime ratmr_t -#define _SIZEOF_bleScannerPar 36 - -#define _POSITION_bleInitiatorPar_pRxQ 0 -#define _TYPE_bleInitiatorPar_pRxQ dataQueue_t* -#define _POSITION_bleInitiatorPar_rxConfig 4 -#define _TYPE_bleInitiatorPar_rxConfig uint8_t -#define _BITPOS_bleInitiatorPar_rxConfig_bAutoFlushIgnored 0 -#define _NBITS_bleInitiatorPar_rxConfig_bAutoFlushIgnored 1 -#define _BITPOS_bleInitiatorPar_rxConfig_bAutoFlushCrcErr 1 -#define _NBITS_bleInitiatorPar_rxConfig_bAutoFlushCrcErr 1 -#define _BITPOS_bleInitiatorPar_rxConfig_bAutoFlushEmpty 2 -#define _NBITS_bleInitiatorPar_rxConfig_bAutoFlushEmpty 1 -#define _BITPOS_bleInitiatorPar_rxConfig_bIncludeLenByte 3 -#define _NBITS_bleInitiatorPar_rxConfig_bIncludeLenByte 1 -#define _BITPOS_bleInitiatorPar_rxConfig_bIncludeCrc 4 -#define _NBITS_bleInitiatorPar_rxConfig_bIncludeCrc 1 -#define _BITPOS_bleInitiatorPar_rxConfig_bAppendRssi 5 -#define _NBITS_bleInitiatorPar_rxConfig_bAppendRssi 1 -#define _BITPOS_bleInitiatorPar_rxConfig_bAppendStatus 6 -#define _NBITS_bleInitiatorPar_rxConfig_bAppendStatus 1 -#define _BITPOS_bleInitiatorPar_rxConfig_bAppendTimestamp 7 -#define _NBITS_bleInitiatorPar_rxConfig_bAppendTimestamp 1 -#define _POSITION_bleInitiatorPar_initConfig 5 -#define _TYPE_bleInitiatorPar_initConfig uint8_t -#define _BITPOS_bleInitiatorPar_initConfig_bUseWhiteList 0 -#define _NBITS_bleInitiatorPar_initConfig_bUseWhiteList 1 -#define _BITPOS_bleInitiatorPar_initConfig_bDynamicWinOffset 1 -#define _NBITS_bleInitiatorPar_initConfig_bDynamicWinOffset 1 -#define _BITPOS_bleInitiatorPar_initConfig_deviceAddrType 2 -#define _NBITS_bleInitiatorPar_initConfig_deviceAddrType 1 -#define _BITPOS_bleInitiatorPar_initConfig_peerAddrType 3 -#define _NBITS_bleInitiatorPar_initConfig_peerAddrType 1 -#define _BITPOS_bleInitiatorPar_initConfig_bStrictLenFilter 4 -#define _NBITS_bleInitiatorPar_initConfig_bStrictLenFilter 1 -#define _POSITION_bleInitiatorPar_connectReqLen 7 -#define _TYPE_bleInitiatorPar_connectReqLen uint8_t -#define _POSITION_bleInitiatorPar_pConnectReqData 8 -#define _TYPE_bleInitiatorPar_pConnectReqData uint8_t* -#define _POSITION_bleInitiatorPar_pDeviceAddress 12 -#define _TYPE_bleInitiatorPar_pDeviceAddress uint16_t* -#define _POSITION_bleInitiatorPar_pWhiteList 16 -#define _TYPE_bleInitiatorPar_pWhiteList uint32_t* -#define _POSITION_bleInitiatorPar_connectTime 20 -#define _TYPE_bleInitiatorPar_connectTime ratmr_t -#define _POSITION_bleInitiatorPar_timeoutTrigger 26 -#define _TYPE_bleInitiatorPar_timeoutTrigger uint8_t -#define _BITPOS_bleInitiatorPar_timeoutTrigger_triggerType 0 -#define _NBITS_bleInitiatorPar_timeoutTrigger_triggerType 4 -#define _BITPOS_bleInitiatorPar_timeoutTrigger_bEnaCmd 4 -#define _NBITS_bleInitiatorPar_timeoutTrigger_bEnaCmd 1 -#define _BITPOS_bleInitiatorPar_timeoutTrigger_triggerNo 5 -#define _NBITS_bleInitiatorPar_timeoutTrigger_triggerNo 2 -#define _BITPOS_bleInitiatorPar_timeoutTrigger_pastTrig 7 -#define _NBITS_bleInitiatorPar_timeoutTrigger_pastTrig 1 -#define _POSITION_bleInitiatorPar_endTrigger 27 -#define _TYPE_bleInitiatorPar_endTrigger uint8_t -#define _BITPOS_bleInitiatorPar_endTrigger_triggerType 0 -#define _NBITS_bleInitiatorPar_endTrigger_triggerType 4 -#define _BITPOS_bleInitiatorPar_endTrigger_bEnaCmd 4 -#define _NBITS_bleInitiatorPar_endTrigger_bEnaCmd 1 -#define _BITPOS_bleInitiatorPar_endTrigger_triggerNo 5 -#define _NBITS_bleInitiatorPar_endTrigger_triggerNo 2 -#define _BITPOS_bleInitiatorPar_endTrigger_pastTrig 7 -#define _NBITS_bleInitiatorPar_endTrigger_pastTrig 1 -#define _POSITION_bleInitiatorPar_timeoutTime 28 -#define _TYPE_bleInitiatorPar_timeoutTime ratmr_t -#define _POSITION_bleInitiatorPar_endTime 32 -#define _TYPE_bleInitiatorPar_endTime ratmr_t -#define _SIZEOF_bleInitiatorPar 36 - -#define _POSITION_bleGenericRxPar_pRxQ 0 -#define _TYPE_bleGenericRxPar_pRxQ dataQueue_t* -#define _POSITION_bleGenericRxPar_rxConfig 4 -#define _TYPE_bleGenericRxPar_rxConfig uint8_t -#define _BITPOS_bleGenericRxPar_rxConfig_bAutoFlushIgnored 0 -#define _NBITS_bleGenericRxPar_rxConfig_bAutoFlushIgnored 1 -#define _BITPOS_bleGenericRxPar_rxConfig_bAutoFlushCrcErr 1 -#define _NBITS_bleGenericRxPar_rxConfig_bAutoFlushCrcErr 1 -#define _BITPOS_bleGenericRxPar_rxConfig_bAutoFlushEmpty 2 -#define _NBITS_bleGenericRxPar_rxConfig_bAutoFlushEmpty 1 -#define _BITPOS_bleGenericRxPar_rxConfig_bIncludeLenByte 3 -#define _NBITS_bleGenericRxPar_rxConfig_bIncludeLenByte 1 -#define _BITPOS_bleGenericRxPar_rxConfig_bIncludeCrc 4 -#define _NBITS_bleGenericRxPar_rxConfig_bIncludeCrc 1 -#define _BITPOS_bleGenericRxPar_rxConfig_bAppendRssi 5 -#define _NBITS_bleGenericRxPar_rxConfig_bAppendRssi 1 -#define _BITPOS_bleGenericRxPar_rxConfig_bAppendStatus 6 -#define _NBITS_bleGenericRxPar_rxConfig_bAppendStatus 1 -#define _BITPOS_bleGenericRxPar_rxConfig_bAppendTimestamp 7 -#define _NBITS_bleGenericRxPar_rxConfig_bAppendTimestamp 1 -#define _POSITION_bleGenericRxPar_bRepeat 5 -#define _TYPE_bleGenericRxPar_bRepeat uint8_t -#define _POSITION_bleGenericRxPar_accessAddress 8 -#define _TYPE_bleGenericRxPar_accessAddress uint32_t -#define _POSITION_bleGenericRxPar_crcInit0 12 -#define _TYPE_bleGenericRxPar_crcInit0 uint8_t -#define _POSITION_bleGenericRxPar_crcInit1 13 -#define _TYPE_bleGenericRxPar_crcInit1 uint8_t -#define _POSITION_bleGenericRxPar_crcInit2 14 -#define _TYPE_bleGenericRxPar_crcInit2 uint8_t -#define _POSITION_bleGenericRxPar_crcInit 12 -#define _TYPE_bleGenericRxPar_crcInit uint32_t -#define _POSITION_bleGenericRxPar_endTrigger 15 -#define _TYPE_bleGenericRxPar_endTrigger uint8_t -#define _BITPOS_bleGenericRxPar_endTrigger_triggerType 0 -#define _NBITS_bleGenericRxPar_endTrigger_triggerType 4 -#define _BITPOS_bleGenericRxPar_endTrigger_bEnaCmd 4 -#define _NBITS_bleGenericRxPar_endTrigger_bEnaCmd 1 -#define _BITPOS_bleGenericRxPar_endTrigger_triggerNo 5 -#define _NBITS_bleGenericRxPar_endTrigger_triggerNo 2 -#define _BITPOS_bleGenericRxPar_endTrigger_pastTrig 7 -#define _NBITS_bleGenericRxPar_endTrigger_pastTrig 1 -#define _POSITION_bleGenericRxPar_endTime 16 -#define _TYPE_bleGenericRxPar_endTime ratmr_t -#define _SIZEOF_bleGenericRxPar 20 - -#define _POSITION_bleTxTestPar_numPackets 0 -#define _TYPE_bleTxTestPar_numPackets uint16_t -#define _POSITION_bleTxTestPar_payloadLength 2 -#define _TYPE_bleTxTestPar_payloadLength uint8_t -#define _POSITION_bleTxTestPar_packetType 3 -#define _TYPE_bleTxTestPar_packetType uint8_t -#define _POSITION_bleTxTestPar_period 4 -#define _TYPE_bleTxTestPar_period ratmr_t -#define _POSITION_bleTxTestPar_config 8 -#define _TYPE_bleTxTestPar_config uint8_t -#define _BITPOS_bleTxTestPar_config_bOverrideDefault 0 -#define _NBITS_bleTxTestPar_config_bOverrideDefault 1 -#define _BITPOS_bleTxTestPar_config_bUsePrbs9 1 -#define _NBITS_bleTxTestPar_config_bUsePrbs9 1 -#define _BITPOS_bleTxTestPar_config_bUsePrbs15 2 -#define _NBITS_bleTxTestPar_config_bUsePrbs15 1 -#define _POSITION_bleTxTestPar_byteVal 9 -#define _TYPE_bleTxTestPar_byteVal uint8_t -#define _POSITION_bleTxTestPar_endTrigger 11 -#define _TYPE_bleTxTestPar_endTrigger uint8_t -#define _BITPOS_bleTxTestPar_endTrigger_triggerType 0 -#define _NBITS_bleTxTestPar_endTrigger_triggerType 4 -#define _BITPOS_bleTxTestPar_endTrigger_bEnaCmd 4 -#define _NBITS_bleTxTestPar_endTrigger_bEnaCmd 1 -#define _BITPOS_bleTxTestPar_endTrigger_triggerNo 5 -#define _NBITS_bleTxTestPar_endTrigger_triggerNo 2 -#define _BITPOS_bleTxTestPar_endTrigger_pastTrig 7 -#define _NBITS_bleTxTestPar_endTrigger_pastTrig 1 -#define _POSITION_bleTxTestPar_endTime 12 -#define _TYPE_bleTxTestPar_endTime ratmr_t -#define _SIZEOF_bleTxTestPar 16 - -#define _POSITION_bleMasterSlaveOutput_nTx 0 -#define _TYPE_bleMasterSlaveOutput_nTx uint8_t -#define _POSITION_bleMasterSlaveOutput_nTxAck 1 -#define _TYPE_bleMasterSlaveOutput_nTxAck uint8_t -#define _POSITION_bleMasterSlaveOutput_nTxCtrl 2 -#define _TYPE_bleMasterSlaveOutput_nTxCtrl uint8_t -#define _POSITION_bleMasterSlaveOutput_nTxCtrlAck 3 -#define _TYPE_bleMasterSlaveOutput_nTxCtrlAck uint8_t -#define _POSITION_bleMasterSlaveOutput_nTxCtrlAckAck 4 -#define _TYPE_bleMasterSlaveOutput_nTxCtrlAckAck uint8_t -#define _POSITION_bleMasterSlaveOutput_nTxRetrans 5 -#define _TYPE_bleMasterSlaveOutput_nTxRetrans uint8_t -#define _POSITION_bleMasterSlaveOutput_nTxEntryDone 6 -#define _TYPE_bleMasterSlaveOutput_nTxEntryDone uint8_t -#define _POSITION_bleMasterSlaveOutput_nRxOk 7 -#define _TYPE_bleMasterSlaveOutput_nRxOk uint8_t -#define _POSITION_bleMasterSlaveOutput_nRxCtrl 8 -#define _TYPE_bleMasterSlaveOutput_nRxCtrl uint8_t -#define _POSITION_bleMasterSlaveOutput_nRxCtrlAck 9 -#define _TYPE_bleMasterSlaveOutput_nRxCtrlAck uint8_t -#define _POSITION_bleMasterSlaveOutput_nRxNok 10 -#define _TYPE_bleMasterSlaveOutput_nRxNok uint8_t -#define _POSITION_bleMasterSlaveOutput_nRxIgnored 11 -#define _TYPE_bleMasterSlaveOutput_nRxIgnored uint8_t -#define _POSITION_bleMasterSlaveOutput_nRxEmpty 12 -#define _TYPE_bleMasterSlaveOutput_nRxEmpty uint8_t -#define _POSITION_bleMasterSlaveOutput_nRxBufFull 13 -#define _TYPE_bleMasterSlaveOutput_nRxBufFull uint8_t -#define _POSITION_bleMasterSlaveOutput_lastRssi 14 -#define _TYPE_bleMasterSlaveOutput_lastRssi int8_t -#define _POSITION_bleMasterSlaveOutput_pktStatus 15 -#define _TYPE_bleMasterSlaveOutput_pktStatus uint8_t -#define _BITPOS_bleMasterSlaveOutput_pktStatus_bTimeStampValid 0 -#define _NBITS_bleMasterSlaveOutput_pktStatus_bTimeStampValid 1 -#define _BITPOS_bleMasterSlaveOutput_pktStatus_bLastCrcErr 1 -#define _NBITS_bleMasterSlaveOutput_pktStatus_bLastCrcErr 1 -#define _BITPOS_bleMasterSlaveOutput_pktStatus_bLastIgnored 2 -#define _NBITS_bleMasterSlaveOutput_pktStatus_bLastIgnored 1 -#define _BITPOS_bleMasterSlaveOutput_pktStatus_bLastEmpty 3 -#define _NBITS_bleMasterSlaveOutput_pktStatus_bLastEmpty 1 -#define _BITPOS_bleMasterSlaveOutput_pktStatus_bLastCtrl 4 -#define _NBITS_bleMasterSlaveOutput_pktStatus_bLastCtrl 1 -#define _BITPOS_bleMasterSlaveOutput_pktStatus_bLastMd 5 -#define _NBITS_bleMasterSlaveOutput_pktStatus_bLastMd 1 -#define _BITPOS_bleMasterSlaveOutput_pktStatus_bLastAck 6 -#define _NBITS_bleMasterSlaveOutput_pktStatus_bLastAck 1 -#define _POSITION_bleMasterSlaveOutput_timeStamp 16 -#define _TYPE_bleMasterSlaveOutput_timeStamp ratmr_t -#define _SIZEOF_bleMasterSlaveOutput 20 - -#define _POSITION_bleAdvOutput_nTxAdvInd 0 -#define _TYPE_bleAdvOutput_nTxAdvInd uint16_t -#define _POSITION_bleAdvOutput_nTxScanRsp 2 -#define _TYPE_bleAdvOutput_nTxScanRsp uint8_t -#define _POSITION_bleAdvOutput_nRxScanReq 3 -#define _TYPE_bleAdvOutput_nRxScanReq uint8_t -#define _POSITION_bleAdvOutput_nRxConnectReq 4 -#define _TYPE_bleAdvOutput_nRxConnectReq uint8_t -#define _POSITION_bleAdvOutput_nRxNok 6 -#define _TYPE_bleAdvOutput_nRxNok uint16_t -#define _POSITION_bleAdvOutput_nRxIgnored 8 -#define _TYPE_bleAdvOutput_nRxIgnored uint16_t -#define _POSITION_bleAdvOutput_nRxBufFull 10 -#define _TYPE_bleAdvOutput_nRxBufFull uint8_t -#define _POSITION_bleAdvOutput_lastRssi 11 -#define _TYPE_bleAdvOutput_lastRssi int8_t -#define _POSITION_bleAdvOutput_timeStamp 12 -#define _TYPE_bleAdvOutput_timeStamp ratmr_t -#define _SIZEOF_bleAdvOutput 16 - -#define _POSITION_bleScannerOutput_nTxScanReq 0 -#define _TYPE_bleScannerOutput_nTxScanReq uint16_t -#define _POSITION_bleScannerOutput_nBackedOffScanReq 2 -#define _TYPE_bleScannerOutput_nBackedOffScanReq uint16_t -#define _POSITION_bleScannerOutput_nRxAdvOk 4 -#define _TYPE_bleScannerOutput_nRxAdvOk uint16_t -#define _POSITION_bleScannerOutput_nRxAdvIgnored 6 -#define _TYPE_bleScannerOutput_nRxAdvIgnored uint16_t -#define _POSITION_bleScannerOutput_nRxAdvNok 8 -#define _TYPE_bleScannerOutput_nRxAdvNok uint16_t -#define _POSITION_bleScannerOutput_nRxScanRspOk 10 -#define _TYPE_bleScannerOutput_nRxScanRspOk uint16_t -#define _POSITION_bleScannerOutput_nRxScanRspIgnored 12 -#define _TYPE_bleScannerOutput_nRxScanRspIgnored uint16_t -#define _POSITION_bleScannerOutput_nRxScanRspNok 14 -#define _TYPE_bleScannerOutput_nRxScanRspNok uint16_t -#define _POSITION_bleScannerOutput_nRxAdvBufFull 16 -#define _TYPE_bleScannerOutput_nRxAdvBufFull uint8_t -#define _POSITION_bleScannerOutput_nRxScanRspBufFull 17 -#define _TYPE_bleScannerOutput_nRxScanRspBufFull uint8_t -#define _POSITION_bleScannerOutput_lastRssi 18 -#define _TYPE_bleScannerOutput_lastRssi int8_t -#define _POSITION_bleScannerOutput_timeStamp 20 -#define _TYPE_bleScannerOutput_timeStamp ratmr_t -#define _SIZEOF_bleScannerOutput 24 - -#define _POSITION_bleInitiatorOutput_nTxConnectReq 0 -#define _TYPE_bleInitiatorOutput_nTxConnectReq uint8_t -#define _POSITION_bleInitiatorOutput_nRxAdvOk 1 -#define _TYPE_bleInitiatorOutput_nRxAdvOk uint8_t -#define _POSITION_bleInitiatorOutput_nRxAdvIgnored 2 -#define _TYPE_bleInitiatorOutput_nRxAdvIgnored uint16_t -#define _POSITION_bleInitiatorOutput_nRxAdvNok 4 -#define _TYPE_bleInitiatorOutput_nRxAdvNok uint16_t -#define _POSITION_bleInitiatorOutput_nRxAdvBufFull 6 -#define _TYPE_bleInitiatorOutput_nRxAdvBufFull uint8_t -#define _POSITION_bleInitiatorOutput_lastRssi 7 -#define _TYPE_bleInitiatorOutput_lastRssi int8_t -#define _POSITION_bleInitiatorOutput_timeStamp 8 -#define _TYPE_bleInitiatorOutput_timeStamp ratmr_t -#define _SIZEOF_bleInitiatorOutput 12 - -#define _POSITION_bleGenericRxOutput_nRxOk 0 -#define _TYPE_bleGenericRxOutput_nRxOk uint16_t -#define _POSITION_bleGenericRxOutput_nRxNok 2 -#define _TYPE_bleGenericRxOutput_nRxNok uint16_t -#define _POSITION_bleGenericRxOutput_nRxBufFull 4 -#define _TYPE_bleGenericRxOutput_nRxBufFull uint16_t -#define _POSITION_bleGenericRxOutput_lastRssi 6 -#define _TYPE_bleGenericRxOutput_lastRssi int8_t -#define _POSITION_bleGenericRxOutput_timeStamp 8 -#define _TYPE_bleGenericRxOutput_timeStamp ratmr_t -#define _SIZEOF_bleGenericRxOutput 12 - -#define _POSITION_bleTxTestOutput_nTx 0 -#define _TYPE_bleTxTestOutput_nTx uint16_t -#define _SIZEOF_bleTxTestOutput 2 - -#define _POSITION_bleWhiteListEntry_size 0 -#define _TYPE_bleWhiteListEntry_size uint8_t -#define _POSITION_bleWhiteListEntry_conf 1 -#define _TYPE_bleWhiteListEntry_conf uint8_t -#define _BITPOS_bleWhiteListEntry_conf_bEnable 0 -#define _NBITS_bleWhiteListEntry_conf_bEnable 1 -#define _BITPOS_bleWhiteListEntry_conf_addrType 1 -#define _NBITS_bleWhiteListEntry_conf_addrType 1 -#define _BITPOS_bleWhiteListEntry_conf_bWlIgn 2 -#define _NBITS_bleWhiteListEntry_conf_bWlIgn 1 -#define _POSITION_bleWhiteListEntry_address 2 -#define _TYPE_bleWhiteListEntry_address uint16_t -#define _POSITION_bleWhiteListEntry_addressHi 4 -#define _TYPE_bleWhiteListEntry_addressHi uint32_t -#define _SIZEOF_bleWhiteListEntry 8 - -#define _POSITION_bleRxStatus_status 0 -#define _TYPE_bleRxStatus_status uint8_t -#define _BITPOS_bleRxStatus_status_channel 0 -#define _NBITS_bleRxStatus_status_channel 6 -#define _BITPOS_bleRxStatus_status_bIgnore 6 -#define _NBITS_bleRxStatus_status_bIgnore 1 -#define _BITPOS_bleRxStatus_status_bCrcErr 7 -#define _NBITS_bleRxStatus_status_bCrcErr 1 -#define _SIZEOF_bleRxStatus 1 - -#endif diff --git a/cpu/cc26xx/dev/rfc-api/common_cmd_field.h b/cpu/cc26xx/dev/rfc-api/common_cmd_field.h deleted file mode 100755 index d9e9431f6..000000000 --- a/cpu/cc26xx/dev/rfc-api/common_cmd_field.h +++ /dev/null @@ -1,448 +0,0 @@ -/****************************************************************************** -* Filename: common_cmd_field.h -* Revised: $ $ -* Revision: $ $ -* -* Description: CC26xx API for common/generic commands -* -* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -******************************************************************************/ - -#ifndef __COMMON_CMD_FIELD_H -#define __COMMON_CMD_FIELD_H - -#include -#include "mailbox.h" - -#define _POSITION_command_commandNo 0 -#define _TYPE_command_commandNo uint16_t -#define _SIZEOF_command 2 - -#define _POSITION_radioOp_commandNo 0 -#define _TYPE_radioOp_commandNo uint16_t -#define _POSITION_radioOp_status 2 -#define _TYPE_radioOp_status uint16_t -#define _POSITION_radioOp_pNextOp 4 -#define _TYPE_radioOp_pNextOp uint8_t* -#define _POSITION_radioOp_startTime 8 -#define _TYPE_radioOp_startTime ratmr_t -#define _POSITION_radioOp_startTrigger 12 -#define _TYPE_radioOp_startTrigger uint8_t -#define _BITPOS_radioOp_startTrigger_triggerType 0 -#define _NBITS_radioOp_startTrigger_triggerType 4 -#define _BITPOS_radioOp_startTrigger_bEnaCmd 4 -#define _NBITS_radioOp_startTrigger_bEnaCmd 1 -#define _BITPOS_radioOp_startTrigger_triggerNo 5 -#define _NBITS_radioOp_startTrigger_triggerNo 2 -#define _BITPOS_radioOp_startTrigger_pastTrig 7 -#define _NBITS_radioOp_startTrigger_pastTrig 1 -#define _POSITION_radioOp_condition 13 -#define _TYPE_radioOp_condition uint8_t -#define _BITPOS_radioOp_condition_rule 0 -#define _NBITS_radioOp_condition_rule 4 -#define _BITPOS_radioOp_condition_nSkip 4 -#define _NBITS_radioOp_condition_nSkip 4 -#define _SIZEOF_radioOp 14 - -#define _SIZEOF_CMD_NOP 14 - -#define _POSITION_CMD_RADIO_SETUP_mode 14 -#define _TYPE_CMD_RADIO_SETUP_mode uint8_t -#define _POSITION_CMD_RADIO_SETUP_config 16 -#define _TYPE_CMD_RADIO_SETUP_config uint16_t -#define _BITPOS_CMD_RADIO_SETUP_config_frontEndMode 0 -#define _NBITS_CMD_RADIO_SETUP_config_frontEndMode 3 -#define _BITPOS_CMD_RADIO_SETUP_config_biasMode 3 -#define _NBITS_CMD_RADIO_SETUP_config_biasMode 1 -#define _BITPOS_CMD_RADIO_SETUP_config_bNoAdi0Setup 4 -#define _NBITS_CMD_RADIO_SETUP_config_bNoAdi0Setup 1 -#define _BITPOS_CMD_RADIO_SETUP_config_bNoAdi0Trim 5 -#define _NBITS_CMD_RADIO_SETUP_config_bNoAdi0Trim 1 -#define _BITPOS_CMD_RADIO_SETUP_config_bNoAdi0Ovr 6 -#define _NBITS_CMD_RADIO_SETUP_config_bNoAdi0Ovr 1 -#define _BITPOS_CMD_RADIO_SETUP_config_bNoAdi1Setup 7 -#define _NBITS_CMD_RADIO_SETUP_config_bNoAdi1Setup 1 -#define _BITPOS_CMD_RADIO_SETUP_config_bNoAdi1Trim 8 -#define _NBITS_CMD_RADIO_SETUP_config_bNoAdi1Trim 1 -#define _BITPOS_CMD_RADIO_SETUP_config_bNoAdi1Ovr 9 -#define _NBITS_CMD_RADIO_SETUP_config_bNoAdi1Ovr 1 -#define _BITPOS_CMD_RADIO_SETUP_config_bNoFsPowerUp 10 -#define _NBITS_CMD_RADIO_SETUP_config_bNoFsPowerUp 1 -#define _POSITION_CMD_RADIO_SETUP_txPower 18 -#define _TYPE_CMD_RADIO_SETUP_txPower uint16_t -#define _BITPOS_CMD_RADIO_SETUP_txPower_IB 0 -#define _NBITS_CMD_RADIO_SETUP_txPower_IB 6 -#define _BITPOS_CMD_RADIO_SETUP_txPower_GC 6 -#define _NBITS_CMD_RADIO_SETUP_txPower_GC 2 -#define _BITPOS_CMD_RADIO_SETUP_txPower_tempCoeff 8 -#define _NBITS_CMD_RADIO_SETUP_txPower_tempCoeff 8 -#define _POSITION_CMD_RADIO_SETUP_pRegOverride 20 -#define _TYPE_CMD_RADIO_SETUP_pRegOverride uint32_t* -#define _SIZEOF_CMD_RADIO_SETUP 24 - -#define _POSITION_CMD_FS_frequency 14 -#define _TYPE_CMD_FS_frequency uint16_t -#define _POSITION_CMD_FS_fractFreq 16 -#define _TYPE_CMD_FS_fractFreq uint16_t -#define _POSITION_CMD_FS_synthConf 18 -#define _TYPE_CMD_FS_synthConf uint8_t -#define _BITPOS_CMD_FS_synthConf_bTxMode 0 -#define _NBITS_CMD_FS_synthConf_bTxMode 1 -#define _BITPOS_CMD_FS_synthConf_refFreq 1 -#define _NBITS_CMD_FS_synthConf_refFreq 6 -#define _POSITION_CMD_FS_calibConf 19 -#define _TYPE_CMD_FS_calibConf uint8_t -#define _BITPOS_CMD_FS_calibConf_bOverrideCalib 0 -#define _NBITS_CMD_FS_calibConf_bOverrideCalib 1 -#define _BITPOS_CMD_FS_calibConf_bSkipTdcCalib 1 -#define _NBITS_CMD_FS_calibConf_bSkipTdcCalib 1 -#define _BITPOS_CMD_FS_calibConf_bSkipCoarseCalib 2 -#define _NBITS_CMD_FS_calibConf_bSkipCoarseCalib 1 -#define _BITPOS_CMD_FS_calibConf_bSkipMidCalib 3 -#define _NBITS_CMD_FS_calibConf_bSkipMidCalib 1 -#define _BITPOS_CMD_FS_calibConf_coarsePrecal 4 -#define _NBITS_CMD_FS_calibConf_coarsePrecal 4 -#define _POSITION_CMD_FS_midPrecal 20 -#define _TYPE_CMD_FS_midPrecal uint8_t -#define _POSITION_CMD_FS_ktPrecal 21 -#define _TYPE_CMD_FS_ktPrecal uint8_t -#define _POSITION_CMD_FS_tdcPrecal 22 -#define _TYPE_CMD_FS_tdcPrecal uint16_t -#define _SIZEOF_CMD_FS 24 - -#define _SIZEOF_CMD_FS_OFF 14 - -#define _POSITION_CMD_RX_pktConfig 14 -#define _TYPE_CMD_RX_pktConfig uint16_t -#define _BITPOS_CMD_RX_pktConfig_endianness 0 -#define _NBITS_CMD_RX_pktConfig_endianness 1 -#define _BITPOS_CMD_RX_pktConfig_numHdrBits 1 -#define _NBITS_CMD_RX_pktConfig_numHdrBits 6 -#define _BITPOS_CMD_RX_pktConfig_bFsOff 7 -#define _NBITS_CMD_RX_pktConfig_bFsOff 1 -#define _BITPOS_CMD_RX_pktConfig_bUseCrc 8 -#define _NBITS_CMD_RX_pktConfig_bUseCrc 1 -#define _BITPOS_CMD_RX_pktConfig_bCrcIncSw 9 -#define _NBITS_CMD_RX_pktConfig_bCrcIncSw 1 -#define _BITPOS_CMD_RX_pktConfig_bCrcIncHdr 10 -#define _NBITS_CMD_RX_pktConfig_bCrcIncHdr 1 -#define _BITPOS_CMD_RX_pktConfig_bReportCrc 11 -#define _NBITS_CMD_RX_pktConfig_bReportCrc 1 -#define _BITPOS_CMD_RX_pktConfig_endType 12 -#define _NBITS_CMD_RX_pktConfig_endType 1 -#define _BITPOS_CMD_RX_pktConfig_bDualSw 13 -#define _NBITS_CMD_RX_pktConfig_bDualSw 1 -#define _POSITION_CMD_RX_syncWord 16 -#define _TYPE_CMD_RX_syncWord uint32_t -#define _POSITION_CMD_RX_syncWord2 20 -#define _TYPE_CMD_RX_syncWord2 uint32_t -#define _POSITION_CMD_RX_lenConfig 24 -#define _TYPE_CMD_RX_lenConfig uint16_t -#define _BITPOS_CMD_RX_lenConfig_numLenBits 0 -#define _NBITS_CMD_RX_lenConfig_numLenBits 4 -#define _BITPOS_CMD_RX_lenConfig_lenFieldPos 4 -#define _NBITS_CMD_RX_lenConfig_lenFieldPos 5 -#define _BITPOS_CMD_RX_lenConfig_lenOffset 9 -#define _NBITS_CMD_RX_lenConfig_lenOffset 7 -#define _POSITION_CMD_RX_maxLen 26 -#define _TYPE_CMD_RX_maxLen uint16_t -#define _POSITION_CMD_RX_pRecPkt 28 -#define _TYPE_CMD_RX_pRecPkt uint8_t* -#define _POSITION_CMD_RX_endTime 32 -#define _TYPE_CMD_RX_endTime ratmr_t -#define _POSITION_CMD_RX_endTrigger 36 -#define _TYPE_CMD_RX_endTrigger uint8_t -#define _BITPOS_CMD_RX_endTrigger_triggerType 0 -#define _NBITS_CMD_RX_endTrigger_triggerType 4 -#define _BITPOS_CMD_RX_endTrigger_bEnaCmd 4 -#define _NBITS_CMD_RX_endTrigger_bEnaCmd 1 -#define _BITPOS_CMD_RX_endTrigger_triggerNo 5 -#define _NBITS_CMD_RX_endTrigger_triggerNo 2 -#define _BITPOS_CMD_RX_endTrigger_pastTrig 7 -#define _NBITS_CMD_RX_endTrigger_pastTrig 1 -#define _POSITION_CMD_RX_rssi 37 -#define _TYPE_CMD_RX_rssi int8_t -#define _POSITION_CMD_RX_recLen 38 -#define _TYPE_CMD_RX_recLen uint16_t -#define _POSITION_CMD_RX_timeStamp 40 -#define _TYPE_CMD_RX_timeStamp ratmr_t -#define _POSITION_CMD_RX_nRxOk 44 -#define _TYPE_CMD_RX_nRxOk uint16_t -#define _POSITION_CMD_RX_nRxNok 46 -#define _TYPE_CMD_RX_nRxNok uint16_t -#define _POSITION_CMD_RX_nRx2Ok 48 -#define _TYPE_CMD_RX_nRx2Ok uint16_t -#define _POSITION_CMD_RX_nRx2Nok 50 -#define _TYPE_CMD_RX_nRx2Nok uint16_t -#define _SIZEOF_CMD_RX 52 - -#define _POSITION_CMD_TX_pktConfig 14 -#define _TYPE_CMD_TX_pktConfig uint16_t -#define _BITPOS_CMD_TX_pktConfig_endianness 0 -#define _NBITS_CMD_TX_pktConfig_endianness 1 -#define _BITPOS_CMD_TX_pktConfig_numHdrBits 1 -#define _NBITS_CMD_TX_pktConfig_numHdrBits 6 -#define _BITPOS_CMD_TX_pktConfig_bFsOff 7 -#define _NBITS_CMD_TX_pktConfig_bFsOff 1 -#define _BITPOS_CMD_TX_pktConfig_bUseCrc 8 -#define _NBITS_CMD_TX_pktConfig_bUseCrc 1 -#define _BITPOS_CMD_TX_pktConfig_bCrcIncSw 9 -#define _NBITS_CMD_TX_pktConfig_bCrcIncSw 1 -#define _BITPOS_CMD_TX_pktConfig_bCrcIncHdr 10 -#define _NBITS_CMD_TX_pktConfig_bCrcIncHdr 1 -#define _POSITION_CMD_TX_syncWord 16 -#define _TYPE_CMD_TX_syncWord uint32_t -#define _POSITION_CMD_TX_pTxPkt 20 -#define _TYPE_CMD_TX_pTxPkt uint8_t* -#define _POSITION_CMD_TX_pktLen 24 -#define _TYPE_CMD_TX_pktLen uint16_t -#define _SIZEOF_CMD_TX 26 - -#define _POSITION_CMD_RX_TEST_config 14 -#define _TYPE_CMD_RX_TEST_config uint8_t -#define _BITPOS_CMD_RX_TEST_config_bEnaFifo 0 -#define _NBITS_CMD_RX_TEST_config_bEnaFifo 1 -#define _BITPOS_CMD_RX_TEST_config_bFsOff 1 -#define _NBITS_CMD_RX_TEST_config_bFsOff 1 -#define _BITPOS_CMD_RX_TEST_config_bNoSync 2 -#define _NBITS_CMD_RX_TEST_config_bNoSync 1 -#define _POSITION_CMD_RX_TEST_endTrigger 15 -#define _TYPE_CMD_RX_TEST_endTrigger uint8_t -#define _BITPOS_CMD_RX_TEST_endTrigger_triggerType 0 -#define _NBITS_CMD_RX_TEST_endTrigger_triggerType 4 -#define _BITPOS_CMD_RX_TEST_endTrigger_bEnaCmd 4 -#define _NBITS_CMD_RX_TEST_endTrigger_bEnaCmd 1 -#define _BITPOS_CMD_RX_TEST_endTrigger_triggerNo 5 -#define _NBITS_CMD_RX_TEST_endTrigger_triggerNo 2 -#define _BITPOS_CMD_RX_TEST_endTrigger_pastTrig 7 -#define _NBITS_CMD_RX_TEST_endTrigger_pastTrig 1 -#define _POSITION_CMD_RX_TEST_syncWord 16 -#define _TYPE_CMD_RX_TEST_syncWord uint32_t -#define _POSITION_CMD_RX_TEST_endTime 20 -#define _TYPE_CMD_RX_TEST_endTime ratmr_t -#define _SIZEOF_CMD_RX_TEST 24 - -#define _POSITION_CMD_TX_TEST_config 14 -#define _TYPE_CMD_TX_TEST_config uint8_t -#define _BITPOS_CMD_TX_TEST_config_bUseCw 0 -#define _NBITS_CMD_TX_TEST_config_bUseCw 1 -#define _BITPOS_CMD_TX_TEST_config_bFsOff 1 -#define _NBITS_CMD_TX_TEST_config_bFsOff 1 -#define _BITPOS_CMD_TX_TEST_config_whitenMode 2 -#define _NBITS_CMD_TX_TEST_config_whitenMode 2 -#define _POSITION_CMD_TX_TEST_txWord 16 -#define _TYPE_CMD_TX_TEST_txWord uint16_t -#define _POSITION_CMD_TX_TEST_endTrigger 19 -#define _TYPE_CMD_TX_TEST_endTrigger uint8_t -#define _BITPOS_CMD_TX_TEST_endTrigger_triggerType 0 -#define _NBITS_CMD_TX_TEST_endTrigger_triggerType 4 -#define _BITPOS_CMD_TX_TEST_endTrigger_bEnaCmd 4 -#define _NBITS_CMD_TX_TEST_endTrigger_bEnaCmd 1 -#define _BITPOS_CMD_TX_TEST_endTrigger_triggerNo 5 -#define _NBITS_CMD_TX_TEST_endTrigger_triggerNo 2 -#define _BITPOS_CMD_TX_TEST_endTrigger_pastTrig 7 -#define _NBITS_CMD_TX_TEST_endTrigger_pastTrig 1 -#define _POSITION_CMD_TX_TEST_syncWord 20 -#define _TYPE_CMD_TX_TEST_syncWord uint32_t -#define _POSITION_CMD_TX_TEST_endTime 24 -#define _TYPE_CMD_TX_TEST_endTime ratmr_t -#define _SIZEOF_CMD_TX_TEST 28 - -#define _POSITION_CMD_SYNC_STOP_RAT_rat0 16 -#define _TYPE_CMD_SYNC_STOP_RAT_rat0 ratmr_t -#define _SIZEOF_CMD_SYNC_STOP_RAT 20 - -#define _POSITION_CMD_SYNC_START_RAT_rat0 16 -#define _TYPE_CMD_SYNC_START_RAT_rat0 ratmr_t -#define _SIZEOF_CMD_SYNC_START_RAT 20 - -#define _POSITION_CMD_COUNT_counter 14 -#define _TYPE_CMD_COUNT_counter uint16_t -#define _SIZEOF_CMD_COUNT 16 - -#define _POSITION_CMD_FS_POWERUP_pRegOverride 16 -#define _TYPE_CMD_FS_POWERUP_pRegOverride uint32_t* -#define _SIZEOF_CMD_FS_POWERUP 20 - -#define _SIZEOF_CMD_FS_POWERDOWN 14 - -#define _POSITION_CMD_SCH_IMM_cmdrVal 16 -#define _TYPE_CMD_SCH_IMM_cmdrVal uint32_t -#define _POSITION_CMD_SCH_IMM_cmdstaVal 20 -#define _TYPE_CMD_SCH_IMM_cmdstaVal uint32_t -#define _SIZEOF_CMD_SCH_IMM 24 - -#define _POSITION_CMD_COUNT_BRANCH_counter 14 -#define _TYPE_CMD_COUNT_BRANCH_counter uint16_t -#define _POSITION_CMD_COUNT_BRANCH_pNextOpIfOk 16 -#define _TYPE_CMD_COUNT_BRANCH_pNextOpIfOk uint8_t* -#define _SIZEOF_CMD_COUNT_BRANCH 20 - -#define _POSITION_CMD_PATTERN_CHECK_patternOpt 14 -#define _TYPE_CMD_PATTERN_CHECK_patternOpt uint16_t -#define _BITPOS_CMD_PATTERN_CHECK_patternOpt_operation 0 -#define _NBITS_CMD_PATTERN_CHECK_patternOpt_operation 2 -#define _BITPOS_CMD_PATTERN_CHECK_patternOpt_bByteRev 2 -#define _NBITS_CMD_PATTERN_CHECK_patternOpt_bByteRev 1 -#define _BITPOS_CMD_PATTERN_CHECK_patternOpt_bBitRev 3 -#define _NBITS_CMD_PATTERN_CHECK_patternOpt_bBitRev 1 -#define _BITPOS_CMD_PATTERN_CHECK_patternOpt_signExtend 4 -#define _NBITS_CMD_PATTERN_CHECK_patternOpt_signExtend 5 -#define _BITPOS_CMD_PATTERN_CHECK_patternOpt_bRxVal 9 -#define _NBITS_CMD_PATTERN_CHECK_patternOpt_bRxVal 1 -#define _POSITION_CMD_PATTERN_CHECK_pNextOpIfOk 16 -#define _TYPE_CMD_PATTERN_CHECK_pNextOpIfOk uint8_t* -#define _POSITION_CMD_PATTERN_CHECK_pValue 20 -#define _TYPE_CMD_PATTERN_CHECK_pValue uint8_t* -#define _POSITION_CMD_PATTERN_CHECK_mask 24 -#define _TYPE_CMD_PATTERN_CHECK_mask uint32_t -#define _POSITION_CMD_PATTERN_CHECK_compareVal 28 -#define _TYPE_CMD_PATTERN_CHECK_compareVal uint32_t -#define _SIZEOF_CMD_PATTERN_CHECK 32 - -#define _SIZEOF_CMD_ABORT 2 - -#define _SIZEOF_CMD_STOP 2 - -#define _SIZEOF_CMD_GET_RSSI 2 - -#define _POSITION_CMD_UPDATE_RADIO_SETUP_pRegOverride 4 -#define _TYPE_CMD_UPDATE_RADIO_SETUP_pRegOverride uint32_t* -#define _SIZEOF_CMD_UPDATE_RADIO_SETUP 8 - -#define _POSITION_CMD_TRIGGER_triggerNo 2 -#define _TYPE_CMD_TRIGGER_triggerNo uint8_t -#define _SIZEOF_CMD_TRIGGER 3 - -#define _POSITION_CMD_GET_FW_INFO_versionNo 2 -#define _TYPE_CMD_GET_FW_INFO_versionNo uint16_t -#define _POSITION_CMD_GET_FW_INFO_startOffset 4 -#define _TYPE_CMD_GET_FW_INFO_startOffset uint16_t -#define _POSITION_CMD_GET_FW_INFO_freeRamSz 6 -#define _TYPE_CMD_GET_FW_INFO_freeRamSz uint16_t -#define _POSITION_CMD_GET_FW_INFO_availRatCh 8 -#define _TYPE_CMD_GET_FW_INFO_availRatCh uint16_t -#define _SIZEOF_CMD_GET_FW_INFO 10 - -#define _SIZEOF_CMD_START_RAT 2 - -#define _SIZEOF_CMD_PING 2 - -#define _POSITION_CMD_ADD_DATA_ENTRY_pQueue 4 -#define _TYPE_CMD_ADD_DATA_ENTRY_pQueue dataQueue_t* -#define _POSITION_CMD_ADD_DATA_ENTRY_pEntry 8 -#define _TYPE_CMD_ADD_DATA_ENTRY_pEntry uint8_t* -#define _SIZEOF_CMD_ADD_DATA_ENTRY 12 - -#define _POSITION_CMD_REMOVE_DATA_ENTRY_pQueue 4 -#define _TYPE_CMD_REMOVE_DATA_ENTRY_pQueue dataQueue_t* -#define _POSITION_CMD_REMOVE_DATA_ENTRY_pEntry 8 -#define _TYPE_CMD_REMOVE_DATA_ENTRY_pEntry uint8_t* -#define _SIZEOF_CMD_REMOVE_DATA_ENTRY 12 - -#define _POSITION_CMD_FLUSH_QUEUE_pQueue 4 -#define _TYPE_CMD_FLUSH_QUEUE_pQueue dataQueue_t* -#define _POSITION_CMD_FLUSH_QUEUE_pFirstEntry 8 -#define _TYPE_CMD_FLUSH_QUEUE_pFirstEntry uint8_t* -#define _SIZEOF_CMD_FLUSH_QUEUE 12 - -#define _POSITION_CMD_CLEAR_RX_pQueue 4 -#define _TYPE_CMD_CLEAR_RX_pQueue dataQueue_t* -#define _SIZEOF_CMD_CLEAR_RX 8 - -#define _POSITION_CMD_REMOVE_PENDING_ENTRIES_pQueue 4 -#define _TYPE_CMD_REMOVE_PENDING_ENTRIES_pQueue dataQueue_t* -#define _POSITION_CMD_REMOVE_PENDING_ENTRIES_pFirstEntry 8 -#define _TYPE_CMD_REMOVE_PENDING_ENTRIES_pFirstEntry uint8_t* -#define _SIZEOF_CMD_REMOVE_PENDING_ENTRIES 12 - -#define _POSITION_CMD_SET_RAT_CMP_ratCh 2 -#define _TYPE_CMD_SET_RAT_CMP_ratCh uint8_t -#define _POSITION_CMD_SET_RAT_CMP_compareTime 4 -#define _TYPE_CMD_SET_RAT_CMP_compareTime ratmr_t -#define _SIZEOF_CMD_SET_RAT_CMP 8 - -#define _POSITION_CMD_SET_RAT_CPT_config 2 -#define _TYPE_CMD_SET_RAT_CPT_config uint16_t -#define _BITPOS_CMD_SET_RAT_CPT_config_inputSrc 3 -#define _NBITS_CMD_SET_RAT_CPT_config_inputSrc 5 -#define _BITPOS_CMD_SET_RAT_CPT_config_ratCh 8 -#define _NBITS_CMD_SET_RAT_CPT_config_ratCh 4 -#define _BITPOS_CMD_SET_RAT_CPT_config_bRepeated 12 -#define _NBITS_CMD_SET_RAT_CPT_config_bRepeated 1 -#define _BITPOS_CMD_SET_RAT_CPT_config_inputMode 13 -#define _NBITS_CMD_SET_RAT_CPT_config_inputMode 2 -#define _SIZEOF_CMD_SET_RAT_CPT 4 - -#define _POSITION_CMD_DISABLE_RAT_CH_ratCh 2 -#define _TYPE_CMD_DISABLE_RAT_CH_ratCh uint8_t -#define _SIZEOF_CMD_DISABLE_RAT_CH 3 - -#define _POSITION_CMD_SET_RAT_OUTPUT_config 2 -#define _TYPE_CMD_SET_RAT_OUTPUT_config uint16_t -#define _BITPOS_CMD_SET_RAT_OUTPUT_config_outputSel 2 -#define _NBITS_CMD_SET_RAT_OUTPUT_config_outputSel 3 -#define _BITPOS_CMD_SET_RAT_OUTPUT_config_outputMode 5 -#define _NBITS_CMD_SET_RAT_OUTPUT_config_outputMode 3 -#define _BITPOS_CMD_SET_RAT_OUTPUT_config_ratCh 8 -#define _NBITS_CMD_SET_RAT_OUTPUT_config_ratCh 4 -#define _SIZEOF_CMD_SET_RAT_OUTPUT 4 - -#define _POSITION_CMD_ARM_RAT_CH_ratCh 2 -#define _TYPE_CMD_ARM_RAT_CH_ratCh uint8_t -#define _SIZEOF_CMD_ARM_RAT_CH 3 - -#define _POSITION_CMD_DISARM_RAT_CH_ratCh 2 -#define _TYPE_CMD_DISARM_RAT_CH_ratCh uint8_t -#define _SIZEOF_CMD_DISARM_RAT_CH 3 - -#define _POSITION_CMD_SET_TX_POWER_txPower 2 -#define _TYPE_CMD_SET_TX_POWER_txPower uint16_t -#define _BITPOS_CMD_SET_TX_POWER_txPower_IB 0 -#define _NBITS_CMD_SET_TX_POWER_txPower_IB 6 -#define _BITPOS_CMD_SET_TX_POWER_txPower_GC 6 -#define _NBITS_CMD_SET_TX_POWER_txPower_GC 2 -#define _BITPOS_CMD_SET_TX_POWER_txPower_tempCoeff 8 -#define _NBITS_CMD_SET_TX_POWER_txPower_tempCoeff 8 -#define _SIZEOF_CMD_SET_TX_POWER 4 - -#define _POSITION_CMD_UPDATE_FS_frequency 2 -#define _TYPE_CMD_UPDATE_FS_frequency uint16_t -#define _POSITION_CMD_UPDATE_FS_fractFreq 4 -#define _TYPE_CMD_UPDATE_FS_fractFreq uint16_t -#define _SIZEOF_CMD_UPDATE_FS 6 - -#define _POSITION_CMD_BUS_REQUEST_bSysBusNeeded 2 -#define _TYPE_CMD_BUS_REQUEST_bSysBusNeeded uint8_t -#define _SIZEOF_CMD_BUS_REQUEST 3 - -#endif diff --git a/cpu/cc26xx/dev/rfc-api/data_entry.h b/cpu/cc26xx/dev/rfc-api/data_entry.h deleted file mode 100644 index 91c1826de..000000000 --- a/cpu/cc26xx/dev/rfc-api/data_entry.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/*---------------------------------------------------------------------------*/ -#ifndef __DATA_ENTRY_H -#define __DATA_ENTRY_H - -#include -#include "mailbox.h" - -typedef struct rfc_dataEntry_s rfc_dataEntry_t; - -#define _POSITION_dataEntry_pNextEntry 0 -#define _TYPE_dataEntry_pNextEntry uint8_t* -#define _POSITION_dataEntry_status 4 -#define _TYPE_dataEntry_status uint8_t -#define _POSITION_dataEntry_config 5 -#define _TYPE_dataEntry_config uint8_t -#define _BITPOS_dataEntry_config_type 0 -#define _NBITS_dataEntry_config_type 2 -#define _BITPOS_dataEntry_config_lenSz 2 -#define _NBITS_dataEntry_config_lenSz 2 -#define _BITPOS_dataEntry_config_irqIntv 4 -#define _NBITS_dataEntry_config_irqIntv 4 -#define _POSITION_dataEntry_length 6 -#define _TYPE_dataEntry_length uint16_t -#define _POSITION_dataEntry_data 8 -#define _TYPE_dataEntry_data uint8_t -#define _POSITION_dataEntry_pData 8 -#define _TYPE_dataEntry_pData uint8_t* -#define _POSITION_dataEntry_numElements 8 -#define _TYPE_dataEntry_numElements uint16_t -#define _POSITION_dataEntry_pktStatus 8 -#define _TYPE_dataEntry_pktStatus uint16_t -#define _BITPOS_dataEntry_pktStatus_numElements 0 -#define _NBITS_dataEntry_pktStatus_numElements 13 -#define _BITPOS_dataEntry_pktStatus_bEntryOpen 13 -#define _NBITS_dataEntry_pktStatus_bEntryOpen 1 -#define _BITPOS_dataEntry_pktStatus_bFirstCont 14 -#define _NBITS_dataEntry_pktStatus_bFirstCont 1 -#define _BITPOS_dataEntry_pktStatus_bLastCont 15 -#define _NBITS_dataEntry_pktStatus_bLastCont 1 -#define _POSITION_dataEntry_nextIndex 10 -#define _TYPE_dataEntry_nextIndex uint16_t -#define _POSITION_dataEntry_rxData 12 -#define _TYPE_dataEntry_rxData uint8_t -#define _LAST_POSITION_dataEntry 12 -#define _LAST_TYPE_dataEntry uint8_t - -struct rfc_dataEntry_s { - uint8_t* pNextEntry; - uint8_t status; - struct { - uint8_t type:2; - uint8_t lenSz:2; - uint8_t irqIntv:4; - } config; - uint16_t length; - uint8_t data; - uint8_t __dummy0; - uint16_t nextIndex; - uint8_t rxData; -}; - -#endif diff --git a/cpu/cc26xx/dev/rfc-api/ieee_cmd_field.h b/cpu/cc26xx/dev/rfc-api/ieee_cmd_field.h deleted file mode 100755 index 149940f79..000000000 --- a/cpu/cc26xx/dev/rfc-api/ieee_cmd_field.h +++ /dev/null @@ -1,403 +0,0 @@ -/****************************************************************************** -* Filename: ieee_cmd_field.h -* Revised: $ $ -* Revision: $ $ -* -* Description: CC26xx/CC13xx API for IEEE 802.15.4 commands -* -* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/ -* -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* Neither the name of Texas Instruments Incorporated nor the names of -* its contributors may be used to endorse or promote products derived -* from this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -******************************************************************************/ - -#ifndef __IEEE_CMD_FIELD_H -#define __IEEE_CMD_FIELD_H - -#include -#include "mailbox.h" -#include "common_cmd.h" - -#define _POSITION_CMD_IEEE_RX_channel 14 -#define _TYPE_CMD_IEEE_RX_channel uint8_t -#define _POSITION_CMD_IEEE_RX_rxConfig 15 -#define _TYPE_CMD_IEEE_RX_rxConfig uint8_t -#define _BITPOS_CMD_IEEE_RX_rxConfig_bAutoFlushCrc 0 -#define _NBITS_CMD_IEEE_RX_rxConfig_bAutoFlushCrc 1 -#define _BITPOS_CMD_IEEE_RX_rxConfig_bAutoFlushIgn 1 -#define _NBITS_CMD_IEEE_RX_rxConfig_bAutoFlushIgn 1 -#define _BITPOS_CMD_IEEE_RX_rxConfig_bIncludePhyHdr 2 -#define _NBITS_CMD_IEEE_RX_rxConfig_bIncludePhyHdr 1 -#define _BITPOS_CMD_IEEE_RX_rxConfig_bIncludeCrc 3 -#define _NBITS_CMD_IEEE_RX_rxConfig_bIncludeCrc 1 -#define _BITPOS_CMD_IEEE_RX_rxConfig_bAppendRssi 4 -#define _NBITS_CMD_IEEE_RX_rxConfig_bAppendRssi 1 -#define _BITPOS_CMD_IEEE_RX_rxConfig_bAppendCorrCrc 5 -#define _NBITS_CMD_IEEE_RX_rxConfig_bAppendCorrCrc 1 -#define _BITPOS_CMD_IEEE_RX_rxConfig_bAppendSrcInd 6 -#define _NBITS_CMD_IEEE_RX_rxConfig_bAppendSrcInd 1 -#define _BITPOS_CMD_IEEE_RX_rxConfig_bAppendTimestamp 7 -#define _NBITS_CMD_IEEE_RX_rxConfig_bAppendTimestamp 1 -#define _POSITION_CMD_IEEE_RX_pRxQ 16 -#define _TYPE_CMD_IEEE_RX_pRxQ dataQueue_t* -#define _POSITION_CMD_IEEE_RX_pOutput 20 -#define _TYPE_CMD_IEEE_RX_pOutput uint8_t* -#define _POSITION_CMD_IEEE_RX_frameFiltOpt 24 -#define _TYPE_CMD_IEEE_RX_frameFiltOpt uint16_t -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_frameFiltEn 0 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_frameFiltEn 1 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_frameFiltStop 1 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_frameFiltStop 1 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_autoAckEn 2 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_autoAckEn 1 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_slottedAckEn 3 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_slottedAckEn 1 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_autoPendEn 4 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_autoPendEn 1 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_defaultPend 5 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_defaultPend 1 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_bPendDataReqOnly 6 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_bPendDataReqOnly 1 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_bPanCoord 7 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_bPanCoord 1 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_maxFrameVersion 8 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_maxFrameVersion 2 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_fcfReservedMask 10 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_fcfReservedMask 3 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_modifyFtFilter 13 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_modifyFtFilter 2 -#define _BITPOS_CMD_IEEE_RX_frameFiltOpt_bStrictLenFilter 15 -#define _NBITS_CMD_IEEE_RX_frameFiltOpt_bStrictLenFilter 1 -#define _POSITION_CMD_IEEE_RX_frameTypes 26 -#define _TYPE_CMD_IEEE_RX_frameTypes uint8_t -#define _BITPOS_CMD_IEEE_RX_frameTypes_bAcceptFt0Beacon 0 -#define _NBITS_CMD_IEEE_RX_frameTypes_bAcceptFt0Beacon 1 -#define _BITPOS_CMD_IEEE_RX_frameTypes_bAcceptFt1Data 1 -#define _NBITS_CMD_IEEE_RX_frameTypes_bAcceptFt1Data 1 -#define _BITPOS_CMD_IEEE_RX_frameTypes_bAcceptFt2Ack 2 -#define _NBITS_CMD_IEEE_RX_frameTypes_bAcceptFt2Ack 1 -#define _BITPOS_CMD_IEEE_RX_frameTypes_bAcceptFt3MacCmd 3 -#define _NBITS_CMD_IEEE_RX_frameTypes_bAcceptFt3MacCmd 1 -#define _BITPOS_CMD_IEEE_RX_frameTypes_bAcceptFt4Reserved 4 -#define _NBITS_CMD_IEEE_RX_frameTypes_bAcceptFt4Reserved 1 -#define _BITPOS_CMD_IEEE_RX_frameTypes_bAcceptFt5Reserved 5 -#define _NBITS_CMD_IEEE_RX_frameTypes_bAcceptFt5Reserved 1 -#define _BITPOS_CMD_IEEE_RX_frameTypes_bAcceptFt6Reserved 6 -#define _NBITS_CMD_IEEE_RX_frameTypes_bAcceptFt6Reserved 1 -#define _BITPOS_CMD_IEEE_RX_frameTypes_bAcceptFt7Reserved 7 -#define _NBITS_CMD_IEEE_RX_frameTypes_bAcceptFt7Reserved 1 -#define _POSITION_CMD_IEEE_RX_ccaOpt 27 -#define _TYPE_CMD_IEEE_RX_ccaOpt uint8_t -#define _BITPOS_CMD_IEEE_RX_ccaOpt_ccaEnEnergy 0 -#define _NBITS_CMD_IEEE_RX_ccaOpt_ccaEnEnergy 1 -#define _BITPOS_CMD_IEEE_RX_ccaOpt_ccaEnCorr 1 -#define _NBITS_CMD_IEEE_RX_ccaOpt_ccaEnCorr 1 -#define _BITPOS_CMD_IEEE_RX_ccaOpt_ccaEnSync 2 -#define _NBITS_CMD_IEEE_RX_ccaOpt_ccaEnSync 1 -#define _BITPOS_CMD_IEEE_RX_ccaOpt_ccaCorrOp 3 -#define _NBITS_CMD_IEEE_RX_ccaOpt_ccaCorrOp 1 -#define _BITPOS_CMD_IEEE_RX_ccaOpt_ccaSyncOp 4 -#define _NBITS_CMD_IEEE_RX_ccaOpt_ccaSyncOp 1 -#define _BITPOS_CMD_IEEE_RX_ccaOpt_ccaCorrThr 5 -#define _NBITS_CMD_IEEE_RX_ccaOpt_ccaCorrThr 2 -#define _POSITION_CMD_IEEE_RX_ccaRssiThr 28 -#define _TYPE_CMD_IEEE_RX_ccaRssiThr int8_t -#define _POSITION_CMD_IEEE_RX_numExtEntries 30 -#define _TYPE_CMD_IEEE_RX_numExtEntries uint8_t -#define _POSITION_CMD_IEEE_RX_numShortEntries 31 -#define _TYPE_CMD_IEEE_RX_numShortEntries uint8_t -#define _POSITION_CMD_IEEE_RX_pExtEntryList 32 -#define _TYPE_CMD_IEEE_RX_pExtEntryList uint32_t* -#define _POSITION_CMD_IEEE_RX_pShortEntryList 36 -#define _TYPE_CMD_IEEE_RX_pShortEntryList uint32_t* -#define _POSITION_CMD_IEEE_RX_localExtAddr 40 -#define _TYPE_CMD_IEEE_RX_localExtAddr uint64_t -#define _POSITION_CMD_IEEE_RX_localShortAddr 48 -#define _TYPE_CMD_IEEE_RX_localShortAddr uint16_t -#define _POSITION_CMD_IEEE_RX_localPanID 50 -#define _TYPE_CMD_IEEE_RX_localPanID uint16_t -#define _POSITION_CMD_IEEE_RX_endTrigger 55 -#define _TYPE_CMD_IEEE_RX_endTrigger uint8_t -#define _BITPOS_CMD_IEEE_RX_endTrigger_triggerType 0 -#define _NBITS_CMD_IEEE_RX_endTrigger_triggerType 4 -#define _BITPOS_CMD_IEEE_RX_endTrigger_bEnaCmd 4 -#define _NBITS_CMD_IEEE_RX_endTrigger_bEnaCmd 1 -#define _BITPOS_CMD_IEEE_RX_endTrigger_triggerNo 5 -#define _NBITS_CMD_IEEE_RX_endTrigger_triggerNo 2 -#define _BITPOS_CMD_IEEE_RX_endTrigger_pastTrig 7 -#define _NBITS_CMD_IEEE_RX_endTrigger_pastTrig 1 -#define _POSITION_CMD_IEEE_RX_endTime 56 -#define _TYPE_CMD_IEEE_RX_endTime ratmr_t -#define _SIZEOF_CMD_IEEE_RX 60 - -#define _POSITION_CMD_IEEE_ED_SCAN_channel 14 -#define _TYPE_CMD_IEEE_ED_SCAN_channel uint8_t -#define _POSITION_CMD_IEEE_ED_SCAN_ccaOpt 15 -#define _TYPE_CMD_IEEE_ED_SCAN_ccaOpt uint8_t -#define _BITPOS_CMD_IEEE_ED_SCAN_ccaOpt_ccaEnEnergy 0 -#define _NBITS_CMD_IEEE_ED_SCAN_ccaOpt_ccaEnEnergy 1 -#define _BITPOS_CMD_IEEE_ED_SCAN_ccaOpt_ccaEnCorr 1 -#define _NBITS_CMD_IEEE_ED_SCAN_ccaOpt_ccaEnCorr 1 -#define _BITPOS_CMD_IEEE_ED_SCAN_ccaOpt_ccaEnSync 2 -#define _NBITS_CMD_IEEE_ED_SCAN_ccaOpt_ccaEnSync 1 -#define _BITPOS_CMD_IEEE_ED_SCAN_ccaOpt_ccaCorrOp 3 -#define _NBITS_CMD_IEEE_ED_SCAN_ccaOpt_ccaCorrOp 1 -#define _BITPOS_CMD_IEEE_ED_SCAN_ccaOpt_ccaSyncOp 4 -#define _NBITS_CMD_IEEE_ED_SCAN_ccaOpt_ccaSyncOp 1 -#define _BITPOS_CMD_IEEE_ED_SCAN_ccaOpt_ccaCorrThr 5 -#define _NBITS_CMD_IEEE_ED_SCAN_ccaOpt_ccaCorrThr 2 -#define _POSITION_CMD_IEEE_ED_SCAN_ccaRssiThr 16 -#define _TYPE_CMD_IEEE_ED_SCAN_ccaRssiThr int8_t -#define _POSITION_CMD_IEEE_ED_SCAN_maxRssi 18 -#define _TYPE_CMD_IEEE_ED_SCAN_maxRssi int8_t -#define _POSITION_CMD_IEEE_ED_SCAN_endTrigger 19 -#define _TYPE_CMD_IEEE_ED_SCAN_endTrigger uint8_t -#define _BITPOS_CMD_IEEE_ED_SCAN_endTrigger_triggerType 0 -#define _NBITS_CMD_IEEE_ED_SCAN_endTrigger_triggerType 4 -#define _BITPOS_CMD_IEEE_ED_SCAN_endTrigger_bEnaCmd 4 -#define _NBITS_CMD_IEEE_ED_SCAN_endTrigger_bEnaCmd 1 -#define _BITPOS_CMD_IEEE_ED_SCAN_endTrigger_triggerNo 5 -#define _NBITS_CMD_IEEE_ED_SCAN_endTrigger_triggerNo 2 -#define _BITPOS_CMD_IEEE_ED_SCAN_endTrigger_pastTrig 7 -#define _NBITS_CMD_IEEE_ED_SCAN_endTrigger_pastTrig 1 -#define _POSITION_CMD_IEEE_ED_SCAN_endTime 20 -#define _TYPE_CMD_IEEE_ED_SCAN_endTime ratmr_t -#define _SIZEOF_CMD_IEEE_ED_SCAN 24 - -#define _POSITION_CMD_IEEE_TX_txOpt 14 -#define _TYPE_CMD_IEEE_TX_txOpt uint8_t -#define _BITPOS_CMD_IEEE_TX_txOpt_bIncludePhyHdr 0 -#define _NBITS_CMD_IEEE_TX_txOpt_bIncludePhyHdr 1 -#define _BITPOS_CMD_IEEE_TX_txOpt_bIncludeCrc 1 -#define _NBITS_CMD_IEEE_TX_txOpt_bIncludeCrc 1 -#define _BITPOS_CMD_IEEE_TX_txOpt_payloadLenMsb 3 -#define _NBITS_CMD_IEEE_TX_txOpt_payloadLenMsb 5 -#define _POSITION_CMD_IEEE_TX_payloadLen 15 -#define _TYPE_CMD_IEEE_TX_payloadLen uint8_t -#define _POSITION_CMD_IEEE_TX_pPayload 16 -#define _TYPE_CMD_IEEE_TX_pPayload uint8_t* -#define _POSITION_CMD_IEEE_TX_timeStamp 20 -#define _TYPE_CMD_IEEE_TX_timeStamp ratmr_t -#define _SIZEOF_CMD_IEEE_TX 24 - -#define _POSITION_CMD_IEEE_CSMA_randomState 14 -#define _TYPE_CMD_IEEE_CSMA_randomState uint16_t -#define _POSITION_CMD_IEEE_CSMA_macMaxBE 16 -#define _TYPE_CMD_IEEE_CSMA_macMaxBE uint8_t -#define _POSITION_CMD_IEEE_CSMA_macMaxCSMABackoffs 17 -#define _TYPE_CMD_IEEE_CSMA_macMaxCSMABackoffs uint8_t -#define _POSITION_CMD_IEEE_CSMA_csmaConfig 18 -#define _TYPE_CMD_IEEE_CSMA_csmaConfig uint8_t -#define _BITPOS_CMD_IEEE_CSMA_csmaConfig_initCW 0 -#define _NBITS_CMD_IEEE_CSMA_csmaConfig_initCW 5 -#define _BITPOS_CMD_IEEE_CSMA_csmaConfig_bSlotted 5 -#define _NBITS_CMD_IEEE_CSMA_csmaConfig_bSlotted 1 -#define _BITPOS_CMD_IEEE_CSMA_csmaConfig_rxOffMode 6 -#define _NBITS_CMD_IEEE_CSMA_csmaConfig_rxOffMode 2 -#define _POSITION_CMD_IEEE_CSMA_NB 19 -#define _TYPE_CMD_IEEE_CSMA_NB uint8_t -#define _POSITION_CMD_IEEE_CSMA_BE 20 -#define _TYPE_CMD_IEEE_CSMA_BE uint8_t -#define _POSITION_CMD_IEEE_CSMA_remainingPeriods 21 -#define _TYPE_CMD_IEEE_CSMA_remainingPeriods uint8_t -#define _POSITION_CMD_IEEE_CSMA_lastRssi 22 -#define _TYPE_CMD_IEEE_CSMA_lastRssi int8_t -#define _POSITION_CMD_IEEE_CSMA_endTrigger 23 -#define _TYPE_CMD_IEEE_CSMA_endTrigger uint8_t -#define _BITPOS_CMD_IEEE_CSMA_endTrigger_triggerType 0 -#define _NBITS_CMD_IEEE_CSMA_endTrigger_triggerType 4 -#define _BITPOS_CMD_IEEE_CSMA_endTrigger_bEnaCmd 4 -#define _NBITS_CMD_IEEE_CSMA_endTrigger_bEnaCmd 1 -#define _BITPOS_CMD_IEEE_CSMA_endTrigger_triggerNo 5 -#define _NBITS_CMD_IEEE_CSMA_endTrigger_triggerNo 2 -#define _BITPOS_CMD_IEEE_CSMA_endTrigger_pastTrig 7 -#define _NBITS_CMD_IEEE_CSMA_endTrigger_pastTrig 1 -#define _POSITION_CMD_IEEE_CSMA_lastTimeStamp 24 -#define _TYPE_CMD_IEEE_CSMA_lastTimeStamp ratmr_t -#define _POSITION_CMD_IEEE_CSMA_endTime 28 -#define _TYPE_CMD_IEEE_CSMA_endTime ratmr_t -#define _SIZEOF_CMD_IEEE_CSMA 32 - -#define _POSITION_CMD_IEEE_RX_ACK_seqNo 14 -#define _TYPE_CMD_IEEE_RX_ACK_seqNo uint8_t -#define _POSITION_CMD_IEEE_RX_ACK_endTrigger 15 -#define _TYPE_CMD_IEEE_RX_ACK_endTrigger uint8_t -#define _BITPOS_CMD_IEEE_RX_ACK_endTrigger_triggerType 0 -#define _NBITS_CMD_IEEE_RX_ACK_endTrigger_triggerType 4 -#define _BITPOS_CMD_IEEE_RX_ACK_endTrigger_bEnaCmd 4 -#define _NBITS_CMD_IEEE_RX_ACK_endTrigger_bEnaCmd 1 -#define _BITPOS_CMD_IEEE_RX_ACK_endTrigger_triggerNo 5 -#define _NBITS_CMD_IEEE_RX_ACK_endTrigger_triggerNo 2 -#define _BITPOS_CMD_IEEE_RX_ACK_endTrigger_pastTrig 7 -#define _NBITS_CMD_IEEE_RX_ACK_endTrigger_pastTrig 1 -#define _POSITION_CMD_IEEE_RX_ACK_endTime 16 -#define _TYPE_CMD_IEEE_RX_ACK_endTime ratmr_t -#define _SIZEOF_CMD_IEEE_RX_ACK 20 - -#define _SIZEOF_CMD_IEEE_ABORT_BG 14 - -#define _POSITION_CMD_IEEE_MOD_CCA_newCcaOpt 2 -#define _TYPE_CMD_IEEE_MOD_CCA_newCcaOpt uint8_t -#define _BITPOS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaEnEnergy 0 -#define _NBITS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaEnEnergy 1 -#define _BITPOS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaEnCorr 1 -#define _NBITS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaEnCorr 1 -#define _BITPOS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaEnSync 2 -#define _NBITS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaEnSync 1 -#define _BITPOS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaCorrOp 3 -#define _NBITS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaCorrOp 1 -#define _BITPOS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaSyncOp 4 -#define _NBITS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaSyncOp 1 -#define _BITPOS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaCorrThr 5 -#define _NBITS_CMD_IEEE_MOD_CCA_newCcaOpt_ccaCorrThr 2 -#define _POSITION_CMD_IEEE_MOD_CCA_newCcaRssiThr 3 -#define _TYPE_CMD_IEEE_MOD_CCA_newCcaRssiThr int8_t -#define _SIZEOF_CMD_IEEE_MOD_CCA 4 - -#define _POSITION_CMD_IEEE_MOD_FILT_newFrameFiltOpt 2 -#define _TYPE_CMD_IEEE_MOD_FILT_newFrameFiltOpt uint16_t -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_frameFiltEn 0 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_frameFiltEn 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_frameFiltStop 1 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_frameFiltStop 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_autoAckEn 2 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_autoAckEn 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_slottedAckEn 3 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_slottedAckEn 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_autoPendEn 4 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_autoPendEn 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_defaultPend 5 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_defaultPend 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_bPendDataReqOnly 6 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_bPendDataReqOnly 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_bPanCoord 7 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_bPanCoord 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_maxFrameVersion 8 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_maxFrameVersion 2 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_fcfReservedMask 10 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_fcfReservedMask 3 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_modifyFtFilter 13 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_modifyFtFilter 2 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_bStrictLenFilter 15 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameFiltOpt_bStrictLenFilter 1 -#define _POSITION_CMD_IEEE_MOD_FILT_newFrameTypes 4 -#define _TYPE_CMD_IEEE_MOD_FILT_newFrameTypes uint8_t -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt0Beacon 0 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt0Beacon 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt1Data 1 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt1Data 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt2Ack 2 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt2Ack 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt3MacCmd 3 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt3MacCmd 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt4Reserved 4 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt4Reserved 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt5Reserved 5 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt5Reserved 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt6Reserved 6 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt6Reserved 1 -#define _BITPOS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt7Reserved 7 -#define _NBITS_CMD_IEEE_MOD_FILT_newFrameTypes_bAcceptFt7Reserved 1 -#define _SIZEOF_CMD_IEEE_MOD_FILT 5 - -#define _POSITION_CMD_IEEE_MOD_SRC_MATCH_options 2 -#define _TYPE_CMD_IEEE_MOD_SRC_MATCH_options uint8_t -#define _BITPOS_CMD_IEEE_MOD_SRC_MATCH_options_bEnable 0 -#define _NBITS_CMD_IEEE_MOD_SRC_MATCH_options_bEnable 1 -#define _BITPOS_CMD_IEEE_MOD_SRC_MATCH_options_srcPend 1 -#define _NBITS_CMD_IEEE_MOD_SRC_MATCH_options_srcPend 1 -#define _BITPOS_CMD_IEEE_MOD_SRC_MATCH_options_entryType 2 -#define _NBITS_CMD_IEEE_MOD_SRC_MATCH_options_entryType 1 -#define _POSITION_CMD_IEEE_MOD_SRC_MATCH_entryNo 3 -#define _TYPE_CMD_IEEE_MOD_SRC_MATCH_entryNo uint8_t -#define _SIZEOF_CMD_IEEE_MOD_SRC_MATCH 4 - -#define _SIZEOF_CMD_IEEE_ABORT_FG 2 - -#define _SIZEOF_CMD_IEEE_STOP_FG 2 - -#define _POSITION_CMD_IEEE_CCA_REQ_currentRssi 2 -#define _TYPE_CMD_IEEE_CCA_REQ_currentRssi int8_t -#define _POSITION_CMD_IEEE_CCA_REQ_maxRssi 3 -#define _TYPE_CMD_IEEE_CCA_REQ_maxRssi int8_t -#define _POSITION_CMD_IEEE_CCA_REQ_ccaInfo 4 -#define _TYPE_CMD_IEEE_CCA_REQ_ccaInfo uint8_t -#define _BITPOS_CMD_IEEE_CCA_REQ_ccaInfo_ccaState 0 -#define _NBITS_CMD_IEEE_CCA_REQ_ccaInfo_ccaState 2 -#define _BITPOS_CMD_IEEE_CCA_REQ_ccaInfo_ccaEnergy 2 -#define _NBITS_CMD_IEEE_CCA_REQ_ccaInfo_ccaEnergy 2 -#define _BITPOS_CMD_IEEE_CCA_REQ_ccaInfo_ccaCorr 4 -#define _NBITS_CMD_IEEE_CCA_REQ_ccaInfo_ccaCorr 2 -#define _BITPOS_CMD_IEEE_CCA_REQ_ccaInfo_ccaSync 6 -#define _NBITS_CMD_IEEE_CCA_REQ_ccaInfo_ccaSync 1 -#define _SIZEOF_CMD_IEEE_CCA_REQ 5 - -#define _POSITION_ieeeRxOutput_nTxAck 0 -#define _TYPE_ieeeRxOutput_nTxAck uint8_t -#define _POSITION_ieeeRxOutput_nRxBeacon 1 -#define _TYPE_ieeeRxOutput_nRxBeacon uint8_t -#define _POSITION_ieeeRxOutput_nRxData 2 -#define _TYPE_ieeeRxOutput_nRxData uint8_t -#define _POSITION_ieeeRxOutput_nRxAck 3 -#define _TYPE_ieeeRxOutput_nRxAck uint8_t -#define _POSITION_ieeeRxOutput_nRxMacCmd 4 -#define _TYPE_ieeeRxOutput_nRxMacCmd uint8_t -#define _POSITION_ieeeRxOutput_nRxReserved 5 -#define _TYPE_ieeeRxOutput_nRxReserved uint8_t -#define _POSITION_ieeeRxOutput_nRxNok 6 -#define _TYPE_ieeeRxOutput_nRxNok uint8_t -#define _POSITION_ieeeRxOutput_nRxIgnored 7 -#define _TYPE_ieeeRxOutput_nRxIgnored uint8_t -#define _POSITION_ieeeRxOutput_nRxBufFull 8 -#define _TYPE_ieeeRxOutput_nRxBufFull uint8_t -#define _POSITION_ieeeRxOutput_lastRssi 9 -#define _TYPE_ieeeRxOutput_lastRssi int8_t -#define _POSITION_ieeeRxOutput_maxRssi 10 -#define _TYPE_ieeeRxOutput_maxRssi int8_t -#define _POSITION_ieeeRxOutput_beaconTimeStamp 12 -#define _TYPE_ieeeRxOutput_beaconTimeStamp ratmr_t -#define _SIZEOF_ieeeRxOutput 16 - -#define _POSITION_shortAddrEntry_shortAddr 0 -#define _TYPE_shortAddrEntry_shortAddr uint16_t -#define _POSITION_shortAddrEntry_panId 2 -#define _TYPE_shortAddrEntry_panId uint16_t -#define _SIZEOF_shortAddrEntry 4 - -#define _POSITION_ieeeRxCorrCrc_status 0 -#define _TYPE_ieeeRxCorrCrc_status uint8_t -#define _BITPOS_ieeeRxCorrCrc_status_corr 0 -#define _NBITS_ieeeRxCorrCrc_status_corr 6 -#define _BITPOS_ieeeRxCorrCrc_status_bIgnore 6 -#define _NBITS_ieeeRxCorrCrc_status_bIgnore 1 -#define _BITPOS_ieeeRxCorrCrc_status_bCrcErr 7 -#define _NBITS_ieeeRxCorrCrc_status_bCrcErr 1 -#define _SIZEOF_ieeeRxCorrCrc 1 - -#endif diff --git a/cpu/cc26xx/lib/cc26xxware b/cpu/cc26xx/lib/cc26xxware deleted file mode 160000 index 420ae3682..000000000 --- a/cpu/cc26xx/lib/cc26xxware +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 420ae3682c11619c1340697632b2dc49f7e53037 diff --git a/cpu/msp430/Makefile.msp430 b/cpu/msp430/Makefile.msp430 index 2090c2465..81c71f51a 100644 --- a/cpu/msp430/Makefile.msp430 +++ b/cpu/msp430/Makefile.msp430 @@ -39,6 +39,10 @@ MSP430 = msp430.c flash.c clock.c leds.c leds-arch.c \ UIPDRIVERS = me.c me_tabs.c slip.c crc16.c ELFLOADER = elfloader.c elfloader-msp430.c symtab.c +ifeq ($(TARGET_MEMORY_MODEL),large) +ELFLOADER = elfloader-msp430x.c symtab.c +endif + CONTIKI_TARGET_SOURCEFILES += $(MSP430) \ $(SYSAPPS) $(ELFLOADER) \ $(UIPDRIVERS) @@ -151,10 +155,16 @@ endif ifndef IAR ifneq (,$(findstring 4.7.,$(shell msp430-gcc -dumpversion))) ifdef CPU_HAS_MSP430X - TARGET_MEMORY_MODEL ?= medium + ifeq ($(TARGET_MEMORY_MODEL),large) + CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) + CFLAGS += -mcode-region=far -mdata-region=far -msr20 -mc20 -md20 + LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -mcode-region=far -mdata-region=far -msr20 -mc20 -md20 + else + TARGET_MEMORY_MODEL = medium CFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) CFLAGS += -ffunction-sections -fdata-sections -mcode-region=any LDFLAGS += -mmemory-model=$(TARGET_MEMORY_MODEL) -Wl,-gc-sections + endif endif endif endif diff --git a/cpu/native/net/tapdev-drv.c b/cpu/native/net/tapdev-drv.c index 8a7aeed53..d2d4a1ac0 100644 --- a/cpu/native/net/tapdev-drv.c +++ b/cpu/native/net/tapdev-drv.c @@ -83,7 +83,7 @@ pollhandler(void) } #endif } else { - uip_len = 0; + uip_clear_buf(); } } } diff --git a/cpu/native/net/wpcap-drv.c b/cpu/native/net/wpcap-drv.c index 0b3cf926a..7ff8457b6 100644 --- a/cpu/native/net/wpcap-drv.c +++ b/cpu/native/net/wpcap-drv.c @@ -103,7 +103,7 @@ pollhandler(void) } #endif /* !NETSTACK_CONF_WITH_IPV6 */ } else { - uip_len = 0; + uip_clear_buf(); } } #endif @@ -146,7 +146,7 @@ pollhandler(void) #endif /* !NETSTACK_CONF_WITH_IPV6 */ } else { bail: - uip_len = 0; + uip_clear_buf(); } } #endif diff --git a/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c b/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c new file mode 100644 index 000000000..95fae730c --- /dev/null +++ b/dev/cc1200/cc1200-802154g-863-870-fsk-50kbps.c @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +#include "cc1200-rf-cfg.h" +#include "cc1200-const.h" + +/* + * This is a setup for the following configuration: + * + * 802.15.4g + * ========= + * Table 68f: Frequency band identifier 4 (863-870 MHz) + * Table 68g: Modulation scheme identifier 0 (Filtered FSK) + * Table 68h: Mode #1 (50kbps) + */ + +/* Base frequency in kHz */ +#define RF_CFG_CHAN_CENTER_F0 863125 +/* Channel spacing in kHz */ +#define RF_CFG_CHAN_SPACING 200 +/* The minimum channel */ +#define RF_CFG_MIN_CHANNEL 0 +/* The maximum channel */ +#define RF_CFG_MAX_CHANNEL 33 +/* The maximum output power in dBm */ +#define RF_CFG_MAX_TXPOWER CC1200_CONST_TX_POWER_MAX +/* The carrier sense level used for CCA in dBm */ +#define RF_CFG_CCA_THRESHOLD (-91) +/*---------------------------------------------------------------------------*/ +static const char rf_cfg_descriptor[] = "802.15.4g 863-870MHz MR-FSK mode #1"; +/*---------------------------------------------------------------------------*/ +/* + * Register settings exported from SmartRF Studio using the standard template + * "trxEB RF Settings Performance Line". + */ + +// Modulation format = 2-GFSK +// Whitening = false +// Packet length = 255 +// Packet length mode = Variable +// Packet bit length = 0 +// Symbol rate = 50 +// Deviation = 24.948120 +// Carrier frequency = 867.999878 +// Device address = 0 +// Manchester enable = false +// Address config = No address check +// Bit rate = 50 +// RX filter BW = 104.166667 + +static const registerSetting_t preferredSettings[]= +{ + {CC1200_IOCFG2, 0x06}, + {CC1200_SYNC3, 0x6E}, + {CC1200_SYNC2, 0x4E}, + {CC1200_SYNC1, 0x90}, + {CC1200_SYNC0, 0x4E}, + {CC1200_SYNC_CFG1, 0xE5}, + {CC1200_SYNC_CFG0, 0x23}, + {CC1200_DEVIATION_M, 0x47}, + {CC1200_MODCFG_DEV_E, 0x0B}, + {CC1200_DCFILT_CFG, 0x56}, + + /* + * 18.1.1.1 Preamble field + * The Preamble field shall contain phyFSKPreambleLength (as defined in 9.3) + * multiples of the 8-bit sequence “01010101†for filtered 2FSK. + * The Preamble field shall contain phyFSKPreambleLength multiples of the + * 16-bit sequence “0111 0111 0111 0111†for filtered 4FSK. + * + * We need to define this in order to be able to compute e.g. timeouts for the + * MAC layer. According to 9.3, phyFSKPreambleLength can be configured between + * 4 and 1000. We set it to 4. Attention: Once we use a long wake-up preamble, + * the timing parameters have to change accordingly. Will we use a shorter + * preamble for an ACK in this case??? + */ + {CC1200_PREAMBLE_CFG1, 0x19}, + + {CC1200_PREAMBLE_CFG0, 0xBA}, + {CC1200_IQIC, 0xC8}, + {CC1200_CHAN_BW, 0x84}, + {CC1200_MDMCFG1, 0x42}, + {CC1200_MDMCFG0, 0x05}, + {CC1200_SYMBOL_RATE2, 0x94}, + {CC1200_SYMBOL_RATE1, 0x7A}, + {CC1200_SYMBOL_RATE0, 0xE1}, + {CC1200_AGC_REF, 0x27}, + {CC1200_AGC_CS_THR, 0xF1}, + {CC1200_AGC_CFG1, 0x11}, + {CC1200_AGC_CFG0, 0x90}, + {CC1200_FIFO_CFG, 0x00}, + {CC1200_FS_CFG, 0x12}, + {CC1200_PKT_CFG2, 0x24}, + {CC1200_PKT_CFG0, 0x20}, + {CC1200_PKT_LEN, 0xFF}, + {CC1200_IF_MIX_CFG, 0x18}, + {CC1200_TOC_CFG, 0x03}, + {CC1200_MDMCFG2, 0x02}, + {CC1200_FREQ2, 0x56}, + {CC1200_FREQ1, 0xCC}, + {CC1200_FREQ0, 0xCC}, + {CC1200_IF_ADC1, 0xEE}, + {CC1200_IF_ADC0, 0x10}, + {CC1200_FS_DIG1, 0x04}, + {CC1200_FS_DIG0, 0x50}, + {CC1200_FS_CAL1, 0x40}, + {CC1200_FS_CAL0, 0x0E}, + {CC1200_FS_DIVTWO, 0x03}, + {CC1200_FS_DSM0, 0x33}, + {CC1200_FS_DVC1, 0xF7}, + {CC1200_FS_DVC0, 0x0F}, + {CC1200_FS_PFD, 0x00}, + {CC1200_FS_PRE, 0x6E}, + {CC1200_FS_REG_DIV_CML, 0x1C}, + {CC1200_FS_SPARE, 0xAC}, + {CC1200_FS_VCO0, 0xB5}, + {CC1200_IFAMP, 0x05}, + {CC1200_XOSC5, 0x0E}, + {CC1200_XOSC1, 0x03}, +}; +/*---------------------------------------------------------------------------*/ +/* Global linkage: symbol name must be different in each exported file! */ +const cc1200_rf_cfg_t cc1200_802154g_863_870_fsk_50kbps = { + .cfg_descriptor = rf_cfg_descriptor, + .register_settings = preferredSettings, + .size_of_register_settings = sizeof(preferredSettings), + .tx_pkt_lifetime = (RTIMER_SECOND / 20), + .chan_center_freq0 = RF_CFG_CHAN_CENTER_F0, + .chan_spacing = RF_CFG_CHAN_SPACING, + .min_channel = RF_CFG_MIN_CHANNEL, + .max_channel = RF_CFG_MAX_CHANNEL, + .max_txpower = RF_CFG_MAX_TXPOWER, + .cca_threshold = RF_CFG_CCA_THRESHOLD, +}; +/*---------------------------------------------------------------------------*/ diff --git a/dev/cc1200/cc1200-arch.h b/dev/cc1200/cc1200-arch.h new file mode 100644 index 000000000..c48a8798d --- /dev/null +++ b/dev/cc1200/cc1200-arch.h @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +#ifndef CC1200_ARCH_H +#define CC1200_ARCH_H + +#include +/*---------------------------------------------------------------------------*/ +/* + * Initialize SPI module & Pins. + * + * The function has to accomplish the following tasks: + * - Enable SPI and configure SPI (CPOL = 0, CPHA = 0) + * - Configure MISO, MOSI, SCLK accordingly + * - Configure GPIOx (input) + * - Configure RESET_N (output high) + * - Configure CSn (output high) + */ +void +cc1200_arch_init(void); +/*---------------------------------------------------------------------------*/ +/* Select CC1200 (pull down CSn pin). */ +void +cc1200_arch_spi_select(void); +/*---------------------------------------------------------------------------*/ +/* De-select CC1200 (release CSn pin). */ +void +cc1200_arch_spi_deselect(void); +/*---------------------------------------------------------------------------*/ +/* + * Configure port IRQ for GPIO0. + * If rising == 1: configure IRQ for rising edge, else falling edge + * Interrupt has to call cc1200_rx_interrupt()! + */ +void +cc1200_arch_gpio0_setup_irq(int rising); +/*---------------------------------------------------------------------------*/ +/* + * Configure port IRQ for GPIO2. + * + * GPIO2 might not be needed at all depending on the driver's + * configuration (see cc1200-conf.h) + * + * If rising == 1: configure IRQ for rising edge, else falling edge + * Interrupt has to call cc1200_rx_interrupt()! + */ +void +cc1200_arch_gpio2_setup_irq(int rising); +/*---------------------------------------------------------------------------*/ +/* Reset interrupt flag and enable GPIO0 port IRQ. */ +void +cc1200_arch_gpio0_enable_irq(void); +/*---------------------------------------------------------------------------*/ +/* Disable GPIO0 port IRQ. */ +void +cc1200_arch_gpio0_disable_irq(void); +/*---------------------------------------------------------------------------*/ +/* + * Reset interrupt flag and enable GPIO2 port IRQ + * + * GPIO2 might not be needed at all depending on the driver's + * configuration (see cc1200-conf.h) + */ +void +cc1200_arch_gpio2_enable_irq(void); +/*---------------------------------------------------------------------------*/ +/* + * Disable GPIO2 port IRQ. + * + * GPIO2 might not be needed at all depending on the driver's + * configuration (see cc1200-conf.h) + */ +void +cc1200_arch_gpio2_disable_irq(void); +/*---------------------------------------------------------------------------*/ +/* + * Read back the status of the GPIO0 pin. + * Returns 0 if the pin is low, otherwise 1 + */ +int +cc1200_arch_gpio0_read_pin(void); +/*---------------------------------------------------------------------------*/ +/* + * Read back the status of the GPIO2 pin. + * + * GPIO2 might not be needed at all depending on the driver's + * configuration (see cc1200-conf.h) + * + * Returns 0 if the pin is low, otherwise 1 + */ +int +cc1200_arch_gpio2_read_pin(void); +/*---------------------------------------------------------------------------*/ +/* + * Read back the status of the GPIO3 pin. + * + * Currently only used for rf test modes. + * + * Returns 0 if the pin is low, otherwise 1 + */ +int +cc1200_arch_gpio3_read_pin(void); +/*---------------------------------------------------------------------------*/ +/* Write a single byte via SPI, return response. */ +int +cc1200_arch_spi_rw_byte(uint8_t c); +/*---------------------------------------------------------------------------*/ +/* + * Write a sequence of bytes while reading back the response. + * Either read_buf or write_buf can be NULL. + */ +int +cc1200_arch_spi_rw(uint8_t *read_buf, + const uint8_t *write_buf, + uint16_t len); +/*---------------------------------------------------------------------------*/ +/* + * The CC1200 interrupt handler exported from the cc1200 driver. + * + * To be called by the hardware interrupt handler(s), + * which are defined as part of the cc1200-arch interface. + */ +int +cc1200_rx_interrupt(void); + +#endif /* CC1200_ARCH_H */ diff --git a/dev/cc1200/cc1200-conf.h b/dev/cc1200/cc1200-conf.h new file mode 100644 index 000000000..83d8d625c --- /dev/null +++ b/dev/cc1200/cc1200-conf.h @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +#ifndef CC1200_H_ +#define CC1200_H_ + +#include "contiki.h" + +/*---------------------------------------------------------------------------*/ +/* + * Can we use GPIO2 (in addition to GPIO0)? + * + * If this is the case, we can easily handle payloads > 125 bytes + * (and even > 127 bytes). If GPIO2 is available, we use it as an indicator + * pin for RX / TX FIFO threshold. + */ +#ifdef CC1200_CONF_USE_GPIO2 +#define CC1200_USE_GPIO2 CC1200_CONF_USE_GPIO2 +#else +#define CC1200_USE_GPIO2 1 +#endif +/*---------------------------------------------------------------------------*/ +/* + * The maximum payload length the driver can handle. + * + * - If CC1200_MAX_PAYLOAD_LEN <= 125 and CC1200_USE_GPIO2 == 0, we read + * out the RX FIFO at the end of the packet. RXOFF_MODE is set to RX in this + * case. + * - If 125 < CC1200_MAX_PAYLOAD_LEN <= 127 and CC1200_USE_GPIO2 == 0, we + * also read out the RX FIFO at the end of the packet, but read out + * RSSI + LQI "by hand". In this case, we also have to restart RX + * manually because RSSI + LQI are overwritten as soon as RX re-starts. + * This will lead to an increased RX/RX turnaround time. + * - If CC1200_USE_GPIO2 is set, we can use an arbitrary payload length + * (only limited by the payload length defined in the phy header). + * + * See below for 802.15.4g support. + */ +#ifdef CC1200_CONF_MAX_PAYLOAD_LEN +#define CC1200_MAX_PAYLOAD_LEN CC1200_CONF_MAX_PAYLOAD_LEN +#else +#define CC1200_MAX_PAYLOAD_LEN 127 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Use 802.15.4g frame format? Supports frame lenghts up to 2047 bytes! + */ +#ifdef CC1200_CONF_802154G +#define CC1200_802154G CC1200_CONF_802154G +#else +#define CC1200_802154G 0 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Do we use withening in 802.15.4g mode? Set to 1 if enabled, 0 otherwise. + */ +#ifdef CC1200_CONF_802154G_WHITENING +#define CC1200_802154G_WHITENING CC1200_CONF_802154G_WHITENING +#else +#define CC1200_802154G_WHITENING 0 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Do we use CRC16 in 802.15.4g mode? Set to 1 if enabled, 0 otherwise. + * + * It set to 0, we use FCS type 0: CRC32. + */ +#ifdef CC1200_CONF_802154G_CRC16 +#define CC1200_802154G_CRC16 CC1200_CONF_802154G_CRC16 +#else +/* Use FCS type 0: CRC32 */ +#define CC1200_802154G_CRC16 0 +#endif +/*---------------------------------------------------------------------------*/ +/* The RF configuration to be used. */ +#ifdef CC1200_CONF_RF_CFG +#define CC1200_RF_CFG CC1200_CONF_RF_CFG +#else +#define CC1200_RF_CFG cc1200_802154g_863_870_fsk_50kbps +#endif +/*---------------------------------------------------------------------------*/ +/* + * The RSSI offset in dBm (int8_t) + * + * Might be hardware dependent, so we make it a configuration parameter. + * This parameter is written to AGC_GAIN_ADJUST.GAIN_ADJUSTMENT + */ +#ifdef CC1200_CONF_RSSI_OFFSET +#define CC1200_RSSI_OFFSET CC1200_CONF_RSSI_OFFSET +#else +#define CC1200_RSSI_OFFSET (-81) +#endif +/*---------------------------------------------------------------------------*/ +/* + * The frequency offset + * + * Might be hardware dependent (e.g. depending on crystal load capacitances), + * so we make it a configuration parameter. Written to FREQOFF1 / FREQOFF2. + * Signed 16 bit number, see cc1200 user's guide. + * + * TODO: Make it a parameter for set_value() / get_value() + */ +#ifdef CC1200_CONF_FREQ_OFFSET +#define CC1200_FREQ_OFFSET CC1200_CONF_FREQ_OFFSET +#else +#define CC1200_FREQ_OFFSET (0) +#endif +/*---------------------------------------------------------------------------*/ +/* + * The default channel to use. + * + * Permitted values depending on the data rate + band used are defined + * in the appropriate rf configuration file. Make sure the default value + * is within these limits! + */ +#ifdef CC1200_CONF_DEFAULT_CHANNEL +#define CC1200_DEFAULT_CHANNEL CC1200_CONF_DEFAULT_CHANNEL +#else +/* 868.325 MHz */ +//#define CC1200_DEFAULT_CHANNEL 26 +/* 865.725 MHz */ +#define CC1200_DEFAULT_CHANNEL 13 +#endif +/*---------------------------------------------------------------------------*/ +/* + * Wether to use auto calibration or not. + * + * If set to 0, calibration is performed manually when turning the radio + * on (on()), when transmitting (transmit()) or when changing the channel. + * Enabling auto calibration will increase turn around times + + * energy consumption. If enabled, we calibrate every time we go from + * IDLE to RX or TX. + * When RDC or channel hopping is used, there is no need to turn calibration + * on because either on() is called frequently or the channel is updated. + */ +#ifdef CC1200_CONF_AUTOCAL +#define CC1200_AUTOCAL CC1200_CONF_AUTOCAL +#else +#define CC1200_AUTOCAL 0 +#endif +/*---------------------------------------------------------------------------*/ +/* + * If CC1200_AUTOCAL is 0, a timeout is used to decide when to calibrate when + * going to TX. + * + * Therefore, we don't calibrate every time we transmit. Set this parameter + * to 0 when this feature is not used. + */ +#ifdef CC1200_CONF_CAL_TIMEOUT_SECONDS +#define CC1200_CAL_TIMEOUT_SECONDS CC1200_CONF_CAL_TIMEOUT_SECONDS +#else +/* Calibrate at the latest every 15 minutes */ +#define CC1200_CAL_TIMEOUT_SECONDS 900 +#endif +/*---------------------------------------------------------------------------*/ +/* + * If defined, use these LEDS to indicate TX activity + * + * The LEDs are turned on once the radio enters TX mode + * (together with ENERGEST_ON(ENERGEST_TYPE_TRANSMIT), + * and turned of as soon as TX has completed. + */ +#ifdef CC1200_CONF_TX_LEDS +#define CC1200_TX_LEDS CC1200_CONF_TX_LEDS +#endif +/*---------------------------------------------------------------------------*/ +/* + * If defined, use these LEDS to indicate RX activity + * + * The LEDs are turned on as soon as the first byte is read out from + * the RX FIFO + */ +#ifdef CC1200_CONF_RX_LED +#define CC1200_RX_LEDS CC1200_CONF_RX_LEDS +#endif +/*---------------------------------------------------------------------------*/ +/* + * If set, enable sniff mode: turn radio on (and keep it on), disable + * address filter and auto ack + */ +#ifdef CC1200_CONF_SNIFFER +#define CC1200_SNIFFER CC1200_CONF_SNIFFER +#else +#define CC1200_SNIFFER 0 +#endif +/*---------------------------------------------------------------------------*/ + +#endif /* CC1200_H_ */ diff --git a/dev/cc1200/cc1200-const.h b/dev/cc1200/cc1200-const.h new file mode 100644 index 000000000..077ade559 --- /dev/null +++ b/dev/cc1200/cc1200-const.h @@ -0,0 +1,335 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +#ifndef CC1200_CONST_H_ +#define CC1200_CONST_H_ + +/*---------------------------------------------------------------------------*/ +/* Register addresses exported from SmartRF Studio */ +#define CC1200_IOCFG3 0x0000 /* GPIO3 IO Pin Configuration */ +#define CC1200_IOCFG2 0x0001 /* GPIO2 IO Pin Configuration */ +#define CC1200_IOCFG1 0x0002 /* GPIO1 IO Pin Configuration */ +#define CC1200_IOCFG0 0x0003 /* GPIO0 IO Pin Configuration */ +#define CC1200_SYNC3 0x0004 /* Sync Word Configuration [31:24] */ +#define CC1200_SYNC2 0x0005 /* Sync Word Configuration [23:16] */ +#define CC1200_SYNC1 0x0006 /* Sync Word Configuration [15:8] */ +#define CC1200_SYNC0 0x0007 /* Sync Word Configuration [7:0] */ +#define CC1200_SYNC_CFG1 0x0008 /* Sync Word Detection Configuration Reg. 1 */ +#define CC1200_SYNC_CFG0 0x0009 /* Sync Word Detection Configuration Reg. 0 */ +#define CC1200_DEVIATION_M 0x000A /* Frequency Deviation Configuration */ +#define CC1200_MODCFG_DEV_E 0x000B /* Modulation Format and Frequency Deviation Configur.. */ +#define CC1200_DCFILT_CFG 0x000C /* Digital DC Removal Configuration */ +#define CC1200_PREAMBLE_CFG1 0x000D /* Preamble Length Configuration Reg. 1 */ +#define CC1200_PREAMBLE_CFG0 0x000E /* Preamble Detection Configuration Reg. 0 */ +#define CC1200_IQIC 0x000F /* Digital Image Channel Compensation Configuration */ +#define CC1200_CHAN_BW 0x0010 /* Channel Filter Configuration */ +#define CC1200_MDMCFG1 0x0011 /* General Modem Parameter Configuration Reg. 1 */ +#define CC1200_MDMCFG0 0x0012 /* General Modem Parameter Configuration Reg. 0 */ +#define CC1200_SYMBOL_RATE2 0x0013 /* Symbol Rate Configuration Exponent and Mantissa [1.. */ +#define CC1200_SYMBOL_RATE1 0x0014 /* Symbol Rate Configuration Mantissa [15:8] */ +#define CC1200_SYMBOL_RATE0 0x0015 /* Symbol Rate Configuration Mantissa [7:0] */ +#define CC1200_AGC_REF 0x0016 /* AGC Reference Level Configuration */ +#define CC1200_AGC_CS_THR 0x0017 /* Carrier Sense Threshold Configuration */ +#define CC1200_AGC_GAIN_ADJUST 0x0018 /* RSSI Offset Configuration */ +#define CC1200_AGC_CFG3 0x0019 /* Automatic Gain Control Configuration Reg. 3 */ +#define CC1200_AGC_CFG2 0x001A /* Automatic Gain Control Configuration Reg. 2 */ +#define CC1200_AGC_CFG1 0x001B /* Automatic Gain Control Configuration Reg. 1 */ +#define CC1200_AGC_CFG0 0x001C /* Automatic Gain Control Configuration Reg. 0 */ +#define CC1200_FIFO_CFG 0x001D /* FIFO Configuration */ +#define CC1200_DEV_ADDR 0x001E /* Device Address Configuration */ +#define CC1200_SETTLING_CFG 0x001F /* Frequency Synthesizer Calibration and Settling Con.. */ +#define CC1200_FS_CFG 0x0020 /* Frequency Synthesizer Configuration */ +#define CC1200_WOR_CFG1 0x0021 /* eWOR Configuration Reg. 1 */ +#define CC1200_WOR_CFG0 0x0022 /* eWOR Configuration Reg. 0 */ +#define CC1200_WOR_EVENT0_MSB 0x0023 /* Event 0 Configuration MSB */ +#define CC1200_WOR_EVENT0_LSB 0x0024 /* Event 0 Configuration LSB */ +#define CC1200_RXDCM_TIME 0x0025 /* RX Duty Cycle Mode Configuration */ +#define CC1200_PKT_CFG2 0x0026 /* Packet Configuration Reg. 2 */ +#define CC1200_PKT_CFG1 0x0027 /* Packet Configuration Reg. 1 */ +#define CC1200_PKT_CFG0 0x0028 /* Packet Configuration Reg. 0 */ +#define CC1200_RFEND_CFG1 0x0029 /* RFEND Configuration Reg. 1 */ +#define CC1200_RFEND_CFG0 0x002A /* RFEND Configuration Reg. 0 */ +#define CC1200_PA_CFG1 0x002B /* Power Amplifier Configuration Reg. 1 */ +#define CC1200_PA_CFG0 0x002C /* Power Amplifier Configuration Reg. 0 */ +#define CC1200_ASK_CFG 0x002D /* ASK Configuration */ +#define CC1200_PKT_LEN 0x002E /* Packet Length Configuration */ +#define CC1200_IF_MIX_CFG 0x2F00 /* IF Mix Configuration */ +#define CC1200_FREQOFF_CFG 0x2F01 /* Frequency Offset Correction Configuration */ +#define CC1200_TOC_CFG 0x2F02 /* Timing Offset Correction Configuration */ +#define CC1200_MARC_SPARE 0x2F03 /* MARC Spare */ +#define CC1200_ECG_CFG 0x2F04 /* External Clock Frequency Configuration */ +#define CC1200_MDMCFG2 0x2F05 /* General Modem Parameter Configuration Reg. 2 */ +#define CC1200_EXT_CTRL 0x2F06 /* External Control Configuration */ +#define CC1200_RCCAL_FINE 0x2F07 /* RC Oscillator Calibration Fine */ +#define CC1200_RCCAL_COARSE 0x2F08 /* RC Oscillator Calibration Coarse */ +#define CC1200_RCCAL_OFFSET 0x2F09 /* RC Oscillator Calibration Clock Offset */ +#define CC1200_FREQOFF1 0x2F0A /* Frequency Offset MSB */ +#define CC1200_FREQOFF0 0x2F0B /* Frequency Offset LSB */ +#define CC1200_FREQ2 0x2F0C /* Frequency Configuration [23:16] */ +#define CC1200_FREQ1 0x2F0D /* Frequency Configuration [15:8] */ +#define CC1200_FREQ0 0x2F0E /* Frequency Configuration [7:0] */ +#define CC1200_IF_ADC2 0x2F0F /* Analog to Digital Converter Configuration Reg. 2 */ +#define CC1200_IF_ADC1 0x2F10 /* Analog to Digital Converter Configuration Reg. 1 */ +#define CC1200_IF_ADC0 0x2F11 /* Analog to Digital Converter Configuration Reg. 0 */ +#define CC1200_FS_DIG1 0x2F12 /* Frequency Synthesizer Digital Reg. 1 */ +#define CC1200_FS_DIG0 0x2F13 /* Frequency Synthesizer Digital Reg. 0 */ +#define CC1200_FS_CAL3 0x2F14 /* Frequency Synthesizer Calibration Reg. 3 */ +#define CC1200_FS_CAL2 0x2F15 /* Frequency Synthesizer Calibration Reg. 2 */ +#define CC1200_FS_CAL1 0x2F16 /* Frequency Synthesizer Calibration Reg. 1 */ +#define CC1200_FS_CAL0 0x2F17 /* Frequency Synthesizer Calibration Reg. 0 */ +#define CC1200_FS_CHP 0x2F18 /* Frequency Synthesizer Charge Pump Configuration */ +#define CC1200_FS_DIVTWO 0x2F19 /* Frequency Synthesizer Divide by 2 */ +#define CC1200_FS_DSM1 0x2F1A /* FS Digital Synthesizer Module Configuration Reg. 1 */ +#define CC1200_FS_DSM0 0x2F1B /* FS Digital Synthesizer Module Configuration Reg. 0 */ +#define CC1200_FS_DVC1 0x2F1C /* Frequency Synthesizer Divider Chain Configuration .. */ +#define CC1200_FS_DVC0 0x2F1D /* Frequency Synthesizer Divider Chain Configuration .. */ +#define CC1200_FS_LBI 0x2F1E /* Frequency Synthesizer Local Bias Configuration */ +#define CC1200_FS_PFD 0x2F1F /* Frequency Synthesizer Phase Frequency Detector Con.. */ +#define CC1200_FS_PRE 0x2F20 /* Frequency Synthesizer Prescaler Configuration */ +#define CC1200_FS_REG_DIV_CML 0x2F21 /* Frequency Synthesizer Divider Regulator Configurat.. */ +#define CC1200_FS_SPARE 0x2F22 /* Frequency Synthesizer Spare */ +#define CC1200_FS_VCO4 0x2F23 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_FS_VCO3 0x2F24 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_FS_VCO2 0x2F25 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_FS_VCO1 0x2F26 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_FS_VCO0 0x2F27 /* FS Voltage Controlled Oscillator Configuration Reg.. */ +#define CC1200_GBIAS6 0x2F28 /* Global Bias Configuration Reg. 6 */ +#define CC1200_GBIAS5 0x2F29 /* Global Bias Configuration Reg. 5 */ +#define CC1200_GBIAS4 0x2F2A /* Global Bias Configuration Reg. 4 */ +#define CC1200_GBIAS3 0x2F2B /* Global Bias Configuration Reg. 3 */ +#define CC1200_GBIAS2 0x2F2C /* Global Bias Configuration Reg. 2 */ +#define CC1200_GBIAS1 0x2F2D /* Global Bias Configuration Reg. 1 */ +#define CC1200_GBIAS0 0x2F2E /* Global Bias Configuration Reg. 0 */ +#define CC1200_IFAMP 0x2F2F /* Intermediate Frequency Amplifier Configuration */ +#define CC1200_LNA 0x2F30 /* Low Noise Amplifier Configuration */ +#define CC1200_RXMIX 0x2F31 /* RX Mixer Configuration */ +#define CC1200_XOSC5 0x2F32 /* Crystal Oscillator Configuration Reg. 5 */ +#define CC1200_XOSC4 0x2F33 /* Crystal Oscillator Configuration Reg. 4 */ +#define CC1200_XOSC3 0x2F34 /* Crystal Oscillator Configuration Reg. 3 */ +#define CC1200_XOSC2 0x2F35 /* Crystal Oscillator Configuration Reg. 2 */ +#define CC1200_XOSC1 0x2F36 /* Crystal Oscillator Configuration Reg. 1 */ +#define CC1200_XOSC0 0x2F37 /* Crystal Oscillator Configuration Reg. 0 */ +#define CC1200_ANALOG_SPARE 0x2F38 /* Analog Spare */ +#define CC1200_PA_CFG3 0x2F39 /* Power Amplifier Configuration Reg. 3 */ +#define CC1200_WOR_TIME1 0x2F64 /* eWOR Timer Counter Value MSB */ +#define CC1200_WOR_TIME0 0x2F65 /* eWOR Timer Counter Value LSB */ +#define CC1200_WOR_CAPTURE1 0x2F66 /* eWOR Timer Capture Value MSB */ +#define CC1200_WOR_CAPTURE0 0x2F67 /* eWOR Timer Capture Value LSB */ +#define CC1200_BIST 0x2F68 /* MARC Built-In Self-Test */ +#define CC1200_DCFILTOFFSET_I1 0x2F69 /* DC Filter Offset I MSB */ +#define CC1200_DCFILTOFFSET_I0 0x2F6A /* DC Filter Offset I LSB */ +#define CC1200_DCFILTOFFSET_Q1 0x2F6B /* DC Filter Offset Q MSB */ +#define CC1200_DCFILTOFFSET_Q0 0x2F6C /* DC Filter Offset Q LSB */ +#define CC1200_IQIE_I1 0x2F6D /* IQ Imbalance Value I MSB */ +#define CC1200_IQIE_I0 0x2F6E /* IQ Imbalance Value I LSB */ +#define CC1200_IQIE_Q1 0x2F6F /* IQ Imbalance Value Q MSB */ +#define CC1200_IQIE_Q0 0x2F70 /* IQ Imbalance Value Q LSB */ +#define CC1200_RSSI1 0x2F71 /* Received Signal Strength Indicator Reg. 1 */ +#define CC1200_RSSI0 0x2F72 /* Received Signal Strength Indicator Reg.0 */ +#define CC1200_MARCSTATE 0x2F73 /* MARC State */ +#define CC1200_LQI_VAL 0x2F74 /* Link Quality Indicator Value */ +#define CC1200_PQT_SYNC_ERR 0x2F75 /* Preamble and Sync Word Error */ +#define CC1200_DEM_STATUS 0x2F76 /* Demodulator Status */ +#define CC1200_FREQOFF_EST1 0x2F77 /* Frequency Offset Estimate MSB */ +#define CC1200_FREQOFF_EST0 0x2F78 /* Frequency Offset Estimate LSB */ +#define CC1200_AGC_GAIN3 0x2F79 /* Automatic Gain Control Reg. 3 */ +#define CC1200_AGC_GAIN2 0x2F7A /* Automatic Gain Control Reg. 2 */ +#define CC1200_AGC_GAIN1 0x2F7B /* Automatic Gain Control Reg. 1 */ +#define CC1200_AGC_GAIN0 0x2F7C /* Automatic Gain Control Reg. 0 */ +#define CC1200_CFM_RX_DATA_OUT 0x2F7D /* Custom Frequency Modulation RX Data */ +#define CC1200_CFM_TX_DATA_IN 0x2F7E /* Custom Frequency Modulation TX Data */ +#define CC1200_ASK_SOFT_RX_DATA 0x2F7F /* ASK Soft Decision Output */ +#define CC1200_RNDGEN 0x2F80 /* Random Number Generator Value */ +#define CC1200_MAGN2 0x2F81 /* Signal Magnitude after CORDIC [16] */ +#define CC1200_MAGN1 0x2F82 /* Signal Magnitude after CORDIC [15:8] */ +#define CC1200_MAGN0 0x2F83 /* Signal Magnitude after CORDIC [7:0] */ +#define CC1200_ANG1 0x2F84 /* Signal Angular after CORDIC [9:8] */ +#define CC1200_ANG0 0x2F85 /* Signal Angular after CORDIC [7:0] */ +#define CC1200_CHFILT_I2 0x2F86 /* Channel Filter Data Real Part [16] */ +#define CC1200_CHFILT_I1 0x2F87 /* Channel Filter Data Real Part [15:8] */ +#define CC1200_CHFILT_I0 0x2F88 /* Channel Filter Data Real Part [7:0] */ +#define CC1200_CHFILT_Q2 0x2F89 /* Channel Filter Data Imaginary Part [16] */ +#define CC1200_CHFILT_Q1 0x2F8A /* Channel Filter Data Imaginary Part [15:8] */ +#define CC1200_CHFILT_Q0 0x2F8B /* Channel Filter Data Imaginary Part [7:0] */ +#define CC1200_GPIO_STATUS 0x2F8C /* General Purpose Input/Output Status */ +#define CC1200_FSCAL_CTRL 0x2F8D /* Frequency Synthesizer Calibration Control */ +#define CC1200_PHASE_ADJUST 0x2F8E /* Frequency Synthesizer Phase Adjust */ +#define CC1200_PARTNUMBER 0x2F8F /* Part Number */ +#define CC1200_PARTVERSION 0x2F90 /* Part Revision */ +#define CC1200_SERIAL_STATUS 0x2F91 /* Serial Status */ +#define CC1200_MODEM_STATUS1 0x2F92 /* Modem Status Reg. 1 */ +#define CC1200_MODEM_STATUS0 0x2F93 /* Modem Status Reg. 0 */ +#define CC1200_MARC_STATUS1 0x2F94 /* MARC Status Reg. 1 */ +#define CC1200_MARC_STATUS0 0x2F95 /* MARC Status Reg. 0 */ +#define CC1200_PA_IFAMP_TEST 0x2F96 /* Power Amplifier Intermediate Frequency Amplifier T.. */ +#define CC1200_FSRF_TEST 0x2F97 /* Frequency Synthesizer Test */ +#define CC1200_PRE_TEST 0x2F98 /* Frequency Synthesizer Prescaler Test */ +#define CC1200_PRE_OVR 0x2F99 /* Frequency Synthesizer Prescaler Override */ +#define CC1200_ADC_TEST 0x2F9A /* Analog to Digital Converter Test */ +#define CC1200_DVC_TEST 0x2F9B /* Digital Divider Chain Test */ +#define CC1200_ATEST 0x2F9C /* Analog Test */ +#define CC1200_ATEST_LVDS 0x2F9D /* Analog Test LVDS */ +#define CC1200_ATEST_MODE 0x2F9E /* Analog Test Mode */ +#define CC1200_XOSC_TEST1 0x2F9F /* Crystal Oscillator Test Reg. 1 */ +#define CC1200_XOSC_TEST0 0x2FA0 /* Crystal Oscillator Test Reg. 0 */ +#define CC1200_AES 0x2FA1 /* AES */ +#define CC1200_MDM_TEST 0x2FA2 /* MODEM Test */ +#define CC1200_RXFIRST 0x2FD2 /* RX FIFO Pointer First Entry */ +#define CC1200_TXFIRST 0x2FD3 /* TX FIFO Pointer First Entry */ +#define CC1200_RXLAST 0x2FD4 /* RX FIFO Pointer Last Entry */ +#define CC1200_TXLAST 0x2FD5 /* TX FIFO Pointer Last Entry */ +#define CC1200_NUM_TXBYTES 0x2FD6 /* TX FIFO Status */ +#define CC1200_NUM_RXBYTES 0x2FD7 /* RX FIFO Status */ +#define CC1200_FIFO_NUM_TXBYTES 0x2FD8 /* TX FIFO Status */ +#define CC1200_FIFO_NUM_RXBYTES 0x2FD9 /* RX FIFO Status */ +#define CC1200_RXFIFO_PRE_BUF 0x2FDA /* RX FIFO Status */ +#define CC1200_AES_KEY15 0x2FE0 /* Advanced Encryption Standard Key [127:120] */ +#define CC1200_AES_KEY14 0x2FE1 /* Advanced Encryption Standard Key [119:112] */ +#define CC1200_AES_KEY13 0x2FE2 /* Advanced Encryption Standard Key [111:104] */ +#define CC1200_AES_KEY12 0x2FE3 /* Advanced Encryption Standard Key [103:96] */ +#define CC1200_AES_KEY11 0x2FE4 /* Advanced Encryption Standard Key [95:88] */ +#define CC1200_AES_KEY10 0x2FE5 /* Advanced Encryption Standard Key [87:80] */ +#define CC1200_AES_KEY9 0x2FE6 /* Advanced Encryption Standard Key [79:72] */ +#define CC1200_AES_KEY8 0x2FE7 /* Advanced Encryption Standard Key [71:64] */ +#define CC1200_AES_KEY7 0x2FE8 /* Advanced Encryption Standard Key [63:56] */ +#define CC1200_AES_KEY6 0x2FE9 /* Advanced Encryption Standard Key [55:48] */ +#define CC1200_AES_KEY5 0x2FEA /* Advanced Encryption Standard Key [47:40] */ +#define CC1200_AES_KEY4 0x2FEB /* Advanced Encryption Standard Key [39:32] */ +#define CC1200_AES_KEY3 0x2FEC /* Advanced Encryption Standard Key [31:24] */ +#define CC1200_AES_KEY2 0x2FED /* Advanced Encryption Standard Key [23:16] */ +#define CC1200_AES_KEY1 0x2FEE /* Advanced Encryption Standard Key [15:8] */ +#define CC1200_AES_KEY0 0x2FEF /* Advanced Encryption Standard Key [7:0] */ +#define CC1200_AES_BUFFER15 0x2FF0 /* Advanced Encryption Standard Buffer [127:120] */ +#define CC1200_AES_BUFFER14 0x2FF1 /* Advanced Encryption Standard Buffer [119:112] */ +#define CC1200_AES_BUFFER13 0x2FF2 /* Advanced Encryption Standard Buffer [111:104] */ +#define CC1200_AES_BUFFER12 0x2FF3 /* Advanced Encryption Standard Buffer [103:93] */ +#define CC1200_AES_BUFFER11 0x2FF4 /* Advanced Encryption Standard Buffer [95:88] */ +#define CC1200_AES_BUFFER10 0x2FF5 /* Advanced Encryption Standard Buffer [87:80] */ +#define CC1200_AES_BUFFER9 0x2FF6 /* Advanced Encryption Standard Buffer [79:72] */ +#define CC1200_AES_BUFFER8 0x2FF7 /* Advanced Encryption Standard Buffer [71:64] */ +#define CC1200_AES_BUFFER7 0x2FF8 /* Advanced Encryption Standard Buffer [63:56] */ +#define CC1200_AES_BUFFER6 0x2FF9 /* Advanced Encryption Standard Buffer [55:48] */ +#define CC1200_AES_BUFFER5 0x2FFA /* Advanced Encryption Standard Buffer [47:40] */ +#define CC1200_AES_BUFFER4 0x2FFB /* Advanced Encryption Standard Buffer [39:32] */ +#define CC1200_AES_BUFFER3 0x2FFC /* Advanced Encryption Standard Buffer [31:24] */ +#define CC1200_AES_BUFFER2 0x2FFD /* Advanced Encryption Standard Buffer [23:16] */ +#define CC1200_AES_BUFFER1 0x2FFE /* Advanced Encryption Standard Buffer [15:8] */ +#define CC1200_AES_BUFFER0 0x2FFF /* Advanced Encryption Standard Buffer [7:0] */ +/*---------------------------------------------------------------------------*/ +/* Access to RX / TX FIFO */ +#define CC1200_TXFIFO 0x3F +#define CC1200_RXFIFO 0x3F +/*---------------------------------------------------------------------------*/ +/* MARC_STATE */ +#define CC1200_MARC_STATE_SLEEP 0x00 +#define CC1200_MARC_STATE_IDLE 0x01 +#define CC1200_MARC_STATE_RX 0x0D +#define CC1200_MARC_STATE_RX_FIFO_ERR 0x11 +#define CC1200_MARC_STATE_TX 0x13 +#define CC1200_MARC_STATE_TX_FIFO_ERR 0x16 +/*---------------------------------------------------------------------------*/ +/* Status byte */ +#define CC1200_STATUS_BYTE_IDLE (0 << 4) +#define CC1200_STATUS_BYTE_RX (1 << 4) +#define CC1200_STATUS_BYTE_TX (2 << 4) +#define CC1200_STATUS_BYTE_FSTXON (3 << 4) +#define CC1200_STATUS_BYTE_CALIBRATE (4 << 4) +#define CC1200_STATUS_BYTE_SETTLING (5 << 4) +#define CC1200_STATUS_BYTE_RX_FIFO_ERR (6 << 4) +#define CC1200_STATUS_BYTE_TX_FIFO_ERR (7 << 4) +/*---------------------------------------------------------------------------*/ +/* GPIO configuration */ +#define CC1200_IOCFG_RXFIFO_THR 0 +#define CC1200_IOCFG_RXFFIFO_THR_PKT 1 +#define CC1200_IOCFG_TXFIFO_THR 2 +#define CC1200_IOCFG_PKT_SYNC_RXTX 6 +#define CC1200_IOCFG_SERIAL_CLK 8 +#define CC1200_IOCFG_SERIAL_RX 9 +#define CC1200_IOCFG_CARRIER_SENSE 17 +#define CC1200_IOCFG_MARC_2PIN_STATUS_1 37 +#define CC1200_IOCFG_MARC_2PIN_STATUS_0 38 +#define CC1200_IOCFG_RXFIFO_CHIP_RDY_N 50 +/*---------------------------------------------------------------------------*/ +/* Command strobes */ +#define CC1200_SRES 0x30 +#define CC1200_SFSTXON 0x31 +#define CC1200_SXOFF 0x32 +#define CC1200_SCAL 0x33 +#define CC1200_SRX 0x34 +#define CC1200_STX 0x35 +#define CC1200_SIDLE 0x36 +#define CC1200_SPWD 0x39 +#define CC1200_SFRX 0x3A +#define CC1200_SFTX 0x3B +#define CC1200_SNOP 0x3D +/*---------------------------------------------------------------------------*/ +/* SPI access modifier */ +#define CC1200_WRITE_BIT 0x00 +#define CC1200_READ_BIT 0x80 +#define CC1200_BURST_BIT 0x40 +#define CC1200_EXTENDED_WRITE_CMD (0x2F | CC1200_WRITE_BIT) +#define CC1200_EXTENDED_BURST_WRITE_CMD \ + (0x2F | CC1200_BURST_BIT | CC1200_WRITE_BIT) +#define CC1200_EXTENDED_READ_CMD (0x2F | CC1200_READ_BIT) +#define CC1200_EXTENDED_BURST_READ_CMD \ + (0x2F | CC1200_BURST_BIT | CC1200_READ_BIT) +/*---------------------------------------------------------------------------*/ +#define CC1200_IS_EXTENDED_ADDR(x) (x & 0x2F00) +/*---------------------------------------------------------------------------*/ +/* RSSI0 register */ +#define CC1200_CARRIER_SENSE_VALID (1 << 1) +#define CC1200_CARRIER_SENSE (1 << 2) +/*---------------------------------------------------------------------------*/ +/* MODEM_STATUS1 register */ +#define CC1200_SYNC_FOUND (1 << 7) +#define CC1200_PQT_REACHED (1 << 1) +/*---------------------------------------------------------------------------*/ +#define CC1200_FIFO_SIZE 128 +/*---------------------------------------------------------------------------*/ +/* Output power in dBm */ +/* Up to now we don't handle the special power levels PA_POWER_RAMP < 3, hence + * the minimum tx power is -16. See update_txpower(). + */ +#define CC1200_CONST_TX_POWER_MIN (-16) +/* + * Maximum output power will propably depend on the band we use due to + * regulation issues + */ +#define CC1200_CONST_TX_POWER_MAX 14 +/*---------------------------------------------------------------------------*/ +/* CCA threshold in dBm */ +#define CC1200_CONST_CCA_THRESHOLD_MIN (-127) +#define CC1200_CONST_CCA_THRESHOLD_MAX 127 + +#endif /* CC1200_CONST_H_ */ diff --git a/dev/cc1200/cc1200-rf-cfg.h b/dev/cc1200/cc1200-rf-cfg.h new file mode 100644 index 000000000..c7ba53527 --- /dev/null +++ b/dev/cc1200/cc1200-rf-cfg.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +#ifndef CC1200_RF_CFG_H +#define CC1200_RF_CFG_H + +#include "contiki.h" + +#include +#include + +/*---------------------------------------------------------------------------*/ +/* + * We export the register setup from SmartRF using the standard template + * "trxEB RF Settings Performance Line" and have therefore to typedef + * the following struct. + */ +typedef struct cc1200_registerSetting { + uint16_t addr; + uint8_t val; +} registerSetting_t; +/*---------------------------------------------------------------------------*/ +/* Map SmartRF typedef to reflect Contiki's naming conventions */ +typedef registerSetting_t cc1200_register_settings_t; +/*---------------------------------------------------------------------------*/ +/* This struct holds the complete configuration for a given mode */ +typedef struct cc1200_rf_cfg { + /* A string describing the mode */ + const char *cfg_descriptor; + /* A pointer to a register setup exported from SmartRF */ + const cc1200_register_settings_t *register_settings; + /* The size of the register setup */ + size_t size_of_register_settings; + /* + * TX packet lifetime. Maximum duration of a TX packet including preamble, + * synch word + phy header, payload + CRC. + */ + rtimer_clock_t tx_pkt_lifetime; + /* Base frequency in kHz */ + uint32_t chan_center_freq0; + /* Channel spacing in kHz */ + uint16_t chan_spacing; + /* The minimum channel */ + uint8_t min_channel; + /* The maximum channel */ + uint8_t max_channel; + /* The maximum output power in dBm */ + int8_t max_txpower; + /* + * The carrier sense level used for CCA in dBm (int8_t). Limited by + * CC1200_CONST_CCA_THRESHOLD_MIN and CC1200_CONST_CCA_THRESHOLD_MAX. + */ + int8_t cca_threshold; +} cc1200_rf_cfg_t; +/*---------------------------------------------------------------------------*/ +#endif /* CC1200_RF_CFG_H */ diff --git a/dev/cc1200/cc1200.c b/dev/cc1200/cc1200.c new file mode 100644 index 000000000..bee144dd4 --- /dev/null +++ b/dev/cc1200/cc1200.c @@ -0,0 +1,2442 @@ +/* + * Copyright (c) 2015, Weptech elektronik GmbH Germany + * http://www.weptech.de + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + */ + +#include "cc1200-const.h" +#include "cc1200-conf.h" +#include "cc1200-arch.h" +#include "cc1200-rf-cfg.h" + +#include "net/netstack.h" +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" + +#include "dev/leds.h" + +#include +#include + +/*---------------------------------------------------------------------------*/ +/* Various implementation specific defines */ +/*---------------------------------------------------------------------------*/ +/* + * The debug level to use + * - 0: No output at all + * - 1: Print errors (unrecoverable) + * - 2: Print errors + warnings (recoverable errors) + * - 3: Print errors + warnings + information (what's going on...) + */ +#define DEBUG_LEVEL 2 +/* If set to 1, we use a timer to poll RX mode inside the cc1200 process */ +#define USE_RX_WATCHDOG 1 +/* + * RF test mode. Blocks inside "configure()". + * - Set this parameter to 1 in order to produce an modulated carrier (PN9) + * - Set this parameter to 2 in order to produce an unmodulated carrier + * - Set this parameter to 3 in order to switch to rx synchronous mode + * The channel is set according to CC1200_DEFAULT_CHANNEL + */ +#define RF_TESTMODE 0 +#if RF_TESTMODE +#undef CC1200_RF_CFG +#if RF_TESTMODE == 1 +#define CC1200_RF_CFG cc1200_802154g_863_870_fsk_50kbps +#elif RF_TESTMODE == 2 +#define CC1200_RF_CFG cc1200_802154g_863_870_fsk_50kbps +#elif RF_TESTMODE == 3 +#define CC1200_RF_CFG cc1200_802154g_863_870_fsk_50kbps +#endif +#endif +/* + * Set this parameter to 1 in order to use the MARC_STATE register when + * polling the chips's status. Else use the status byte returned when sending + * a NOP strobe. + * + * TODO: Option to be removed upon approval of the driver + */ +#define STATE_USES_MARC_STATE 0 +/* + * Set this parameter to 1 in order to speed up transmission by + * sending a FSTXON strobe before filling the FIFO. + * + * TODO: Option to be removed upon approval of the driver + */ +#define USE_SFSTXON 1 +/*---------------------------------------------------------------------------*/ +/* Phy header length */ +#if CC1200_802154G +/* Phy header = 2 byte */ +#define PHR_LEN 2 +#else +/* Phy header = length byte = 1 byte */ +#define PHR_LEN 1 +#endif /* #if CC1200_802154G */ +/*---------------------------------------------------------------------------*/ +/* Size of appendix (rssi + lqi) appended to the rx pkt */ +#define APPENDIX_LEN 2 +/*---------------------------------------------------------------------------*/ +/* Verify payload length */ +/*---------------------------------------------------------------------------*/ +#if CC1200_802154G +#if CC1200_USE_GPIO2 +#if CC1200_MAX_PAYLOAD_LEN > (2048 - PHR_LEN) +#error Payload length not supported by this driver +#endif +#else +#if CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN) +/* PHR_LEN = 2 -> we can only place 126 payload bytes bytes in the FIFO */ +#error Payload length not supported without GPIO2 +#endif +#endif /* #if CC1200_USE_GPIO2 */ +#else /* #if CC1200_802154G */ +#if CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN) +/* PHR_LEN = 1 -> we can only place 127 payload bytes bytes in the FIFO */ +#error Payload length not supported without enabling 802.15.4g mode +#endif +#endif /* #if CC1200_802154G */ +/*---------------------------------------------------------------------------*/ +/* Main driver configurations settings. Don't touch! */ +/*---------------------------------------------------------------------------*/ +#if CC1200_USE_GPIO2 +/* Use GPIO2 as RX / TX FIFO threshold indicator pin */ +#define GPIO2_IOCFG CC1200_IOCFG_RXFIFO_THR +/* This is the FIFO threshold we use */ +#define FIFO_THRESHOLD 32 +/* Turn on RX after packet reception */ +#define RXOFF_MODE_RX 1 +/* Let the CC1200 append RSSI + LQI */ +#define APPEND_STATUS 1 +#else +/* Arbitrary configuration for GPIO2 */ +#define GPIO2_IOCFG CC1200_IOCFG_MARC_2PIN_STATUS_0 +#if (CC1200_MAX_PAYLOAD_LEN <= (CC1200_FIFO_SIZE - PHR_LEN - APPENDIX_LEN)) +/* + * Read out RX FIFO at the end of the packet (GPIO0 falling edge). RX restarts + * automatically + */ +#define RXOFF_MODE_RX 1 +/* Let the CC1200 append RSSI + LQI */ +#define APPEND_STATUS 1 +#else +/* + * Read out RX FIFO at the end of the packet (GPIO0 falling edge). RX has + * to be started manually in this case + */ +#define RXOFF_MODE_RX 0 +/* No space for appendix in the RX FIFO. Read it out by hand */ +#define APPEND_STATUS 0 +#endif /* #if CC1200_MAX_PAYLOAD_LEN <= 125 */ +#endif /* #if CC1200_USE_GPIO2 */ + +/* Read out packet on falling edge of GPIO0 */ +#define GPIO0_IOCFG CC1200_IOCFG_PKT_SYNC_RXTX +/* Arbitrary configuration for GPIO3 */ +#define GPIO3_IOCFG CC1200_IOCFG_MARC_2PIN_STATUS_0 +/* Turn on RX automatically after TX */ +#define TXOFF_MODE_RX 1 +#if APPEND_STATUS +/* CC1200 places two bytes in the RX FIFO */ +#define CC_APPENDIX_LEN 2 +#else +/* CC1200 doesn't add appendix to RX FIFO */ +#define CC_APPENDIX_LEN 0 +#endif /* #if APPEND_STATUS */ +/*---------------------------------------------------------------------------*/ +/* RF configuration */ +/*---------------------------------------------------------------------------*/ +/* Import the rf configuration set by CC1200_RF_CFG */ +extern const cc1200_rf_cfg_t CC1200_RF_CFG; +/*---------------------------------------------------------------------------*/ +/* This defines the way we calculate the frequency registers */ +/*---------------------------------------------------------------------------*/ +/* XTAL frequency in kHz */ +#define XTAL_FREQ_KHZ 40000 +/* + * Divider + multiplier for calculation of FREQ registers + * f * 2^16 * 4 / 40000 = f * 2^12 / 625 (no overflow up to frequencies of + * 1048.576 MHz using uint32_t) + */ +#define LO_DIVIDER 4 +#if (XTAL_FREQ_KHZ == 40000) && (LO_DIVIDER == 4) +#define FREQ_DIVIDER 625 +#define FREQ_MULTIPLIER 4096 +#else +#error Invalid settings for frequency calculation +#endif +/*---------------------------------------------------------------------------*/ +#if STATE_USES_MARC_STATE +/* We use the MARC_STATE register to poll the chip's status */ +#define STATE_IDLE CC1200_MARC_STATE_IDLE +#define STATE_RX CC1200_MARC_STATE_RX +#define STATE_TX CC1200_MARC_STATE_TX +#define STATE_RX_FIFO_ERROR CC1200_MARC_STATE_RX_FIFO_ERR +#define STATE_TX_FIFO_ERROR CC1200_MARC_STATE_TX_FIFO_ERR +#else +/* We use the status byte read out using a NOP strobe */ +#define STATE_IDLE CC1200_STATUS_BYTE_IDLE +#define STATE_RX CC1200_STATUS_BYTE_RX +#define STATE_TX CC1200_STATUS_BYTE_TX +#define STATE_FSTXON CC1200_STATUS_BYTE_FSTXON +#define STATE_CALIBRATE CC1200_STATUS_BYTE_CALIBRATE +#define STATE_SETTLING CC1200_STATUS_BYTE_SETTLING +#define STATE_RX_FIFO_ERR CC1200_STATUS_BYTE_RX_FIFO_ERR +#define STATE_TX_FIFO_ERR CC1200_STATUS_BYTE_TX_FIFO_ERR +#endif /* #if STATE_USES_MARC_STATE */ +/*---------------------------------------------------------------------------*/ +/* Return values for addr_check_auto_ack() */ +/*---------------------------------------------------------------------------*/ +/* Frame cannot be parsed / is to short */ +#define INVALID_FRAME 0 +/* Address check failed */ +#define ADDR_CHECK_FAILED 1 +/* Address check succeeded */ +#define ADDR_CHECK_OK 2 +/* Address check succeeded and ACK was send */ +#define ADDR_CHECK_OK_ACK_SEND 3 +/*---------------------------------------------------------------------------*/ +/* Return values for set_channel() */ +/*---------------------------------------------------------------------------*/ +/* Channel update was performed */ +#define CHANNEL_UPDATE_SUCCEEDED 0 +/* Busy, channel update postponed */ +#define CHANNEL_UPDATE_POSTPONED 1 +/* Invalid channel */ +#define CHANNEL_OUT_OF_LIMITS 2 +/*---------------------------------------------------------------------------*/ +/* Various flags indicating the operating state of the radio. See rf_flags */ +/*---------------------------------------------------------------------------*/ +/* Radio was initialized (= init() was called) */ +#define RF_INITIALIZED 0x01 +/* The radio is on (= not in standby) */ +#define RF_ON 0x02 +/* An incoming packet was detected (at least payload length was received */ +#define RF_RX_PROCESSING_PKT 0x04 +/* TX is ongoing */ +#define RF_TX_ACTIVE 0x08 +/* Channel update required */ +#define RF_UPDATE_CHANNEL 0x10 +/* SPI was locked when calling RX interrupt, let the pollhandler do the job */ +#define RF_POLL_RX_INTERRUPT 0x20 +/*---------------------------------------------------------------------------*/ +/* Length of 802.15.4 ACK. We discard packets with a smaller size */ +#define ACK_LEN 3 +/*---------------------------------------------------------------------------*/ +/* This is the way we handle the LEDs */ +/*---------------------------------------------------------------------------*/ +#ifdef CC1200_TX_LEDS +#define TX_LEDS_ON() leds_on(CC1200_TX_LEDS) +#define TX_LEDS_OFF() leds_off(CC1200_TX_LEDS) +#else +#define TX_LEDS_ON() +#define TX_LEDS_OFF() +#endif /* #ifdef CC1200_TX_LEDS */ + +#ifdef CC1200_RX_LEDS +#define RX_LEDS_ON() leds_on(CC1200_RX_LEDS) +#define RX_LEDS_OFF() leds_off(CC1200_RX_LEDS) +#else +#define RX_LEDS_ON() +#define RX_LEDS_OFF() +#endif /* #ifdef CC1200_RX_LEDS */ +/*---------------------------------------------------------------------------*/ +/* + * We have to prevent duplicate SPI access. + * We therefore LOCK SPI in order to prevent the rx interrupt to + * interfere. + */ +#define LOCK_SPI() do { spi_locked++; } while(0) +#define SPI_IS_LOCKED() (spi_locked != 0) +#define RELEASE_SPI() do { spi_locked--; } while(0) +/*---------------------------------------------------------------------------*/ +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))) {} \ + } while(0) +/*---------------------------------------------------------------------------*/ +#if CC1200_USE_GPIO2 +/* Configure GPIO interrupts. GPIO0: falling, GPIO2: rising edge */ +#define SETUP_GPIO_INTERRUPTS() \ + do { \ + cc1200_arch_gpio0_setup_irq(0); \ + cc1200_arch_gpio2_setup_irq(1); \ + } while(0) +#define ENABLE_GPIO_INTERRUPTS() \ + do { \ + cc1200_arch_gpio0_enable_irq(); \ + cc1200_arch_gpio2_enable_irq(); \ + } while(0) +#define DISABLE_GPIO_INTERRUPTS() \ + do { \ + cc1200_arch_gpio0_disable_irq(); \ + cc1200_arch_gpio2_disable_irq(); \ + } while(0) +#else +#define SETUP_GPIO_INTERRUPTS() cc1200_arch_gpio0_setup_irq(0) +#define ENABLE_GPIO_INTERRUPTS() cc1200_arch_gpio0_enable_irq() +#define DISABLE_GPIO_INTERRUPTS() cc1200_arch_gpio0_disable_irq() +#endif /* #if CC1200_USE_GPIO2 */ +/*---------------------------------------------------------------------------*/ +/* Debug macros */ +/*---------------------------------------------------------------------------*/ +#if DEBUG_LEVEL > 0 +/* Show all kind of errors e.g. when passing invalid payload length */ +#define ERROR(...) printf(__VA_ARGS__) +#else +#define ERROR(...) +#endif + +#if DEBUG_LEVEL > 0 +/* This macro is used to check if the radio is in a valid state */ +#define RF_ASSERT(condition) \ + do { \ + if(!(condition)) { \ + printf("RF: Assertion failed in line %d\n", __LINE__); \ + } \ + } while(0) +#else +#define RF_ASSERT(condition) +#endif + +#if DEBUG_LEVEL > 1 +/* Show warnings e.g. for FIFO errors */ +#define WARNING(...) printf(__VA_ARGS__) +#else +#define WARNING(...) +#endif + +#if DEBUG_LEVEL > 2 +/* We just print out what's going on */ +#define INFO(...) printf(__VA_ARGS__) +#else +#define INFO(...) +#endif + +#if DEBUG_LEVEL > 0 +/* + * As BUSYWAIT_UNTIL was mainly used to test for a state transition, + * we define a separate macro for this adding the possibility to + * throw an error message when the timeout exceeds + */ +#define BUSYWAIT_UNTIL_STATE(s, t) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while((state() != s) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (t))) {} \ + if(!(RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (t)))) { \ + printf("RF: Timeout exceeded in line %d!\n", __LINE__); \ + } \ + } while(0) +#else +#define BUSYWAIT_UNTIL_STATE(s, t) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while((state() != s) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (t))) {} \ + } while(0) +#endif +/*---------------------------------------------------------------------------*/ +/* Variables */ +/*---------------------------------------------------------------------------*/ +/* Flag indicating whether non-interrupt routines are using SPI */ +static volatile uint8_t spi_locked = 0; +/* Packet buffer for transmission, filled within prepare() */ +static uint8_t tx_pkt[CC1200_MAX_PAYLOAD_LEN]; +/* The number of bytes waiting in tx_pkt */ +static uint16_t tx_pkt_len; +/* Packet buffer for reception */ +static uint8_t rx_pkt[CC1200_MAX_PAYLOAD_LEN + APPENDIX_LEN]; +/* The number of bytes placed in rx_pkt */ +static volatile uint16_t rx_pkt_len = 0; +/* + * The current channel in the range CC1200_RF_CHANNEL_MIN + * to CC1200_RF_CHANNEL_MAX + */ +static uint8_t rf_channel; +/* The next channel requested */ +static uint8_t new_rf_channel; +/* RADIO_PARAM_RX_MODE. Initialized in init() */ +static radio_value_t rx_mode_value; +/* RADIO_PARAM_RX_MODE. Initialized in init() */ +static radio_value_t tx_mode_value; +/* RADIO_PARAM_TXPOWER in dBm. Initialized in init() */ +static int8_t txpower; +static int8_t new_txpower; +/* RADIO_PARAM_CCA_THRESHOLD. Initialized in init() */ +static int8_t cca_threshold; +static int8_t new_cca_threshold; +/* The radio drivers state */ +static uint8_t rf_flags = 0; +#if !CC1200_AUTOCAL && CC1200_CAL_TIMEOUT_SECONDS +/* Use a timeout to decide when to calibrate */ +static unsigned long cal_timer; +#endif +#if USE_RX_WATCHDOG +/* Timer used for RX watchdog */ +static struct etimer et; +#endif +/*---------------------------------------------------------------------------*/ +/* Prototypes for Netstack API radio driver functions */ +/*---------------------------------------------------------------------------*/ +/* Init the radio. */ +static int +init(void); +/* Prepare the radio with a packet to be sent. */ +static int +prepare(const void *payload, unsigned short payload_len); +/* Send the packet that has previously been prepared. */ +static int +transmit(unsigned short payload_len); +/* Prepare & transmit a packet. */ +static int +send(const void *payload, unsigned short payload_len); +/* Read a received packet into a buffer. */ +static int +read(void *buf, unsigned short bufsize); +/* + * Perform a Clear-Channel Assessment (CCA) to find out if there is + * a packet in the air or not. + */ +static int +channel_clear(void); +/* Check if the radio driver is currently receiving a packet. */ +static int +receiving_packet(void); +/* Check if the radio driver has just received a packet. */ +static int +pending_packet(void); +/* Turn the radio on. */ +static int +on(void); +/* Turn the radio off. */ +static int +off(void); +/* Get a radio parameter value. */ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value); +/* Set a radio parameter value. */ +static radio_result_t +set_value(radio_param_t param, radio_value_t value); +/* Get a radio parameter object. */ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size); +/* Set a radio parameter object. */ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size); +/*---------------------------------------------------------------------------*/ +/* The radio driver exported to contiki */ +/*---------------------------------------------------------------------------*/ +const struct radio_driver cc1200_driver = { + init, + prepare, + transmit, + send, + read, + channel_clear, + receiving_packet, + pending_packet, + on, + off, + get_value, + set_value, + get_object, + set_object +}; +/*---------------------------------------------------------------------------*/ +/* Prototypes for CC1200 low level function. All of these functions are + called by the radio driver functions or the rx interrupt, + so there is no need to lock SPI within these functions */ +/*---------------------------------------------------------------------------*/ +/* Send a command strobe. */ +static uint8_t +strobe(uint8_t strobe); +/* Reset CC1200. */ +static void +reset(void); +/* Write a single byte to the specified address. */ +static uint8_t +single_write(uint16_t addr, uint8_t value); +/* Read a single byte from the specified address. */ +static uint8_t +single_read(uint16_t addr); +/* Write a burst of bytes starting at the specified address. */ +static void +burst_write(uint16_t addr, const uint8_t *data, uint8_t data_len); +/* Read a burst of bytes starting at the specified address. */ +static void +burst_read(uint16_t addr, uint8_t *data, uint8_t data_len); +/* Write a list of register settings. */ +static void +write_reg_settings(const registerSetting_t *reg_settings, + uint16_t sizeof_reg_settings); +/* Configure the radio (write basic configuration). */ +static void +configure(void); +/* Return the radio's state. */ +static uint8_t +state(void); +#if !CC1200_AUTOCAL +/* Perform manual calibration. */ +static void +calibrate(void); +#endif +/* Enter IDLE state. */ +static void +idle(void); +/* Enter RX state. */ +static void +idle_calibrate_rx(void); +/* Restart RX from within RX interrupt. */ +static void +rx_rx(void); +/* Fill TX FIFO, start TX and wait for TX to complete (blocking!). */ +static int +idle_tx_rx(const uint8_t *payload, uint16_t payload_len); +/* Update TX power */ +static void +update_txpower(int8_t txpower_dbm); +/* Update CCA threshold */ +static void +update_cca_threshold(int8_t threshold_dbm); +/* Calculate FREQ register from channel */ +static uint32_t +calculate_freq(uint8_t channel); +/* Update rf channel if possible, else postpone it (-> pollhandler). */ +static int +set_channel(uint8_t channel); +#if !CC1200_SNIFFER +/* Check broadcast address. */ +static int +is_broadcast_addr(uint8_t mode, uint8_t *addr); +#endif /* CC1200_SNIFFER */ +/* Validate address and send ACK if requested. */ +static int +addr_check_auto_ack(uint8_t *frame, uint16_t frame_len); +/*---------------------------------------------------------------------------*/ +/* Handle tasks left over from rx interrupt or because SPI was locked */ +static void pollhandler(void); +/*---------------------------------------------------------------------------*/ +PROCESS(cc1200_process, "CC1200 driver"); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(cc1200_process, ev, data) +{ + + PROCESS_POLLHANDLER(pollhandler()); + + PROCESS_BEGIN(); + +#if USE_RX_WATCHDOG && !CC1200_SNIFFER + /* RX watchdog interferes with sniffer. Reason unknown... */ + while(1) { + + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + + if((rf_flags & (RF_ON | RF_TX_ACTIVE)) == RF_ON) { + + /* + * We are on and not in TX. As every function of this driver + * assures that we are in RX mode + * (using BUSYWAIT_UNTIL_STATE(STATE_RX, ...) construct) in + * either rx_rx(), idle_calibrate_rx() or transmit(), + * something probably went wrong in the rx interrupt handler + * if we are not in RX at this point. + */ + + if(cc1200_arch_gpio0_read_pin() == 0) { + + /* + * GPIO de-asserts as soon as we leave RX for what reason ever. No + * reason to check RX as long as it is asserted (we are receiving a + * packet). We should never interfere with the rx interrupt if we + * check GPIO0 in advance... + */ + + LOCK_SPI(); + if(state() != STATE_RX) { + WARNING("RF: RX watchdog triggered!\n"); + rx_rx(); + } + RELEASE_SPI(); + + } + + } + + } +#endif /* #if USE_RX_WATCHDOG */ + + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_EXIT); + + PROCESS_END(); + +} +/*---------------------------------------------------------------------------*/ +/* Handle tasks left over from rx interrupt or because SPI was locked */ +static void +pollhandler(void) +{ + + if((rf_flags & (RF_ON + RF_POLL_RX_INTERRUPT)) == + (RF_ON + RF_POLL_RX_INTERRUPT)) { + cc1200_rx_interrupt(); + } + + if(rf_flags & RF_UPDATE_CHANNEL) { + /* We couldn't set the channel because we were busy. Try again now. */ + set_channel(new_rf_channel); + } + + if(rx_pkt_len > 0) { + + int len; + + /* + * We received a valid packet. CRC was checked before, + * address filtering was performed (if configured) + * and ACK was send (if configured) + */ + + packetbuf_clear(); + len = read(packetbuf_dataptr(), PACKETBUF_SIZE); + + if(len > 0) { + packetbuf_set_datalen(len); + NETSTACK_RDC.input(); + } + + } + +} +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/* + * Netstack API radio driver functions + */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/* Initialize radio. */ +static int +init(void) +{ + + INFO("RF: Init (%s)\n", CC1200_RF_CFG.cfg_descriptor); + + if(!(rf_flags & RF_INITIALIZED)) { + + LOCK_SPI(); + + /* Perform low level initialization */ + cc1200_arch_init(); + + /* Configure GPIO interrupts */ + SETUP_GPIO_INTERRUPTS(); + + /* Write initial configuration */ + configure(); + + /* Enable address filtering + auto ack */ + rx_mode_value = (RADIO_RX_MODE_AUTOACK | RADIO_RX_MODE_ADDRESS_FILTER); + + /* Enable CCA */ + tx_mode_value = (RADIO_TX_MODE_SEND_ON_CCA); + + /* Set output power */ + new_txpower = CC1200_RF_CFG.max_txpower; + update_txpower(new_txpower); + + /* Adjust CAA threshold */ + new_cca_threshold = CC1200_RF_CFG.cca_threshold; + update_cca_threshold(new_cca_threshold); + + process_start(&cc1200_process, NULL); + + /* We are on + initialized at this point */ + rf_flags |= (RF_INITIALIZED + RF_ON); + + RELEASE_SPI(); + + /* Set default channel */ + set_channel(CC1200_DEFAULT_CHANNEL); + + /* + * We have to call off() before on() because on() relies on the + * configuration of the GPIO0 pin (even if we turn the radio on in + * sniffer mode afterwards) + */ + off(); + +#if CC1200_SNIFFER + on(); +#endif + + } + + return 1; + +} +/*---------------------------------------------------------------------------*/ +/* Prepare the radio with a packet to be sent. */ +static int +prepare(const void *payload, unsigned short payload_len) +{ + + INFO("RF: Prepare (%d)\n", payload_len); + + if((payload_len < ACK_LEN) || + (payload_len > CC1200_MAX_PAYLOAD_LEN)) { + ERROR("RF: Invalid payload length!\n"); + return RADIO_TX_ERR; + } + + tx_pkt_len = payload_len; + memcpy(tx_pkt, payload, tx_pkt_len); + + return RADIO_TX_OK; + +} +/*---------------------------------------------------------------------------*/ +/* Send the packet that has previously been prepared. */ +static int +transmit(unsigned short transmit_len) +{ + + uint8_t was_off = 0; + int ret = RADIO_TX_OK; + + INFO("RF: Transmit (%d)\n", transmit_len); + + if(transmit_len != tx_pkt_len) { + ERROR("RF: TX length mismatch!\n"); + return RADIO_TX_ERR; + } + + /* TX ongoing. Inhibit channel update & ACK as soon as possible */ + rf_flags |= RF_TX_ACTIVE; + + if(!(rf_flags & RF_ON)) { + /* Radio is off - turn it on */ + was_off = 1; + on(); + /* Radio is in RX now (and calibrated...) */ + } + + if(tx_mode_value & RADIO_TX_MODE_SEND_ON_CCA) { + /* Perform clear channel assessment */ + if(!channel_clear()) { + /* Channel occupied */ + RIMESTATS_ADD(contentiondrop); + if(was_off) { + off(); + } + rf_flags &= ~RF_TX_ACTIVE; + return RADIO_TX_COLLISION; + } + } + + /* + * Lock SPI here because "on()" and "channel_clear()" + * won't work if SPI is locked! + */ + LOCK_SPI(); + + /* + * Make sure we start from a sane state. idle() also disables + * the GPIO interrupt(s). + */ + idle(); + + /* Update output power */ + if(new_txpower != txpower) { + update_txpower(new_txpower); + } + +#if !CC1200_AUTOCAL + /* Perform manual calibration unless just turned on */ + if(!was_off) { +#if CC1200_CAL_TIMEOUT_SECONDS + /* Calibrate after a delay defined by CC1200_CAL_TIMEOUT_SECONDS */ + if((clock_seconds() - cal_timer) > CC1200_CAL_TIMEOUT_SECONDS) { + calibrate(); + } +#else + calibrate(); +#endif + } +#endif + + RIMESTATS_ADD(lltx); + + /* Send data using TX FIFO */ + if(idle_tx_rx((const uint8_t *)tx_pkt, tx_pkt_len) == RADIO_TX_OK) { + + /* + * TXOFF_MODE is set to RX, + * let's wait until we are in RX and turn on the GPIO IRQs + * again as they were turned off in idle() + */ + + BUSYWAIT_UNTIL_STATE(STATE_RX, + RTIMER_SECOND / 100); + + ENABLE_GPIO_INTERRUPTS(); + + } else { + + /* + * Something went wrong during TX, idle_tx_rx() returns in IDLE + * state in this case. + * Turn on RX again unless we turn off anyway + */ + + ret = RADIO_TX_ERR; + if(!was_off) { + idle_calibrate_rx(); + } + } + + /* Release SPI here because "off()" won't work if SPI is locked! */ + RELEASE_SPI(); + + if(was_off) { + off(); + } + + /* TX completed */ + rf_flags &= ~RF_TX_ACTIVE; + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Prepare & transmit a packet. */ +static int +send(const void *payload, unsigned short payload_len) +{ + + int ret; + + INFO("RF: Send (%d)\n", payload_len); + + /* payload_len checked within prepare() */ + if((ret = prepare(payload, payload_len)) == RADIO_TX_OK) { + ret = transmit(payload_len); + } + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Read a received packet into a buffer. */ +static int +read(void *buf, unsigned short buf_len) +{ + + int len = 0; + + if(rx_pkt_len > 0) { + + int8_t rssi = rx_pkt[rx_pkt_len - 2]; + /* CRC is already checked */ + uint8_t crc_lqi = rx_pkt[rx_pkt_len - 1]; + + len = rx_pkt_len - APPENDIX_LEN; + + if(len > buf_len) { + + ERROR("RF: Failed to read packet (too big)!\n"); + + } else { + + INFO("RF: Read (%d bytes, %d dBm)\n", len, rssi); + + memcpy((void *)buf, (const void *)rx_pkt, len); + + /* Release rx_pkt */ + rx_pkt_len = 0; + + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi); + /* Mask out CRC bit */ + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, + crc_lqi & ~(1 << 7)); + + RIMESTATS_ADD(llrx); + + } + + } + + return len; + +} +/*---------------------------------------------------------------------------*/ +/* + * Perform a Clear-Channel Assessment (CCA) to find out if there is a + * packet in the air or not. + */ +static int +channel_clear(void) +{ + + uint8_t cca, was_off = 0; + + if(SPI_IS_LOCKED()) { + /* Probably locked in rx interrupt. Return "channel occupied" */ + return 0; + } + + if(!(rf_flags & RF_ON)) { + /* We are off */ + was_off = 1; + on(); + } + + LOCK_SPI(); + + RF_ASSERT(state() == STATE_RX); + + /* + * At this point we should be in RX. If GPIO0 is set, we are currently + * receiving a packet, no need to check the RSSI. Or is there any situation + * when we want access the channel even if we are currently receiving a + * packet??? + */ + + if(cc1200_arch_gpio0_read_pin() == 1) { + /* Channel occupied */ + INFO("RF: CCA (0)\n"); + cca = 0; + } else { + + uint8_t rssi0; + + /* Update CCA threshold */ + if(new_cca_threshold != cca_threshold) { + update_cca_threshold(new_cca_threshold); + } + + /* Wait for CARRIER_SENSE_VALID signal */ + BUSYWAIT_UNTIL(((rssi0 = single_read(CC1200_RSSI0)) + & CC1200_CARRIER_SENSE_VALID), + RTIMER_SECOND / 100); + RF_ASSERT(rssi0 & CC1200_CARRIER_SENSE_VALID); + + if(rssi0 & CC1200_CARRIER_SENSE) { + /* Channel occupied */ + INFO("RF: CCA (0)\n"); + cca = 0; + } else { + /* Channel clear */ + INFO("RF: CCA (1)\n"); + cca = 1; + } + + } + + RELEASE_SPI(); + + if(was_off) { + off(); + } + + return cca; + +} +/*---------------------------------------------------------------------------*/ +/* + * Check if the radio driver is currently receiving a packet. + * + * nullrdc uses this function + * - to detect a collision before transmit() + * - to detect an incoming ACK + */ +static int +receiving_packet(void) +{ + + int ret = 0; + + if((rf_flags & (RF_ON | RF_TX_ACTIVE)) == RF_ON) { + /* We are on and not in TX */ + if((cc1200_arch_gpio0_read_pin() == 1) || (rx_pkt_len != 0)) { + + /* + * SYNC word found or packet just received. Changing the criteria + * for this event might make it necessary to review the MAC timing + * parameters! Instead of (or in addition to) using GPIO0 we could also + * read out MODEM_STATUS1 (e.g. PQT reached), but this would not change + * the situation at least for nullrdc as it uses two "blocking" timers + * (does not perform polling...). Therefore the overall timing + * of the ACK handling wouldn't change. It would just allow to detect an + * incoming packet a little bit earlier and help us with respect to + * collision avoidance (why not use channel_clear() in nullrdc + * at this point?). + */ + + ret = 1; + + } + } + + INFO("RF: Receiving (%d)\n", ret); + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Check if the radio driver has just received a packet. */ +static int +pending_packet(void) +{ + + INFO("RF: Pending (%d)\n", ((rx_pkt_len != 0) ? 1 : 0)); + return (rx_pkt_len != 0) ? 1 : 0; + +} +/*---------------------------------------------------------------------------*/ +/* Turn the radio on. */ +static int +on(void) +{ + + INFO("RF: On\n"); + + /* Don't turn on if we are on already */ + if(!(rf_flags & RF_ON)) { + + if(SPI_IS_LOCKED()) { + return 0; + } + + LOCK_SPI(); + + /* Wake-up procedure. Wait for GPIO0 to de-assert (CHIP_RDYn) */ + cc1200_arch_spi_select(); + BUSYWAIT_UNTIL((cc1200_arch_gpio0_read_pin() == 0), + RTIMER_SECOND / 100); + RF_ASSERT((cc1200_arch_gpio0_read_pin() == 0)); + cc1200_arch_spi_deselect(); + + rf_flags |= RF_ON; + + /* Radio is IDLE now, re-configure GPIO0 (modified inside off()) */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + /* Turn on RX */ + idle_calibrate_rx(); + + RELEASE_SPI(); + +#if USE_RX_WATCHDOG + etimer_set(&et, CLOCK_SECOND); +#endif + + } else { + INFO("RF: Already on\n"); + } + + return 1; + +} +/*---------------------------------------------------------------------------*/ +/* Turn the radio off. */ +static int +off(void) +{ + + INFO("RF: Off\n"); + + /* Don't turn off if we are off already */ + if(rf_flags & RF_ON) { + + if(SPI_IS_LOCKED()) { + return 0; + } + + LOCK_SPI(); + + idle(); + + /* + * As we use GPIO as CHIP_RDYn signal on wake-up / on(), + * we re-configure it for CHIP_RDYn. + */ + single_write(CC1200_IOCFG0, CC1200_IOCFG_RXFIFO_CHIP_RDY_N); + + /* Say goodbye ... */ + strobe(CC1200_SPWD); + + /* Clear all but the initialized flag */ + rf_flags = RF_INITIALIZED; + + RELEASE_SPI(); + +#if USE_RX_WATCHDOG + etimer_stop(&et); +#endif + + } else { + INFO("RF: Already off\n"); + } + + return 1; + +} +/*---------------------------------------------------------------------------*/ +/* Get a radio parameter value. */ +static radio_result_t +get_value(radio_param_t param, radio_value_t *value) +{ + + if(!value) { + return RADIO_RESULT_INVALID_VALUE; + } + + switch(param) { + case RADIO_PARAM_POWER_MODE: + + if(rf_flags & RF_ON) { + *value = (radio_value_t)RADIO_POWER_MODE_ON; + } else { + *value = (radio_value_t)RADIO_POWER_MODE_OFF; + } + return RADIO_RESULT_OK; + + case RADIO_PARAM_CHANNEL: + + *value = (radio_value_t)rf_channel; + return RADIO_RESULT_OK; + + case RADIO_PARAM_PAN_ID: + case RADIO_PARAM_16BIT_ADDR: + + return RADIO_RESULT_NOT_SUPPORTED; + + case RADIO_PARAM_RX_MODE: + + *value = (radio_value_t)rx_mode_value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_TX_MODE: + + *value = (radio_value_t)tx_mode_value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_TXPOWER: + + *value = (radio_value_t)txpower; + return RADIO_RESULT_OK; + + case RADIO_PARAM_CCA_THRESHOLD: + + *value = (radio_value_t)cca_threshold; + return RADIO_RESULT_OK; + + case RADIO_PARAM_RSSI: + case RADIO_PARAM_64BIT_ADDR: + + return RADIO_RESULT_NOT_SUPPORTED; + + case RADIO_CONST_CHANNEL_MIN: + + *value = (radio_value_t)CC1200_RF_CFG.min_channel; + return RADIO_RESULT_OK; + + case RADIO_CONST_CHANNEL_MAX: + + *value = (radio_value_t)CC1200_RF_CFG.max_channel; + return RADIO_RESULT_OK; + + case RADIO_CONST_TXPOWER_MIN: + + *value = (radio_value_t)CC1200_CONST_TX_POWER_MIN; + return RADIO_RESULT_OK; + + case RADIO_CONST_TXPOWER_MAX: + + *value = (radio_value_t)CC1200_RF_CFG.max_txpower; + return RADIO_RESULT_OK; + + default: + + return RADIO_RESULT_NOT_SUPPORTED; + + } + +} +/*---------------------------------------------------------------------------*/ +/* Set a radio parameter value. */ +static radio_result_t +set_value(radio_param_t param, radio_value_t value) +{ + + switch(param) { + case RADIO_PARAM_POWER_MODE: + + if(value == RADIO_POWER_MODE_ON) { + on(); + return RADIO_RESULT_OK; + } + + if(value == RADIO_POWER_MODE_OFF) { + off(); + return RADIO_RESULT_OK; + } + + return RADIO_RESULT_INVALID_VALUE; + + case RADIO_PARAM_CHANNEL: + + if(set_channel(value) == CHANNEL_OUT_OF_LIMITS) { + return RADIO_RESULT_INVALID_VALUE; + } + + /* + * We always return OK here even if the channel update was + * postponed. rf_channel is NOT updated in this case until + * the channel update was performed. So reading back + * the channel using get_value() might return the "old" channel + * until the channel was actually changed + */ + + return RADIO_RESULT_OK; + + case RADIO_PARAM_PAN_ID: + case RADIO_PARAM_16BIT_ADDR: + + return RADIO_RESULT_NOT_SUPPORTED; + + case RADIO_PARAM_RX_MODE: + + rx_mode_value = value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_TX_MODE: + + tx_mode_value = value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_TXPOWER: + + if(value > (radio_value_t)CC1200_RF_CFG.max_txpower) { + value = (radio_value_t)CC1200_RF_CFG.max_txpower; + } + + if(value < (radio_value_t)CC1200_CONST_TX_POWER_MIN) { + value = (radio_value_t)CC1200_CONST_TX_POWER_MIN; + } + + /* We update the output power as soon as we transmit the next packet */ + new_txpower = (int8_t)value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_CCA_THRESHOLD: + + if(value > (radio_value_t)CC1200_CONST_CCA_THRESHOLD_MAX) { + value = (radio_value_t)CC1200_CONST_CCA_THRESHOLD_MAX; + } + + if(value < (radio_value_t)CC1200_CONST_CCA_THRESHOLD_MIN) { + value = (radio_value_t)CC1200_CONST_CCA_THRESHOLD_MIN; + } + + /* When to update the threshold? Let's do it in channel_clear() ... */ + new_cca_threshold = (int8_t)value; + return RADIO_RESULT_OK; + + case RADIO_PARAM_RSSI: + case RADIO_PARAM_64BIT_ADDR: + + default: + + return RADIO_RESULT_NOT_SUPPORTED; + + } + +} +/*---------------------------------------------------------------------------*/ +/* Get a radio parameter object. */ +static radio_result_t +get_object(radio_param_t param, void *dest, size_t size) +{ + + return RADIO_RESULT_NOT_SUPPORTED; + +} +/*---------------------------------------------------------------------------*/ +/* Set a radio parameter object. */ +static radio_result_t +set_object(radio_param_t param, const void *src, size_t size) +{ + + return RADIO_RESULT_NOT_SUPPORTED; + +} +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ +/* + * CC1200 low level functions + */ +/*---------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ + +/* Send a command strobe. */ +static uint8_t +strobe(uint8_t strobe) +{ + + uint8_t ret; + + cc1200_arch_spi_select(); + ret = cc1200_arch_spi_rw_byte(strobe); + cc1200_arch_spi_deselect(); + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Reset CC1200. */ +static void +reset(void) +{ + + cc1200_arch_spi_select(); + cc1200_arch_spi_rw_byte(CC1200_SRES); + /* + * Here we should wait for SO to go low again. + * As we don't have access to this pin we just wait for 100µs. + */ + clock_delay(100); + cc1200_arch_spi_deselect(); + +} +/*---------------------------------------------------------------------------*/ +/* Write a single byte to the specified address. */ +static uint8_t +single_write(uint16_t addr, uint8_t val) +{ + + uint8_t ret; + + cc1200_arch_spi_select(); + if(CC1200_IS_EXTENDED_ADDR(addr)) { + cc1200_arch_spi_rw_byte(CC1200_EXTENDED_WRITE_CMD); + cc1200_arch_spi_rw_byte((uint8_t)addr); + } else { + cc1200_arch_spi_rw_byte(addr | CC1200_WRITE_BIT); + } + ret = cc1200_arch_spi_rw_byte(val); + cc1200_arch_spi_deselect(); + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Read a single byte from the specified address. */ +static uint8_t +single_read(uint16_t addr) +{ + + uint8_t ret; + + cc1200_arch_spi_select(); + if(CC1200_IS_EXTENDED_ADDR(addr)) { + cc1200_arch_spi_rw_byte(CC1200_EXTENDED_READ_CMD); + cc1200_arch_spi_rw_byte((uint8_t)addr); + } else { + cc1200_arch_spi_rw_byte(addr | CC1200_READ_BIT); + } + ret = cc1200_arch_spi_rw_byte(0); + cc1200_arch_spi_deselect(); + + return ret; + +} +/*---------------------------------------------------------------------------*/ +/* Write a burst of bytes starting at the specified address. */ +static void +burst_write(uint16_t addr, const uint8_t *data, uint8_t data_len) +{ + + cc1200_arch_spi_select(); + if(CC1200_IS_EXTENDED_ADDR(addr)) { + cc1200_arch_spi_rw_byte(CC1200_EXTENDED_BURST_WRITE_CMD); + cc1200_arch_spi_rw_byte((uint8_t)addr); + } else { + cc1200_arch_spi_rw_byte(addr | CC1200_WRITE_BIT | CC1200_BURST_BIT); + } + cc1200_arch_spi_rw(NULL, data, data_len); + cc1200_arch_spi_deselect(); + +} +/*---------------------------------------------------------------------------*/ +/* Read a burst of bytes starting at the specified address. */ +static void +burst_read(uint16_t addr, uint8_t *data, uint8_t data_len) +{ + + cc1200_arch_spi_select(); + if(CC1200_IS_EXTENDED_ADDR(addr)) { + cc1200_arch_spi_rw_byte(CC1200_EXTENDED_BURST_READ_CMD); + cc1200_arch_spi_rw_byte((uint8_t)addr); + } else { + cc1200_arch_spi_rw_byte(addr | CC1200_READ_BIT | CC1200_BURST_BIT); + } + cc1200_arch_spi_rw(data, NULL, data_len); + cc1200_arch_spi_deselect(); + +} +/*---------------------------------------------------------------------------*/ +/* Write a list of register settings. */ +static void +write_reg_settings(const registerSetting_t *reg_settings, + uint16_t sizeof_reg_settings) +{ + + int i = sizeof_reg_settings / sizeof(registerSetting_t); + + if(reg_settings != NULL) { + while(i--) { + single_write(reg_settings->addr, + reg_settings->val); + reg_settings++; + } + } + +} +/*---------------------------------------------------------------------------*/ +/* Configure the radio (write basic configuration). */ +static void +configure(void) +{ + + uint8_t reg; +#if RF_TESTMODE + uint32_t freq; +#endif + + /* + * As we only write registers which are different from the chip's reset + * state, let's assure that the chip is in a clean state + */ + reset(); + + /* Write the configuration as exported from SmartRF Studio */ + write_reg_settings(CC1200_RF_CFG.register_settings, + CC1200_RF_CFG.size_of_register_settings); + + /* Write frequency offset */ +#if CC1200_FREQ_OFFSET + /* MSB */ + single_write(CC1200_FREQOFF1, (uint8_t)(CC1200_FREQ_OFFSET >> 8)); + /* LSB */ + single_write(CC1200_FREQOFF0, (uint8_t)(CC1200_FREQ_OFFSET)); +#endif + + /* RSSI offset */ + single_write(CC1200_AGC_GAIN_ADJUST, (int8_t)CC1200_RSSI_OFFSET); + + /*************************************************************************** + * RF test modes needed during hardware development + **************************************************************************/ + +#if (RF_TESTMODE == 1) || (RF_TESTMODE == 2) + + strobe(CC1200_SFTX); + single_write(CC1200_TXFIRST, 0); + single_write(CC1200_TXLAST, 0xFF); + update_txpower(CC1200_CONST_TX_POWER_MAX); + single_write(CC1200_PKT_CFG2, 0x02); + freq = calculate_freq(CC1200_DEFAULT_CHANNEL - CC1200_RF_CFG.min_channel); + single_write(CC1200_FREQ0, ((uint8_t *)&freq)[0]); + single_write(CC1200_FREQ1, ((uint8_t *)&freq)[1]); + single_write(CC1200_FREQ2, ((uint8_t *)&freq)[2]); + + printf("RF: Freq0 0x%02x\n", ((uint8_t *)&freq)[0]); + printf("RF: Freq1 0x%02x\n", ((uint8_t *)&freq)[1]); + printf("RF: Freq2 0x%02x\n", ((uint8_t *)&freq)[2]); + +#if (RF_TESTMODE == 1) + single_write(CC1200_SYNC_CFG1, 0xE8); + single_write(CC1200_PREAMBLE_CFG1, 0x00); + single_write(CC1200_MDMCFG1, 0x46); + single_write(CC1200_PKT_CFG0, 0x40); + single_write(CC1200_FS_DIG1, 0x07); + single_write(CC1200_FS_DIG0, 0xAA); + single_write(CC1200_FS_DVC1, 0xFF); + single_write(CC1200_FS_DVC0, 0x17); +#endif + +#if (RF_TESTMODE == 2) + single_write(CC1200_SYNC_CFG1, 0xE8); + single_write(CC1200_PREAMBLE_CFG1, 0x00); + single_write(CC1200_MDMCFG1, 0x06); + single_write(CC1200_PA_CFG1, 0x3F); + single_write(CC1200_MDMCFG2, 0x03); + single_write(CC1200_FS_DIG1, 0x07); + single_write(CC1200_FS_DIG0, 0xAA); + single_write(CC1200_FS_DVC0, 0x17); + single_write(CC1200_SERIAL_STATUS, 0x08); +#endif + + strobe(CC1200_STX); + + while(1) { +#if (RF_TESTMODE == 1) + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_YELLOW); + leds_on(LEDS_RED); + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_RED); + leds_on(LEDS_YELLOW); +#else + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_GREEN); + leds_on(LEDS_RED); + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_RED); + leds_on(LEDS_GREEN); +#endif + } + +#elif (RF_TESTMODE == 3) + + /* CS on GPIO3 */ + single_write(CC1200_IOCFG3, CC1200_IOCFG_CARRIER_SENSE); + single_write(CC1200_IOCFG2, CC1200_IOCFG_SERIAL_CLK); + single_write(CC1200_IOCFG0, CC1200_IOCFG_SERIAL_RX); + update_cca_threshold(CC1200_RF_CFG.cca_threshold); + freq = calculate_freq(CC1200_DEFAULT_CHANNEL - CC1200_RF_CFG.min_channel); + single_write(CC1200_FREQ0, ((uint8_t *)&freq)[0]); + single_write(CC1200_FREQ1, ((uint8_t *)&freq)[1]); + single_write(CC1200_FREQ2, ((uint8_t *)&freq)[2]); + strobe(CC1200_SRX); + + while(1) { + + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_GREEN); + leds_on(LEDS_YELLOW); + watchdog_periodic(); + BUSYWAIT_UNTIL(0, RTIMER_SECOND / 10); + leds_off(LEDS_YELLOW); + leds_on(LEDS_GREEN); + clock_delay_usec(1000); + + /* CS on GPIO3 */ + if(cc1200_arch_gpio3_read_pin() == 1) { + leds_on(LEDS_RED); + } else { + leds_off(LEDS_RED); + } + + } + +#endif /* #if RF_TESTMODE == ... */ + + /*************************************************************************** + * Set the stuff we need for this driver to work. Don't touch! + **************************************************************************/ + + /* GPIOx configuration */ + single_write(CC1200_IOCFG3, GPIO3_IOCFG); + single_write(CC1200_IOCFG2, GPIO2_IOCFG); + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + reg = single_read(CC1200_SETTLING_CFG); + /* + * Turn of auto calibration. This gives us better control + * over the timing (RX/TX & TX /RX turnaround!). We calibrate manually: + * - Upon wake-up (on()) + * - Before going to TX (transmit()) + * - When setting an new channel (set_channel()) + */ + reg &= ~(3 << 3); +#if CC1200_AUTOCAL + /* We calibrate when going from idle to RX or TX */ + reg |= (1 << 3); +#endif + single_write(CC1200_SETTLING_CFG, reg); + + /* Configure RXOFF_MODE */ + reg = single_read(CC1200_RFEND_CFG1); + reg &= ~(3 << 4); /* RXOFF_MODE = IDLE */ +#if RXOFF_MODE_RX + reg |= (3 << 4); /* RXOFF_MODE = RX */ +#endif + reg |= 0x0F; /* Disable RX timeout */ + single_write(CC1200_RFEND_CFG1, reg); + + /* Configure TXOFF_MODE */ + reg = single_read(CC1200_RFEND_CFG0); + reg &= ~(3 << 4); /* TXOFF_MODE = IDLE */ +#if TXOFF_MODE_RX + reg |= (3 << 4); /* TXOFF_MODE = RX */ +#endif + single_write(CC1200_RFEND_CFG0, reg); + + /* + * CCA Mode 0: Always give clear channel indication. + * CCA is done "by hand". Keep in mind: automatic CCA would also + * affect the transmission of the ACK and is not implemented yet! + */ +#if CC1200_802154G + single_write(CC1200_PKT_CFG2, (1 << 5)); +#else + single_write(CC1200_PKT_CFG2, 0x00); +#endif + + /* Configure appendix */ + reg = single_read(CC1200_PKT_CFG1); +#if APPEND_STATUS + reg |= (1 << 0); +#else + reg &= ~(1 << 0); +#endif + single_write(CC1200_PKT_CFG1, reg); + + /* Variable packet length mode */ + reg = single_read(CC1200_PKT_CFG0); + reg &= ~(3 << 5); + reg |= (1 << 5); + single_write(CC1200_PKT_CFG0, reg); + +#ifdef FIFO_THRESHOLD + /* FIFO threshold */ + single_write(CC1200_FIFO_CFG, FIFO_THRESHOLD); +#endif + +} +/*---------------------------------------------------------------------------*/ +/* Return the radio's state. */ +static uint8_t +state(void) +{ + +#if STATE_USES_MARC_STATE + return single_read(CC1200_MARCSTATE) & 0x1f; +#else + return strobe(CC1200_SNOP) & 0x70; +#endif + +} +/*---------------------------------------------------------------------------*/ +#if !CC1200_AUTOCAL +/* Perform manual calibration. */ +static void +calibrate(void) +{ + + INFO("RF: Calibrate\n"); + + strobe(CC1200_SCAL); + BUSYWAIT_UNTIL_STATE(STATE_CALIBRATE, RTIMER_SECOND / 100); + BUSYWAIT_UNTIL_STATE(STATE_IDLE, RTIMER_SECOND / 100); + +#if CC1200_CAL_TIMEOUT_SECONDS + cal_timer = clock_seconds(); +#endif + +} +#endif +/*---------------------------------------------------------------------------*/ +/* Enter IDLE state. */ +static void +idle(void) +{ + + uint8_t s; + + DISABLE_GPIO_INTERRUPTS(); + + TX_LEDS_OFF(); + RX_LEDS_OFF(); + + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + + s = state(); + + if(s == STATE_IDLE) { + return; + } else if(s == STATE_RX_FIFO_ERR) { + WARNING("RF: RX FIFO error!\n"); + strobe(CC1200_SFRX); + } else if(s == STATE_TX_FIFO_ERR) { + WARNING("RF: TX FIFO error!\n"); + strobe(CC1200_SFTX); + } + + strobe(CC1200_SIDLE); + BUSYWAIT_UNTIL_STATE(STATE_IDLE, RTIMER_SECOND / 100); + +} /* idle(), 21.05.2015 */ +/*---------------------------------------------------------------------------*/ +/* Enter RX state. */ +static void +idle_calibrate_rx(void) +{ + + RF_ASSERT(state() == STATE_IDLE); + +#if !CC1200_AUTOCAL + calibrate(); +#endif + + rf_flags &= ~RF_RX_PROCESSING_PKT; + strobe(CC1200_SFRX); + strobe(CC1200_SRX); + BUSYWAIT_UNTIL_STATE(STATE_RX, RTIMER_SECOND / 100); + + ENABLE_GPIO_INTERRUPTS(); + + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + +} +/*---------------------------------------------------------------------------*/ +/* Restart RX from within RX interrupt. */ +static void +rx_rx(void) +{ + + uint8_t s = state(); + + if(s == STATE_RX) { + /* Already in RX. Flush RX FIFO */ + single_write(CC1200_RXFIRST, + single_read(CC1200_RXLAST)); + } else if(s == STATE_IDLE) { + /* Proceed to rx */ + } else if(s == STATE_RX_FIFO_ERR) { + WARNING("RF: RX FIFO error!\n"); + strobe(CC1200_SFRX); + } else if(s == STATE_TX_FIFO_ERR) { + WARNING("RF: TX FIFO error!\n"); + strobe(CC1200_SFTX); + } else { + strobe(CC1200_SIDLE); + BUSYWAIT_UNTIL_STATE(STATE_IDLE, + RTIMER_SECOND / 100); + } + + RX_LEDS_OFF(); + rf_flags &= ~RF_RX_PROCESSING_PKT; + + /* Clear pending GPIO interrupts */ + ENABLE_GPIO_INTERRUPTS(); + + if(s != STATE_RX) { + strobe(CC1200_SFRX); + strobe(CC1200_SRX); + BUSYWAIT_UNTIL_STATE(STATE_RX, RTIMER_SECOND / 100); + } + +} +/*---------------------------------------------------------------------------*/ +/* Fill TX FIFO, start TX and wait for TX to complete (blocking!). */ +static int +idle_tx_rx(const uint8_t *payload, uint16_t payload_len) +{ + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + uint16_t bytes_left_to_write; + uint8_t to_write; + const uint8_t *p; +#endif + +#if CC1200_802154G + /* Prepare PHR for 802.15.4g frames */ + struct { + uint8_t phra; + uint8_t phrb; + } phr; +#if CC1200_802154G_CRC16 + payload_len += 2; +#else + payload_len += 4; +#endif + /* Frame length */ + phr.phrb = (uint8_t)(payload_len & 0x00FF); + phr.phra = (uint8_t)((payload_len >> 8) & 0x0007); +#if CC1200_802154G_WHITENING + /* Enable Whitening */ + phr.phra |= (1 << 3); +#endif /* #if CC1200_802154G_WHITENING */ +#if CC1200_802154G_CRC16 + /* FCS type 1, 2 Byte CRC */ + phr.phra |= (1 << 4); +#endif /* #if CC1200_802154G_CRC16 */ +#endif /* #if CC1200_802154G */ + + /* Prepare for RX */ + rf_flags &= ~RF_RX_PROCESSING_PKT; + strobe(CC1200_SFRX); + + /* Flush TX FIFO */ + strobe(CC1200_SFTX); + +#if USE_SFSTXON + /* + * Enable synthesizer. Saves us a few µs especially if it takes + * long enough to fill the FIFO. This strobe must not be + * send before SFTX! + */ + strobe(CC1200_SFSTXON); +#endif + + /* Configure GPIO0 to detect TX state */ + single_write(CC1200_IOCFG0, CC1200_IOCFG_MARC_2PIN_STATUS_0); + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + /* + * We already checked that GPIO2 is used if + * CC1200_MAX_PAYLOAD_LEN > 127 / 126 in the header of this file + */ + single_write(CC1200_IOCFG2, CC1200_IOCFG_TXFIFO_THR); +#endif + +#if CC1200_802154G + /* Write PHR */ + burst_write(CC1200_TXFIFO, (uint8_t *)&phr, PHR_LEN); +#else + /* Write length byte */ + burst_write(CC1200_TXFIFO, (uint8_t *)&payload_len, PHR_LEN); +#endif /* #if CC1200_802154G */ + + /* + * Fill FIFO with data. If SPI is slow it might make sense + * to divide this process into several chunks. + * The best solution would be to perform TX FIFO refill + * using an interrupt, but we are blocking here (= in TX) anyway... + */ + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + to_write = MIN(payload_len, (CC1200_FIFO_SIZE - PHR_LEN)); + burst_write(CC1200_TXFIFO, payload, to_write); + bytes_left_to_write = payload_len - to_write; + p = payload + to_write; +#else + burst_write(CC1200_TXFIFO, payload, payload_len); +#endif + +#if USE_SFSTXON + /* Wait for synthesizer to be ready */ + BUSYWAIT_UNTIL_STATE(STATE_FSTXON, RTIMER_SECOND / 100); +#endif + + /* Start TX */ + strobe(CC1200_STX); + + /* Wait for TX to start. */ + BUSYWAIT_UNTIL((cc1200_arch_gpio0_read_pin() == 1), RTIMER_SECOND / 100); + + /* Turned off at the latest in idle() */ + TX_LEDS_ON(); + + /* Turned off at the latest in idle() */ + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + + if((cc1200_arch_gpio0_read_pin() == 0) && + (single_read(CC1200_NUM_TXBYTES) != 0)) { + + /* + * TX didn't start in time. We also check NUM_TXBYES + * in case we missed the rising edge of the GPIO signal + */ + + ERROR("RF: TX doesn't start!\n"); +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + single_write(CC1200_IOCFG2, GPIO2_IOCFG); +#endif + idle(); + + /* Re-configure GPIO0 */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + return RADIO_TX_ERR; + + } + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + if(bytes_left_to_write != 0) { + rtimer_clock_t t0; + uint8_t s; + t0 = RTIMER_NOW(); + do { + if((bytes_left_to_write != 0) && + (cc1200_arch_gpio2_read_pin() == 0)) { + /* TX TIFO is drained below FIFO_THRESHOLD. Re-fill... */ + to_write = MIN(bytes_left_to_write, FIFO_THRESHOLD); + burst_write(CC1200_TXFIFO, p, to_write); + bytes_left_to_write -= to_write; + p += to_write; + t0 += CC1200_RF_CFG.tx_pkt_lifetime; + } + } while((cc1200_arch_gpio0_read_pin() == 1) && + RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + CC1200_RF_CFG.tx_pkt_lifetime)); + + /* + * At this point we either left TX or a timeout occurred. If all went + * well, we are in RX (or at least settling) now. + * If we didn't manage to refill the TX FIFO, an underflow might + * have occur-ed - the radio might be still in TX here! + */ + + s = state(); + if((s != STATE_RX) && (s != STATE_SETTLING)) { + + /* + * Something bad happened. Wait for radio to enter a + * stable state (in case of an error we are in TX here) + */ + + INFO("RF: TX failure!\n"); + BUSYWAIT_UNTIL((state() != STATE_TX), RTIMER_SECOND / 100); + /* Re-configure GPIO2 */ + single_write(CC1200_IOCFG2, GPIO2_IOCFG); + idle(); + + /* Re-configure GPIO0 */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + return RADIO_TX_ERR; + + } + + } else { + /* Wait for TX to complete */ + BUSYWAIT_UNTIL((cc1200_arch_gpio0_read_pin() == 0), + CC1200_RF_CFG.tx_pkt_lifetime); + } +#else + /* Wait for TX to complete */ + BUSYWAIT_UNTIL((cc1200_arch_gpio0_read_pin() == 0), + CC1200_RF_CFG.tx_pkt_lifetime); +#endif + + if(cc1200_arch_gpio0_read_pin() == 1) { + /* TX takes to long - abort */ + ERROR("RF: TX takes to long!\n"); +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + /* Re-configure GPIO2 */ + single_write(CC1200_IOCFG2, GPIO2_IOCFG); +#endif + idle(); + + /* Re-configure GPIO0 */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + return RADIO_TX_ERR; + + } + +#if (CC1200_MAX_PAYLOAD_LEN > (CC1200_FIFO_SIZE - PHR_LEN)) + /* Re-configure GPIO2 */ + single_write(CC1200_IOCFG2, GPIO2_IOCFG); +#endif + + /* Re-configure GPIO0 */ + single_write(CC1200_IOCFG0, GPIO0_IOCFG); + + TX_LEDS_OFF(); + + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + + return RADIO_TX_OK; + +} +/*---------------------------------------------------------------------------*/ +/* Update TX power */ +static void +update_txpower(int8_t txpower_dbm) +{ + + uint8_t reg = single_read(CC1200_PA_CFG1); + + reg &= ~0x3F; + /* Up to now we don't handle the special power levels PA_POWER_RAMP < 3 */ + reg |= ((((txpower_dbm + 18) * 2) - 1) & 0x3F); + single_write(CC1200_PA_CFG1, reg); + + txpower = txpower_dbm; + +} +/*---------------------------------------------------------------------------*/ +/* Update CCA threshold */ +static void +update_cca_threshold(int8_t threshold_dbm) +{ + + single_write(CC1200_AGC_CS_THR, (uint8_t)threshold_dbm); + cca_threshold = threshold_dbm; + +} +/*---------------------------------------------------------------------------*/ +/* Calculate FREQ register from channel */ +static uint32_t +calculate_freq(uint8_t channel) +{ + + uint32_t freq; + + freq = CC1200_RF_CFG.chan_center_freq0 + channel * CC1200_RF_CFG.chan_spacing; + freq *= FREQ_MULTIPLIER; + freq /= FREQ_DIVIDER; + + return freq; + +} +/*---------------------------------------------------------------------------*/ +/* Update rf channel if possible, else postpone it (->pollhandler) */ +static int +set_channel(uint8_t channel) +{ + + uint8_t was_off = 0; + uint32_t freq; + +#if 0 + /* + * We explicitly allow a channel update even if the channel does not change. + * This feature can be used to manually force a calibration. + */ + if(channel == rf_channel) { + return rf_channel; + } +#endif + + if(channel < CC1200_RF_CFG.min_channel || + channel > CC1200_RF_CFG.max_channel) { + /* Invalid channel */ + return CHANNEL_OUT_OF_LIMITS; + } + + if(SPI_IS_LOCKED() || (rf_flags & RF_TX_ACTIVE) || receiving_packet()) { + + /* We are busy, postpone channel update */ + + new_rf_channel = channel; + rf_flags |= RF_UPDATE_CHANNEL; + process_poll(&cc1200_process); + INFO("RF: Channel update postponed\n"); + + return CHANNEL_UPDATE_POSTPONED; + + } + rf_flags &= ~RF_UPDATE_CHANNEL; + + INFO("RF: Channel update (%d)\n", channel); + + if(!(rf_flags & RF_ON)) { + was_off = 1; + on(); + } + + LOCK_SPI(); + + idle(); + + freq = calculate_freq(channel - CC1200_RF_CFG.min_channel); + single_write(CC1200_FREQ0, ((uint8_t *)&freq)[0]); + single_write(CC1200_FREQ1, ((uint8_t *)&freq)[1]); + single_write(CC1200_FREQ2, ((uint8_t *)&freq)[2]); + + rf_channel = channel; + + /* Turn on RX again unless we turn off anyway */ + if(!was_off) { + idle_calibrate_rx(); + } + + RELEASE_SPI(); + + if(was_off) { + off(); + } + + return CHANNEL_UPDATE_SUCCEEDED; + +} +/*---------------------------------------------------------------------------*/ +/* Check broadcast address. */ +#if !CC1200_SNIFFER +static int +is_broadcast_addr(uint8_t mode, uint8_t *addr) +{ + + int i = mode == FRAME802154_SHORTADDRMODE ? 2 : 8; + + while(i-- > 0) { + if(addr[i] != 0xff) { + return 0; + } + } + + return 1; + +} +#endif /* CC12100_SNIFFER */ +/*---------------------------------------------------------------------------*/ +/* Validate address and send ACK if requested. */ +#if CC1200_SNIFFER +static int +addr_check_auto_ack(uint8_t *frame, uint16_t frame_len) +{ + + frame802154_t info154; + + if(frame802154_parse(frame, frame_len, &info154) != 0) { + + /* We accept all 802.15.4 frames ... */ + return ADDR_CHECK_OK; + + } else { + + /* .. and discard others. */ + return INVALID_FRAME; + + } + +} +#else /* CC1200_SNIFFER */ +static int +addr_check_auto_ack(uint8_t *frame, uint16_t frame_len) +{ + + frame802154_t info154; + + if(frame802154_parse(frame, frame_len, &info154) != 0) { + + /* We received a valid 802.15.4 frame */ + + if(!(rx_mode_value & RADIO_RX_MODE_ADDRESS_FILTER) || + info154.fcf.frame_type == FRAME802154_ACKFRAME || + is_broadcast_addr(info154.fcf.dest_addr_mode, + (uint8_t *)&info154.dest_addr) || + linkaddr_cmp((linkaddr_t *)&info154.dest_addr, + &linkaddr_node_addr)) { + + /* + * Address check succeeded or address filter disabled. + * We send an ACK in case a corresponding data frame + * is received even in promiscuous mode (if auto-ack is + * enabled)! + */ + + if((rx_mode_value & RADIO_RX_MODE_AUTOACK) && + info154.fcf.frame_type == FRAME802154_DATAFRAME && + info154.fcf.ack_required != 0 && + (!(rx_mode_value & RADIO_RX_MODE_ADDRESS_FILTER) || + linkaddr_cmp((linkaddr_t *)&info154.dest_addr, + &linkaddr_node_addr))) { + + /* + * Data frame destined for us & ACK request bit set -> send ACK. + * Make sure the preamble length is configured accordingly as + * MAC timing parameters rely on this! + */ + + uint8_t ack[ACK_LEN] = { FRAME802154_ACKFRAME, 0, info154.seq }; + +#if (RXOFF_MODE_RX == 1) + /* + * This turns off GPIOx interrupts. Make sure they are turned on + * in rx_rx() later on! + */ + idle(); +#endif + + idle_tx_rx((const uint8_t *)ack, ACK_LEN); + + /* rx_rx() will follow */ + + return ADDR_CHECK_OK_ACK_SEND; + + } + + return ADDR_CHECK_OK; + + } else { + + return ADDR_CHECK_FAILED; + + } + + } + + return INVALID_FRAME; + +} +#endif /* CC1200_SNIFFER */ +/*---------------------------------------------------------------------------*/ +/* + * The CC1200 interrupt handler: called by the hardware interrupt + * handler, which is defined as part of the cc1200-arch interface. + */ +int +cc1200_rx_interrupt(void) +{ + + /* The radio's state */ + uint8_t s; + /* The number of bytes in the RX FIFO waiting for read-out */ + uint8_t num_rxbytes; + /* The payload length read as the first byte from the RX FIFO */ + static uint16_t payload_len; + /* + * The number of bytes already read out and placed in the + * intermediate buffer + */ + static uint16_t bytes_read; + /* + * We use an intermediate buffer for the packet before + * we pass it to the next upper layer. We also place RSSI + + * LQI in this buffer + */ + static uint8_t buf[CC1200_MAX_PAYLOAD_LEN + APPENDIX_LEN]; + + if(SPI_IS_LOCKED()) { + + /* + * SPI is in use. Exit and make sure this + * function is called from the poll handler as soon + * as SPI is available again + */ + + rf_flags |= RF_POLL_RX_INTERRUPT; + process_poll(&cc1200_process); + return 1; + + } + rf_flags &= ~RF_POLL_RX_INTERRUPT; + + LOCK_SPI(); + + /* + * If CC1200_USE_GPIO2 is enabled, we come here either once RX FIFO + * threshold is reached (GPIO2 rising edge) + * or at the end of the packet (GPIO0 falling edge). + */ + + /* Make sure we are in a sane state. Sane means: either RX or IDLE */ + s = state(); + if((s == STATE_RX_FIFO_ERR) || (s == STATE_TX_FIFO_ERR)) { + + rx_rx(); + RELEASE_SPI(); + return 0; + + } + + num_rxbytes = single_read(CC1200_NUM_RXBYTES); + + if(num_rxbytes == 0) { + + /* + * This might happen from time to time because + * this function is also called by the pollhandler and / or + * from TWO interrupts which can occur at the same time. + */ + + INFO("RF: RX FIFO empty!\n"); + RELEASE_SPI(); + return 0; + + } + + if(!(rf_flags & RF_RX_PROCESSING_PKT)) { + +#if CC1200_802154G + struct { + uint8_t phra; + uint8_t phrb; + } + phr; + + if(num_rxbytes < PHR_LEN) { + + WARNING("RF: PHR incomplete!\n"); + rx_rx(); + RELEASE_SPI(); + return 0; + + } + + burst_read(CC1200_RXFIFO, + &phr, + PHR_LEN); + payload_len = (phr.phra & 0x07); + payload_len <<= 8; + payload_len += phr.phrb; + + if(phr.phra & (1 << 4)) { + /* CRC16, payload_len += 2 */ + payload_len -= 2; + } else { + /* CRC16, payload_len += 4 */ + payload_len -= 4; + } +#else + /* Read first byte in RX FIFO (payload length) */ + burst_read(CC1200_RXFIFO, + (uint8_t *)&payload_len, + PHR_LEN); +#endif + + if(payload_len < ACK_LEN) { + /* Packet to short. Discard it */ + WARNING("RF: Packet too short!\n"); + RIMESTATS_ADD(tooshort); + rx_rx(); + RELEASE_SPI(); + return 0; + } + + if(payload_len > CC1200_MAX_PAYLOAD_LEN) { + /* Packet to long. Discard it */ + WARNING("RF: Packet to long!\n"); + RIMESTATS_ADD(toolong); + rx_rx(); + RELEASE_SPI(); + return 0; + } + + RX_LEDS_ON(); + bytes_read = 0; + num_rxbytes -= PHR_LEN; + + rf_flags |= RF_RX_PROCESSING_PKT; + + /* Fall through... */ + + } + + if(rf_flags & RF_RX_PROCESSING_PKT) { + + /* + * Read out remaining bytes unless FIFO is empty. + * We have at least num_rxbytes in the FIFO to be read out. + */ + + if((num_rxbytes + bytes_read) > (payload_len + CC_APPENDIX_LEN)) { + + /* + * We have a mismatch between the number of bytes in the RX FIFO + * and the payload_len. This would lead to an buffer overflow, + * so we catch this error here. + */ + + WARNING("RF: RX length mismatch %d %d %d!\n", num_rxbytes, + bytes_read, + payload_len); + rx_rx(); + RELEASE_SPI(); + return 0; + + } + + burst_read(CC1200_RXFIFO, + &buf[bytes_read], + num_rxbytes); + + bytes_read += num_rxbytes; + num_rxbytes = 0; + + if(bytes_read == (payload_len + CC_APPENDIX_LEN)) { + + /* + * End of packet. Read appendix (if available), check CRC + * and copy the data from temporary buffer to rx_pkt + * RSSI offset already set using AGC_GAIN_ADJUST.GAIN_ADJUSTMENT + */ + +#if APPEND_STATUS + uint8_t crc_lqi = buf[bytes_read - 1]; +#else + int8_t rssi = single_read(CC1200_RSSI1); + uint8_t crc_lqi = single_read(CC1200_LQI_VAL); +#endif + + if(!(crc_lqi & (1 << 7))) { + /* CRC error. Drop the packet */ + INFO("RF: CRC error!\n"); + RIMESTATS_ADD(badcrc); + } else if(rx_pkt_len != 0) { + /* An old packet is pending. Drop the packet */ + WARNING("RF: Packet pending!\n"); + } else { + + int ret = addr_check_auto_ack(buf, bytes_read); + + if((ret == ADDR_CHECK_OK) || + (ret == ADDR_CHECK_OK_ACK_SEND)) { +#if APPEND_STATUS + /* RSSI + LQI already read out and placed into buf */ +#else + buf[bytes_read++] = (uint8_t)rssi; + buf[bytes_read++] = crc_lqi; +#endif + rx_pkt_len = bytes_read; + memcpy((void *)rx_pkt, buf, rx_pkt_len); + rx_rx(); + process_poll(&cc1200_process); + RELEASE_SPI(); + return 1; + + } else { + /* Invalid address. Drop the packet */ + } + + } + + /* Buffer full, address or CRC check failed */ + rx_rx(); + RELEASE_SPI(); + return 0; + + } /* if (bytes_read == payload_len) */ + + } + + RELEASE_SPI(); + return 0; + +} +/*---------------------------------------------------------------------------*/ diff --git a/doc/Doxyfile b/doc/Doxyfile index fcf372ed2..7b80be871 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -807,7 +807,8 @@ EXCLUDE_SYMLINKS = NO # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* -EXCLUDE_PATTERNS = */cpu/cc26xx/lib/* \ +EXCLUDE_PATTERNS = */cpu/cc26xx-cc13xx/lib/* \ + */cpu/cc26xx-cc13xx/rf-core/api/* \ */platform/stm32nucleo-spirit1/stm32cube-lib/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names diff --git a/examples/cc2530dk/border-router/border-router.c b/examples/cc2530dk/border-router/border-router.c index 0df514474..843632b23 100644 --- a/examples/cc2530dk/border-router/border-router.c +++ b/examples/cc2530dk/border-router/border-router.c @@ -90,7 +90,7 @@ request_prefix(void) CC_NON_BANKED uip_buf[1] = 'P'; uip_len = 2; slip_send(); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ /* Set our prefix when we receive one over SLIP */ diff --git a/examples/cc2530dk/border-router/slip-bridge.c b/examples/cc2530dk/border-router/slip-bridge.c index 98aee3bf9..30bd4a429 100644 --- a/examples/cc2530dk/border-router/slip-bridge.c +++ b/examples/cc2530dk/border-router/slip-bridge.c @@ -59,7 +59,7 @@ slip_input_callback(void) PRINTF("SIN: %u\n", uip_len); if((char)uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); if((char)uip_buf[1] == 'P') { uip_ipaddr_t prefix; /* Here we set a prefix !!! */ diff --git a/examples/cc2530dk/cc2531-usb-demo/cc2531-usb-demo.c b/examples/cc2530dk/cc2531-usb-demo/cc2531-usb-demo.c index ca0dce11e..639c09bbf 100644 --- a/examples/cc2530dk/cc2531-usb-demo/cc2531-usb-demo.c +++ b/examples/cc2530dk/cc2531-usb-demo/cc2531-usb-demo.c @@ -35,7 +35,7 @@ * USB (CDC_ACM) functionality. * * It will print out periodically. Anything you type in the dongle's - * serial console will be echoed back + * serial console will be echoed back after a newline. * * \author * George Oikonomou - diff --git a/examples/cc26xx/README.md b/examples/cc26xx/README.md index 411bc9407..af20f6e3f 100644 --- a/examples/cc26xx/README.md +++ b/examples/cc26xx/README.md @@ -6,8 +6,9 @@ boards. More specifically, the example demonstrates: * How to take sensor readings * How to use buttons and the reed relay (triggered by holding a magnet near S3 on the SensorTag). -* How to send out BLE advertisements. The device will periodically send out BLE - beacons with the platform name as payload. Those beacons/BLE ADV packets can - be captured with any BLE capable device. Two such applications for iOS are the - TI Multitool and the TI Sensortag app. They can be found in the Apple App - Store. If you have a BLE-capable Mac, you can also use LightBlue for OS X. +* How to send out BLE advertisements, if the chip has BLE capability. The + device will periodically send out BLE beacons with the platform name as + payload. Those beacons/BLE ADV packets can be captured with any BLE-capable + device. Two such applications for iOS are the TI Multitool and the TI + Sensortag app. They can be found in the Apple App Store. If you have a + BLE-capable Mac, you can also use LightBlue for OS X. diff --git a/examples/cc26xx/cc26xx-demo.c b/examples/cc26xx/cc26xx-demo.c index 1426bb983..544ae4dd8 100644 --- a/examples/cc26xx/cc26xx-demo.c +++ b/examples/cc26xx/cc26xx-demo.c @@ -88,13 +88,12 @@ #include "sys/etimer.h" #include "sys/ctimer.h" #include "dev/leds.h" -#include "dev/serial-line.h" #include "dev/watchdog.h" #include "random.h" #include "button-sensor.h" #include "batmon-sensor.h" #include "board-peripherals.h" -#include "cc26xx-rf.h" +#include "rf-core/rf-ble.h" #include "ti-lib.h" @@ -104,7 +103,6 @@ #define CC26XX_DEMO_LOOP_INTERVAL (CLOCK_SECOND * 20) #define CC26XX_DEMO_LEDS_PERIODIC LEDS_YELLOW #define CC26XX_DEMO_LEDS_BUTTON LEDS_RED -#define CC26XX_DEMO_LEDS_SERIAL_IN LEDS_ORANGE #define CC26XX_DEMO_LEDS_REBOOT LEDS_ALL /*---------------------------------------------------------------------------*/ #define CC26XX_DEMO_SENSOR_NONE (void *)0xFFFFFFFF @@ -370,8 +368,8 @@ PROCESS_THREAD(cc26xx_demo_process, ev, data) init_sensors(); /* Init the BLE advertisement daemon */ - cc26xx_rf_ble_beacond_config(0, BOARD_STRING); - cc26xx_rf_ble_beacond_start(); + rf_ble_beacond_config(0, BOARD_STRING); + rf_ble_beacond_start(); etimer_set(&et, CC26XX_DEMO_LOOP_INTERVAL); get_sync_sensor_readings(); diff --git a/examples/cc26xx/cc26xx-web-demo/Makefile b/examples/cc26xx/cc26xx-web-demo/Makefile index 622156a4d..1da0a7747 100644 --- a/examples/cc26xx/cc26xx-web-demo/Makefile +++ b/examples/cc26xx/cc26xx-web-demo/Makefile @@ -5,7 +5,7 @@ all: cc26xx-web-demo REST_RESOURCES_DIR = ./resources REST_RESOURCES_FILES += res-leds.c res-toggle-leds.c res-device.c -REST_RESOURCES_FILES += res-sensors.c res-ble-advd.c +REST_RESOURCES_FILES += res-sensors.c res-ble-advd.c res-net.c PROJECTDIRS += $(REST_RESOURCES_DIR) PROJECT_SOURCEFILES += $(REST_RESOURCES_FILES) diff --git a/examples/cc26xx/cc26xx-web-demo/README.md b/examples/cc26xx/cc26xx-web-demo/README.md index 194336a56..67b28ba93 100644 --- a/examples/cc26xx/cc26xx-web-demo/README.md +++ b/examples/cc26xx/cc26xx-web-demo/README.md @@ -10,12 +10,11 @@ demonstrate the CC26xx capability. The applications are: * A web server which can be used to display sensor readings but also to configure MQTT functionality -The example has been configured to run for both CC26xx-based boards: i) The -SensorTag 2.0 and ii) The Srf06EB with a CC26xx EM mounted on it. +The example has been configured to run for all CC26xx-based boards: i) The +SensorTag 2.0 and ii) The Srf06EB with a CC26xx or CC13xx EM mounted on it. -To build the example for the Srf, simply run `make`. To build for the tag, -run `make BOARD=sensortag`. Do not forget to `make clean` when switching -between the two platforms. +To change between target boards, follow the instructions in the platform's +REDME file. Do not forget to `make clean` when switching between the boards. You can disable some of those individual components by changing the respective defines in `project-conf.h`. For instance, to disable the CoAP functionality, diff --git a/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.c b/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.c index 4d8c9ca86..1eaf35648 100644 --- a/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.c +++ b/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.c @@ -44,6 +44,7 @@ #include "lib/sensors.h" #include "lib/list.h" #include "sys/process.h" +#include "net/ipv6/sicslowpan.h" #include "button-sensor.h" #include "batmon-sensor.h" #include "httpd-simple.h" @@ -77,13 +78,20 @@ struct ctimer bmp_timer, hdc_timer, tmp_timer, opt_timer, mpu_timer; static struct etimer et; static struct ctimer ct; /*---------------------------------------------------------------------------*/ +/* Parent RSSI functionality */ +#if CC26XX_WEB_DEMO_READ_PARENT_RSSI +static struct uip_icmp6_echo_reply_notification echo_reply_notification; +static struct etimer echo_request_timer; +int def_rt_rssi = 0; +#endif +/*---------------------------------------------------------------------------*/ process_event_t cc26xx_web_demo_publish_event; process_event_t cc26xx_web_demo_config_loaded_event; process_event_t cc26xx_web_demo_load_config_defaults; /*---------------------------------------------------------------------------*/ /* Saved settings on flash: store, offset, magic */ #define CONFIG_FLASH_OFFSET 0 -#define CONFIG_MAGIC 0xCC265001 +#define CONFIG_MAGIC 0xCC265002 cc26xx_web_demo_config_t cc26xx_web_demo_config; /*---------------------------------------------------------------------------*/ @@ -374,8 +382,57 @@ sensor_readings_handler(char *key, int key_len, char *val, int val_len) return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; } /*---------------------------------------------------------------------------*/ +#if CC26XX_WEB_DEMO_READ_PARENT_RSSI +static int +ping_interval_post_handler(char *key, int key_len, char *val, int val_len) +{ + int rv = 0; + + if(key_len != strlen("ping_interval") || + strncasecmp(key, "ping_interval", strlen("ping_interval")) != 0) { + /* Not ours */ + return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; + } + + rv = atoi(val); + + if(rv < CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MIN || + rv > CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MAX) { + return HTTPD_SIMPLE_POST_HANDLER_ERROR; + } + + cc26xx_web_demo_config.def_rt_ping_interval = rv * CLOCK_SECOND; + + return HTTPD_SIMPLE_POST_HANDLER_OK; +} +#endif +/*---------------------------------------------------------------------------*/ HTTPD_SIMPLE_POST_HANDLER(sensor, sensor_readings_handler); HTTPD_SIMPLE_POST_HANDLER(defaults, defaults_post_handler); + +#if CC26XX_WEB_DEMO_READ_PARENT_RSSI +HTTPD_SIMPLE_POST_HANDLER(ping_interval, ping_interval_post_handler); +/*---------------------------------------------------------------------------*/ +static void +echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data, + uint16_t datalen) +{ + if(uip_ip6addr_cmp(source, uip_ds6_defrt_choose())) { + def_rt_rssi = sicslowpan_get_last_rssi(); + } +} +/*---------------------------------------------------------------------------*/ +static void +ping_parent(void) +{ + if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) { + return; + } + + uip_icmp6_send(uip_ds6_defrt_choose(), ICMP6_ECHO_REQUEST, 0, + CC26XX_WEB_DEMO_ECHO_REQ_PAYLOAD_LEN); +} +#endif /*---------------------------------------------------------------------------*/ static void get_batmon_reading(void *data) @@ -828,6 +885,8 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data) * own defaults and restore saved config from flash... */ cc26xx_web_demo_config.sensors_bitmap = 0xFFFFFFFF; /* all on by default */ + cc26xx_web_demo_config.def_rt_ping_interval = + CC26XX_WEB_DEMO_DEFAULT_RSSI_MEAS_INTERVAL; load_config(); /* @@ -841,6 +900,15 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data) httpd_simple_register_post_handler(&sensor_handler); httpd_simple_register_post_handler(&defaults_handler); +#if CC26XX_WEB_DEMO_READ_PARENT_RSSI + httpd_simple_register_post_handler(&ping_interval_handler); + + def_rt_rssi = 0x8000000; + uip_icmp6_echo_reply_callback_add(&echo_reply_notification, + echo_reply_handler); + etimer_set(&echo_request_timer, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC); +#endif + etimer_set(&et, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC); /* @@ -848,6 +916,25 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data) * (e.g a button press / or reed trigger) */ while(1) { + if(ev == PROCESS_EVENT_TIMER && etimer_expired(&et)) { + if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) { + leds_on(CC26XX_WEB_DEMO_STATUS_LED); + ctimer_set(&ct, NO_NET_LED_DURATION, publish_led_off, NULL); + etimer_set(&et, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC); + } + } + +#if CC26XX_WEB_DEMO_READ_PARENT_RSSI + if(ev == PROCESS_EVENT_TIMER && etimer_expired(&echo_request_timer)) { + if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) { + etimer_set(&echo_request_timer, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC); + } else { + ping_parent(); + etimer_set(&echo_request_timer, cc26xx_web_demo_config.def_rt_ping_interval); + } + } +#endif + if(ev == sensors_event && data == CC26XX_WEB_DEMO_SENSOR_READING_TRIGGER) { if((CC26XX_WEB_DEMO_SENSOR_READING_TRIGGER)->value( BUTTON_SENSOR_VALUE_DURATION) > CLOCK_SECOND * 5) { @@ -858,12 +945,6 @@ PROCESS_THREAD(cc26xx_web_demo_process, ev, data) process_post(PROCESS_BROADCAST, cc26xx_web_demo_publish_event, NULL); } - } else if(ev == PROCESS_EVENT_TIMER && etimer_expired(&et)) { - if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) { - leds_on(CC26XX_WEB_DEMO_STATUS_LED); - ctimer_set(&ct, NO_NET_LED_DURATION, publish_led_off, NULL); - etimer_set(&et, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC); - } } else if(ev == httpd_simple_event_new_config) { save_config(); #if BOARD_SENSORTAG diff --git a/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.h b/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.h index a501925e8..026461f32 100644 --- a/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.h +++ b/examples/cc26xx/cc26xx-web-demo/cc26xx-web-demo.h @@ -80,6 +80,16 @@ #define CC26XX_WEB_DEMO_NET_UART 1 #endif /*---------------------------------------------------------------------------*/ +/* Active probing of RSSI from our preferred parent */ +#if (CC26XX_WEB_DEMO_COAP_SERVER || CC26XX_WEB_DEMO_MQTT_CLIENT) +#define CC26XX_WEB_DEMO_READ_PARENT_RSSI 1 +#else +#define CC26XX_WEB_DEMO_READ_PARENT_RSSI 0 +#endif + +#define CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MAX 86400 /* secs: 1 day */ +#define CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MIN 5 /* secs */ +/*---------------------------------------------------------------------------*/ /* User configuration */ /* Take a sensor reading on button press */ #define CC26XX_WEB_DEMO_SENSOR_READING_TRIGGER &button_left_sensor @@ -91,7 +101,7 @@ /* Force an MQTT publish on sensor event */ #define CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER &reed_relay_sensor #else -#define CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER &button_right_sensor +#define CC26XX_WEB_DEMO_MQTT_PUBLISH_TRIGGER &button_down_sensor #endif #define CC26XX_WEB_DEMO_STATUS_LED LEDS_GREEN @@ -101,7 +111,11 @@ /*---------------------------------------------------------------------------*/ /* Default configuration values */ #define CC26XX_WEB_DEMO_DEFAULT_ORG_ID "quickstart" +#if CPU_FAMILY_CC13XX +#define CC26XX_WEB_DEMO_DEFAULT_TYPE_ID "cc13xx" +#else #define CC26XX_WEB_DEMO_DEFAULT_TYPE_ID "cc26xx" +#endif #define CC26XX_WEB_DEMO_DEFAULT_EVENT_TYPE_ID "status" #define CC26XX_WEB_DEMO_DEFAULT_SUBSCRIBE_CMD_TYPE "+" #define CC26XX_WEB_DEMO_DEFAULT_BROKER_PORT 1883 @@ -165,6 +179,7 @@ typedef struct cc26xx_web_demo_config_s { uint32_t magic; int len; uint32_t sensors_bitmap; + int def_rt_ping_interval; mqtt_client_config_t mqtt_config; net_uart_config_t net_uart; } cc26xx_web_demo_config_t; diff --git a/examples/cc26xx/cc26xx-web-demo/coap-server.c b/examples/cc26xx/cc26xx-web-demo/coap-server.c index 0b434d170..9b4155d00 100644 --- a/examples/cc26xx/cc26xx-web-demo/coap-server.c +++ b/examples/cc26xx/cc26xx-web-demo/coap-server.c @@ -39,7 +39,7 @@ #include "contiki-net.h" #include "rest-engine.h" #include "board-peripherals.h" -#include "dev/cc26xx-rf.h" +#include "rf-core/rf-ble.h" #include #include @@ -56,7 +56,10 @@ extern resource_t res_device_hw; extern resource_t res_device_uptime; extern resource_t res_device_cfg_reset; -#if CC26XX_RF_BLE_SUPPORT +extern resource_t res_parent_rssi; +extern resource_t res_parent_ip; + +#if RF_BLE_ENABLED extern resource_t res_ble_advd; #endif @@ -138,7 +141,10 @@ PROCESS_THREAD(coap_server_process, ev, data) rest_activate_resource(&res_device_uptime, "dev/uptime"); rest_activate_resource(&res_device_cfg_reset, "dev/cfg_reset"); -#if CC26XX_RF_BLE_SUPPORT + rest_activate_resource(&res_parent_rssi, "net/parent/RSSI"); + rest_activate_resource(&res_parent_ip, "net/parent/IPv6"); + +#if RF_BLE_ENABLED rest_activate_resource(&res_ble_advd, "dev/ble_advd"); #endif diff --git a/examples/cc26xx/cc26xx-web-demo/httpd-simple.c b/examples/cc26xx/cc26xx-web-demo/httpd-simple.c index 29c22d22b..9800bbc48 100644 --- a/examples/cc26xx/cc26xx-web-demo/httpd-simple.c +++ b/examples/cc26xx/cc26xx-web-demo/httpd-simple.c @@ -93,8 +93,8 @@ static int state; #define STRINGIFY(x) XSTR(x) #define XSTR(x) #x -#define RSSI_INT_MAX STRINGIFY(MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MAX) -#define RSSI_INT_MIN STRINGIFY(MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MIN) +#define RSSI_INT_MAX STRINGIFY(CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MAX) +#define RSSI_INT_MIN STRINGIFY(CC26XX_WEB_DEMO_RSSI_MEASURE_INTERVAL_MIN) #define PUB_INT_MAX STRINGIFY(MQTT_CLIENT_PUBLISH_INTERVAL_MAX) #define PUB_INT_MIN STRINGIFY(MQTT_CLIENT_PUBLISH_INTERVAL_MIN) /*---------------------------------------------------------------------------*/ @@ -568,12 +568,54 @@ PT_THREAD(generate_config(struct httpd_state *s)) s->reading->publish ? "" : " Checked", config_div_close)); } + PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "")); PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "")); + /* RSSI measurements */ +#if CC26XX_WEB_DEMO_READ_PARENT_RSSI + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "

RSSI Probing

")); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "
generate_pt, + enqueue_chunk(s, 0, "method=\"post\" enctype=\"")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "application/x-www-form-urlencoded\" ")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "accept-charset=\"UTF-8\">")); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sPeriod (secs):%s", + config_div_left, config_div_close)); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "%sgenerate_pt, + enqueue_chunk(s, 0, "value=\"%lu\" ", + (clock_time_t) + (cc26xx_web_demo_config.def_rt_ping_interval + / CLOCK_SECOND))); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "min=\"" RSSI_INT_MIN "\" " + "max=\"" RSSI_INT_MAX "\" " + "name=\"ping_interval\">%s", + config_div_close)); + + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, + "")); + PT_WAIT_THREAD(&s->generate_pt, + enqueue_chunk(s, 0, "
")); +#endif + /* Actions */ PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "

Actions

")); PT_WAIT_THREAD(&s->generate_pt, @@ -732,24 +774,6 @@ PT_THREAD(generate_mqtt_config(struct httpd_state *s)) "name=\"broker_port\">%s", config_div_close)); - PT_WAIT_THREAD(&s->generate_pt, - enqueue_chunk(s, 0, "%sRSSI Interval (secs):%s", - config_div_left, config_div_close)); - PT_WAIT_THREAD(&s->generate_pt, - enqueue_chunk(s, 0, "%sgenerate_pt, - enqueue_chunk(s, 0, "value=\"%lu\" ", - (clock_time_t) - (cc26xx_web_demo_config.mqtt_config.def_rt_ping_interval - / CLOCK_SECOND))); - PT_WAIT_THREAD(&s->generate_pt, - enqueue_chunk(s, 0, - "min=\"" RSSI_INT_MIN "\" " - "max=\"" RSSI_INT_MAX "\" " - "name=\"ping_interval\">%s", - config_div_close)); - PT_WAIT_THREAD(&s->generate_pt, enqueue_chunk(s, 0, "")); diff --git a/examples/cc26xx/cc26xx-web-demo/httpd-simple.h b/examples/cc26xx/cc26xx-web-demo/httpd-simple.h index c7631adb1..25b8db3e5 100644 --- a/examples/cc26xx/cc26xx-web-demo/httpd-simple.h +++ b/examples/cc26xx/cc26xx-web-demo/httpd-simple.h @@ -48,7 +48,7 @@ /*---------------------------------------------------------------------------*/ /* Ideally a multiple of TCP_MSS */ #ifdef HTTPD_SIMPLE_CONF_MAIN_BUF_SIZE -#define HTTPD_SIMPLE_MAIN_BUF_SIZE HTTPD_SIMPLE_CONF_BUF_SIZE +#define HTTPD_SIMPLE_MAIN_BUF_SIZE HTTPD_SIMPLE_CONF_MAIN_BUF_SIZE #else #define HTTPD_SIMPLE_MAIN_BUF_SIZE UIP_TCP_MSS #endif diff --git a/examples/cc26xx/cc26xx-web-demo/mqtt-client.c b/examples/cc26xx/cc26xx-web-demo/mqtt-client.c index 4fa0736ef..cf60d6c63 100644 --- a/examples/cc26xx/cc26xx-web-demo/mqtt-client.c +++ b/examples/cc26xx/cc26xx-web-demo/mqtt-client.c @@ -41,7 +41,6 @@ #include "net/rpl/rpl.h" #include "net/ip/uip.h" #include "net/ipv6/uip-icmp6.h" -#include "net/ipv6/sicslowpan.h" #include "sys/etimer.h" #include "sys/ctimer.h" #include "lib/sensors.h" @@ -86,7 +85,7 @@ static const char *broker_ip = "0064:ff9b:0000:0000:0000:0000:b8ac:7cbd"; * Number of times to try reconnecting to the broker. * Can be a limited number (e.g. 3, 10 etc) or can be set to RETRY_FOREVER */ -#define RECONNECT_ATTEMPTS RETRY_FOREVER +#define RECONNECT_ATTEMPTS 5 #define CONNECTION_STABLE_TIME (CLOCK_SECOND * 5) #define NEW_CONFIG_WAIT_INTERVAL (CLOCK_SECOND * 20) static struct timer connection_life; @@ -139,9 +138,7 @@ static uint16_t seq_nr_value = 0; static uip_ip6addr_t def_route; /*---------------------------------------------------------------------------*/ /* Parent RSSI functionality */ -static struct uip_icmp6_echo_reply_notification echo_reply_notification; -static struct etimer echo_request_timer; -int def_rt_rssi = 0; +extern int def_rt_rssi; /*---------------------------------------------------------------------------*/ const static cc26xx_web_demo_sensor_reading_t *reading; /*---------------------------------------------------------------------------*/ @@ -388,29 +385,6 @@ reconnect_post_handler(char *key, int key_len, char *val, int val_len) return HTTPD_SIMPLE_POST_HANDLER_OK; } /*---------------------------------------------------------------------------*/ -static int -ping_interval_post_handler(char *key, int key_len, char *val, int val_len) -{ - int rv = 0; - - if(key_len != strlen("ping_interval") || - strncasecmp(key, "ping_interval", strlen("ping_interval")) != 0) { - /* Not ours */ - return HTTPD_SIMPLE_POST_HANDLER_UNKNOWN; - } - - rv = atoi(val); - - if(rv < MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MIN || - rv > MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MAX) { - return HTTPD_SIMPLE_POST_HANDLER_ERROR; - } - - conf->def_rt_ping_interval = rv * CLOCK_SECOND; - - return HTTPD_SIMPLE_POST_HANDLER_OK; -} -/*---------------------------------------------------------------------------*/ HTTPD_SIMPLE_POST_HANDLER(org_id, org_id_post_handler); HTTPD_SIMPLE_POST_HANDLER(type_id, type_id_post_handler); HTTPD_SIMPLE_POST_HANDLER(event_type_id, event_type_id_post_handler); @@ -420,16 +394,6 @@ HTTPD_SIMPLE_POST_HANDLER(ip_addr, ip_addr_post_handler); HTTPD_SIMPLE_POST_HANDLER(port, port_post_handler); HTTPD_SIMPLE_POST_HANDLER(interval, interval_post_handler); HTTPD_SIMPLE_POST_HANDLER(reconnect, reconnect_post_handler); -HTTPD_SIMPLE_POST_HANDLER(ping_interval, ping_interval_post_handler); -/*---------------------------------------------------------------------------*/ -static void -echo_reply_handler(uip_ipaddr_t *source, uint8_t ttl, uint8_t *data, - uint16_t datalen) -{ - if(uip_ip6addr_cmp(source, uip_ds6_defrt_choose())) { - def_rt_rssi = sicslowpan_get_last_rssi(); - } -} /*---------------------------------------------------------------------------*/ static void pub_handler(const char *topic, uint16_t topic_len, const uint8_t *chunk, @@ -624,7 +588,6 @@ init_config() conf->broker_port = CC26XX_WEB_DEMO_DEFAULT_BROKER_PORT; conf->pub_interval = CC26XX_WEB_DEMO_DEFAULT_PUBLISH_INTERVAL; - conf->def_rt_ping_interval = CC26XX_WEB_DEMO_DEFAULT_RSSI_MEAS_INTERVAL; return 1; } @@ -641,7 +604,6 @@ register_http_post_handlers(void) httpd_simple_register_post_handler(&port_handler); httpd_simple_register_post_handler(&ip_addr_handler); httpd_simple_register_post_handler(&reconnect_handler); - httpd_simple_register_post_handler(&ping_interval_handler); } /*---------------------------------------------------------------------------*/ static void @@ -664,6 +626,7 @@ publish(void) /* Publish MQTT topic in IBM quickstart format */ int len; int remaining = APP_BUFFER_SIZE; + char def_rt_str[64]; seq_nr_value++; @@ -686,7 +649,6 @@ publish(void) buf_ptr += len; /* Put our Default route's string representation in a buffer */ - char def_rt_str[64]; memset(def_rt_str, 0, sizeof(def_rt_str)); cc26xx_web_demo_ipaddr_sprintf(def_rt_str, sizeof(def_rt_str), uip_ds6_defrt_choose()); @@ -743,17 +705,6 @@ connect_to_broker(void) } /*---------------------------------------------------------------------------*/ static void -ping_parent(void) -{ - if(uip_ds6_get_global(ADDR_PREFERRED) == NULL) { - return; - } - - uip_icmp6_send(uip_ds6_defrt_choose(), ICMP6_ECHO_REQUEST, 0, - CC26XX_WEB_DEMO_ECHO_REQ_PAYLOAD_LEN); -} -/*---------------------------------------------------------------------------*/ -static void state_machine(void) { switch(state) { @@ -794,7 +745,6 @@ state_machine(void) if(uip_ds6_get_global(ADDR_PREFERRED) != NULL) { /* Registered and with a public IP. Connect */ DBG("Registered. Connect attempt %u\n", connect_attempt); - ping_parent(); connect_to_broker(); } etimer_set(&publish_periodic_timer, CC26XX_WEB_DEMO_NET_CONNECT_PERIODIC); @@ -923,11 +873,6 @@ PROCESS_THREAD(mqtt_client_process, ev, data) update_config(); - def_rt_rssi = 0x8000000; - uip_icmp6_echo_reply_callback_add(&echo_reply_notification, - echo_reply_handler); - etimer_set(&echo_request_timer, conf->def_rt_ping_interval); - /* Main loop */ while(1) { @@ -956,11 +901,6 @@ PROCESS_THREAD(mqtt_client_process, ev, data) state_machine(); } - if(ev == PROCESS_EVENT_TIMER && data == &echo_request_timer) { - ping_parent(); - etimer_set(&echo_request_timer, conf->def_rt_ping_interval); - } - if(ev == cc26xx_web_demo_load_config_defaults) { init_config(); etimer_set(&publish_periodic_timer, NEW_CONFIG_WAIT_INTERVAL); diff --git a/examples/cc26xx/cc26xx-web-demo/mqtt-client.h b/examples/cc26xx/cc26xx-web-demo/mqtt-client.h index b4b50085f..ab7c08227 100644 --- a/examples/cc26xx/cc26xx-web-demo/mqtt-client.h +++ b/examples/cc26xx/cc26xx-web-demo/mqtt-client.h @@ -45,8 +45,6 @@ #define MQTT_CLIENT_CONFIG_CMD_TYPE_LEN 8 #define MQTT_CLIENT_CONFIG_IP_ADDR_STR_LEN 64 /*---------------------------------------------------------------------------*/ -#define MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MAX 86400 /* secs: 1 day */ -#define MQTT_CLIENT_RSSI_MEASURE_INTERVAL_MIN 5 /* secs */ #define MQTT_CLIENT_PUBLISH_INTERVAL_MAX 86400 /* secs: 1 day */ #define MQTT_CLIENT_PUBLISH_INTERVAL_MIN 5 /* secs */ /*---------------------------------------------------------------------------*/ @@ -63,7 +61,6 @@ typedef struct mqtt_client_config { char broker_ip[MQTT_CLIENT_CONFIG_IP_ADDR_STR_LEN]; char cmd_type[MQTT_CLIENT_CONFIG_CMD_TYPE_LEN]; clock_time_t pub_interval; - int def_rt_ping_interval; uint16_t broker_port; } mqtt_client_config_t; /*---------------------------------------------------------------------------*/ diff --git a/examples/cc26xx/cc26xx-web-demo/project-conf.h b/examples/cc26xx/cc26xx-web-demo/project-conf.h index b7baac119..ee77b125f 100644 --- a/examples/cc26xx/cc26xx-web-demo/project-conf.h +++ b/examples/cc26xx/cc26xx-web-demo/project-conf.h @@ -32,11 +32,9 @@ #define PROJECT_CONF_H_ /*---------------------------------------------------------------------------*/ /* Change to match your configuration */ -#define NETSTACK_CONF_RDC contikimac_driver #define IEEE802154_CONF_PANID 0xABCD -#define CC26XX_RF_CONF_CHANNEL 25 -#define CC26XX_MODEL_CONF_CPU_VARIANT 2650 /* CC2650 */ -#define CC26XX_RF_CONF_BLE_SUPPORT 1 /* Only available with CC2650 */ +#define RF_CORE_CONF_CHANNEL 25 +#define RF_BLE_CONF_ENABLED 1 /*---------------------------------------------------------------------------*/ /* Enable/Disable Components of this Demo */ #define CC26XX_WEB_DEMO_CONF_MQTT_CLIENT 1 diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-ble-advd.c b/examples/cc26xx/cc26xx-web-demo/resources/res-ble-advd.c index 0604c7ac9..68693b737 100644 --- a/examples/cc26xx/cc26xx-web-demo/resources/res-ble-advd.c +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-ble-advd.c @@ -38,7 +38,7 @@ #include "contiki.h" #include "rest-engine.h" #include "er-coap.h" -#include "dev/cc26xx-rf.h" +#include "rf-core/rf-ble.h" #include #include @@ -64,7 +64,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer, if(len > 0 && len < BLE_NAME_BUF_LEN) { memcpy(name, text, len); - cc26xx_rf_ble_beacond_config(0, name); + rf_ble_beacond_config(0, name); success = 1; } @@ -73,7 +73,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer, rv = atoi(text); if(rv > 0) { - cc26xx_rf_ble_beacond_config((clock_time_t)(rv * CLOCK_SECOND), NULL); + rf_ble_beacond_config((clock_time_t)(rv * CLOCK_SECOND), NULL); success = 1; } @@ -81,7 +81,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer, if(len) { if(strncmp(text, "on", len) == 0) { - if(cc26xx_rf_ble_beacond_start()) { + if(rf_ble_beacond_start()) { success = 1; } else { REST.set_response_status(response, REST.status.FORBIDDEN); @@ -90,7 +90,7 @@ res_ble_post_put_handler(void *request, void *response, uint8_t *buffer, return; } } else if(strncmp(text, "off", len) == 0) { - cc26xx_rf_ble_beacond_stop(); + rf_ble_beacond_stop(); success = 1; } else { success = 0; diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-device.c b/examples/cc26xx/cc26xx-web-demo/resources/res-device.c index 84cef8e24..62e8dc6dc 100644 --- a/examples/cc26xx/cc26xx-web-demo/resources/res-device.c +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-device.c @@ -40,37 +40,65 @@ #include "rest-engine.h" #include "er-coap.h" #include "sys/clock.h" -#include "cc26xx-model.h" #include "coap-server.h" #include "cc26xx-web-demo.h" +#include "ti-lib.h" + #include /*---------------------------------------------------------------------------*/ +static uint16_t +detect_chip(void) +{ + if(ti_lib_chipinfo_chip_family_is_cc26xx()) { + if(ti_lib_chipinfo_supports_ieee_802_15_4() == true) { + if(ti_lib_chipinfo_supports_ble() == true) { + return 2650; + } else { + return 2630; + } + } else { + return 2640; + } + } else if(ti_lib_chipinfo_chip_family_is_cc13xx()) { + if(ti_lib_chipinfo_supports_ble() == false && + ti_lib_chipinfo_supports_ieee_802_15_4() == false) { + return 1310; + } else if(ti_lib_chipinfo_supports_ble() == true && + ti_lib_chipinfo_supports_ieee_802_15_4() == true) { + return 1350; + } + } + + return 0; +} +/*---------------------------------------------------------------------------*/ static void res_get_handler_hw(void *request, void *response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { unsigned int accept = -1; + uint16_t chip = detect_chip(); REST.get_header_accept(request, &accept); if(accept == -1 || accept == REST.type.TEXT_PLAIN) { REST.set_header_content_type(response, REST.type.TEXT_PLAIN); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s on CC%u", BOARD_STRING, - CC26XX_MODEL_CPU_VARIANT); + chip); REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); } else if(accept == REST.type.APPLICATION_JSON) { REST.set_header_content_type(response, REST.type.APPLICATION_JSON); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"HW Ver\":\"%s on CC%u\"}", - BOARD_STRING, CC26XX_MODEL_CPU_VARIANT); + BOARD_STRING, chip); REST.set_response_payload(response, buffer, strlen((char *)buffer)); } else if(accept == REST.type.APPLICATION_XML) { REST.set_header_content_type(response, REST.type.APPLICATION_XML); snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "", BOARD_STRING, - CC26XX_MODEL_CPU_VARIANT); + chip); REST.set_response_payload(response, buffer, strlen((char *)buffer)); } else { diff --git a/examples/cc26xx/cc26xx-web-demo/resources/res-net.c b/examples/cc26xx/cc26xx-web-demo/resources/res-net.c new file mode 100644 index 000000000..1a5ce7b81 --- /dev/null +++ b/examples/cc26xx/cc26xx-web-demo/resources/res-net.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup cc26xx-web-demo + * @{ + * + * \file + * CoAP resource handler for network-related resources + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "rest-engine.h" +#include "er-coap.h" +#include "coap-server.h" +#include "cc26xx-web-demo.h" + +#include "ti-lib.h" + +#include +/*---------------------------------------------------------------------------*/ +extern int def_rt_rssi; +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_parent_rssi(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + + REST.get_header_accept(request, &accept); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%d", def_rt_rssi); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"Parent RSSI\":\"%d\"}", + def_rt_rssi); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "", def_rt_rssi); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, coap_server_supported_msg, + strlen(coap_server_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +static void +res_get_handler_pref_parent(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + char def_rt_str[64]; + + REST.get_header_accept(request, &accept); + + memset(def_rt_str, 0, sizeof(def_rt_str)); + cc26xx_web_demo_ipaddr_sprintf(def_rt_str, sizeof(def_rt_str), + uip_ds6_defrt_choose()); + + if(accept == -1 || accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "%s", def_rt_str); + + REST.set_response_payload(response, (uint8_t *)buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "{\"Parent\":\"%s\"}", + def_rt_str); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.APPLICATION_XML) { + REST.set_header_content_type(response, REST.type.APPLICATION_XML); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "", def_rt_str); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, coap_server_supported_msg, + strlen(coap_server_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +RESOURCE(res_parent_rssi, "title=\"Parent RSSI\";rt=\"dBm\"", + res_get_handler_parent_rssi, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +RESOURCE(res_parent_ip, "title=\"Preferred Parent\";rt=\"IPv6 address\"", + res_get_handler_pref_parent, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/examples/cc26xx/project-conf.h b/examples/cc26xx/project-conf.h index 97bb52591..7c1363c16 100644 --- a/examples/cc26xx/project-conf.h +++ b/examples/cc26xx/project-conf.h @@ -35,11 +35,9 @@ #define BUTTON_SENSOR_CONF_ENABLE_SHUTDOWN 0 /*---------------------------------------------------------------------------*/ /* Change to match your configuration */ -#define NETSTACK_CONF_RDC contikimac_driver #define IEEE802154_CONF_PANID 0xABCD -#define CC26XX_RF_CONF_CHANNEL 25 -#define CC26XX_MODEL_CONF_CPU_VARIANT 2650 /* CC2650 */ -#define CC26XX_RF_CONF_BLE_SUPPORT 1 /* Only available with CC2650 */ +#define RF_CORE_CONF_CHANNEL 25 +#define RF_BLE_CONF_ENABLED 1 /*---------------------------------------------------------------------------*/ #endif /* PROJECT_CONF_H_ */ /*---------------------------------------------------------------------------*/ diff --git a/examples/cc26xx/very-sleepy-demo/Makefile b/examples/cc26xx/very-sleepy-demo/Makefile new file mode 100644 index 000000000..a1e794957 --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/Makefile @@ -0,0 +1,12 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = very-sleepy-demo + +all: $(CONTIKI_PROJECT) + +CONTIKI_WITH_IPV6 = 1 + +APPS += er-coap +APPS += rest-engine + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/cc26xx/very-sleepy-demo/Makefile.target b/examples/cc26xx/very-sleepy-demo/Makefile.target new file mode 100644 index 000000000..15890aa6a --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/Makefile.target @@ -0,0 +1 @@ +TARGET = srf06-cc26xx diff --git a/examples/cc26xx/very-sleepy-demo/README.md b/examples/cc26xx/very-sleepy-demo/README.md new file mode 100644 index 000000000..fcdedf77f --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/README.md @@ -0,0 +1,91 @@ +# CC13xx/CC26xx Very Sleepy Demo + +This example demonstrates a way of deploying a very low-consuming, very sleepy +node. The node has two modes of operation: + +* Normal: ContikiMAC duty-cycles the radio as usual. The node is reachable. +* Very Sleepy: Radio cycling mostly off, except when we need to perform network + maintenance tasks. In this mode, the node is unreachable for most of the time. + +The node will operate in RPL leaf mode. This means that it will be reachable +downwards, but it will not advertise the DODAG and it will not participate in +routing. + +After booting, the node will enter "normal" mode. + +The node exposes an OBSERVEable CoAP resource. It will notify subscribers with +a new value for this resource every `interval` seconds. It will then stay in +normal mode for `duration` seconds. During this time window, it will be +reachable over the network in order to e.g. receive a new configuration. +When this time window expires, the node will switch back to very sleepy mode. +This will only happen if very sleepy mode has been enabled by setting `mode=1` +as per the instructions below. + +When the node is duty-cycling the radio, either because it is in normal mode or +because network maintenance is taking place, it will keep its green LED on thus +providing an indication that it is reachable. + +A normal mode stint can be manually triggered by pressing the left button. + +## Requirements + +To run this example you will need: + +* A border router operating with the same RDC, same channel, same radio mode + (e.g. IEEE or sub-ghz), same PAN ID. Alternatively, you can + use [6lbr](https://github.com/cetic/6lbr) with a suitable slip-radio. +* The [Copper (Cu)](https://addons.mozilla.org/en-US/firefox/addon/copper-270430/) + addon for Firefox + +## Configuration + +To configure the node, send a CoAP POST message to the `very_sleepy_config` +resource. The POST message's payload must specify _at least one_ of: + +* `mode=0|1`: Send `mode=1` to enable very sleepy mode, `mode=0` to disable it. +* `interval=n` where `n` is the number of seconds between two consecutive normal + mode periods. This interval also dictates the OBSERVEr notification period. +* `duration=n` where `n` is the number of seconds that the node will stay in + normal mode before dropping to very sleepy mode. This value is only relevant + if `mode==1`. + +A POST request must contain at least one of the above, but they are otherwise +all optional. So, for example, a POST may simply specify `interval=n`. To send +multiple values, delimit them with `&`. So you can send something like +`mode=1&interval=60&duration=20` + +The current running configuration can be retrieved by sending a GET request to +the same CoAP resource. + +## Running the example + +* Deploy your border router or 6lbr +* Turn on the very sleepy node. +* Fire up the Copper addon +* Select `.well-known/core` and hit `GET` +* Configure very sleepy operation: + * Select the `very_sleepy_config` resource + * In the `Outgoing` pane, type your POST payload as per the instructions + above. For example, you can type: `mode=1&interval=30&duration=10` + * Hit `POST` +* Select the `sen/readings` resource and hit `OBSERVE` + +## Caveats + +If you click on a resource in the Copper resources tree while you are observing +a different resource, the OBSERVEr for the latter will be stopped without +notifying the CoAP server. This will result in the server sending out OBSERVE +notifications that will be responded to with port unreachable ICMPv6 messages. +This will continue for quite a while, until the server detects that the +OBSERVEr has been lost (a test currently performed once every 20 notifications). +In order to prevent this from happening, hit the "Cancel" button for the +OBSERVE before switching views to a different resource. This will unregister +the observer. + +In very sleepy mode, the radio is not truly always off. The contiki core needs +to perform other periodic tasks in order to maintain network connectivity. For +that reason, this example will allow the radio to turn on periodically even +while in very sleepy mode. Thus, you may see that the node becomes briefly +reachable every now and then. However, do not count on those periods of +reachability to perform any tasks, as they will be brief and will be disrupted +without warning. diff --git a/cpu/cc26xx/cc26xx-model.h b/examples/cc26xx/very-sleepy-demo/project-conf.h similarity index 65% rename from cpu/cc26xx/cc26xx-model.h rename to examples/cc26xx/very-sleepy-demo/project-conf.h index 44ee1cfe3..477a535bf 100644 --- a/cpu/cc26xx/cc26xx-model.h +++ b/examples/cc26xx/very-sleepy-demo/project-conf.h @@ -10,7 +10,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * * 3. Neither the name of the copyright holder nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. @@ -29,46 +28,24 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ /*---------------------------------------------------------------------------*/ -/** - * \addtogroup cc26xx - * @{ - * - * \defgroup cc26xx-models CC26xx models - * - * The CC26xx comes out in various flavours. Most notable within the context - * of this Contiki port: The CC2630 with IEEE (but no BLE) support and the - * CC2650 with IEEE and BLE support. - * - * This port supports both models and will automatically turn off the BLE code - * if the CC2630 is selected. - * - * @{ - */ -/** - * \file - * Header file with definitions relating to various CC26xx variants - */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ /*---------------------------------------------------------------------------*/ -#ifndef CC26XX_MODEL_H_ -#define CC26XX_MODEL_H_ +/* Change to match your configuration */ +#define IEEE802154_CONF_PANID 0xABCD +#define RF_CORE_CONF_CHANNEL 25 /*---------------------------------------------------------------------------*/ -#include "contiki-conf.h" -/*---------------------------------------------------------------------------*/ -#ifdef CC26XX_MODEL_CONF_CPU_VARIANT -#define CC26XX_MODEL_CPU_VARIANT CC26XX_MODEL_CONF_CPU_VARIANT -#else -#define CC26XX_MODEL_CPU_VARIANT 2650 -#endif +/* For very sleepy operation */ +#define RF_BLE_CONF_ENABLED 0 +#define UIP_DS6_CONF_PERIOD CLOCK_SECOND +#define UIP_CONF_TCP 0 +#define RPL_CONF_LEAF_ONLY 1 -#if (CC26XX_MODEL_CPU_VARIANT != 2630) && (CC26XX_MODEL_CPU_VARIANT != 2650) -#error Incorrect CC26xx variant selected. -#error Check the value of CC26XX_MODEL_CONF_CPU_VARIANT -#error Supported values: 2630 and 2650 -#endif -/*---------------------------------------------------------------------------*/ -#endif /* CC26XX_MODEL_H_ */ -/*---------------------------------------------------------------------------*/ -/** - * @} - * @} +/* + * We'll fail without RPL probing, so turn it on explicitly even though it's + * on by default */ +#define RPL_CONF_WITH_PROBING 1 +/*---------------------------------------------------------------------------*/ +#endif /* PROJECT_CONF_H_ */ +/*---------------------------------------------------------------------------*/ diff --git a/examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c b/examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c new file mode 100644 index 000000000..5719e11ce --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/very-sleepy-demo.c @@ -0,0 +1,423 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/etimer.h" +#include "sys/stimer.h" +#include "sys/process.h" +#include "dev/leds.h" +#include "dev/watchdog.h" +#include "button-sensor.h" +#include "batmon-sensor.h" +#include "board-peripherals.h" +#include "net/netstack.h" +#include "net/ipv6/uip-ds6-nbr.h" +#include "net/ipv6/uip-ds6-route.h" +#include "net/rpl/rpl.h" +#include "net/rpl/rpl-private.h" +#include "rest-engine.h" +#include "er-coap.h" + +#include "ti-lib.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +/* Normal mode duration params in seconds */ +#define NORMAL_OP_DURATION_DEFAULT 10 +#define NORMAL_OP_DURATION_MIN 10 +#define NORMAL_OP_DURATION_MAX 60 +/*---------------------------------------------------------------------------*/ +/* Observer notification period params in seconds */ +#define PERIODIC_INTERVAL_DEFAULT 30 +#define PERIODIC_INTERVAL_MIN 30 +#define PERIODIC_INTERVAL_MAX 86400 /* 1 day */ +/*---------------------------------------------------------------------------*/ +#define VERY_SLEEPY_MODE_OFF 0 +#define VERY_SLEEPY_MODE_ON 1 +/*---------------------------------------------------------------------------*/ +#define MAC_CAN_BE_TURNED_OFF 0 +#define MAC_MUST_STAY_ON 1 + +#define KEEP_MAC_ON_MIN_PERIOD 10 /* secs */ +/*---------------------------------------------------------------------------*/ +#define PERIODIC_INTERVAL CLOCK_SECOND +/*---------------------------------------------------------------------------*/ +#define POST_STATUS_BAD 0x80 +#define POST_STATUS_HAS_MODE 0x40 +#define POST_STATUS_HAS_DURATION 0x20 +#define POST_STATUS_HAS_INTERVAL 0x10 +#define POST_STATUS_NONE 0x00 +/*---------------------------------------------------------------------------*/ +typedef struct sleepy_config_s { + unsigned long interval; + unsigned long duration; + uint8_t mode; +} sleepy_config_t; + +sleepy_config_t config; +/*---------------------------------------------------------------------------*/ +#define STATE_NORMAL 0 +#define STATE_NOTIFY_OBSERVERS 1 +#define STATE_VERY_SLEEPY 2 +/*---------------------------------------------------------------------------*/ +static struct stimer st_duration; +static struct stimer st_interval; +static struct stimer st_min_mac_on_duration; +static struct etimer et_periodic; +static process_event_t event_new_config; +static uint8_t state; +/*---------------------------------------------------------------------------*/ +const char *not_supported_msg = "Supported:text/plain,application/json"; +/*---------------------------------------------------------------------------*/ +PROCESS(very_sleepy_demo_process, "CC13xx/CC26xx very sleepy process"); +AUTOSTART_PROCESSES(&very_sleepy_demo_process); +/*---------------------------------------------------------------------------*/ +static void +readings_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + int temp; + int voltage; + + if(request != NULL) { + REST.get_header_accept(request, &accept); + } + + temp = batmon_sensor.value(BATMON_SENSOR_TYPE_TEMP); + + voltage = batmon_sensor.value(BATMON_SENSOR_TYPE_VOLT); + + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "{\"temp\":{\"v\":%d,\"u\":\"C\"}," + "\"voltage\":{\"v\":%d,\"u\":\"mV\"}}", + temp, (voltage * 125) >> 5); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, "Temp=%dC, Voltage=%dmV", + temp, (voltage * 125) >> 5); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, not_supported_msg, + strlen(not_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +RESOURCE(readings_resource, "title=\"Sensor Readings\";obs", + readings_get_handler, NULL, NULL, NULL); +/*---------------------------------------------------------------------------*/ +static void +conf_get_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + unsigned int accept = -1; + + if(request != NULL) { + REST.get_header_accept(request, &accept); + } + + if(accept == -1 || accept == REST.type.APPLICATION_JSON) { + REST.set_header_content_type(response, REST.type.APPLICATION_JSON); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "{\"config\":{\"mode\":%u,\"duration\":%lu,\"interval\":%lu}}", + config.mode, config.duration, config.interval); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else if(accept == REST.type.TEXT_PLAIN) { + REST.set_header_content_type(response, REST.type.TEXT_PLAIN); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "Mode=%u, Duration=%lusecs, Interval=%lusecs", + config.mode, config.duration, config.interval); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + } else { + REST.set_response_status(response, REST.status.NOT_ACCEPTABLE); + REST.set_response_payload(response, not_supported_msg, + strlen(not_supported_msg)); + } +} +/*---------------------------------------------------------------------------*/ +static void +conf_post_handler(void *request, void *response, uint8_t *buffer, + uint16_t preferred_size, int32_t *offset) +{ + const char *ptr = NULL; + char tmp_buf[16]; + unsigned long interval = 0; + unsigned long duration = 0; + uint8_t mode = VERY_SLEEPY_MODE_OFF; + uint8_t post_status = POST_STATUS_NONE; + int rv; + + rv = REST.get_post_variable(request, "mode", &ptr); + if(rv && rv < 16) { + memset(tmp_buf, 0, sizeof(tmp_buf)); + memcpy(tmp_buf, ptr, rv); + rv = atoi(tmp_buf); + + if(rv == 1) { + mode = VERY_SLEEPY_MODE_ON; + post_status |= POST_STATUS_HAS_MODE; + } else if(rv == 0) { + mode = VERY_SLEEPY_MODE_OFF; + post_status |= POST_STATUS_HAS_MODE; + } else { + post_status = POST_STATUS_BAD; + } + } + + rv = REST.get_post_variable(request, "duration", &ptr); + if(rv && rv < 16) { + memset(tmp_buf, 0, sizeof(tmp_buf)); + memcpy(tmp_buf, ptr, rv); + rv = atoi(tmp_buf); + + duration = (unsigned long)rv; + if(duration < NORMAL_OP_DURATION_MIN || duration > NORMAL_OP_DURATION_MAX) { + post_status = POST_STATUS_BAD; + } else { + post_status |= POST_STATUS_HAS_DURATION; + } + } + + rv = REST.get_post_variable(request, "interval", &ptr); + if(rv && rv < 16) { + memset(tmp_buf, 0, sizeof(tmp_buf)); + memcpy(tmp_buf, ptr, rv); + rv = atoi(tmp_buf); + interval = (unsigned long)rv; + if(interval < PERIODIC_INTERVAL_MIN || interval > PERIODIC_INTERVAL_MAX) { + post_status = POST_STATUS_BAD; + } else { + post_status |= POST_STATUS_HAS_INTERVAL; + } + } + + if((post_status & POST_STATUS_BAD) == POST_STATUS_BAD || + post_status == POST_STATUS_NONE) { + REST.set_response_status(response, REST.status.BAD_REQUEST); + snprintf((char *)buffer, REST_MAX_CHUNK_SIZE, + "mode=0|1&duration=[%u,%u]&interval=[%u,%u]", + NORMAL_OP_DURATION_MIN, NORMAL_OP_DURATION_MAX, + PERIODIC_INTERVAL_MIN, PERIODIC_INTERVAL_MAX); + + REST.set_response_payload(response, buffer, strlen((char *)buffer)); + return; + } + + /* Values are sane. Update the config and notify the process */ + if(post_status & POST_STATUS_HAS_MODE) { + config.mode = mode; + } + + if(post_status & POST_STATUS_HAS_INTERVAL) { + config.interval = interval; + } + + if(post_status & POST_STATUS_HAS_DURATION) { + config.duration = duration; + } + + process_post(&very_sleepy_demo_process, event_new_config, NULL); +} +/*---------------------------------------------------------------------------*/ +RESOURCE(very_sleepy_conf, + "title=\"Very sleepy conf: " + "GET|POST mode=0|1&interval=&duration=\";rt=\"Control\"", + conf_get_handler, conf_post_handler, NULL, NULL); +/*---------------------------------------------------------------------------*/ +/* + * If our preferred parent is not NBR_REACHABLE in the ND cache, NUD will send + * a unicast NS and wait for NA. If NA fails then the neighbour will be removed + * from the ND cache and the default route will be deleted. To prevent this, + * keep the MAC on until the parent becomes NBR_REACHABLE. We also keep the MAC + * on if we are about to do RPL probing. + * + * In all cases, the radio will be locked on for KEEP_MAC_ON_MIN_PERIOD secs + */ +static uint8_t +keep_mac_on(void) +{ + uip_ds6_nbr_t *nbr; + uint8_t rv = MAC_CAN_BE_TURNED_OFF; + + if(!stimer_expired(&st_min_mac_on_duration)) { + return MAC_MUST_STAY_ON; + } + +#if RPL_WITH_PROBING + /* Determine if we are about to send a RPL probe */ + if(CLOCK_LT(etimer_expiration_time( + &rpl_get_default_instance()->probing_timer.etimer), + (clock_time() + PERIODIC_INTERVAL))) { + rv = MAC_MUST_STAY_ON; + } +#endif + + /* It's OK to pass a NULL pointer, the callee checks and returns NULL */ + nbr = uip_ds6_nbr_lookup(uip_ds6_defrt_choose()); + + if(nbr == NULL) { + /* We don't have a default route, or it's not reachable (NUD likely). */ + rv = MAC_MUST_STAY_ON; + } else { + if(nbr->state != NBR_REACHABLE) { + rv = MAC_MUST_STAY_ON; + } + } + + if(rv == MAC_MUST_STAY_ON && stimer_expired(&st_min_mac_on_duration)) { + stimer_set(&st_min_mac_on_duration, KEEP_MAC_ON_MIN_PERIOD); + } + + return rv; +} +/*---------------------------------------------------------------------------*/ +static void +switch_to_normal(void) +{ + state = STATE_NOTIFY_OBSERVERS; + + /* + * Stay in normal mode for 'duration' secs. + * Transition back to normal in 'interval' secs, _including_ 'duration' + */ + stimer_set(&st_duration, config.duration); + stimer_set(&st_interval, config.interval); +} +/*---------------------------------------------------------------------------*/ +static void +switch_to_very_sleepy(void) +{ + state = STATE_VERY_SLEEPY; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(very_sleepy_demo_process, ev, data) +{ + uint8_t mac_keep_on; + + PROCESS_BEGIN(); + + SENSORS_ACTIVATE(batmon_sensor); + + config.mode = VERY_SLEEPY_MODE_OFF; + config.interval = PERIODIC_INTERVAL_DEFAULT; + config.duration = NORMAL_OP_DURATION_DEFAULT; + + state = STATE_NORMAL; + + event_new_config = process_alloc_event(); + + rest_init_engine(); + + readings_resource.flags += IS_OBSERVABLE; + rest_activate_resource(&readings_resource, "sen/readings"); + rest_activate_resource(&very_sleepy_conf, "very_sleepy_config"); + + printf("Very Sleepy Demo Process\n"); + + switch_to_normal(); + + etimer_set(&et_periodic, PERIODIC_INTERVAL); + + while(1) { + + PROCESS_YIELD(); + + if(ev == sensors_event && data == &button_left_sensor) { + switch_to_normal(); + } + + if(ev == event_new_config) { + stimer_set(&st_interval, config.interval); + stimer_set(&st_duration, config.duration); + } + + if((ev == PROCESS_EVENT_TIMER && data == &et_periodic) || + (ev == sensors_event && data == &button_left_sensor) || + (ev == event_new_config)) { + + /* + * Determine if the stack is about to do essential network maintenance + * and, if so, keep the MAC layer on + */ + mac_keep_on = keep_mac_on(); + + if(mac_keep_on == MAC_MUST_STAY_ON || state != STATE_VERY_SLEEPY) { + leds_on(LEDS_GREEN); + NETSTACK_MAC.on(); + } + + /* + * Next, switch between normal and very sleepy mode depending on config, + * send notifications to observers as required. + */ + if(state == STATE_NOTIFY_OBSERVERS) { + REST.notify_subscribers(&readings_resource); + state = STATE_NORMAL; + } + + if(state == STATE_NORMAL) { + if(stimer_expired(&st_duration)) { + stimer_set(&st_duration, config.duration); + if(config.mode == VERY_SLEEPY_MODE_ON) { + switch_to_very_sleepy(); + } + } + } else if(state == STATE_VERY_SLEEPY) { + if(stimer_expired(&st_interval)) { + switch_to_normal(); + } + } + + if(mac_keep_on == MAC_CAN_BE_TURNED_OFF && state == STATE_VERY_SLEEPY) { + leds_off(LEDS_GREEN); + NETSTACK_MAC.off(0); + } else { + leds_on(LEDS_GREEN); + NETSTACK_MAC.on(); + } + + /* Schedule next pass */ + etimer_set(&et_periodic, PERIODIC_INTERVAL); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/examples/ipv6/rpl-border-router/border-router.c b/examples/ipv6/rpl-border-router/border-router.c index 106107ccb..84943e68f 100644 --- a/examples/ipv6/rpl-border-router/border-router.c +++ b/examples/ipv6/rpl-border-router/border-router.c @@ -311,7 +311,7 @@ request_prefix(void) uip_buf[1] = 'P'; uip_len = 2; slip_send(); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ void diff --git a/examples/ipv6/rpl-border-router/slip-bridge.c b/examples/ipv6/rpl-border-router/slip-bridge.c index 52b4a4060..582f626e7 100644 --- a/examples/ipv6/rpl-border-router/slip-bridge.c +++ b/examples/ipv6/rpl-border-router/slip-bridge.c @@ -59,7 +59,7 @@ slip_input_callback(void) // PRINTF("SIN: %u\n", uip_len); if(uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); if(uip_buf[1] == 'P') { uip_ipaddr_t prefix; /* Here we set a prefix !!! */ @@ -85,7 +85,7 @@ slip_input_callback(void) slip_send(); } - uip_len = 0; + uip_clear_buf(); } /* Save the last sender received over SLIP to avoid bouncing the packet back if no route is found */ diff --git a/examples/ipv6/slip-radio/slip-radio.c b/examples/ipv6/slip-radio/slip-radio.c index 255cfefb5..b20e559ec 100644 --- a/examples/ipv6/slip-radio/slip-radio.c +++ b/examples/ipv6/slip-radio/slip-radio.c @@ -162,7 +162,7 @@ slip_input_callback(void) { PRINTF("SR-SIN: %u '%c%c'\n", uip_len, uip_buf[0], uip_buf[1]); cmd_input(uip_buf, uip_len); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ static void diff --git a/examples/irc/Makefile.c128.defines b/examples/irc/Makefile.c128.defines index 688d85113..7e0762e68 100644 --- a/examples/irc/Makefile.c128.defines +++ b/examples/irc/Makefile.c128.defines @@ -1 +1 @@ -DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_PFS +DEFINES = WITH_CLIENT,WITH_DNS,WITH_GUI,WITH_PFS,MTU_SIZE=1000 diff --git a/examples/ravenusbstick/fakeuip.c b/examples/ravenusbstick/fakeuip.c index a1e980aab..1f7232a64 100644 --- a/examples/ravenusbstick/fakeuip.c +++ b/examples/ravenusbstick/fakeuip.c @@ -13,6 +13,8 @@ uip_buf_t uip_aligned_buf; uint16_t uip_len; +uint8_t uip_ext_len; + struct uip_stats uip_stat; uip_lladdr_t uip_lladdr; diff --git a/examples/sensinode/border-router/border-router.c b/examples/sensinode/border-router/border-router.c index 028a2f770..9442c9e03 100644 --- a/examples/sensinode/border-router/border-router.c +++ b/examples/sensinode/border-router/border-router.c @@ -90,7 +90,7 @@ request_prefix(void) CC_NON_BANKED uip_buf[1] = 'P'; uip_len = 2; slip_send(); - uip_len = 0; + uip_clear_buf(); } /*---------------------------------------------------------------------------*/ /* Set our prefix when we receive one over SLIP */ diff --git a/examples/sensinode/border-router/slip-bridge.c b/examples/sensinode/border-router/slip-bridge.c index fc9f95a28..edd048a7d 100644 --- a/examples/sensinode/border-router/slip-bridge.c +++ b/examples/sensinode/border-router/slip-bridge.c @@ -60,7 +60,7 @@ slip_input_callback(void) PRINTF("SIN: %u\n", uip_len); if((char)uip_buf[0] == '!') { PRINTF("Got configuration message of type %c\n", uip_buf[1]); - uip_len = 0; + uip_clear_buf(); if((char)uip_buf[1] == 'P') { uip_ipaddr_t prefix; /* Here we set a prefix !!! */ diff --git a/examples/sky-shell-exec/sky-shell-exec.c b/examples/sky-shell-exec/sky-shell-exec.c index bab3969c0..469d824c4 100644 --- a/examples/sky-shell-exec/sky-shell-exec.c +++ b/examples/sky-shell-exec/sky-shell-exec.c @@ -34,20 +34,6 @@ #include "shell.h" #include "serial-shell.h" -#include "dev/watchdog.h" - -#include "net/rime/rime.h" -#include "cc2420.h" -#include "dev/leds.h" -#include "dev/light.h" -#include "dev/sht11/sht11.h" -#include "dev/battery-sensor.h" - -#include "net/rime/timesynch.h" - -#include -#include - /*---------------------------------------------------------------------------*/ PROCESS(sky_shell_process, "Sky Contiki shell"); AUTOSTART_PROCESSES(&sky_shell_process); diff --git a/examples/wget/Makefile.c128.defines b/examples/wget/Makefile.c128.defines index a4bbe71fb..91a6f26ad 100644 --- a/examples/wget/Makefile.c128.defines +++ b/examples/wget/Makefile.c128.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_ARGS +DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS,WITH_ARGS diff --git a/platform/apple2enh/sys/clock.c b/platform/apple2enh/sys/clock.c index e17cc922f..f8b33e9c1 100644 --- a/platform/apple2enh/sys/clock.c +++ b/platform/apple2enh/sys/clock.c @@ -63,7 +63,7 @@ clock_update(void) static unsigned int count; count += tick; - if(count > 2000) { + if(count > 1000) { count = 0; ++time; } diff --git a/platform/avr-ravenusb/sicslow_ethernet.c b/platform/avr-ravenusb/sicslow_ethernet.c index 46b9244cc..5f70928ba 100644 --- a/platform/avr-ravenusb/sicslow_ethernet.c +++ b/platform/avr-ravenusb/sicslow_ethernet.c @@ -342,7 +342,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* In sniffer or sneezr mode we don't ever send anything */ if ((usbstick_mode.sendToRf == 0) || (usbstick_mode.sneeze != 0)) { - uip_len = 0; + uip_clear_buf(); return; } @@ -354,7 +354,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if !RF230BB usb_eth_stat.txbad++; #endif - uip_len = 0; + uip_clear_buf(); return; } @@ -375,7 +375,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if !RF230BB usb_eth_stat.txbad++; #endif - uip_len = 0; + uip_clear_buf(); return; } else { @@ -409,7 +409,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if UIP_CONF_SIMPLE_JACKDAW_ADDR_TRANS else { //Not addressed to us - uip_len = 0; + uip_clear_buf(); return; } #else @@ -422,7 +422,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if !RF230BB usb_eth_stat.txbad++; #endif - uip_len = 0; + uip_clear_buf(); return; } PRINTF(" translated OK\n\r"); @@ -463,7 +463,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) #if !RF230BB usb_eth_stat.txok++; #endif - uip_len = 0; + uip_clear_buf(); } @@ -543,7 +543,7 @@ void mac_LowpanToEthernet(void) #if !RF230BB usb_eth_stat.rxok++; #endif - uip_len = 0; + uip_clear_buf(); } /** diff --git a/platform/c128/lib/pfs.S b/platform/c128/lib/pfs.S index e82a1cb7c..a2edb1cfd 100644 --- a/platform/c128/lib/pfs.S +++ b/platform/c128/lib/pfs.S @@ -73,8 +73,7 @@ flags: .res 10 .data illchr: .byte $3A, $2A, $3F, $3D ;illegal chars -pw: .byte $2C -filet: .byte $50, $2C, $57 ;,p,w +pw: .byte $2C, $50, $2C, $57 ;,p,w ;--------------------------------------------------------------------- .segment "INIT" @@ -149,7 +148,7 @@ nopath: lda #$3A lsr ptr2 bcs ro ;read only lda __filetype - sta filet ;set filetype + sta pw+1 ;set filetype ldx #252 @L20: lda pw-252,x sta (sp),y ;write diff --git a/platform/c64/lib/pfs.S b/platform/c64/lib/pfs.S index 89eb03ae0..02f9744ec 100644 --- a/platform/c64/lib/pfs.S +++ b/platform/c64/lib/pfs.S @@ -73,8 +73,7 @@ flags: .res 10 .data illchr: .byte $3A, $2A, $3F, $3D ;illegal chars -pw: .byte $2C -filet: .byte $50, $2C, $57 ;,p,w +pw: .byte $2C, $50, $2C, $57 ;,p,w ;--------------------------------------------------------------------- .segment "INIT" @@ -149,7 +148,7 @@ nopath: lda #$3A lsr ptr2 bcs ro ;read only lda __filetype - sta filet ;set filetype + sta pw+1 ;set filetype ldx #252 @L20: lda pw-252,x sta (sp),y ;write diff --git a/platform/cc2530dk/contiki-conf.h b/platform/cc2530dk/contiki-conf.h index ef933dc1c..5d3beb6bb 100644 --- a/platform/cc2530dk/contiki-conf.h +++ b/platform/cc2530dk/contiki-conf.h @@ -226,7 +226,7 @@ #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif diff --git a/platform/cc2538dk/contiki-conf.h b/platform/cc2538dk/contiki-conf.h index 354f042db..7d5924de4 100644 --- a/platform/cc2538dk/contiki-conf.h +++ b/platform/cc2538dk/contiki-conf.h @@ -448,7 +448,7 @@ typedef uint32_t rtimer_clock_t; #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif diff --git a/platform/cooja/dev/rs232.c b/platform/cooja/dev/rs232.c index a52b9a130..51ee5b6a9 100644 --- a/platform/cooja/dev/rs232.c +++ b/platform/cooja/dev/rs232.c @@ -37,7 +37,7 @@ const struct simInterface rs232_interface; -#define SERIAL_BUF_SIZE 1024 +#define SERIAL_BUF_SIZE 2048 // COOJA variables char simSerialReceivingData[SERIAL_BUF_SIZE]; diff --git a/platform/remote/contiki-conf.h b/platform/remote/contiki-conf.h index 959e5fe4b..10e689cdf 100644 --- a/platform/remote/contiki-conf.h +++ b/platform/remote/contiki-conf.h @@ -452,7 +452,7 @@ typedef uint32_t rtimer_clock_t; #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif diff --git a/platform/sensinode/contiki-conf.h b/platform/sensinode/contiki-conf.h index 3866bc3b4..d09fdbcbd 100644 --- a/platform/sensinode/contiki-conf.h +++ b/platform/sensinode/contiki-conf.h @@ -222,7 +222,7 @@ #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif diff --git a/platform/sky/dev/light.c b/platform/sky/dev/light.c deleted file mode 100644 index 53f610fa9..000000000 --- a/platform/sky/dev/light.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include -#include "contiki.h" -#include "dev/light.h" - -/* - * Initialize periodic readings from the 2 photo diodes. The most - * recent readings will be stored in ADC internal registers/memory. - */ -void -sensors_light_init(void) -{ - P6SEL |= 0x30; - P6DIR = 0xff; - P6OUT = 0x00; - - /* Set up the ADC. */ - ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC; // Setup ADC12, ref., sampling time - ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; // Use sampling timer, repeat-sequenc-of-channels - - ADC12MCTL0 = (INCH_4 + SREF_0); // photodiode 1 (P64) - ADC12MCTL1 = (INCH_5 + SREF_0); // photodiode 2 (P65) - - ADC12CTL0 |= ADC12ON + REFON; - - ADC12CTL0 |= ENC; // enable conversion - ADC12CTL0 |= ADC12SC; // sample & convert -} - -/* Photosynthetically Active Radiation. */ -unsigned -sensors_light1(void) -{ - return ADC12MEM0; -} - -/* Total Solar Radiation. */ -unsigned -sensors_light2(void) -{ - return ADC12MEM1; -} - -/* - * Most of this information taken from - * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors - * - * The Photosynthetically Active Radiation (PAR) sensor as well as the - * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage - * to produce the raw ADC value. - - * The voltage across each sensor is: - * - * VsensorPAR = ADCValuePAR/4096 * Vref (1a) - * VsensorTSR = ADCValueTSR/4096 * Vref (1b) - * where Vref = 2.5V - * - * This voltage creates a current through a resistor R=100KOhm and this - * current has a linear relationship with the light intensity in Lux. - * IPAR = VsensorPAR / 100,000 (2a) - * ITSR = VsensorTSR / 100,000 (2b) - * - * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) - * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) - * - * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or - * lxPAR = 3125* ADCvaluePAR / 512 - * and - * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or - * lxTSR = 625* ADCvalueTSR / 1024 -*/ - -#if 0 -/* Photosynthetically Active Radiation in Lux units. */ -unsigned -sensors_light1_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM0; - - temp = (temp*3125)>> 9; - return (uint16_t)(temp & 0xFFFF); -} - -/* Total Solar Radiation in Lux units. */ -unsigned -sensors_light2_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM1; - - temp = (temp*625)>> 10; - return (uint16_t)(temp & 0xFFFF); -} -#endif diff --git a/platform/sky/dev/light.h b/platform/sky/dev/light.h deleted file mode 100644 index 52962b162..000000000 --- a/platform/sky/dev/light.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef LIGHT_H_ -#define LIGHT_H_ - -void sensors_light_init(void); - -unsigned sensors_light1(void); -unsigned sensors_light2(void); - -#endif /* LIGHT_H_ */ diff --git a/platform/srf06-cc26xx/Makefile.srf06-cc26xx b/platform/srf06-cc26xx/Makefile.srf06-cc26xx index 7feefa126..a5f82493c 100644 --- a/platform/srf06-cc26xx/Makefile.srf06-cc26xx +++ b/platform/srf06-cc26xx/Makefile.srf06-cc26xx @@ -6,15 +6,14 @@ endif ### Board and BSP selection ifeq ($(BOARD),) - BOARD=srf06 + BOARD=srf06/cc26xx endif -### Configure the build for the board and pull in board-specific sources -CONTIKI_TARGET_DIRS += . $(BOARD) -PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) +CONTIKI_TARGET_DIRS += . -### Include the board dir if one exists --include $(PLATFORM_ROOT_DIR)/$(BOARD)/Makefile.$(BOARD) +### Include the board-specific makefile +PLATFORM_ROOT_DIR = $(CONTIKI)/platform/$(TARGET) +-include $(PLATFORM_ROOT_DIR)/$(BOARD)/Makefile.$(notdir $(BOARD)) CONTIKI_TARGET_SOURCEFILES += contiki-main.c CONTIKI_TARGET_SOURCEFILES += sensors.c leds.c @@ -29,8 +28,10 @@ ifndef SMALL SMALL = 0 endif -### Define the CPU directory -CONTIKI_CPU=$(CONTIKI)/cpu/cc26xx -include $(CONTIKI_CPU)/Makefile.cc26xx +### Define the CPU directory and pull in the correct CPU makefile. This will +### be defined by one of the makefiles included above and it can be either +### Makefile.cc26xx or Makefile.cc13xx +CONTIKI_CPU=$(CONTIKI)/cpu/cc26xx-cc13xx +include $(CONTIKI_CPU)/Makefile.$(CPU_FAMILY) MODULES += core/net core/net/mac core/net/mac/contikimac core/net/llsec diff --git a/platform/srf06-cc26xx/README.md b/platform/srf06-cc26xx/README.md index 4188c59fb..de86ef380 100644 --- a/platform/srf06-cc26xx/README.md +++ b/platform/srf06-cc26xx/README.md @@ -4,11 +4,11 @@ Getting Started with Contiki for TI CC26xx This guide's aim is to help you start using Contiki for TI's CC26xx. The platform supports two different boards: -* SmartRF 06 Evaluation Board with a CC26xx Evaluation Module (relevant files - and drivers are under `srf06/`) -* CC26xx SensorTag 2.0 (relevant drivers under `sensortag/`) +* SmartRF 06 Evaluation Board with a CC26xx or CC13xx Evaluation Module + (relevant files and drivers are under `srf06/`) +* CC2650 SensorTag 2.0 (relevant drivers under `sensortag/cc2650`) -The CPU code, common for both platforms, can be found under `$(CONTIKI)/cpu/cc26xx`. +The CPU code, common for both platforms, can be found under `$(CONTIKI)/cpu/cc26xx-cc13xx`. The port was developed and tested with CC2650s, but the intention is for it to work with the CC2630 as well. Thus, bug reports are welcome for both chips. Bear in mind that the CC2630 does not have BLE capability. @@ -25,6 +25,7 @@ The platform has the following key features: * Deep Sleep support with RAM retention for ultra-low energy consumption. * Support for CC26xx RF in IEEE as well as BLE mode (BLE support is very basic since Contiki does not provide a BLE stack). +* Support for CC13xx prop mode: IEEE 802.15.4g-compliant sub GHz operation In terms of hardware support, the following drivers have been implemented: @@ -55,12 +56,52 @@ can be used to configure the rest of the example. More details about those two examples can be found in their respective READMEs. +CC13xx/CC26xx Border Router over UART +===================================== +The platform code can be used as a border router (SLIP over UART) by using the +example under `examples/ipv6/rpl-border-router`. This example defines the +following: + + + #ifndef UIP_CONF_BUFFER_SIZE + #define UIP_CONF_BUFFER_SIZE 140 + #endif + + #ifndef UIP_CONF_RECEIVE_WINDOW + #define UIP_CONF_RECEIVE_WINDOW 60 + #endif + +The CC26xx port has much higher capability than some other platforms used as +border routers. Thus, before building the example, it is recommended to delete +these two configuration directives. This will allow platform defaults to take +effect and this will improve performance and stability. + +Do not forget to set the correct channel by defining `RF_CORE_CONF_CHANNEL` as +required. + +CC13xx/CC26xx slip-radio with 6lbr +================================== +The platform can also operate as a slip-radio over UART, to be used with +[6lbr](http://cetic.github.io/6lbr/). + +Similar to the border router configuration, you will need to remove the defines +that limit the size of the uIP buffer. Removing the two lines below from +`examples/ipv6/slip-radio/project-conf.h` should do it. + + #undef UIP_CONF_BUFFER_SIZE + #define UIP_CONF_BUFFER_SIZE 140 + +Do not forget to set the correct channel by defining `RF_CORE_CONF_CHANNEL` as +required. + Requirements ============ To use the port you need: * TI's CC26xxware sources. The correct version will be installed automatically as a submodule when you clone Contiki. +* TI's CC13xxware sources. The correct version will be installed automatically + as a submodule when you clone Contiki. * Software to program the nodes. Use TI's SmartRF Flash Programmer * A toolchain to build firmware: The port has been developed and tested with GNU Tools for ARM Embedded Processors . @@ -85,17 +126,38 @@ From `cpu/cc26xx/lib/cc26xxware/driverlib/timer.c` to `driverlib-timer.c` Sensortag vs Srf06 ================== -To build for the sensortag, set `BOARD=sensortag`. You can do that by exporting -it as an environment variable, by adding it to your Makefile or by adding it to -your make command as an argument +To build for the sensortag, you will need to set the `BOARD` make variable as +follows: -If the `BOARD` variable is not equal to `sensortag`, an image for the Srf06 -CC26XXEM will be built instead. +* Srf06+CC26xxEM: Set `BOARD=srf06/cc26xx` +* Srf06+CC13xxEM: Set `BOARD=srf06/cc13xx` +* CC2650 tag: Set `BOARD=sensortag/cc2650` + +You can do that by exporting `BOARD` as an environment variable, by adding it +to your Makefile or by adding it to your make command as an argument. + +If the `BOARD` variable is unspecified, an image for the Srf06 CC26XXEM will be +built. If you want to switch between building for one platform to the other, make certain to `make clean` before building for the new one, or you will get linker errors. +Sensortag UART usage (with or without the Debugger Devpack) +=========================================================== +There are two ways to get debugging (printf etc) output from the Sensortag. + +* Purchase a Debugger Devpack and set `BOARD_CONF_DEBUGGER_DEVPACK` to 1 in +`contiki-conf.h` or `project-conf.h`. This will work off the shelf for revision +1.2.0 of the debugger devpack. +* If you have an older (rev 1.0.0) devpack, you will need to do the above and +then to modify `board.h` in order to cross the RX and TX DIO mappings. (TX to +`IOID_28`, RX to `IOID_29`). +* If you don't have/want a debugger devpack, you can use a SmartRF and modify +the jumper configuration on P408 as discussed in +[this thread](https://e2e.ti.com/support/wireless_connectivity/f/158/p/411992/1483824#1483824) +on E2E. For this to work, you need to set `BOARD_CONF_DEBUGGER_DEVPACK` to 0. + Low Power Operation =================== The platform takes advantage of the CC26xx's power saving features. In a diff --git a/platform/srf06-cc26xx/contiki-conf.h b/platform/srf06-cc26xx/contiki-conf.h index 359c922df..e9fc7458b 100644 --- a/platform/srf06-cc26xx/contiki-conf.h +++ b/platform/srf06-cc26xx/contiki-conf.h @@ -44,16 +44,6 @@ #include PROJECT_CONF_H #endif /* PROJECT_CONF_H */ /*---------------------------------------------------------------------------*/ -/** - * \name CC26xx flavour selection - * @{ - */ -#ifndef CC26XX_MODEL_CONF_CPU_VARIANT -#define CC26XX_MODEL_CONF_CPU_VARIANT 2650 /**< 2650 => CC2650, 2630 => CC2630 */ - -#endif -/** @} */ -/*---------------------------------------------------------------------------*/ /** * \name Network Stack Configuration * @@ -76,8 +66,7 @@ #endif /* Configure NullRDC for when it's selected */ -#define NULLRDC_802154_AUTOACK 1 -#define NULLRDC_802154_AUTOACK_HW 1 +#define NULLRDC_CONF_802154_AUTOACK 1 /* Configure ContikiMAC for when it's selected */ #define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 @@ -92,7 +81,35 @@ #define NETSTACK_CONF_FRAMER framer_802154 #endif -#define NETSTACK_CONF_RADIO cc26xx_rf_driver +#if CPU_FAMILY_CC13XX +#define NETSTACK_CONF_RADIO prop_mode_driver + +#ifndef RF_CORE_CONF_CHANNEL +#define RF_CORE_CONF_CHANNEL 0 +#endif + +#define NULLRDC_CONF_ACK_WAIT_TIME (RTIMER_SECOND / 400) +#define NULLRDC_CONF_AFTER_ACK_DETECTED_WAIT_TIME (RTIMER_SECOND / 1000) +#define NULLRDC_CONF_802154_AUTOACK_HW 0 +#define NULLRDC_CONF_SEND_802154_ACK 1 + +#define CONTIKIMAC_CONF_CCA_CHECK_TIME (RTIMER_ARCH_SECOND / 1600) +#define CONTIKIMAC_CONF_CCA_SLEEP_TIME (RTIMER_ARCH_SECOND / 210) +#define CONTIKIMAC_CONF_LISTEN_TIME_AFTER_PACKET_DETECTED (RTIMER_ARCH_SECOND / 20) +#define CONTIKIMAC_CONF_SEND_SW_ACK 1 +#define CONTIKIMAC_CONF_AFTER_ACK_DETECTECT_WAIT_TIME (RTIMER_SECOND / 1000) +#define CONTIKIMAC_CONF_INTER_PACKET_INTERVAL (RTIMER_SECOND / 280) +#else +#define NETSTACK_CONF_RADIO ieee_mode_driver + +#ifndef RF_CORE_CONF_CHANNEL +#define RF_CORE_CONF_CHANNEL 25 +#endif + +#define NULLRDC_CONF_802154_AUTOACK_HW 1 +#define NULLRDC_CONF_SEND_802154_ACK 0 +#endif + #define NETSTACK_RADIO_MAX_PAYLOAD_LEN 125 /* 6LoWPAN */ @@ -136,37 +153,20 @@ #define IEEE802154_CONF_PANID 0xABCD /**< Default PAN ID */ #endif -#ifndef CC26XX_RF_CONF_CHANNEL -#define CC26XX_RF_CONF_CHANNEL 25 /**< Default RF channel */ +#ifndef IEEE_MODE_CONF_AUTOACK +#define IEEE_MODE_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ #endif -#ifndef CC26XX_RF_CONF_AUTOACK -#define CC26XX_RF_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ +#ifndef IEEE_MODE_CONF_PROMISCOUS +#define IEEE_MODE_CONF_PROMISCOUS 0 /**< 1 to enable promiscous mode */ #endif -#ifndef CC26XX_RF_CONF_PROMISCOUS -#define CC26XX_RF_CONF_PROMISCOUS 0 /**< 1 to enable promiscous mode */ +#ifndef RF_BLE_CONF_ENABLED +#define RF_BLE_CONF_ENABLED 0 /**< 0 to disable BLE support */ #endif -#ifndef CC26XX_RF_CONF_BLE_SUPPORT -#define CC26XX_RF_CONF_BLE_SUPPORT 0 /**< 0 to disable BLE support */ -#endif - -/* - * Patch Management for the CPE itself and for BLE and IEEE modes - * - * Don't change these unless you know what you're doing - */ -#ifndef CC26XX_CONF_CPE_HAS_PATCHES -#define CC26XX_CONF_CPE_HAS_PATCHES 0 /**< 1 to enable patching the CPE */ -#endif - -#ifndef CC26XX_CONF_BLE_HAS_PATCHES -#define CC26XX_CONF_BLE_HAS_PATCHES 0 /**< 1 to enable patching BLE mode */ -#endif - -#ifndef CC26XX_CONF_IEEE_HAS_PATCHES -#define CC26XX_CONF_IEEE_HAS_PATCHES 0 /**< 1 to enable patching IEEE mode */ +#ifndef PROP_MODE_CONF_SNIFFER +#define PROP_MODE_CONF_SNIFFER 0 /**< 1 to enable sniffer mode */ #endif /** @} */ /*---------------------------------------------------------------------------*/ @@ -201,7 +201,7 @@ #define UIP_CONF_ND6_SEND_RA 0 #define UIP_CONF_IP_FORWARD 0 #define RPL_CONF_STATS 0 -#define RPL_CONF_MAX_DAG_ENTRIES 1 + #ifndef RPL_CONF_OF #define RPL_CONF_OF rpl_mrhof #endif @@ -259,6 +259,11 @@ #define CC26XX_UART_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */ #endif +/* Enable I/O over the Debugger Devpack - Only relevant for the SensorTag */ +#ifndef BOARD_CONF_DEBUGGER_DEVPACK +#define BOARD_CONF_DEBUGGER_DEVPACK 1 +#endif + /* Turn off example-provided putchars */ #define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 #define SLIP_RADIO_CONF_NO_PUTCHAR 1 diff --git a/platform/srf06-cc26xx/contiki-main.c b/platform/srf06-cc26xx/contiki-main.c index 5cc5d83fa..83b67118f 100644 --- a/platform/srf06-cc26xx/contiki-main.c +++ b/platform/srf06-cc26xx/contiki-main.c @@ -32,11 +32,12 @@ * \addtogroup cc26xx-platforms * @{ * - * \defgroup cc26xx-srf-tag SmartRF+CC26xx EM and the CC26xx SensorTag 2.0 + * \defgroup cc26xx-srf-tag SmartRF+CC13xx/CC26xx EM and the CC2650 SensorTag * - * This platform supports two different boards: - * 1) A standard TI SmartRF06EB with a CC26xx EM mounted on it and - * 2) The new TI SensorTag2.0 + * This platform supports a number of different boards: + * - A standard TI SmartRF06EB with a CC26xx EM mounted on it + * - A standard TI SmartRF06EB with a CC1310 EM mounted on it + * - The new TI SensorTag2.0 * @{ */ #include "ti-lib.h" @@ -49,10 +50,9 @@ #include "dev/oscillators.h" #include "ieee-addr.h" #include "vims.h" -#include "cc26xx-model.h" #include "dev/cc26xx-uart.h" -#include "dev/cc26xx-rtc.h" -#include "dev/cc26xx-rf.h" +#include "dev/soc-rtc.h" +#include "rf-core/rf-core.h" #include "sys_ctrl.h" #include "uart.h" #include "sys/clock.h" @@ -66,6 +66,9 @@ #include /*---------------------------------------------------------------------------*/ +/** \brief Board specific iniatialisation */ +void board_init(void); +/*---------------------------------------------------------------------------*/ static void fade(unsigned char l) { @@ -102,7 +105,7 @@ set_rf_params(void) NETSTACK_RADIO.set_value(RADIO_PARAM_PAN_ID, IEEE802154_PANID); NETSTACK_RADIO.set_value(RADIO_PARAM_16BIT_ADDR, short_addr); - NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, CC26XX_RF_CHANNEL); + NETSTACK_RADIO.set_value(RADIO_PARAM_CHANNEL, RF_CORE_CHANNEL); NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8); NETSTACK_RADIO.get_value(RADIO_PARAM_CHANNEL, &val); @@ -123,7 +126,7 @@ set_rf_params(void) /** * \brief Main function for CC26xx-based platforms * - * The same main() is used for both Srf+CC26xxEM as well as for the SensorTag + * The same main() is used for all supported boards */ int main(void) @@ -157,7 +160,7 @@ main(void) ti_lib_int_master_enable(); - cc26xx_rtc_init(); + soc_rtc_init(); clock_init(); rtimer_init(); @@ -176,7 +179,7 @@ main(void) printf("Starting " CONTIKI_VERSION_STRING "\n"); printf("With DriverLib v%u.%u\n", DRIVERLIB_RELEASE_GROUP, DRIVERLIB_RELEASE_BUILD); - printf(BOARD_STRING " using CC%u\n", CC26XX_MODEL_CPU_VARIANT); + printf(BOARD_STRING "\n"); process_start(&etimer_process, NULL); ctimer_init(); diff --git a/platform/srf06-cc26xx/sensortag/Makefile.sensortag b/platform/srf06-cc26xx/sensortag/Makefile.sensortag index 94de7711f..a37f8dd05 100644 --- a/platform/srf06-cc26xx/sensortag/Makefile.sensortag +++ b/platform/srf06-cc26xx/sensortag/Makefile.sensortag @@ -1,7 +1,9 @@ CFLAGS += -DBOARD_SENSORTAG=1 CFLAGS += -DBACKDOOR_IOID=0x00000000 -BOARD_SOURCEFILES += leds-arch.c sensortag-sensors.c sensor-common.c +CONTIKI_TARGET_DIRS += sensortag + +BOARD_SOURCEFILES += sensortag-sensors.c sensor-common.c BOARD_SOURCEFILES += bmp-280-sensor.c tmp-007-sensor.c opt-3001-sensor.c BOARD_SOURCEFILES += hdc-1000-sensor.c mpu-9250-sensor.c button-sensor.c BOARD_SOURCEFILES += reed-relay.c ext-flash.c buzzer.c diff --git a/platform/srf06-cc26xx/sensortag/board-i2c.c b/platform/srf06-cc26xx/sensortag/board-i2c.c index a2b0ba5d2..7783cf2f0 100644 --- a/platform/srf06-cc26xx/sensortag/board-i2c.c +++ b/platform/srf06-cc26xx/sensortag/board-i2c.c @@ -79,9 +79,6 @@ board_i2c_wakeup() ti_lib_prcm_load_set(); while(!ti_lib_prcm_load_get()); - /* Reset the I2C controller */ - ti_lib_hapi_reset_peripheral(PRCM_PERIPH_I2C0); - /* Enable and initialize the I2C master module */ ti_lib_i2c_master_init_exp_clk(I2C0_BASE, ti_lib_sys_ctrl_clock_get(), true); diff --git a/platform/srf06-cc26xx/sensortag/board-spi.c b/platform/srf06-cc26xx/sensortag/board-spi.c index 640f8266c..960db75c8 100644 --- a/platform/srf06-cc26xx/sensortag/board-spi.c +++ b/platform/srf06-cc26xx/sensortag/board-spi.c @@ -43,8 +43,6 @@ #include /*---------------------------------------------------------------------------*/ -#define CPU_FREQ 48000000ul -/*---------------------------------------------------------------------------*/ static bool accessible(void) { @@ -62,11 +60,11 @@ accessible(void) return true; } /*---------------------------------------------------------------------------*/ -int +bool board_spi_write(const uint8_t *buf, size_t len) { if(accessible() == false) { - return 0; + return false; } while(len > 0) { @@ -78,14 +76,14 @@ board_spi_write(const uint8_t *buf, size_t len) buf++; } - return 0; + return true; } /*---------------------------------------------------------------------------*/ -int +bool board_spi_read(uint8_t *buf, size_t len) { if(accessible() == false) { - return 0; + return false; } while(len > 0) { @@ -93,14 +91,14 @@ board_spi_read(uint8_t *buf, size_t len) if(!ti_lib_rom_ssi_data_put_non_blocking(SSI0_BASE, 0)) { /* Error */ - return -1; + return false; } ti_lib_rom_ssi_data_get(SSI0_BASE, &ul); *buf = (uint8_t)ul; len--; buf++; } - return 0; + return true; } /*---------------------------------------------------------------------------*/ void @@ -132,7 +130,8 @@ board_spi_open(uint32_t bit_rate, uint32_t clk_pin) /* SPI configuration */ ti_lib_ssi_int_disable(SSI0_BASE, SSI_RXOR | SSI_RXFF | SSI_RXTO | SSI_TXFF); ti_lib_ssi_int_clear(SSI0_BASE, SSI_RXOR | SSI_RXTO); - ti_lib_rom_ssi_config_set_exp_clk(SSI0_BASE, CPU_FREQ, SSI_FRF_MOTO_MODE_0, + ti_lib_rom_ssi_config_set_exp_clk(SSI0_BASE, ti_lib_sys_ctrl_clock_get(), + SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, bit_rate, 8); ti_lib_rom_ioc_pin_type_ssi_master(SSI0_BASE, BOARD_IOID_SPI_MISO, BOARD_IOID_SPI_MOSI, IOID_UNUSED, clk_pin); diff --git a/platform/srf06-cc26xx/sensortag/board-spi.h b/platform/srf06-cc26xx/sensortag/board-spi.h index 0c1e49d1f..26bdff162 100644 --- a/platform/srf06-cc26xx/sensortag/board-spi.h +++ b/platform/srf06-cc26xx/sensortag/board-spi.h @@ -51,12 +51,21 @@ * \param bit_rate The bit rate to use * \param clk_pin The IOID for the clock pin. This can be IOID_0 etc * \return none + * + * This function will make sure the peripheral is powered, clocked and + * initialised. A chain of calls to board_spi_read(), board_spi_write() and + * board_spi_flush() must be preceded by a call to this function. It is + * recommended to call board_spi_close() after such chain of calls. */ void board_spi_open(uint32_t bit_rate, uint32_t clk_pin); /** * \brief Close the SPI interface * \return True when successful. + * + * This function will stop clocks to the SSI module and will set MISO, MOSI + * and CLK to a low leakage state. It is recommended to call this function + * after a chain of calls to board_spi_read() and board_spi_write() */ void board_spi_close(void); @@ -71,16 +80,22 @@ void board_spi_flush(void); * \param buf The buffer to store data * \param length The number of bytes to read * \return True when successful. + * + * Calls to this function must be preceded by a call to board_spi_open(). It is + * recommended to call board_spi_close() at the end of an operation. */ -int board_spi_read(uint8_t *buf, size_t length); +bool board_spi_read(uint8_t *buf, size_t length); /** * \brief Write to an SPI device * \param buf The buffer with the data to write * \param length The number of bytes to write * \return True when successful. + * + * Calls to this function must be preceded by a call to board_spi_open(). It is + * recommended to call board_spi_close() at the end of an operation. */ -int board_spi_write(const uint8_t *buf, size_t length); +bool board_spi_write(const uint8_t *buf, size_t length); /*---------------------------------------------------------------------------*/ #endif /* BOARD_SPI_H_ */ /*---------------------------------------------------------------------------*/ diff --git a/platform/srf06-cc26xx/sensortag/button-sensor.c b/platform/srf06-cc26xx/sensortag/button-sensor.c index 06a2d2eaa..921d96b20 100644 --- a/platform/srf06-cc26xx/sensortag/button-sensor.c +++ b/platform/srf06-cc26xx/sensortag/button-sensor.c @@ -55,7 +55,7 @@ /*---------------------------------------------------------------------------*/ #define BUTTON_GPIO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \ IOC_IOPULL_UP | IOC_SLEW_DISABLE | \ - IOC_HYST_ENABLE | IOC_BOTH_EDGES | \ + IOC_HYST_DISABLE | IOC_BOTH_EDGES | \ IOC_INT_ENABLE | IOC_IOMODE_NORMAL | \ IOC_NO_WAKE_UP | IOC_INPUT_ENABLE) /*---------------------------------------------------------------------------*/ diff --git a/platform/srf06-cc26xx/sensortag/cc2650/Makefile.cc2650 b/platform/srf06-cc26xx/sensortag/cc2650/Makefile.cc2650 new file mode 100644 index 000000000..5b7cdadd9 --- /dev/null +++ b/platform/srf06-cc26xx/sensortag/cc2650/Makefile.cc2650 @@ -0,0 +1,11 @@ +### Add to the source list +BOARD_SOURCEFILES += leds-arch.c + +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc26xx + +### Add to the source dirs +CONTIKI_TARGET_DIRS += sensortag/cc2650 + +### Include the common sensortag makefile +include $(PLATFORM_ROOT_DIR)/sensortag/Makefile.sensortag diff --git a/platform/srf06-cc26xx/sensortag/board.h b/platform/srf06-cc26xx/sensortag/cc2650/board.h similarity index 97% rename from platform/srf06-cc26xx/sensortag/board.h rename to platform/srf06-cc26xx/sensortag/cc2650/board.h index fc293f5c0..9f0a7abd3 100644 --- a/platform/srf06-cc26xx/sensortag/board.h +++ b/platform/srf06-cc26xx/sensortag/cc2650/board.h @@ -33,13 +33,13 @@ * * \defgroup sensortag-cc26xx-peripherals Sensortag Peripherals * - * Defines related to the Sensortag-CC26XX + * Defines related to the CC2650 Sensortag * * This file provides connectivity information on LEDs, Buttons, UART and * other peripherals * * This file can be used as the basis to configure other boards using the - * CC26XX code as their basis. + * CC13xx/CC26xx code as their basis. * * This file is not meant to be modified by the user. * @{ @@ -103,8 +103,13 @@ #define BOARD_IOID_DP4_UARTRX IOID_28 #define BOARD_IOID_DP5_UARTTX IOID_29 +#if BOARD_CONF_DEBUGGER_DEVPACK #define BOARD_IOID_UART_RX BOARD_IOID_DP4_UARTRX +#define BOARD_IOID_UART_TX BOARD_IOID_DP5_UARTTX +#else +#define BOARD_IOID_UART_RX IOID_17 #define BOARD_IOID_UART_TX IOID_16 +#endif #define BOARD_IOID_UART_CTS IOID_UNUSED #define BOARD_IOID_UART_RTS IOID_UNUSED @@ -231,13 +236,6 @@ */ #define BOARD_STRING "TI CC2650 SensorTag" -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \brief Board specific iniatialisation - * @{ - */ -void board_init(void); /** @} */ /*---------------------------------------------------------------------------*/ #endif /* BOARD_H_ */ diff --git a/platform/srf06-cc26xx/sensortag/leds-arch.c b/platform/srf06-cc26xx/sensortag/cc2650/leds-arch.c similarity index 100% rename from platform/srf06-cc26xx/sensortag/leds-arch.c rename to platform/srf06-cc26xx/sensortag/cc2650/leds-arch.c diff --git a/platform/srf06-cc26xx/sensortag/ext-flash.c b/platform/srf06-cc26xx/sensortag/ext-flash.c index d896473d3..c734e826a 100644 --- a/platform/srf06-cc26xx/sensortag/ext-flash.c +++ b/platform/srf06-cc26xx/sensortag/ext-flash.c @@ -50,8 +50,8 @@ #define BLS_CODE_SECTOR_ERASE 0x20 /**< Sector Erase */ #define BLS_CODE_MDID 0x90 /**< Manufacturer Device ID */ -#define BLS_CODE_DP 0xB9 /**< Power down */ -#define BLS_CODE_RDP 0xAB /**< Power standby */ +#define BLS_CODE_PD 0xB9 /**< Power down */ +#define BLS_CODE_RPD 0xAB /**< Release Power-Down */ /*---------------------------------------------------------------------------*/ /* Erase instructions */ @@ -70,13 +70,18 @@ #define BLS_STATUS_BIT_BUSY 0x01 /**< Busy bit of the status register */ /*---------------------------------------------------------------------------*/ /* Part specific constants */ +#define BLS_DEVICE_ID_W25X20CL 0x11 +#define BLS_DEVICE_ID_W25X40CL 0x12 #define BLS_MANUFACTURER_ID 0xEF -#define BLS_DEVICE_ID 0x12 #define BLS_PROGRAM_PAGE_SIZE 256 #define BLS_ERASE_SECTOR_SIZE 4096 /*---------------------------------------------------------------------------*/ +#define VERIFY_PART_ERROR -1 +#define VERIFY_PART_POWERED_DOWN 0 +#define VERIFY_PART_OK 1 +/*---------------------------------------------------------------------------*/ /** * Clear external flash CSN line */ @@ -97,11 +102,12 @@ deselect(void) /*---------------------------------------------------------------------------*/ /** * \brief Wait till previous erase/program operation completes. - * \return Zero when successful. + * \return True when successful. */ -static int +static bool wait_ready(void) { + bool ret; const uint8_t wbuf[1] = { BLS_CODE_READ_STATUS }; select(); @@ -109,11 +115,11 @@ wait_ready(void) /* Throw away all garbages */ board_spi_flush(); - int ret = board_spi_write(wbuf, sizeof(wbuf)); + ret = board_spi_write(wbuf, sizeof(wbuf)); - if(ret) { + if(ret == false) { deselect(); - return -2; + return false; } for(;;) { @@ -125,10 +131,10 @@ wait_ready(void) */ ret = board_spi_read(&buf, sizeof(buf)); - if(ret) { + if(ret == false) { /* Error */ deselect(); - return -2; + return false; } if(!(buf & BLS_STATUS_BIT_BUSY)) { /* Now ready */ @@ -136,36 +142,44 @@ wait_ready(void) } } deselect(); - return 0; + return true; } /*---------------------------------------------------------------------------*/ /** * \brief Verify the flash part. - * \return True when successful. + * \retval VERIFY_PART_OK The part was identified successfully + * \retval VERIFY_PART_ERROR There was an error communicating with the part + * \retval VERIFY_PART_POWERED_DOWN Communication was successful, but the part + * was powered down */ -static bool +static uint8_t verify_part(void) { const uint8_t wbuf[] = { BLS_CODE_MDID, 0xFF, 0xFF, 0x00 }; - uint8_t rbuf[2]; - int ret; + uint8_t rbuf[2] = {0, 0}; + bool ret; select(); ret = board_spi_write(wbuf, sizeof(wbuf)); - if(ret) { + if(ret == false) { deselect(); - return false; + return VERIFY_PART_ERROR; } ret = board_spi_read(rbuf, sizeof(rbuf)); deselect(); - if(ret || rbuf[0] != BLS_MANUFACTURER_ID || rbuf[1] != BLS_DEVICE_ID) { - return false; + if(ret == false) { + return VERIFY_PART_ERROR; } - return true; + + if(rbuf[0] != BLS_MANUFACTURER_ID || + (rbuf[1] != BLS_DEVICE_ID_W25X20CL && rbuf[1] != BLS_DEVICE_ID_W25X40CL)) { + return VERIFY_PART_POWERED_DOWN; + } + return VERIFY_PART_OK; } /*---------------------------------------------------------------------------*/ /** @@ -178,15 +192,21 @@ power_down(void) uint8_t cmd; uint8_t i; - cmd = BLS_CODE_DP; + /* First, wait for the device to be ready */ + if(wait_ready() == false) { + /* Entering here will leave the device in standby instead of powerdown */ + return; + } + + cmd = BLS_CODE_PD; select(); board_spi_write(&cmd, sizeof(cmd)); deselect(); i = 0; while(i < 10) { - if(!verify_part()) { - /* Verify Part failed: Device is powered down */ + if(verify_part() == VERIFY_PART_POWERED_DOWN) { + /* Device is powered down */ return; } i++; @@ -206,12 +226,12 @@ power_standby(void) uint8_t cmd; bool success; - cmd = BLS_CODE_RDP; + cmd = BLS_CODE_RPD; select(); success = board_spi_write(&cmd, sizeof(cmd)); if(success) { - success = wait_ready() == 0; + success = wait_ready() == true ? true : false; } deselect(); @@ -221,21 +241,22 @@ power_standby(void) /*---------------------------------------------------------------------------*/ /** * \brief Enable write. - * \return Zero when successful. + * \return True when successful. */ -static int +static bool write_enable(void) { + bool ret; const uint8_t wbuf[] = { BLS_CODE_WRITE_ENABLE }; select(); - int ret = board_spi_write(wbuf, sizeof(wbuf)); + ret = board_spi_write(wbuf, sizeof(wbuf)); deselect(); - if(ret) { - return -3; + if(ret == false) { + return false; } - return 0; + return true; } /*---------------------------------------------------------------------------*/ bool @@ -252,7 +273,7 @@ ext_flash_open() /* Put the part is standby mode */ power_standby(); - return verify_part(); + return verify_part() == VERIFY_PART_OK ? true : false; } /*---------------------------------------------------------------------------*/ void @@ -270,8 +291,8 @@ ext_flash_read(size_t offset, size_t length, uint8_t *buf) uint8_t wbuf[4]; /* Wait till previous erase/program operation completes */ - int ret = wait_ready(); - if(ret) { + bool ret = wait_ready(); + if(ret == false) { return false; } @@ -286,7 +307,7 @@ ext_flash_read(size_t offset, size_t length, uint8_t *buf) select(); - if(board_spi_write(wbuf, sizeof(wbuf))) { + if(board_spi_write(wbuf, sizeof(wbuf)) == false) { /* failure */ deselect(); return false; @@ -296,25 +317,25 @@ ext_flash_read(size_t offset, size_t length, uint8_t *buf) deselect(); - return ret == 0; + return ret; } /*---------------------------------------------------------------------------*/ bool ext_flash_write(size_t offset, size_t length, const uint8_t *buf) { uint8_t wbuf[4]; - int ret; + bool ret; size_t ilen; /* interim length per instruction */ while(length > 0) { /* Wait till previous erase/program operation completes */ ret = wait_ready(); - if(ret) { + if(ret == false) { return false; } ret = write_enable(); - if(ret) { + if(ret == false) { return false; } @@ -338,13 +359,13 @@ ext_flash_write(size_t offset, size_t length, const uint8_t *buf) * as much. */ select(); - if(board_spi_write(wbuf, sizeof(wbuf))) { + if(board_spi_write(wbuf, sizeof(wbuf)) == false) { /* failure */ deselect(); return false; } - if(board_spi_write(buf, ilen)) { + if(board_spi_write(buf, ilen) == false) { /* failure */ deselect(); return false; @@ -365,6 +386,7 @@ ext_flash_erase(size_t offset, size_t length) * sector erase is used blindly. */ uint8_t wbuf[4]; + bool ret; size_t i, numsectors; size_t endoffset = offset + length - 1; @@ -375,13 +397,13 @@ ext_flash_erase(size_t offset, size_t length) for(i = 0; i < numsectors; i++) { /* Wait till previous erase/program operation completes */ - int ret = wait_ready(); - if(ret) { + ret = wait_ready(); + if(ret == false) { return false; } ret = write_enable(); - if(ret) { + if(ret == false) { return false; } @@ -391,7 +413,7 @@ ext_flash_erase(size_t offset, size_t length) select(); - if(board_spi_write(wbuf, sizeof(wbuf))) { + if(board_spi_write(wbuf, sizeof(wbuf)) == false) { /* failure */ deselect(); return false; diff --git a/platform/srf06-cc26xx/srf06/Makefile.srf06 b/platform/srf06-cc26xx/srf06/Makefile.srf06 index ee64aa519..d94181927 100644 --- a/platform/srf06-cc26xx/srf06/Makefile.srf06 +++ b/platform/srf06-cc26xx/srf06/Makefile.srf06 @@ -1,3 +1,5 @@ CFLAGS += -DBOARD_SMARTRF06EB=1 +CONTIKI_TARGET_DIRS += srf06 + BOARD_SOURCEFILES += leds-arch.c srf06-sensors.c button-sensor.c board.c diff --git a/platform/srf06-cc26xx/srf06/board-peripherals.h b/platform/srf06-cc26xx/srf06/board-peripherals.h index def762b56..d76936c2d 100644 --- a/platform/srf06-cc26xx/srf06/board-peripherals.h +++ b/platform/srf06-cc26xx/srf06/board-peripherals.h @@ -28,13 +28,18 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ /*---------------------------------------------------------------------------*/ -/** \addtogroup srf06-cc26xx-peripherals +/** \addtogroup cc26xx-srf-tag * @{ * - * \file - * Header file with definitions related to the Srf06EB peripherals + * \defgroup srf06-common-peripherals SmartRF06EB + CC13xx/CC26xx common * - * \note Do not include this file directly. + * Defines related to the SmartRF06 Evaluation Board irrespective of the EM + * mounted on it + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * @{ */ /*---------------------------------------------------------------------------*/ #ifndef BOARD_PERIPHERALS_H_ @@ -45,5 +50,6 @@ #endif /* BOARD_PERIPHERALS_H_ */ /*---------------------------------------------------------------------------*/ /** + * @} * @} */ diff --git a/platform/srf06-cc26xx/srf06/board.c b/platform/srf06-cc26xx/srf06/board.c index 1d98d4e0d..9f53e8ae8 100644 --- a/platform/srf06-cc26xx/srf06/board.c +++ b/platform/srf06-cc26xx/srf06/board.c @@ -29,11 +29,11 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup sensortag-cc26xx-peripherals + * \addtogroup sensortag-common-peripherals * @{ * * \file - * Board-initialisation for the Srf06EB with a CC26xx EM. + * Board-initialisation for the Srf06EB with a CC13xx/CC26xx EM. */ /*---------------------------------------------------------------------------*/ #include "contiki-conf.h" diff --git a/platform/srf06-cc26xx/srf06/button-sensor.c b/platform/srf06-cc26xx/srf06/button-sensor.c index 5cd541e6c..b397e86f5 100644 --- a/platform/srf06-cc26xx/srf06/button-sensor.c +++ b/platform/srf06-cc26xx/srf06/button-sensor.c @@ -29,11 +29,11 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup srf06-cc26xx-peripherals + * \addtogroup srf06-common-peripherals * @{ * * \file - * Driver for the SmartRF06EB buttons when a CC26xxEM is mounted on the board + * Driver for the SmartRF06EB buttons when a CC13xx/CC26xxEM is mounted on it */ /*---------------------------------------------------------------------------*/ #include "contiki.h" @@ -55,7 +55,7 @@ /*---------------------------------------------------------------------------*/ #define BUTTON_GPIO_CFG (IOC_CURRENT_2MA | IOC_STRENGTH_AUTO | \ IOC_IOPULL_UP | IOC_SLEW_DISABLE | \ - IOC_HYST_ENABLE | IOC_BOTH_EDGES | \ + IOC_HYST_DISABLE | IOC_BOTH_EDGES | \ IOC_INT_ENABLE | IOC_IOMODE_NORMAL | \ IOC_NO_WAKE_UP | IOC_INPUT_ENABLE) /*---------------------------------------------------------------------------*/ diff --git a/platform/srf06-cc26xx/srf06/button-sensor.h b/platform/srf06-cc26xx/srf06/button-sensor.h index 2c47f9118..1c810c96d 100644 --- a/platform/srf06-cc26xx/srf06/button-sensor.h +++ b/platform/srf06-cc26xx/srf06/button-sensor.h @@ -29,11 +29,11 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup srf06-cc26xx-peripherals + * \addtogroup srf06-common-peripherals * @{ * * \file - * Header file for the SmartRF06EB + CC26xxEM Button Driver + * Header file for the SmartRF06EB + CC13xx/CC26xxEM Button Driver */ /*---------------------------------------------------------------------------*/ #ifndef BUTTON_SENSOR_H_ diff --git a/platform/srf06-cc26xx/srf06/cc13xx/Makefile.cc13xx b/platform/srf06-cc26xx/srf06/cc13xx/Makefile.cc13xx new file mode 100644 index 000000000..b83084651 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/cc13xx/Makefile.cc13xx @@ -0,0 +1,7 @@ +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc13xx + +### Include the common sensortag makefile +include $(PLATFORM_ROOT_DIR)/srf06/Makefile.srf06 + +CONTIKI_TARGET_DIRS += srf06/cc13xx diff --git a/platform/srf06-cc26xx/srf06/cc13xx/board.h b/platform/srf06-cc26xx/srf06/cc13xx/board.h new file mode 100644 index 000000000..eff486fc5 --- /dev/null +++ b/platform/srf06-cc26xx/srf06/cc13xx/board.h @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ +/*---------------------------------------------------------------------------*/ +/** \addtogroup cc26xx-srf-tag + * @{ + * + * \defgroup srf06-cc13xx-peripherals Peripherals for the SmartRF06EB + CC1310EM + * + * Defines related to the SmartRF06 Evaluation Board with a CC1310EM + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other peripherals + * + * This file can be used as the basis to configure other boards using the + * CC13xx/CC26xx code as their basis. + * + * This file is not meant to be modified by the user. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the TI + * SmartRF06 Evaluation Board with a CC1310EM + * + * \note Do not include this file directly. It gets included by contiki-conf + * after all relevant directives have been set. + */ +/*---------------------------------------------------------------------------*/ +#ifndef BOARD_H_ +#define BOARD_H_ +/*---------------------------------------------------------------------------*/ +#include "ioc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name LED configurations + * + * Those values are not meant to be modified by the user + * @{ + */ +/* Some files include leds.h before us, so we need to get rid of defaults in + * leds.h before we provide correct definitions */ +#undef LEDS_GREEN +#undef LEDS_YELLOW +#undef LEDS_RED +#undef LEDS_CONF_ALL + +#define LEDS_RED 1 /**< LED1 (Red) */ +#define LEDS_YELLOW 2 /**< LED2 (Yellow) */ +#define LEDS_GREEN 4 /**< LED3 (Green) */ +#define LEDS_ORANGE 8 /**< LED4 (Orange) */ + +#define LEDS_CONF_ALL 15 + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LED IOID mappings + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LED_1 IOID_25 +#define BOARD_IOID_LED_2 IOID_27 +#define BOARD_IOID_LED_3 IOID_7 +#define BOARD_IOID_LED_4 IOID_6 +#define BOARD_LED_1 (1 << BOARD_IOID_LED_1) +#define BOARD_LED_2 (1 << BOARD_IOID_LED_2) +#define BOARD_LED_3 (1 << BOARD_IOID_LED_3) +#define BOARD_LED_4 (1 << BOARD_IOID_LED_4) +#define BOARD_LED_ALL (BOARD_LED_1 | BOARD_LED_2 | BOARD_LED_3 | \ + BOARD_LED_4) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name UART IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_UART_RX IOID_2 +#define BOARD_IOID_UART_TX IOID_3 +#define BOARD_IOID_UART_CTS IOID_UNUSED +#define BOARD_IOID_UART_RTS IOID_UNUSED +#define BOARD_UART_RX (1 << BOARD_IOID_UART_RX) +#define BOARD_UART_TX (1 << BOARD_IOID_UART_TX) +#define BOARD_UART_CTS (1 << BOARD_IOID_UART_CTS) +#define BOARD_UART_RTS (1 << BOARD_IOID_UART_RTS) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Button IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_KEY_LEFT IOID_15 +#define BOARD_IOID_KEY_RIGHT IOID_18 +#define BOARD_IOID_KEY_UP IOID_19 +#define BOARD_IOID_KEY_DOWN IOID_12 +#define BOARD_IOID_KEY_SELECT IOID_11 +#define BOARD_KEY_LEFT (1 << BOARD_IOID_KEY_LEFT) +#define BOARD_KEY_RIGHT (1 << BOARD_IOID_KEY_RIGHT) +#define BOARD_KEY_UP (1 << BOARD_IOID_KEY_UP) +#define BOARD_KEY_DOWN (1 << BOARD_IOID_KEY_DOWN) +#define BOARD_KEY_SELECT (1 << BOARD_IOID_KEY_SELECT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name 3.3V domain IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_3V3_EN IOID_13 +#define BOARD_3V3_EN (1 << BOARD_IOID_3V3_EN) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SPI_SCK IOID_10 +#define BOARD_IOID_SPI_MOSI IOID_9 +#define BOARD_IOID_SPI_MISO IOID_8 +#define BOARD_SPI_SCK (1 << BOARD_IOID_SPI_SCK) +#define BOARD_SPI_MOSI (1 << BOARD_IOID_SPI_MOSI) +#define BOARD_SPI_MISO (1 << BOARD_IOID_SPI_MISO) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LCD IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_LCD_MODE IOID_4 +#define BOARD_IOID_LCD_RST IOID_5 +#define BOARD_IOID_LCD_CS IOID_14 +#define BOARD_IOID_LCD_SCK BOARD_IOID_SPI_SCK +#define BOARD_IOID_LCD_MOSI BOARD_IOID_SPI_MOSI +#define BOARD_LCD_MODE (1 << BOARD_IOID_LCD_MODE) +#define BOARD_LCD_RST (1 << BOARD_IOID_LCD_RST) +#define BOARD_LCD_CS (1 << BOARD_IOID_LCD_CS) +#define BOARD_LCD_SCK BOARD_SPI_SCK +#define BOARD_LCD_MOSI BOARD_SPI_MOSI +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SD Card IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_SDCARD_CS IOID_30 +#define BOARD_SDCARD_CS (1 << BOARD_IOID_SDCARD_CS) +#define BOARD_IOID_SDCARD_SCK BOARD_IOID_SPI_SCK +#define BOARD_SDCARD_SCK BOARD_SPI_SCK +#define BOARD_IOID_SDCARD_MOSI BOARD_IOID_SPI_MOSI +#define BOARD_SDCARD_MOSI BOARD_SPI_MOSI +#define BOARD_IOID_SDCARD_MISO BOARD_IOID_SPI_MISO +#define BOARD_SDCARD_MISO BOARD_SPI_MISO +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ALS IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_ALS_PWR IOID_26 +#define BOARD_IOID_ALS_OUT IOID_23 +#define BOARD_ALS_PWR (1 << BOARD_IOID_ALS_PWR) +#define BOARD_ALS_OUT (1 << BOARD_IOID_ALS_OUT) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ACC IOID mapping + * + * Those values are not meant to be modified by the user + * @{ + */ +#define BOARD_IOID_ACC_PWR IOID_20 +#define BOARD_IOID_ACC_INT IOID_28 +#define BOARD_IOID_ACC_INT1 IOID_28 +#define BOARD_IOID_ACC_INT2 IOID_29 +#define BOARD_IOID_ACC_CS IOID_24 +#define BOARD_ACC_PWR (1 << BOARD_IOID_ACC_PWR) +#define BOARD_ACC_INT (1 << BOARD_IOID_ACC_INT) +#define BOARD_ACC_INT1 (1 << BOARD_IOID_ACC_INT1) +#define BOARD_ACC_INT2 (1 << BOARD_IOID_ACC_INT2) +#define BOARD_ACC_CS (1 << BOARD_IOID_ACC_CS) +#define BOARD_IOID_ACC_SCK BOARD_IOID_SPI_SCK +#define BOARD_ACC_SCK BOARD_SPI_SCK +#define BOARD_IOID_ACC_MOSI BOARD_IOID_SPI_MOSI +#define BOARD_ACC_MOSI BOARD_SPI_MOSI +#define BOARD_IOID_ACC_MISO BOARD_IOID_SPI_MISO +#define BOARD_ACC_MISO BOARD_SPI_MISO +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "TI SmartRF06EB + CC13xx EM" +/** @} */ +/*---------------------------------------------------------------------------*/ +#endif /* BOARD_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/srf06-cc26xx/srf06/cc26xx/Makefile.cc26xx b/platform/srf06-cc26xx/srf06/cc26xx/Makefile.cc26xx new file mode 100644 index 000000000..841442a5c --- /dev/null +++ b/platform/srf06-cc26xx/srf06/cc26xx/Makefile.cc26xx @@ -0,0 +1,7 @@ +### Will allow the inclusion of the correct CPU makefile +CPU_FAMILY = cc26xx + +### Include the common makefile +include $(PLATFORM_ROOT_DIR)/srf06/Makefile.srf06 + +CONTIKI_TARGET_DIRS += srf06/cc26xx diff --git a/platform/srf06-cc26xx/srf06/board.h b/platform/srf06-cc26xx/srf06/cc26xx/board.h similarity index 97% rename from platform/srf06-cc26xx/srf06/board.h rename to platform/srf06-cc26xx/srf06/cc26xx/board.h index b222bb17c..3dd064bc3 100644 --- a/platform/srf06-cc26xx/srf06/board.h +++ b/platform/srf06-cc26xx/srf06/cc26xx/board.h @@ -39,7 +39,7 @@ * other peripherals * * This file can be used as the basis to configure other boards using the - * CC26xx code as their basis. + * CC13xx/CC26xx code as their basis. * * This file is not meant to be modified by the user. * @{ @@ -231,14 +231,7 @@ * \name Device string used on startup * @{ */ -#define BOARD_STRING "TI SmartRF06EB+CC26xx EM" -/** @} */ -/*---------------------------------------------------------------------------*/ -/** - * \brief Board specific iniatialisation - * @{ - */ -void board_init(void); +#define BOARD_STRING "TI SmartRF06EB + CC26xx EM" /** @} */ /*---------------------------------------------------------------------------*/ #endif /* BOARD_H_ */ diff --git a/platform/srf06-cc26xx/srf06/leds-arch.c b/platform/srf06-cc26xx/srf06/leds-arch.c index ce1c29c50..423789350 100644 --- a/platform/srf06-cc26xx/srf06/leds-arch.c +++ b/platform/srf06-cc26xx/srf06/leds-arch.c @@ -29,11 +29,11 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup srf06-cc26xx-peripherals + * \addtogroup srf06-common-peripherals * @{ * * \file - * Driver for the SmartRF06EB LEDs when a CC26xx is mounted on the board + * Driver for the SmartRF06EB LEDs when a CC13xx/CC26xx EM is mounted on it */ /*---------------------------------------------------------------------------*/ #include "contiki.h" diff --git a/platform/srf06-cc26xx/srf06/srf06-sensors.c b/platform/srf06-cc26xx/srf06/srf06-sensors.c index c69b4c22f..9f05c1917 100644 --- a/platform/srf06-cc26xx/srf06/srf06-sensors.c +++ b/platform/srf06-cc26xx/srf06/srf06-sensors.c @@ -29,7 +29,7 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup srf06-cc26xx-peripherals + * \addtogroup srf06-common-peripherals * @{ * * \file diff --git a/platform/wismote/Makefile.wismote b/platform/wismote/Makefile.wismote index 1cf0b0d9f..fd8da1d21 100644 --- a/platform/wismote/Makefile.wismote +++ b/platform/wismote/Makefile.wismote @@ -7,7 +7,7 @@ CONTIKI_TARGET_SOURCEFILES += contiki-wismote-platform.c \ sky-sensors.c uip-ipchksum.c \ uart1.c slip_uart1.c uart1-putchar.c -ARCH=spi.c i2c.c node-id.c sensors.c cfs-coffee.c sht15.c \ +ARCH=spi.c xmem.c i2c.c node-id.c sensors.c cfs-coffee.c sht15.c \ cc2520.c cc2520-arch.c cc2520-arch-sfd.c \ sky-sensors.c uip-ipchksum.c \ uart1.c slip_uart1.c uart1-putchar.c diff --git a/platform/wismote/contiki-wismote-main.c b/platform/wismote/contiki-wismote-main.c index 5e74a22ee..8a79811ac 100644 --- a/platform/wismote/contiki-wismote-main.c +++ b/platform/wismote/contiki-wismote-main.c @@ -221,7 +221,7 @@ main(int argc, char **argv) //ds2411_id[2] &= 0xfe; leds_on(LEDS_BLUE); - //xmem_init(); + xmem_init(); leds_off(LEDS_RED); rtimer_init(); @@ -257,6 +257,7 @@ main(int argc, char **argv) init_platform(); set_rime_addr(); + random_init(linkaddr_node_addr.u8[LINKADDR_SIZE-2] + linkaddr_node_addr.u8[LINKADDR_SIZE-1]); cc2520_init(); { diff --git a/platform/wismote/dev/light.c b/platform/wismote/dev/light.c deleted file mode 100644 index be7d7540f..000000000 --- a/platform/wismote/dev/light.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ - -#include "contiki.h" -#include "dev/light.h" -#include - -/* - * Initialize periodic readings from the 2 photo diodes. The most - * recent readings will be stored in ADC internal registers/memory. - */ -void -sensors_light_init(void) -{ - P6SEL |= 0x30; - P6DIR = 0xff; - P6OUT = 0x00; - - /* Set up the ADC. */ - ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC; // Setup ADC12, ref., sampling time - ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; // Use sampling timer, repeat-sequenc-of-channels - - ADC12MCTL0 = (INCH_4 + SREF_0); // photodiode 1 (P64) - ADC12MCTL1 = (INCH_5 + SREF_0); // photodiode 2 (P65) - - ADC12CTL0 |= ADC12ON + REFON; - - ADC12CTL0 |= ENC; // enable conversion - ADC12CTL0 |= ADC12SC; // sample & convert -} - -/* Photosynthetically Active Radiation. */ -unsigned -sensors_light1(void) -{ - return ADC12MEM0; -} - -/* Total Solar Radiation. */ -unsigned -sensors_light2(void) -{ - return ADC12MEM1; -} - -/* - * Most of this information taken from - * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors - * - * The Photosynthetically Active Radiation (PAR) sensor as well as the - * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage - * to produce the raw ADC value. - - * The voltage across each sensor is: - * - * VsensorPAR = ADCValuePAR/4096 * Vref (1a) - * VsensorTSR = ADCValueTSR/4096 * Vref (1b) - * where Vref = 2.5V - * - * This voltage creates a current through a resistor R=100KOhm and this - * current has a linear relationship with the light intensity in Lux. - * IPAR = VsensorPAR / 100,000 (2a) - * ITSR = VsensorTSR / 100,000 (2b) - * - * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) - * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) - * - * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or - * lxPAR = 3125* ADCvaluePAR / 512 - * and - * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or - * lxTSR = 625* ADCvalueTSR / 1024 -*/ - -#if 0 -/* Photosynthetically Active Radiation in Lux units. */ -unsigned -sensors_light1_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM0; - - temp = (temp*3125)>> 9; - return (uint16_t)(temp & 0xFFFF); -} - -/* Total Solar Radiation in Lux units. */ -unsigned -sensors_light2_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM1; - - temp = (temp*625)>> 10; - return (uint16_t)(temp & 0xFFFF); -} -#endif diff --git a/platform/wismote/dev/light.h b/platform/wismote/dev/light.h deleted file mode 100644 index 52962b162..000000000 --- a/platform/wismote/dev/light.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef LIGHT_H_ -#define LIGHT_H_ - -void sensors_light_init(void); - -unsigned sensors_light1(void); -unsigned sensors_light2(void); - -#endif /* LIGHT_H_ */ diff --git a/platform/wismote/dev/xmem.c b/platform/wismote/dev/xmem.c index d4009f7b0..1e7da66af 100644 --- a/platform/wismote/dev/xmem.c +++ b/platform/wismote/dev/xmem.c @@ -32,13 +32,17 @@ * \file * Device driver for the ST M25P80 40MHz 1Mbyte external memory. * \author - * Björn Grönvall + * Björn Grönvall + * Sumankumar Panchal + * * * Data is written bit inverted (~-operator) to flash so that * unwritten data will read as zeros (UNIX style). */ + #include "contiki.h" +#include #include #include "dev/spi.h" @@ -46,7 +50,6 @@ #include "dev/watchdog.h" #if 0 -#include #define PRINTF(...) printf(__VA_ARGS__) #else #define PRINTF(...) do {} while (0) @@ -72,8 +75,7 @@ write_enable(void) s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_WREN); - //SPI_WAITFORTx_ENDED(); + SPI_WRITE(SPI_FLASH_INS_WREN); SPI_FLASH_DISABLE(); splx(s); @@ -89,11 +91,10 @@ read_status_register(void) s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_RDSR); - //SPI_WAITFORTx_ENDED(); + SPI_WRITE(SPI_FLASH_INS_RDSR); - //FASTSPI_CLEAR_RX(); - //FASTSPI_RX(u); + SPI_FLUSH(); + SPI_READ(u); SPI_FLASH_DISABLE(); splx(s); @@ -110,6 +111,7 @@ wait_ready(void) unsigned u; do { u = read_status_register(); + watchdog_periodic(); } while(u & 0x01); /* WIP=1, write in progress */ return u; } @@ -121,18 +123,18 @@ static void erase_sector(unsigned long offset) { int s; - wait_ready(); + wait_ready(); write_enable(); s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_SE); - //FASTSPI_TX(offset >> 16); /* MSB */ - //FASTSPI_TX(offset >> 8); - //FASTSPI_TX(offset >> 0); /* LSB */ - //SPI_WAITFORTx_ENDED(); + SPI_WRITE_FAST(SPI_FLASH_INS_SE); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ + SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); splx(s); @@ -144,12 +146,20 @@ erase_sector(unsigned long offset) void xmem_init(void) { + int s; spi_init(); - P4DIR |= BV(FLASH_CS) | BV(FLASH_HOLD) | BV(FLASH_PWR); - P4OUT |= BV(FLASH_PWR); /* P4.3 Output, turn on power! */ + + P4DIR |= BIT0; + /* Release from Deep Power-down */ + s = splhigh(); + SPI_FLASH_ENABLE(); + SPI_WRITE_FAST(SPI_FLASH_INS_RES); + SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); /* Unselect flash. */ + splx(s); + SPI_FLASH_UNHOLD(); } /*---------------------------------------------------------------------------*/ @@ -159,6 +169,7 @@ xmem_pread(void *_p, int size, unsigned long offset) unsigned char *p = _p; const unsigned char *end = p + size; int s; + wait_ready(); ENERGEST_ON(ENERGEST_TYPE_FLASH_READ); @@ -166,16 +177,16 @@ xmem_pread(void *_p, int size, unsigned long offset) s = splhigh(); SPI_FLASH_ENABLE(); - //FASTSPI_TX(SPI_FLASH_INS_READ); - //FASTSPI_TX(offset >> 16); /* MSB */ - //FASTSPI_TX(offset >> 8); - //FASTSPI_TX(offset >> 0); /* LSB */ - //SPI_WAITFORTx_ENDED(); + SPI_WRITE_FAST(SPI_FLASH_INS_READ); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ + SPI_WAITFORTx_ENDED(); - //FASTSPI_CLEAR_RX(); + SPI_FLUSH(); for(; p < end; p++) { unsigned char u; - //FASTSPI_RX(u); + SPI_READ(u); *p = ~u; } @@ -187,28 +198,27 @@ xmem_pread(void *_p, int size, unsigned long offset) return size; } /*---------------------------------------------------------------------------*/ -static const char * +static const unsigned char * program_page(unsigned long offset, const unsigned char *p, int nbytes) { const unsigned char *end = p + nbytes; int s; wait_ready(); - write_enable(); s = splhigh(); SPI_FLASH_ENABLE(); - // FASTSPI_TX(SPI_FLASH_INS_PP); - //FASTSPI_TX(offset >> 16); /* MSB */ - //FASTSPI_TX(offset >> 8); - //FASTSPI_TX(offset >> 0); /* LSB */ + SPI_WRITE_FAST(SPI_FLASH_INS_PP); + SPI_WRITE_FAST(offset >> 16); /* MSB */ + SPI_WRITE_FAST(offset >> 8); + SPI_WRITE_FAST(offset >> 0); /* LSB */ for(; p < end; p++) { - //FASTSPI_TX(~*p); + SPI_WRITE_FAST(~*p); } - //SPI_WAITFORTx_ENDED(); + SPI_WAITFORTx_ENDED(); SPI_FLASH_DISABLE(); splx(s); @@ -224,7 +234,7 @@ xmem_pwrite(const void *_buf, int size, unsigned long addr) unsigned long i, next_page; ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); - + for(i = addr; i < end;) { next_page = (i | 0xff) + 1; if(next_page > end) { @@ -254,14 +264,10 @@ xmem_erase(long size, unsigned long addr) return -1; } - watchdog_stop(); - for (; addr < end; addr += XMEM_ERASE_UNIT_SIZE) { erase_sector(addr); } - watchdog_start(); - return size; } /*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/platform-conf.h b/platform/wismote/platform-conf.h index 18fe67de5..e13ed62c0 100644 --- a/platform/wismote/platform-conf.h +++ b/platform/wismote/platform-conf.h @@ -124,8 +124,10 @@ typedef unsigned long off_t; /* Enable/disable flash access to the SPI bus (active low). */ -#define SPI_FLASH_ENABLE() //( P4OUT &= ~BV(FLASH_CS) ) -#define SPI_FLASH_DISABLE() //( P4OUT |= BV(FLASH_CS) ) + /* ENABLE CSn (active low) */ +#define SPI_FLASH_ENABLE() do{ UCB0CTL1 &= ~UCSWRST; clock_delay(5); P4OUT &= ~BIT0;clock_delay(5);}while(0) + /* DISABLE CSn (active low) */ +#define SPI_FLASH_DISABLE() do{clock_delay(5);UCB0CTL1 |= UCSWRST;clock_delay(1); P4OUT |= BIT0;clock_delay(5);}while(0) #define SPI_FLASH_HOLD() // ( P4OUT &= ~BV(FLASH_HOLD) ) #define SPI_FLASH_UNHOLD() //( P4OUT |= BV(FLASH_HOLD) ) diff --git a/platform/z1/contiki-z1-main.c b/platform/z1/contiki-z1-main.c index 78e1f4669..bab055d08 100644 --- a/platform/z1/contiki-z1-main.c +++ b/platform/z1/contiki-z1-main.c @@ -268,6 +268,7 @@ main(int argc, char **argv) /* * Initialize Contiki and our processes. */ + random_init(node_mac[6] + node_mac[7]); process_init(); process_start(&etimer_process, NULL); diff --git a/platform/z1/dev/cc2420-arch.c b/platform/z1/dev/cc2420-arch.c index bc345e29f..929a1e0e6 100644 --- a/platform/z1/dev/cc2420-arch.c +++ b/platform/z1/dev/cc2420-arch.c @@ -34,13 +34,17 @@ #include "cc2420.h" #include "isr_compat.h" +#ifdef CC2420_CONF_SFD_TIMESTAMPS +#define CONF_SFD_TIMESTAMPS CC2420_CONF_SFD_TIMESTAMPS +#endif /* CC2420_CONF_SFD_TIMESTAMPS */ + #ifndef CONF_SFD_TIMESTAMPS #define CONF_SFD_TIMESTAMPS 0 #endif /* CONF_SFD_TIMESTAMPS */ #ifdef CONF_SFD_TIMESTAMPS #include "cc2420-arch-sfd.h" -#endif +#endif /* CONF_SFD_TIMESTAMPS */ /*---------------------------------------------------------------------------*/ #if 0 @@ -67,7 +71,7 @@ cc2420_arch_init(void) #if CONF_SFD_TIMESTAMPS cc2420_arch_sfd_init(); -#endif +#endif /* CONF_SFD_TIMESTAMPS */ CC2420_SPI_DISABLE(); /* Unselect radio. */ } diff --git a/platform/z1/dev/light.c b/platform/z1/dev/light.c deleted file mode 100644 index ad1fb88d6..000000000 --- a/platform/z1/dev/light.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2011, Zolertia(TM) is a trademark of Advancare,SL - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - * - * \file - * Dummy light-sensor to allow as many programs for sky to compile for Z1 - * - * \author - * Enric M. Calvo , adapted from previous work - * - */ - -#include -#include "contiki.h" -#include "dev/light.h" - -/* - * Initialize periodic readings from the 2 photo diodes. The most - * recent readings will be stored in ADC internal registers/memory. - */ -void -sensors_light_init(void) -{ -} - -/* Photosynthetically Active Radiation. */ -unsigned -sensors_light1(void) -{ - return 0; -} - -/* Total Solar Radiation. */ -unsigned -sensors_light2(void) -{ - return 0; -} - -/* - * Most of this information taken from - * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors - * - * The Photosynthetically Active Radiation (PAR) sensor as well as the - * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage - * to produce the raw ADC value. - - * The voltage across each sensor is: - * - * VsensorPAR = ADCValuePAR/4096 * Vref (1a) - * VsensorTSR = ADCValueTSR/4096 * Vref (1b) - * where Vref = 2.5V - * - * This voltage creates a current through a resistor R=100KOhm and this - * current has a linear relationship with the light intensity in Lux. - * IPAR = VsensorPAR / 100,000 (2a) - * ITSR = VsensorTSR / 100,000 (2b) - * - * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) - * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) - * - * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or - * lxPAR = 3125* ADCvaluePAR / 512 - * and - * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or - * lxTSR = 625* ADCvalueTSR / 1024 -*/ - -#if 0 -/* Photosynthetically Active Radiation in Lux units. */ -unsigned -sensors_light1_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM0; - - temp = (temp*3125)>> 9; - return (uint16_t)(temp & 0xFFFF); -} - -/* Total Solar Radiation in Lux units. */ -unsigned -sensors_light2_lux(void) -{ - unsigned temp; - temp = (uint32_t)ADC12MEM1; - - temp = (temp*625)>> 10; - return (uint16_t)(temp & 0xFFFF); -} -#endif diff --git a/platform/z1/dev/light.h b/platform/z1/dev/light.h deleted file mode 100644 index 52962b162..000000000 --- a/platform/z1/dev/light.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2005, Swedish Institute of Computer Science - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the Contiki operating system. - * - */ -#ifndef LIGHT_H_ -#define LIGHT_H_ - -void sensors_light_init(void); - -unsigned sensors_light1(void); -unsigned sensors_light2(void); - -#endif /* LIGHT_H_ */ diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index 3dd5058d7..aa8c6d3c5 100644 --- a/regression-tests/18-compile-arm-ports/Makefile +++ b/regression-tests/18-compile-arm-ports/Makefile @@ -8,6 +8,7 @@ webserver-ipv6/ev-aducrf101mkxz \ ipv6/multicast/ev-aducrf101mkxz \ cc2538dk/sniffer/ev-aducrf101mkxz \ cc26xx/cc26xx-web-demo/srf06-cc26xx \ +cc26xx/very-sleepy-demo/srf06-cc26xx \ hello-world/cc2538dk \ ipv6/rpl-border-router/cc2538dk \ er-rest-example/cc2538dk \ diff --git a/regression-tests/21-large-rpl/01-cooja-http-socket-50.csc b/regression-tests/21-large-rpl/01-cooja-http-socket-50.csc new file mode 100644 index 000000000..48b6f9718 --- /dev/null +++ b/regression-tests/21-large-rpl/01-cooja-http-socket-50.csc @@ -0,0 +1,1006 @@ + + + [APPS_DIR]/mrm + [APPS_DIR]/mspsim + [APPS_DIR]/avrora + [APPS_DIR]/serial_socket + [APPS_DIR]/collect-view + [APPS_DIR]/powertracker + + My simulation + 2.0 + generated + 1000000 + + org.contikios.cooja.radiomediums.UDGM + 50.0 + 100.0 + 1.0 + 1.0 + + + 40000 + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype812 + router TARGET=cooja-ip64 + [CONTIKI_DIR]/regression-tests/21-large-rpl/code/router/router.c + echo make clean TARGET=cooja-ip64 +make router.cooja-ip64 TARGET=cooja-ip64 + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + org.contikios.cooja.contikimote.ContikiMoteType + mtype833 + client + [CONTIKI_DIR]/regression-tests/21-large-rpl/code/node/client.c + echo make clean TARGET=cooja +make client.cooja TARGET=cooja + org.contikios.cooja.interfaces.Position + org.contikios.cooja.interfaces.Battery + org.contikios.cooja.contikimote.interfaces.ContikiVib + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + org.contikios.cooja.contikimote.interfaces.ContikiRS232 + org.contikios.cooja.contikimote.interfaces.ContikiBeeper + org.contikios.cooja.interfaces.RimeAddress + org.contikios.cooja.contikimote.interfaces.ContikiIPAddress + org.contikios.cooja.contikimote.interfaces.ContikiRadio + org.contikios.cooja.contikimote.interfaces.ContikiButton + org.contikios.cooja.contikimote.interfaces.ContikiPIR + org.contikios.cooja.contikimote.interfaces.ContikiClock + org.contikios.cooja.contikimote.interfaces.ContikiLED + org.contikios.cooja.contikimote.interfaces.ContikiCFS + org.contikios.cooja.interfaces.Mote2MoteRelations + org.contikios.cooja.interfaces.MoteAttributes + false + + + + org.contikios.cooja.interfaces.Position + 55.719691912311305 + 37.8697579181178 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 1 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype812 + + + + org.contikios.cooja.interfaces.Position + 33.16398380436391 + 28.280100446725353 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 2 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 64.7333702437188 + 86.25343669492709 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 3 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 34.382213480997194 + 87.3651616010611 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 4 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 11.332821198243948 + 72.43057435800137 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 5 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 95.94512295362799 + 71.39152480287795 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 6 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 34.51186307444599 + 59.489544081261435 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 7 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 63.02063881741806 + 6.725737893296902 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 8 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 67.16488021441937 + 54.31377260130722 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 9 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 9.784878122518437 + 81.00283052134533 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 10 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 32.10074353933871 + 33.071992737644926 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 11 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 91.82438265710196 + 51.23700415853406 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 12 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 21.195462105769337 + 82.08222111459202 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 13 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 55.73823429127498 + 69.24022125144269 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 14 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 69.71587306768029 + 57.37071024636343 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 15 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 66.69012609363311 + 68.93236248473207 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 16 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 66.84314708507073 + 32.20129384563065 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 17 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 75.11303983172269 + 17.658699966744983 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 18 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 27.078612584793017 + 97.3945649089831 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 19 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 63.37580990146204 + 30.66028070022273 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 20 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 3.866240569639967 + 58.00787820279949 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 21 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 57.433437740562496 + 12.398752526430156 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 22 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 15.784041174017371 + 74.78102139434115 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 23 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 40.67175327199246 + 52.46247320344863 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 24 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 38.43045934512656 + 90.56311604010655 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 25 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 0.6068936092190724 + 21.344443973676874 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 26 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 60.36615377515271 + 86.59995801287768 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 27 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 14.39476252794466 + 9.985669338749425 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 28 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 95.14872168386105 + 45.936172484167905 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 29 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 61.80198040806143 + 14.891226267286084 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 30 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 32.11354654266005 + 38.51630620185639 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 31 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 37.711371799794335 + 18.547318360664853 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 32 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 58.34301426026205 + 95.91480486240545 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 33 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 20.456374070589078 + 13.31295283913667 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 34 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 4.789895861056081 + 41.25598476863351 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 35 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 22.62971444227585 + 28.645182034255324 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 36 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 60.457329857492034 + 24.40308696160821 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 37 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 4.1096555252476685 + 27.46211937285302 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 38 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 87.008751083046 + 87.28519710099914 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 39 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 86.65741005585366 + 99.07543884063683 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 40 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 96.56473544385348 + 56.74413810869915 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 41 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 63.1598358033005 + 41.18799873508732 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 42 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 14.556676924656397 + 98.24257311359364 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 43 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 34.70728168935242 + 31.89373622088234 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 44 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 91.35334037714965 + 83.59007856757782 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 45 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 57.18004847306107 + 1.5650913544456135 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 46 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 97.14688174768989 + 29.613231105554448 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 47 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 12.528733239940715 + 23.28442121821601 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 48 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 97.65915972314534 + 57.204021167070664 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 49 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 94.8211477197945 + 15.57384229665848 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 50 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.interfaces.Position + 69.1730393490499 + 35.900983349410275 + 0.0 + + + org.contikios.cooja.contikimote.interfaces.ContikiMoteID + 51 + + + org.contikios.cooja.contikimote.interfaces.ContikiRadio + 250.0 + + mtype833 + + + + org.contikios.cooja.plugins.SimControl + 280 + 3 + 160 + 606 + 15 + + + org.contikios.cooja.plugins.Visualizer + + true + org.contikios.cooja.plugins.skins.IDVisualizerSkin + org.contikios.cooja.plugins.skins.GridVisualizerSkin + org.contikios.cooja.plugins.skins.MoteTypeVisualizerSkin + org.contikios.cooja.plugins.skins.LEDVisualizerSkin + org.contikios.cooja.plugins.skins.UDGMVisualizerSkin + 2.927428245448204 0.0 0.0 2.927428245448204 50.166589953058406 9.691034635016393 + + 401 + 0 + 368 + 29 + 27 + + + org.contikios.cooja.plugins.LogListener + + close + + + + 685 + 2 + 429 + 34 + 307 + + + org.contikios.cooja.plugins.ScriptRunner + + [CONTIKI_DIR]/regression-tests/21-large-rpl/testscript.js + true + + 960 + 1 + 682 + 528 + 192 + + + org.contikios.cooja.serialsocket.SerialSocketServer + 0 + + 60001 + true + + 362 + 4 + 116 + 234 + 101 + + + diff --git a/regression-tests/21-large-rpl/Makefile b/regression-tests/21-large-rpl/Makefile new file mode 100644 index 000000000..272bc7da1 --- /dev/null +++ b/regression-tests/21-large-rpl/Makefile @@ -0,0 +1 @@ +include ../Makefile.simulation-test diff --git a/regression-tests/21-large-rpl/code/node/Makefile b/regression-tests/21-large-rpl/code/node/Makefile new file mode 100644 index 000000000..cbaa72ef7 --- /dev/null +++ b/regression-tests/21-large-rpl/code/node/Makefile @@ -0,0 +1,7 @@ +CONTIKI=../../../.. + +MODULES += core/net/http-socket + +CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" + +include $(CONTIKI)/Makefile.include diff --git a/regression-tests/21-large-rpl/code/node/client.c b/regression-tests/21-large-rpl/code/node/client.c new file mode 100644 index 000000000..386f18529 --- /dev/null +++ b/regression-tests/21-large-rpl/code/node/client.c @@ -0,0 +1,103 @@ +#include "contiki-net.h" +#include "http-socket.h" +#include "ip64-addr.h" +#include "dev/leds.h" +#include "rpl.h" + +#include + +static struct http_socket s; +static int bytes_received = 0; +static int restarts; +static struct ctimer reconnect_timer; + +static void callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen); + +/*---------------------------------------------------------------------------*/ +PROCESS(http_example_process, "HTTP Example"); +AUTOSTART_PROCESSES(&http_example_process); +/*---------------------------------------------------------------------------*/ +static void +reconnect(void *dummy) +{ + rpl_set_mode(RPL_MODE_MESH); + http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, + callback, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +restart(void) +{ + int scale; + restarts++; + printf("restart %d\n", restarts); + + scale = restarts; + if(scale > 5) { + scale = 5; + } + ctimer_set(&reconnect_timer, random_rand() % ((CLOCK_SECOND * 10) << scale), + reconnect, NULL); +} +/*---------------------------------------------------------------------------*/ +static void +callback(struct http_socket *s, void *ptr, + http_socket_event_t e, + const uint8_t *data, uint16_t datalen) +{ + if(e == HTTP_SOCKET_ERR) { + printf("HTTP socket error\n"); + } else if(e == HTTP_SOCKET_TIMEDOUT) { + printf("HTTP socket error: timed out\n"); + restart(); + } else if(e == HTTP_SOCKET_ABORTED) { + printf("HTTP socket error: aborted\n"); + restart(); + } else if(e == HTTP_SOCKET_HOSTNAME_NOT_FOUND) { + printf("HTTP socket error: hostname not found\n"); + restart(); + } else if(e == HTTP_SOCKET_CLOSED) { + if(bytes_received > 0) { + printf("HTTP socket closed, %d bytes received\n", bytes_received); + leds_off(LEDS_RED); + rpl_set_mode(RPL_MODE_FEATHER); + } else { + restart(); + } + } else if(e == HTTP_SOCKET_DATA) { + bytes_received += datalen; + printf("HTTP socket received %d bytes of data\n", datalen); + } +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(http_example_process, ev, data) +{ + static struct etimer et; + uip_ip4addr_t ip4addr; + uip_ip6addr_t ip6addr; + + PROCESS_BEGIN(); + + uip_ipaddr(&ip4addr, 8,8,8,8); + ip64_addr_4to6(&ip4addr, &ip6addr); + uip_nameserver_update(&ip6addr, UIP_NAMESERVER_INFINITE_LIFETIME); + + etimer_set(&et, CLOCK_SECOND * 20); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + + http_socket_init(&s); + http_socket_get(&s, "http://www.contiki-os.org/", 0, 0, + callback, NULL); + leds_on(LEDS_RED); + restarts = 0; + etimer_set(&et, CLOCK_SECOND); + while(1) { + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + etimer_reset(&et); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/21-large-rpl/code/node/project-conf.h b/regression-tests/21-large-rpl/code/node/project-conf.h new file mode 100644 index 000000000..c8cfeb645 --- /dev/null +++ b/regression-tests/21-large-rpl/code/node/project-conf.h @@ -0,0 +1,6 @@ +#define QUEUEBUF_CONF_STATS 1 +#define RESOLV_CONF_SUPPORTS_MDNS 0 +#define COOJA_MTARCH_STACKSIZE 4096 + +#define UIP_CONF_MAX_ROUTES 3 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 3 diff --git a/regression-tests/21-large-rpl/code/router/Makefile b/regression-tests/21-large-rpl/code/router/Makefile new file mode 100644 index 000000000..a482f0a6a --- /dev/null +++ b/regression-tests/21-large-rpl/code/router/Makefile @@ -0,0 +1,5 @@ +CONTIKI=../../../.. + +CFLAGS+=-DPROJECT_CONF_H=\"project-conf.h\" + +include $(CONTIKI)/Makefile.include diff --git a/regression-tests/21-large-rpl/code/router/project-conf.h b/regression-tests/21-large-rpl/code/router/project-conf.h new file mode 100644 index 000000000..2fa5e2977 --- /dev/null +++ b/regression-tests/21-large-rpl/code/router/project-conf.h @@ -0,0 +1,9 @@ +#define QUEUEBUF_CONF_STATS 1 +#define RESOLV_CONF_SUPPORTS_MDNS 0 +#define COOJA_MTARCH_STACKSIZE 4096 + +#define UIP_CONF_MAX_ROUTES 8 +#define NBR_TABLE_CONF_MAX_NEIGHBORS 8 + +/*#define RPL_CONF_DEFAULT_LIFETIME_UNIT 10 + #define RPL_CONF_DEFAULT_LIFETIME 10*/ diff --git a/regression-tests/21-large-rpl/code/router/router.c b/regression-tests/21-large-rpl/code/router/router.c new file mode 100644 index 000000000..391b5038b --- /dev/null +++ b/regression-tests/21-large-rpl/code/router/router.c @@ -0,0 +1,27 @@ +#include "contiki.h" +#include "contiki-net.h" +#include "ip64.h" +#include "net/netstack.h" + +/*---------------------------------------------------------------------------*/ +PROCESS(router_node_process, "Router node"); +AUTOSTART_PROCESSES(&router_node_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(router_node_process, ev, data) +{ + PROCESS_BEGIN(); + + /* Set us up as a RPL root node. */ + rpl_dag_root_init_dag(); + + /* Initialize the IP64 module so we'll start translating packets */ + ip64_init(); + + /* ... and do nothing more. */ + while(1) { + PROCESS_WAIT_EVENT(); + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ diff --git a/regression-tests/21-large-rpl/testscript.js b/regression-tests/21-large-rpl/testscript.js new file mode 100644 index 000000000..0c23bceef --- /dev/null +++ b/regression-tests/21-large-rpl/testscript.js @@ -0,0 +1,78 @@ + +TIMEOUT(2400000); /* 40 minutes */ + +var NR_FEATHERS = mote.getSimulation().getMotesCount() - 1; + +/* conf */ +var travis = java.lang.System.getenv().get("TRAVIS"); +if (travis == null) { + /* Instant Contiki */ + CMD_TUNNEL = "echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; + CMD_PING = "ping -c 5 8.8.8.8"; + CMD_DIR = "../../wpcapslip"; +} else { + /* Travis */ + CMD_TUNNEL = "cd $TRAVIS_BUILD_DIR/tools/wpcapslip && sudo apt-get install slirp && echo '-vj' > ~/.slirprc && make Connect.class && java Connect 'nc localhost 60001' 'script -t -f -c slirp'"; + CMD_PING = "ping -c 5 8.8.8.8"; + CMD_DIR = "."; +} + +/* delay */ +GENERATE_MSG(1000, "continue"); +YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); + +/* realtime speed */ +sim.setSpeedLimit(2.0); + +/* tunnel interface */ +log.log("opening tunnel interface: " + CMD_TUNNEL + "\n"); +launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',CMD_TUNNEL]); +launcher.directory(new java.io.File(CMD_DIR)); +launcher.redirectErrorStream(true); +tunProcess = launcher.start(); +tunRunnable = new Object(); +tunRunnable.run = function() { + var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(tunProcess.getInputStream())); + while ((line = stdIn.readLine()) != null) { + if (line != null && !line.trim().equals("")) { + //log.log("TUN> " + line + "\n"); + } + } + tunProcess.destroy(); +} +new java.lang.Thread(new java.lang.Runnable(tunRunnable)).start(); + +GENERATE_MSG(1000, "continue"); +YIELD_THEN_WAIT_UNTIL(msg.equals("continue")); + +/* ping */ +log.log("pinging: " + CMD_PING + "\n"); +launcher = new java.lang.ProcessBuilder["(java.lang.String[])"](['sh','-c',CMD_PING]); +launcher.directory(new java.io.File(CMD_DIR)); +launcher.redirectErrorStream(true); +tunProcess = launcher.start(); +tunRunnable = new Object(); +tunRunnable.run = function() { + var stdIn = new java.io.BufferedReader(new java.io.InputStreamReader(tunProcess.getInputStream())); + while ((line = stdIn.readLine()) != null) { + if (line != null && !line.trim().equals("")) { + log.log("PING> " + line + "\n"); + } + } + tunProcess.destroy(); +} +new java.lang.Thread(new java.lang.Runnable(tunRunnable)).start(); + +var completed = {}; +while(Object.keys(completed).length < NR_FEATHERS) { + if (!msg.startsWith("#L") && !msg.startsWith("E")) { + //log.log(mote + ": " + msg + "\n"); + } + if (id != 1 && msg.startsWith("HTTP socket closed")) { + completed[id] = id; + log.log("Data compelete " + id + ", heard " + Object.keys(completed).length + " in total\n"); + } + YIELD(); +} + +log.testOK(); diff --git a/tools/cc2538-bsl b/tools/cc2538-bsl index d6711e24c..1223bfe03 160000 --- a/tools/cc2538-bsl +++ b/tools/cc2538-bsl @@ -1 +1 @@ -Subproject commit d6711e24ceeb1de09421166a3dc1b97378648af5 +Subproject commit 1223bfe03cdb31c439f1a51593808cdabc1939d2 diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java index 67d268bc2..1d98efb06 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/AreaViewer.java @@ -229,8 +229,8 @@ public class AreaViewer extends VisPlugin { // We want to listen to changes both in the channel model as well as in the radio medium currentChannelModel.addSettingsObserver(channelModelSettingsObserver); - currentRadioMedium.addSettingsObserver(radioMediumSettingsObserver); - currentRadioMedium.addRadioMediumObserver(radioMediumActivityObserver); + currentRadioMedium.addRadioMediumObserver(radioMediumSettingsObserver); + currentRadioMedium.addRadioTransmissionObserver(radioMediumActivityObserver); // Set initial size etc. setSize(500, 500); @@ -2338,13 +2338,13 @@ public class AreaViewer extends VisPlugin { } if (currentRadioMedium != null && radioMediumSettingsObserver != null) { - currentRadioMedium.deleteSettingsObserver(radioMediumSettingsObserver); + currentRadioMedium.deleteRadioMediumObserver(radioMediumSettingsObserver); } else { logger.fatal("Could not remove observer: " + radioMediumSettingsObserver); } if (currentRadioMedium != null && radioMediumActivityObserver != null) { - currentRadioMedium.deleteRadioMediumObserver(radioMediumActivityObserver); + currentRadioMedium.deleteRadioTransmissionObserver(radioMediumActivityObserver); } else { logger.fatal("Could not remove observer: " + radioMediumActivityObserver); } diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java index 579244f75..9d0427c8a 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/ChannelModel.java @@ -53,6 +53,8 @@ import org.contikios.cooja.Simulation; import org.contikios.cooja.interfaces.DirectionalAntennaRadio; import org.contikios.cooja.interfaces.Radio; import org.contikios.cooja.radiomediums.AbstractRadioMedium; +import org.contikios.cooja.util.ScnObservable; + import statistics.GaussianWrapper; /** @@ -103,13 +105,7 @@ public class ChannelModel { /** * Notifies observers when this channel model has changed settings. */ - private class SettingsObservable extends Observable { - private void notifySettingsChanged() { - setChanged(); - notifyObservers(); - } - } - private SettingsObservable settingsObservable = new SettingsObservable(); + private ScnObservable settingsObservable = new ScnObservable(); public enum Parameter { apply_random, snr_threshold, @@ -330,7 +326,7 @@ public class ChannelModel { */ public void removeAllObstacles() { myObstacleWorld.removeAll(); - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } /** @@ -360,7 +356,7 @@ public class ChannelModel { myObstacleWorld.addObstacle(startX, startY, width, height); if (notify) { - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } } @@ -442,7 +438,7 @@ public class ChannelModel { needToPrecalculateFSPL = true; needToPrecalculateOutputPower = true; - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } /** @@ -450,9 +446,9 @@ public class ChannelModel { * will be notified. */ public void notifySettingsChanged() { - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); } - + /** * Path loss component from Friis' transmission equation. * Uses frequency and distance only. @@ -1884,7 +1880,7 @@ public class ChannelModel { } needToPrecalculateFSPL = true; needToPrecalculateOutputPower = true; - settingsObservable.notifySettingsChanged(); + settingsObservable.setChangedAndNotify(); return true; } diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java index a19dcee58..e8af73370 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java @@ -49,6 +49,7 @@ import org.contikios.cooja.interfaces.Position; import org.contikios.cooja.interfaces.Radio; import org.contikios.cooja.plugins.Visualizer; import org.contikios.cooja.radiomediums.AbstractRadioMedium; +import org.contikios.cooja.util.ScnObservable; import org.contikios.mrm.ChannelModel.Parameter; import org.contikios.mrm.ChannelModel.RadioPair; import org.contikios.mrm.ChannelModel.TxPair; @@ -90,11 +91,6 @@ public class MRM extends AbstractRadioMedium { private Random random = null; private ChannelModel currentChannelModel = null; - /** - * Notifies observers when this radio medium has changed settings. - */ - private SettingsObservable settingsObservable = new SettingsObservable(); - /** * Creates a new Multi-path Ray-tracing Medium (MRM). */ @@ -114,6 +110,9 @@ public class MRM extends AbstractRadioMedium { WITH_CAPTURE_EFFECT = currentChannelModel.getParameterBooleanValue(ChannelModel.Parameter.captureEffect); CAPTURE_EFFECT_THRESHOLD = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectSignalTreshold); CAPTURE_EFFECT_PREAMBLE_DURATION = currentChannelModel.getParameterDoubleValue(ChannelModel.Parameter.captureEffectPreambleDuration); + + /* Radio Medium changed here, so notify */ + radioMediumObservable.setChangedAndNotify(); } }); @@ -142,6 +141,9 @@ public class MRM extends AbstractRadioMedium { public void registerRadioInterface(Radio radio, Simulation sim) { super.registerRadioInterface(radio, sim); + /* Radio Medium changed here so notify Observers */ + radioMediumObservable.setChangedAndNotify(); + if (WITH_NOISE && radio instanceof NoiseSourceRadio) { ((NoiseSourceRadio)radio).addNoiseLevelListener(noiseListener); } @@ -149,6 +151,9 @@ public class MRM extends AbstractRadioMedium { public void unregisterRadioInterface(Radio radio, Simulation sim) { super.unregisterRadioInterface(radio, sim); + /* Radio Medium changed here so notify Observers */ + radioMediumObservable.setChangedAndNotify(); + if (WITH_NOISE && radio instanceof NoiseSourceRadio) { ((NoiseSourceRadio)radio).removeNoiseLevelListener(noiseListener); } @@ -402,25 +407,6 @@ public class MRM extends AbstractRadioMedium { // -- MRM specific methods -- - /** - * Adds an observer which is notified when this radio medium has - * changed settings, such as added or removed radios. - * - * @param obs New observer - */ - public void addSettingsObserver(Observer obs) { - settingsObservable.addObserver(obs); - } - - /** - * Deletes an earlier registered setting observer. - * - * @param obs Earlier registered observer - */ - public void deleteSettingsObserver(Observer obs) { - settingsObservable.deleteObserver(obs); - } - /** * @return Number of registered radios. */ @@ -449,13 +435,6 @@ public class MRM extends AbstractRadioMedium { return currentChannelModel; } - class SettingsObservable extends Observable { - private void notifySettingsChanged() { - setChanged(); - notifyObservers(); - } - } - class MRMRadioConnection extends RadioConnection { private Hashtable signalStrengths = new Hashtable(); diff --git a/tools/cooja/java/org/contikios/cooja/Cooja.java b/tools/cooja/java/org/contikios/cooja/Cooja.java index c131e3e22..0040e7a31 100644 --- a/tools/cooja/java/org/contikios/cooja/Cooja.java +++ b/tools/cooja/java/org/contikios/cooja/Cooja.java @@ -139,6 +139,7 @@ import org.contikios.cooja.plugins.ScriptRunner; import org.contikios.cooja.plugins.SimControl; import org.contikios.cooja.plugins.SimInformation; import org.contikios.cooja.util.ExecuteJAR; +import org.contikios.cooja.util.ScnObservable; /** * Main file of COOJA Simulator. Typically contains a visualizer for the @@ -325,21 +326,10 @@ public class Cooja extends Observable { private Vector> positionerClasses = new Vector>(); - private class HighlightObservable extends Observable { - private void setChangedAndNotify(Mote mote) { - setChanged(); - notifyObservers(mote); - } - } - private HighlightObservable moteHighlightObservable = new HighlightObservable(); - private class MoteRelationsObservable extends Observable { - private void setChangedAndNotify() { - setChanged(); - notifyObservers(); - } - } - private MoteRelationsObservable moteRelationObservable = new MoteRelationsObservable(); + private ScnObservable moteHighlightObservable = new ScnObservable(); + + private ScnObservable moteRelationObservable = new ScnObservable(); private JTextPane quickHelpTextPane; private JScrollPane quickHelpScroll; diff --git a/tools/cooja/java/org/contikios/cooja/RadioMedium.java b/tools/cooja/java/org/contikios/cooja/RadioMedium.java index da60dc492..4905a187f 100644 --- a/tools/cooja/java/org/contikios/cooja/RadioMedium.java +++ b/tools/cooja/java/org/contikios/cooja/RadioMedium.java @@ -100,24 +100,24 @@ public abstract class RadioMedium { * Adds an observer which is notified each time a radio connection has finished. * * @see #getLastConnection() - * @see #deleteRadioMediumObserver(Observer) + * @see #deleteRadioTransmissionObserver(Observer) * @param observer New observer */ - public abstract void addRadioMediumObserver(Observer observer); + public abstract void addRadioTransmissionObserver(Observer observer); /** * @return Radio medium observable */ - public abstract Observable getRadioMediumObservable(); + public abstract Observable getRadioTransmissionObservable(); /** * Deletes an radio medium observer. * - * @see #addRadioMediumObserver(Observer) + * @see #addRadioTransmissionObserver(Observer) * @param observer * Observer to delete */ - public abstract void deleteRadioMediumObserver(Observer observer); + public abstract void deleteRadioTransmissionObserver(Observer observer); /** * @return Last radio connection finished in the radio medium diff --git a/tools/cooja/java/org/contikios/cooja/SafeRandom.java b/tools/cooja/java/org/contikios/cooja/SafeRandom.java new file mode 100644 index 000000000..5dee9c1be --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/SafeRandom.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2014, Friedrich-Alexander University Erlangen-Nuremberg. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the university nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +package org.contikios.cooja; + +import java.util.Random; + +/** + * This ensures that the functions of the random number generator are + * only called by the the thread initializing a simulation or the + * simulation thread itself. + * Rationale: By allowing another thread to use the random number + * generator concurrency is intruduced, thus it can not be guaranteed + * that simulations are reproduceable. + * + */ +public class SafeRandom extends Random { + + Simulation sim = null; + Thread initThread = null; + + private void assertSimThread() { + // It we are in the simulation thread everything is fine (the default) + // sim can be null, because setSeed is called by the super-constructor. + if(sim != null && !sim.isSimulationThread()) { + // The thread initializing the simulation might differ from the simulation thread. + // If they are the same that is ok, too. + if(initThread == null) initThread = Thread.currentThread(); + if(Thread.currentThread() == initThread ) return; + throw new RuntimeException("A random-function was not called from the simulation thread. This can break things!"); + } + } + + public SafeRandom(Simulation sim) { + // assertSimThread is called by the super-constructor. + super(); + this.sim = sim; + } + + public SafeRandom(Simulation sim, long seed) { + // assertSimThread is called by the super-constructor. + super(seed); + this.sim = sim; + } + + synchronized public void setSeed(long seed) { + assertSimThread(); + super.setSeed(seed); + } + + /* + * This function is called by all functions returning random numbers + * @see java.util.Random#next(int) + */ + protected int next(int bits) { + assertSimThread(); + return super.next(bits); + } + +} diff --git a/tools/cooja/java/org/contikios/cooja/Simulation.java b/tools/cooja/java/org/contikios/cooja/Simulation.java index 293a4c2c2..18dfa7fe8 100644 --- a/tools/cooja/java/org/contikios/cooja/Simulation.java +++ b/tools/cooja/java/org/contikios/cooja/Simulation.java @@ -93,7 +93,7 @@ public class Simulation extends Observable implements Runnable { private long maxMoteStartupDelay = 1000*MILLISECOND; - private Random randomGenerator = new Random(); + private SafeRandom randomGenerator; private boolean hasMillisecondObservers = false; private MillisecondObservable millisecondObservable = new MillisecondObservable(); @@ -322,6 +322,7 @@ public class Simulation extends Observable implements Runnable { */ public Simulation(Cooja cooja) { this.cooja = cooja; + randomGenerator = new SafeRandom(this); } /** diff --git a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java index 2607bc1ea..e8e7589e5 100644 --- a/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java +++ b/tools/cooja/java/org/contikios/cooja/contikimote/interfaces/ContikiRS232.java @@ -71,7 +71,7 @@ public class ContikiRS232 extends SerialUI implements ContikiMoteInterface, Poll private ContikiMote mote = null; private VarMemory moteMem = null; - static final int SERIAL_BUF_SIZE = 1024; /* rs232.c:40 */ + static final int SERIAL_BUF_SIZE = 2048; /* rs232.c:40 */ /** * Creates an interface to the RS232 at mote. diff --git a/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java b/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java index 9554d7e90..df6f61d1f 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/DGRMConfigurator.java @@ -111,7 +111,7 @@ public class DGRMConfigurator extends VisPlugin { radioMedium = (DirectedGraphMedium) sim.getRadioMedium(); /* Listen for graph updates */ - radioMedium.addRadioMediumObserver(radioMediumObserver = new Observer() { + radioMedium.addRadioTransmissionObserver(radioMediumObserver = new Observer() { public void update(Observable obs, Object obj) { model.fireTableDataChanged(); } @@ -500,7 +500,7 @@ public class DGRMConfigurator extends VisPlugin { }; public void closePlugin() { - radioMedium.deleteRadioMediumObserver(radioMediumObserver); + radioMedium.deleteRadioTransmissionObserver(radioMediumObserver); } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java b/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java index 887503f3d..bcd454076 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/EventListener.java @@ -223,7 +223,7 @@ public class EventListener extends VisPlugin { JCheckBox radioMediumCheckBox = new JCheckBox("Radio medium event", false); radioMediumCheckBox.putClientProperty("observable", mySimulation - .getRadioMedium().getRadioMediumObservable()); + .getRadioMedium().getRadioTransmissionObservable()); radioMediumCheckBox.addActionListener(generalCheckBoxListener); generalPanel.add(radioMediumCheckBox); diff --git a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java index 17f5417c2..84fc41737 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/RadioLogger.java @@ -509,7 +509,7 @@ public class RadioLogger extends VisPlugin { adjuster.setDynamicAdjustment(true); adjuster.packColumns(); - radioMedium.addRadioMediumObserver(radioMediumObserver = new Observer() { + radioMedium.addRadioTransmissionObserver(radioMediumObserver = new Observer() { @Override public void update(Observable obs, Object obj) { RadioConnection conn = radioMedium.getLastConnection(); @@ -784,7 +784,7 @@ public class RadioLogger extends VisPlugin { @Override public void closePlugin() { if (radioMediumObserver != null) { - radioMedium.deleteRadioMediumObserver(radioMediumObserver); + radioMedium.deleteRadioTransmissionObserver(radioMediumObserver); } } diff --git a/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java b/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java index 0cd05c319..c98c51222 100644 --- a/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java +++ b/tools/cooja/java/org/contikios/cooja/plugins/skins/TrafficVisualizerSkin.java @@ -130,7 +130,7 @@ public class TrafficVisualizerSkin implements VisualizerSkin { historyList.clear(); /* Start observing radio medium for transmissions */ - radioMedium.addRadioMediumObserver(radioMediumObserver); + radioMedium.addRadioTransmissionObserver(radioMediumObserver); /* Fade away arrows */ simulation.scheduleEvent(ageArrowsTimeEvent, simulation.getSimulationTime() + 100*Simulation.MILLISECOND); @@ -147,7 +147,7 @@ public class TrafficVisualizerSkin implements VisualizerSkin { } /* Stop observing radio medium */ - radioMedium.deleteRadioMediumObserver(radioMediumObserver); + radioMedium.deleteRadioTransmissionObserver(radioMediumObserver); } @Override diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java index fce97e927..a31b42b3d 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java @@ -49,8 +49,10 @@ import org.contikios.cooja.Simulation; import org.contikios.cooja.TimeEvent; import org.contikios.cooja.interfaces.CustomDataRadio; import org.contikios.cooja.interfaces.Radio; +import org.contikios.cooja.util.ScnObservable; import org.jdom.Element; + /** * Abstract radio medium provides basic functionality for implementing radio * mediums. @@ -90,17 +92,13 @@ public abstract class AbstractRadioMedium extends RadioMedium { public int COUNTER_RX = 0; public int COUNTER_INTERFERED = 0; - public class RadioMediumObservable extends Observable { - public void setRadioMediumChanged() { - setChanged(); - } - public void setRadioMediumChangedAndNotify() { - setChanged(); - notifyObservers(); - } - } - - private RadioMediumObservable radioMediumObservable = new RadioMediumObservable(); + /** + * Two Observables to observe the radioMedium and radioTransmissions + * @see addRadioTransmissionObserver + * @see addRadioMediumObserver + */ + protected ScnObservable radioMediumObservable = new ScnObservable(); + protected ScnObservable radioTransmissionObservable = new ScnObservable(); /** * This constructor should always be called from implemented radio mediums. @@ -288,7 +286,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { /* Notify observers */ lastConnection = null; - radioMediumObservable.setRadioMediumChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } break; case TRANSMISSION_FINISHED: { @@ -333,7 +331,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { updateSignalStrengths(); /* Notify observers */ - radioMediumObservable.setRadioMediumChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } break; case CUSTOM_DATA_TRANSMITTED: { @@ -348,7 +346,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { /* Custom data object */ Object data = ((CustomDataRadio) radio).getLastCustomDataTransmitted(); if (data == null) { - logger.fatal("No custom data object to forward"); + logger.fatal("No custom data objecTransmissiont to forward"); return; } @@ -446,6 +444,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { registeredRadios.add(radio); radio.addObserver(radioEventsObserver); + radioMediumObservable.setChangedAndNotify(); /* Update signal strengths */ updateSignalStrengths(); @@ -462,6 +461,8 @@ public abstract class AbstractRadioMedium extends RadioMedium { removeFromActiveConnections(radio); + radioMediumObservable.setChangedAndNotify(); + /* Update signal strengths */ updateSignalStrengths(); } @@ -528,10 +529,40 @@ public abstract class AbstractRadioMedium extends RadioMedium { sendRssi.put(radio, rssi); } + /** + * Register an observer that gets notified when the radiotransmissions changed. + * E.g. creating new connections. + * This does not include changes in the settings and (de-)registration of radios. + * @see addRadioMediumObserver + * @param observer the Observer to register + */ + public void addRadioTransmissionObserver(Observer observer) { + radioTransmissionObservable.addObserver(observer); + } + + public Observable getRadioTransmissionObservable() { + return radioTransmissionObservable; + } + + public void deleteRadioTransmissionObserver(Observer observer) { + radioTransmissionObservable.deleteObserver(observer); + } + + /** + * Register an observer that gets notified when the radio medium changed. + * This includes changes in the settings and (de-)registration of radios. + * This does not include transmissions, etc as these are part of the radio + * and not the radio medium itself. + * @see addRadioTransmissionObserver + * @param observer the Observer to register + */ public void addRadioMediumObserver(Observer observer) { radioMediumObservable.addObserver(observer); } + /** + * @return the radioMediumObservable + */ public Observable getRadioMediumObservable() { return radioMediumObservable; } diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java index 57876357c..15806c389 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java @@ -93,8 +93,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { edges.add(e); requestEdgeAnalysis(); - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } public void removeEdge(Edge edge) { @@ -105,16 +104,15 @@ public class DirectedGraphMedium extends AbstractRadioMedium { edges.remove(edge); requestEdgeAnalysis(); - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + + radioTransmissionObservable.setChangedAndNotify(); } public void clearEdges() { edges.clear(); requestEdgeAnalysis(); - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + radioTransmissionObservable.setChangedAndNotify(); } public Edge[] getEdges() { @@ -224,6 +222,9 @@ public class DirectedGraphMedium extends AbstractRadioMedium { this.edgesTable = arrTable; edgesDirty = false; + + /* Radio Medium changed here so notify Observers */ + radioMediumObservable.setChangedAndNotify(); } /** diff --git a/tools/cooja/java/org/contikios/cooja/util/ScnObservable.java b/tools/cooja/java/org/contikios/cooja/util/ScnObservable.java new file mode 100644 index 000000000..d922d76a4 --- /dev/null +++ b/tools/cooja/java/org/contikios/cooja/util/ScnObservable.java @@ -0,0 +1,16 @@ +package org.contikios.cooja.util; + +import java.util.Observable; + +public class ScnObservable extends Observable { + public void setChangedAndNotify() { + setChanged(); + notifyObservers(); + } + + public void setChangedAndNotify(Object obj) { + setChanged(); + notifyObservers(obj); + } + +} diff --git a/tools/sky/serialdump-linux b/tools/sky/serialdump-linux index 8bb8192c2..8c7af779d 100755 Binary files a/tools/sky/serialdump-linux and b/tools/sky/serialdump-linux differ diff --git a/tools/sky/serialdump.c b/tools/sky/serialdump.c index e3e47092b..ed324bb5b 100644 --- a/tools/sky/serialdump.c +++ b/tools/sky/serialdump.c @@ -164,13 +164,21 @@ main(int argc, char **argv) } fprintf(stderr, "connecting to %s (%s)", device, speedname); -#ifdef O_SYNC + + +#ifndef O_SYNC +#define O_SYNC 0 +#endif +#ifdef O_DIRECT fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT | O_SYNC); - if(fd < 0 && errno == EINVAL){ // O_SYNC not supported (e.g. raspberian) - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_DIRECT); + /* Some systems do not support certain parameters (e.g. raspbian) + * Just do some random testing. Not sure whether there is a better way + * of doing this. */ + if(fd < 0 && errno == EINVAL){ + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); } #else - fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC ); + fd = open(device, O_RDWR | O_NOCTTY | O_NDELAY | O_SYNC); #endif if(fd < 0) { fprintf(stderr, "\n"); diff --git a/tools/sky/uip6-bridge/dev/slip.c b/tools/sky/uip6-bridge/dev/slip.c index 42d6760b1..4cb65cfd5 100644 --- a/tools/sky/uip6-bridge/dev/slip.c +++ b/tools/sky/uip6-bridge/dev/slip.c @@ -294,7 +294,7 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); } } else { - uip_len = 0; + uip_clear_buf(); SLIP_STATISTICS(slip_ip_drop++); } #else /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/tools/sky/uip6-bridge/sicslow_ethernet.c b/tools/sky/uip6-bridge/sicslow_ethernet.c index a74415020..7de0694c3 100644 --- a/tools/sky/uip6-bridge/sicslow_ethernet.c +++ b/tools/sky/uip6-bridge/sicslow_ethernet.c @@ -238,13 +238,13 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) { PRINTF("eth2low: Packet is not IPv6, dropping\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } // In sniffer mode we don't ever send anything if (usbstick_mode.sendToRf == 0) { - uip_len = 0; + uip_clear_buf(); return; } @@ -263,7 +263,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* IPv6 does not use broadcast addresses, hence this should not happen */ PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } else { PRINTF("eth2low: Addressed packet received... "); @@ -271,7 +271,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) { PRINTF(" translation failed\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } PRINTF(" translated OK\n"); @@ -295,7 +295,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) } } - uip_len = 0; + uip_clear_buf(); } @@ -343,7 +343,7 @@ void mac_LowpanToEthernet(void) /* rndis_send(uip_buf, uip_len, 1); */ /* rndis_stat.rxok++; */ -/* uip_len = 0; */ +/* uip_clear_buf(); */ } /** diff --git a/tools/sky/uip6-bridge/uip6-bridge-tap.c b/tools/sky/uip6-bridge/uip6-bridge-tap.c index f1c5a0256..9aabd752f 100644 --- a/tools/sky/uip6-bridge/uip6-bridge-tap.c +++ b/tools/sky/uip6-bridge/uip6-bridge-tap.c @@ -95,7 +95,7 @@ tcpip_input(void) packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME));*/ slip_write(uip_buf, uip_len); leds_toggle(LEDS_RED); - uip_len = 0; + uip_clear_buf(); } } } diff --git a/tools/stm32w/uip6_bridge/dev/slip.c b/tools/stm32w/uip6_bridge/dev/slip.c index 1380160d1..543896266 100644 --- a/tools/stm32w/uip6_bridge/dev/slip.c +++ b/tools/stm32w/uip6_bridge/dev/slip.c @@ -370,7 +370,7 @@ PROCESS_THREAD(slip_process, ev, data) tcpip_input(); } } else { - uip_len = 0; + uip_clear_buf(); SLIP_STATISTICS(slip_ip_drop++); } #else /* NETSTACK_CONF_WITH_IPV6 */ diff --git a/tools/stm32w/uip6_bridge/sicslow_ethernet.c b/tools/stm32w/uip6_bridge/sicslow_ethernet.c index 440ed9504..24c2b648c 100644 --- a/tools/stm32w/uip6_bridge/sicslow_ethernet.c +++ b/tools/stm32w/uip6_bridge/sicslow_ethernet.c @@ -267,13 +267,13 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (((struct uip_eth_hdr *) ethHeader)->type != UIP_HTONS(UIP_ETHTYPE_IPV6)) { PRINTF("eth2low: Packet is not IPv6, dropping\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } // In sniffer mode we don't ever send anything if (usbstick_mode.sendToRf == 0) { - uip_len = 0; + uip_clear_buf(); return; } @@ -292,7 +292,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* IPv6 does not use broadcast addresses, hence this should not happen */ PRINTF("eth2low: Ethernet broadcast address received, should not happen?\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } else { PRINTF("eth2low: Addressed packet received... "); @@ -300,7 +300,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) if (mac_createSicslowpanLongAddr( &(((struct uip_eth_hdr *) ethHeader)->dest.addr[0]), &destAddr) == 0) { PRINTF(" translation failed\n"); /* rndis_stat.txbad++; */ - uip_len = 0; + uip_clear_buf(); return; } PRINTF(" translated OK\n"); @@ -322,7 +322,7 @@ void mac_ethernetToLowpan(uint8_t * ethHeader) /* rndis_stat.txok++; */ } - uip_len = 0; + uip_clear_buf(); } @@ -370,7 +370,7 @@ void mac_LowpanToEthernet(void) /* rndis_send(uip_buf, uip_len, 1); */ /* rndis_stat.rxok++; */ -/* uip_len = 0; */ +/* uip_clear_buf(); */ } /** diff --git a/tools/stm32w/uip6_bridge/uip6-bridge-tap.c b/tools/stm32w/uip6_bridge/uip6-bridge-tap.c index 6fea42db2..307d8ea4e 100644 --- a/tools/stm32w/uip6_bridge/uip6-bridge-tap.c +++ b/tools/stm32w/uip6_bridge/uip6-bridge-tap.c @@ -98,7 +98,7 @@ tcpip_input(void) packetbuf_attr(PACKETBUF_ATTR_TRANSMIT_TIME), packetbuf_attr(PACKETBUF_ATTR_LISTEN_TIME));*/ slip_write(uip_buf, uip_len); - uip_len = 0; + uip_clear_buf(); leds_off(LEDS_RED); } }