diff --git a/.gitignore b/.gitignore index d8874dffb..ca86d3acd 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ *.c128 *.c64 *.cc2538dk +*.remote *.srf06-cc26xx *.ev-aducrf101mkxz *.report @@ -79,7 +80,7 @@ contiki-cc2530dk.lib *.S *.eth *.dsk -*.2mg +*.po *.atr *.d64 *.d71 diff --git a/.gitmodules b/.gitmodules index 2a2c532e0..bc0f9bbe8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,7 +7,10 @@ [submodule "platform/osd-merkur/dev/LED_Strip_Suli"] path = platform/osd-merkur/dev/LED_Strip_Suli url = https://github.com/osdomotics/LED_Strip_Suli.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 diff --git a/.travis.yml b/.travis.yml index 9fb8295c5..9087bdd8e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,7 @@ 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 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/Makefile.include b/Makefile.include index 9c0838d3c..4545c9c4f 100644 --- a/Makefile.include +++ b/Makefile.include @@ -147,7 +147,6 @@ endif ifdef MODULES UNIQUEMODULES = $(call uniq,$(MODULES)) - MODULESSUBST = ${subst /,-,$(UNIQUEMODULES)} MODULEDIRS = ${wildcard ${addprefix $(CONTIKI)/, $(UNIQUEMODULES)}} MODULES_SOURCES = ${foreach d, $(MODULEDIRS), ${subst ${d}/,,${wildcard $(d)/*.c}}} CONTIKI_SOURCEFILES += $(MODULES_SOURCES) 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/dhcp/dhcp.c b/apps/dhcp/dhcp.c index 2c9d35003..fd2861811 100644 --- a/apps/dhcp/dhcp.c +++ b/apps/dhcp/dhcp.c @@ -97,9 +97,9 @@ makestrings(void) PROCESS_THREAD(dhcp_process, ev, data) { PROCESS_BEGIN(); - + ctk_window_new(&window, 28, 7, "DHCP"); - + CTK_WIDGET_ADD(&window, &getbutton); CTK_WIDGET_ADD(&window, &statuslabel); CTK_WIDGET_ADD(&window, &ipaddrlabel); @@ -110,22 +110,21 @@ PROCESS_THREAD(dhcp_process, ev, data) CTK_WIDGET_ADD(&window, &gatewayentry); CTK_WIDGET_ADD(&window, &dnsserverlabel); CTK_WIDGET_ADD(&window, &dnsserverentry); - + CTK_WIDGET_FOCUS(&window, &getbutton); ctk_window_open(&window); dhcpc_init(uip_lladdr.addr, sizeof(uip_lladdr.addr)); - while(1) { PROCESS_WAIT_EVENT(); - + if(ev == ctk_signal_widget_activate) { if(data == (process_data_t)&getbutton) { dhcpc_request(); set_statustext("Requesting..."); } - } else if(ev == tcpip_event) { + } else if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) { dhcpc_appcall(ev, data); } else if(ev == PROCESS_EVENT_EXIT || ev == ctk_signal_window_close) { 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/shell/shell-file.c b/apps/shell/shell-file.c index 07f6f3d5d..4376c68a3 100644 --- a/apps/shell/shell-file.c +++ b/apps/shell/shell-file.c @@ -51,7 +51,7 @@ PROCESS(shell_ls_process, "ls"); SHELL_COMMAND(ls_command, "ls", - "ls: list files", + "ls : list files", &shell_ls_process); PROCESS(shell_append_process, "append"); SHELL_COMMAND(append_command, @@ -82,19 +82,21 @@ PROCESS_THREAD(shell_ls_process, ev, data) char buf[32]; PROCESS_BEGIN(); - if(cfs_opendir(&dir, "/") != 0) { - shell_output_str(&ls_command, "Cannot open directory", ""); - } else { - totsize = 0; - while(cfs_readdir(&dir, &dirent) == 0) { - totsize += dirent.size; - sprintf(buf, "%lu ", (unsigned long)dirent.size); - /* printf("'%s'\n", dirent.name);*/ - shell_output_str(&ls_command, buf, dirent.name); + if(data != NULL) { + if(cfs_opendir(&dir, data) != 0) { + shell_output_str(&ls_command, "Cannot open directory", ""); + } else { + totsize = 0; + while(cfs_readdir(&dir, &dirent) == 0) { + totsize += dirent.size; + sprintf(buf, "%lu ", (unsigned long)dirent.size); + /* printf("'%s'\n", dirent.name);*/ + shell_output_str(&ls_command, buf, dirent.name); + } + cfs_closedir(&dir); + sprintf(buf, "%lu", (unsigned long)totsize); + shell_output_str(&ls_command, "Total size: ", buf); } - cfs_closedir(&dir); - sprintf(buf, "%lu", (unsigned long)totsize); - shell_output_str(&ls_command, "Total size: ", buf); } PROCESS_END(); } diff --git a/apps/telnetd/telnetd.c b/apps/telnetd/telnetd.c index c168b19b8..7b211f121 100644 --- a/apps/telnetd/telnetd.c +++ b/apps/telnetd/telnetd.c @@ -62,6 +62,10 @@ static char telnetd_reject_text[] = "Too many connections, please try again later."; #endif +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME (CLOCK_SECOND * 30) +#endif + struct telnetd_state { char buf[TELNETD_CONF_LINELEN + 1]; char bufptr; @@ -74,7 +78,9 @@ struct telnetd_state { #define STATE_DO 4 #define STATE_DONT 5 #define STATE_CLOSE 6 +#if TELNETD_CONF_MAX_IDLE_TIME struct timer silence_timer; +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ }; static struct telnetd_state s; @@ -102,8 +108,6 @@ static struct telnetd_buf buf; static uint8_t connected; -#define MAX_SILENCE_TIME (CLOCK_SECOND * 30) - /*---------------------------------------------------------------------------*/ static void buf_init(struct telnetd_buf *buf) @@ -169,6 +173,8 @@ shell_prompt(char *str) void shell_default_output(const char *str1, int len1, const char *str2, int len2) { + static const char crnl[2] = {ISO_cr, ISO_nl}; + if(len1 > 0 && str1[len1 - 1] == '\n') { --len1; } @@ -183,7 +189,7 @@ shell_default_output(const char *str1, int len1, const char *str2, int len2) #endif /* TELNETD_CONF_GUI */ buf_append(&buf, str1, len1); buf_append(&buf, str2, len2); - buf_append(&buf, "\r\n", 2); + buf_append(&buf, crnl, sizeof(crnl)); } /*---------------------------------------------------------------------------*/ void @@ -359,7 +365,9 @@ telnetd_appcall(void *ts) s.state = STATE_NORMAL; connected = 1; shell_start(); - timer_set(&s.silence_timer, MAX_SILENCE_TIME); +#if TELNETD_CONF_MAX_IDLE_TIME + timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME); +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ ts = (char *)0; } else { uip_send(telnetd_reject_text, strlen(telnetd_reject_text)); @@ -381,11 +389,15 @@ telnetd_appcall(void *ts) connected = 0; } if(uip_acked()) { - timer_set(&s.silence_timer, MAX_SILENCE_TIME); +#if TELNETD_CONF_MAX_IDLE_TIME + timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME); +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ acked(); } if(uip_newdata()) { - timer_set(&s.silence_timer, MAX_SILENCE_TIME); +#if TELNETD_CONF_MAX_IDLE_TIME + timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME); +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ newdata(); } if(uip_rexmit() || @@ -394,16 +406,20 @@ telnetd_appcall(void *ts) uip_connected() || uip_poll()) { senddata(); +#if TELNETD_CONF_MAX_IDLE_TIME if(s.numsent > 0) { - timer_set(&s.silence_timer, MAX_SILENCE_TIME); + timer_set(&s.silence_timer, TELNETD_CONF_MAX_IDLE_TIME); } +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ } +#if TELNETD_CONF_MAX_IDLE_TIME if(uip_poll()) { if(timer_expired(&s.silence_timer)) { uip_close(); tcp_markconn(uip_conn, NULL); } } +#endif /* TELNETD_CONF_MAX_IDLE_TIME */ } } /*---------------------------------------------------------------------------*/ diff --git a/apps/webbrowser/html-strings b/apps/webbrowser/html-strings index e56d8f600..e319dc651 100644 --- a/apps/webbrowser/html-strings +++ b/apps/webbrowser/html-strings @@ -9,7 +9,6 @@ html_a "a\0" html_body "body\0" html_br "br\0" html_form "form\0" -html_frame "frame\0" html_h1 "h1\0" html_h2 "h2\0" html_h3 "h3\0" diff --git a/apps/webbrowser/html-strings.c b/apps/webbrowser/html-strings.c index 51fc3f1cd..5743f1a03 100644 --- a/apps/webbrowser/html-strings.c +++ b/apps/webbrowser/html-strings.c @@ -31,9 +31,6 @@ const char html_br[4] = const char html_form[6] = /* "form\0" */ {0x66, 0x6f, 0x72, 0x6d, 00, }; -const char html_frame[7] = -/* "frame\0" */ -{0x66, 0x72, 0x61, 0x6d, 0x65, 00, }; const char html_h1[4] = /* "h1\0" */ {0x68, 0x31, 00, }; diff --git a/apps/webbrowser/html-strings.h b/apps/webbrowser/html-strings.h index cf09c0107..5bcf03978 100644 --- a/apps/webbrowser/html-strings.h +++ b/apps/webbrowser/html-strings.h @@ -9,7 +9,6 @@ extern const char html_a[3]; extern const char html_body[6]; extern const char html_br[4]; extern const char html_form[6]; -extern const char html_frame[7]; extern const char html_h1[4]; extern const char html_h2[4]; extern const char html_h3[4]; diff --git a/apps/webbrowser/htmlparser.c b/apps/webbrowser/htmlparser.c index 725aae433..5e606d08e 100644 --- a/apps/webbrowser/htmlparser.c +++ b/apps/webbrowser/htmlparser.c @@ -119,9 +119,6 @@ G * (
,

, ), the

  • tag (but does not even try to #define ISO_eq 0x3d #define ISO_gt 0x3e -#define ISO_rbrack 0x5b -#define ISO_lbrack 0x5d - #define MINORSTATE_NONE 0 #define MINORSTATE_TEXT 1 /* Parse normal text */ #define MINORSTATE_EXTCHAR 2 /* Check for semi-colon */ @@ -140,7 +137,7 @@ G * (
    ,

    , ), the

  • tag (but does not even try to #define MAJORSTATE_LINK 2 #define MAJORSTATE_FORM 3 #define MAJORSTATE_DISCARD 4 - +#define MAJORSTATE_SCRIPT 5 struct htmlparser_state { @@ -151,7 +148,7 @@ struct htmlparser_state { unsigned char tagattrptr; char tagattrparam[WWW_CONF_MAX_URLLEN + 1]; unsigned char tagattrparamptr; - unsigned char lastchar, quotechar; + unsigned char quotechar; unsigned char majorstate, lastmajorstate; char linkurl[WWW_CONF_MAX_URLLEN + 1]; @@ -196,33 +193,31 @@ static const char *tags[] = { html_br, #define TAG_FORM 10 html_form, -#define TAG_FRAME 11 - html_frame, -#define TAG_H1 12 +#define TAG_H1 11 html_h1, -#define TAG_H2 13 +#define TAG_H2 12 html_h2, -#define TAG_H3 14 +#define TAG_H3 13 html_h3, -#define TAG_H4 15 +#define TAG_H4 14 html_h4, -#define TAG_IMG 16 +#define TAG_IMG 15 html_img, -#define TAG_INPUT 17 +#define TAG_INPUT 16 html_input, -#define TAG_LI 18 +#define TAG_LI 17 html_li, -#define TAG_P 19 +#define TAG_P 18 html_p, -#define TAG_SCRIPT 20 +#define TAG_SCRIPT 19 html_script, -#define TAG_SELECT 21 +#define TAG_SELECT 20 html_select, -#define TAG_STYLE 22 +#define TAG_STYLE 21 html_style, -#define TAG_TR 23 +#define TAG_TR 22 html_tr, -#define TAG_LAST 24 +#define TAG_LAST 23 last, }; @@ -254,7 +249,7 @@ htmlparser_init(void) { s.majorstate = s.lastmajorstate = MAJORSTATE_DISCARD; s.minorstate = MINORSTATE_TEXT; - s.lastchar = 0; + s.wordlen = 0; #if WWW_CONF_FORMS s.formaction[0] = 0; #endif /* WWW_CONF_FORMS */ @@ -305,10 +300,10 @@ do_word(void) { if(s.wordlen > 0) { if(s.majorstate == MAJORSTATE_LINK) { - if(s.word[s.wordlen] != ISO_space) { + if(s.word[s.wordlen - 1] != ISO_space) { add_char(ISO_space); } - } else if(s.majorstate == MAJORSTATE_DISCARD) { + } else if(s.majorstate >= MAJORSTATE_DISCARD) { s.wordlen = 0; } else { s.word[s.wordlen] = '\0'; @@ -368,13 +363,19 @@ static void parse_tag(void) { static char *tagattrparam; + static unsigned char tag; static unsigned char size; - static char dummy; - + tag = find_tag(s.tag); + /* If we are inside a . */ + if(s.majorstate == MAJORSTATE_SCRIPT && tag != TAG_SLASHSCRIPT) { + return; + } + PRINTF(("Parsing tag '%s' '%s' '%s'\n", s.tag, s.tagattr, s.tagattrparam)); - switch(find_tag(s.tag)) { + switch(tag) { case TAG_P: case TAG_H1: case TAG_H2: @@ -386,15 +387,18 @@ parse_tag(void) case TAG_TR: case TAG_SLASHDIV: case TAG_SLASHH: - dummy = 0; newline(); break; case TAG_LI: - newline(); - add_char(ISO_asterisk); - add_char(ISO_space); + if(s.tagattr[0] == 0) { + newline(); + add_char(ISO_asterisk); + add_char(ISO_space); + } break; case TAG_SCRIPT: + switch_majorstate(MAJORSTATE_SCRIPT); + break; case TAG_STYLE: case TAG_SELECT: switch_majorstate(MAJORSTATE_DISCARD); @@ -408,18 +412,6 @@ parse_tag(void) case TAG_BODY: s.majorstate = s.lastmajorstate = MAJORSTATE_BODY; break; - case TAG_FRAME: - if(strncmp(s.tagattr, html_src, sizeof(html_src)) == 0 && s.tagattrparam[0] != 0) { - switch_majorstate(MAJORSTATE_BODY); - newline(); - add_char(ISO_rbrack); - do_word(); - htmlparser_link((char *)html_frame, (unsigned char)strlen(html_frame), s.tagattrparam); - PRINTF(("Frame [%s]\n", s.tagattrparam)); - add_char(ISO_lbrack); - newline(); - } - break; case TAG_IMG: if(strncmp(s.tagattr, html_alt, sizeof(html_alt)) == 0 && s.tagattrparam[0] != 0) { add_char(ISO_lt); @@ -572,6 +564,15 @@ parse_word(char *data, uint8_t dlen) } break; case MINORSTATE_TAG: + /* If we are inside a we mustn't mistake a JavaScript + equation with a '<' as a tag. So we check for the very next + character to be a '/' as we're only interested in parsing + the . */ + if(s.majorstate == MAJORSTATE_SCRIPT && data[0] != ISO_slash) { + s.minorstate = MINORSTATE_TEXT; + break; + } + /* We are currently parsing within the name of a tag. We check for the end of a tag (the '>' character) or whitespace (which indicates that we should parse a tag attr argument diff --git a/apps/webbrowser/http-strings b/apps/webbrowser/http-strings index 24ddb4f90..ff6a87545 100644 --- a/apps/webbrowser/http-strings +++ b/apps/webbrowser/http-strings @@ -1,4 +1,5 @@ http_http "http://" +http_https "https://" http_200 "200 " http_301 "301 " http_302 "302 " @@ -10,3 +11,4 @@ http_location "location: " http_host "Host: " http_crnl "\r\n" http_html ".html" +http_redirect "Redirect to " diff --git a/apps/webbrowser/http-strings.c b/apps/webbrowser/http-strings.c index aa4d45ece..72ce2c644 100644 --- a/apps/webbrowser/http-strings.c +++ b/apps/webbrowser/http-strings.c @@ -1,6 +1,9 @@ const char http_http[8] = /* "http://" */ {0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, }; +const char http_https[9] = +/* "https://" */ +{0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, }; const char http_200[5] = /* "200 " */ {0x32, 0x30, 0x30, 0x20, }; @@ -34,3 +37,6 @@ const char http_crnl[3] = const char http_html[6] = /* ".html" */ {0x2e, 0x68, 0x74, 0x6d, 0x6c, }; +const char http_redirect[19] = +/* "Redirect to " */ +{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, }; diff --git a/apps/webbrowser/http-strings.h b/apps/webbrowser/http-strings.h index 8b9bee66e..184dcf330 100644 --- a/apps/webbrowser/http-strings.h +++ b/apps/webbrowser/http-strings.h @@ -1,4 +1,5 @@ extern const char http_http[8]; +extern const char http_https[9]; extern const char http_200[5]; extern const char http_301[5]; extern const char http_302[5]; @@ -10,3 +11,4 @@ extern const char http_location[11]; extern const char http_host[7]; extern const char http_crnl[3]; extern const char http_html[6]; +extern const char http_redirect[19]; diff --git a/apps/webbrowser/webclient.c b/apps/webbrowser/webclient.c index 08c6ed211..5d2ce0254 100644 --- a/apps/webbrowser/webclient.c +++ b/apps/webbrowser/webclient.c @@ -49,7 +49,7 @@ #define HTTPFLAG_NONE 0 #define HTTPFLAG_OK 1 #define HTTPFLAG_MOVED 2 -#define HTTPFLAG_ERROR 3 +#define HTTPFLAG_HTTPS 3 #define ISO_nl 0x0a @@ -63,11 +63,11 @@ struct webclient_state { uint16_t port; char host[40]; - char file[WWW_CONF_MAX_URLLEN]; + char file[WWW_CONF_MAX_URLLEN - 10]; // URL - "http:///" uint16_t getrequestptr; uint16_t getrequestleft; - char httpheaderline[200]; + char httpheaderline[WWW_CONF_MAX_URLLEN + 10]; // URL + "Location: " uint16_t httpheaderlineptr; char mimetype[32]; @@ -327,13 +327,12 @@ parse_headers(uint16_t len) char *cptr; static unsigned char i; - while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) { + while(len > 0) { s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata; uip_appdata = (char *)uip_appdata + 1; --len; if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) { - /* We have an entire HTTP header line in s.httpheaderline, so - we parse it. */ + /* We reached the end of an HTTP header line. */ if(s.httpheaderline[0] == ISO_cr) { /* This was the last header line (i.e., and empty "\r\n"), so we are done with the headers and proceed with the actual @@ -342,46 +341,53 @@ parse_headers(uint16_t len) return len; } - s.httpheaderline[s.httpheaderlineptr - 1] = 0; - /* Check for specific HTTP header fields. */ - if(casecmp(s.httpheaderline, http_content_type, - sizeof(http_content_type) - 1) == 0) { - /* Found Content-type field. */ - cptr = strchr(s.httpheaderline, ';'); - if(cptr != NULL) { - *cptr = 0; - } - strncpy(s.mimetype, s.httpheaderline + - sizeof(http_content_type) - 1, sizeof(s.mimetype)); - } else if(casecmp(s.httpheaderline, http_location, - sizeof(http_location) - 1) == 0) { - cptr = s.httpheaderline + - sizeof(http_location) - 1; - - if(strncmp(cptr, http_http, 7) == 0) { - cptr += 7; - for(i = 0; i < s.httpheaderlineptr - 7; ++i) { - if(*cptr == 0 || - *cptr == '/' || - *cptr == ' ' || - *cptr == ':') { - s.host[i] = 0; - break; - } - s.host[i] = *cptr; - ++cptr; + if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) { + /* We have an entire HTTP header line in s.httpheaderline, so + we parse it. */ + s.httpheaderline[s.httpheaderlineptr - 1] = 0; + /* Check for specific HTTP header fields. */ + if(casecmp(s.httpheaderline, http_content_type, + sizeof(http_content_type) - 1) == 0) { + /* Found Content-type field. */ + cptr = strchr(s.httpheaderline, ';'); + if(cptr != NULL) { + *cptr = 0; } - } - strncpy(s.file, cptr, sizeof(s.file)); - /* s.file[s.httpheaderlineptr - i] = 0;*/ - } + strncpy(s.mimetype, s.httpheaderline + + sizeof(http_content_type) - 1, sizeof(s.mimetype)); + } else if(casecmp(s.httpheaderline, http_location, + sizeof(http_location) - 1) == 0) { + cptr = s.httpheaderline + + sizeof(http_location) - 1; + if(strncmp(cptr, http_https, sizeof(http_https) - 1) == 0) { + s.httpflag = HTTPFLAG_HTTPS; + } else if(strncmp(cptr, http_http, 7) == 0) { + cptr += 7; + for(i = 0; i < s.httpheaderlineptr - 7; ++i) { + if(*cptr == 0 || + *cptr == '/' || + *cptr == ' ' || + *cptr == ':') { + s.host[i] = 0; + break; + } + s.host[i] = *cptr; + ++cptr; + } + } + strncpy(s.file, cptr, sizeof(s.file)); + /* s.file[s.httpheaderlineptr - i] = 0;*/ + } + } /* We're done parsing, so we reset the pointer and start the next line. */ s.httpheaderlineptr = 0; } else { - ++s.httpheaderlineptr; + if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) { + ++s.httpheaderlineptr; + } } } return len; @@ -403,7 +409,7 @@ newdata(void) } if(len > 0 && s.state == WEBCLIENT_STATE_DATA && - s.httpflag != HTTPFLAG_MOVED) { + s.httpflag == HTTPFLAG_OK) { webclient_datahandler((char *)uip_appdata, len); } } @@ -441,7 +447,6 @@ webclient_appcall(void *state) return; } - /* The acked() and newdata() functions may alter the uip_appdata ptr, so we need to store it in the "dataptr" variable so that we can restore it before the senddata() function is called. */ @@ -474,10 +479,18 @@ webclient_appcall(void *state) if(uip_closed()) { tcp_markconn(uip_conn, NULL); - if(s.httpflag != HTTPFLAG_MOVED) { + switch(s.httpflag) { + case HTTPFLAG_HTTPS: + /* Send some info to the user. */ + webclient_datahandler((char *)http_redirect, sizeof(http_redirect) - 1); + webclient_datahandler(s.file, strlen(s.file)); + webclient_datahandler((char *)http_crnl, sizeof(http_crnl) - 1); + /* FALLTHROUGH */ + case HTTPFLAG_OK: /* Send NULL data to signal EOF. */ webclient_datahandler(NULL, 0); - } else { + break; + case HTTPFLAG_MOVED: /* conn = uip_connect(uip_conn->ripaddr, s.port); if(conn != NULL) { dispatcher_markconn(conn, NULL); @@ -489,6 +502,7 @@ webclient_appcall(void *state) } #endif /* UIP_UDP */ webclient_get(s.host, s.port, s.file); + break; } } } diff --git a/apps/webbrowser/www.c b/apps/webbrowser/www.c index 8e1331c75..70af0332b 100644 --- a/apps/webbrowser/www.c +++ b/apps/webbrowser/www.c @@ -125,7 +125,7 @@ static struct ctk_button wgetyesbutton = #if WWW_CONF_HISTORY_SIZE > 0 /* The char arrays that hold the history of visited URLs. */ static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN]; -static char history_last; +static unsigned char history_last; #endif /* WWW_CONF_HISTORY_SIZE > 0 */ struct linkattrib { @@ -170,17 +170,19 @@ static struct inputattrib *currptr; #define ISO_nl 0x0a #define ISO_space 0x20 +#define ISO_hash 0x23 #define ISO_ampersand 0x26 -#define ISO_plus 0x2b +#define ISO_plus 0x2b #define ISO_slash 0x2f #define ISO_eq 0x3d -#define ISO_questionmark 0x3f +#define ISO_questionmark 0x3f /* The state of the rendering code. */ static char *webpageptr; static unsigned char x, y; static unsigned char loading; static unsigned short firsty, pagey; +static unsigned char newlines; static unsigned char count; static char receivingmsgs[4][23] = { @@ -194,7 +196,7 @@ PROCESS(www_process, "Web browser"); AUTOSTART_PROCESSES(&www_process); -static void CC_FASTCALL formsubmit(struct formattrib *form); +static void CC_FASTCALL formsubmit(struct inputattrib *trigger); /*-----------------------------------------------------------------------------------*/ /* make_window() @@ -277,6 +279,7 @@ start_loading(void) loading = 1; x = y = 0; pagey = 0; + newlines = 0; webpageptr = webpage; clear_page(); @@ -305,10 +308,13 @@ open_url(void) static uip_ipaddr_t addr; /* Trim off any spaces in the end of the url. */ - urlptr = url + strlen(url) - 1; - while(*urlptr == ' ' && urlptr > url) { - *urlptr = 0; - --urlptr; + urlptr = url + strlen(url); + while(urlptr > url) { + if(*(urlptr - 1) == ' ') { + *--urlptr = 0; + } else { + break; + } } /* Don't even try to go further if the URL is empty. */ @@ -376,7 +382,6 @@ open_url(void) } else { show_statustext("Connecting..."); } - redraw_window(); } /*-----------------------------------------------------------------------------------*/ /* set_link(link): @@ -510,15 +515,17 @@ PROCESS_THREAD(www_process, ev, data) firsty = 0; start_loading(); --history_last; + /* Note: history_last is unsigned ! */ if(history_last > WWW_CONF_HISTORY_SIZE) { history_last = WWW_CONF_HISTORY_SIZE - 1; } memcpy(url, history[(int)history_last], WWW_CONF_MAX_URLLEN); + *history[(int)history_last] = 0; open_url(); CTK_WIDGET_FOCUS(&mainwindow, &backbutton); #endif /* WWW_CONF_HISTORY_SIZE > 0 */ } else if(w == (struct ctk_widget *)&downbutton) { - firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 4; + firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 2; start_loading(); open_url(); CTK_WIDGET_FOCUS(&mainwindow, &downbutton); @@ -557,9 +564,8 @@ PROCESS_THREAD(www_process, ev, data) #if WWW_CONF_FORMS } else { /* Assume form widget. */ - struct inputattrib *input = (struct inputattrib *) - (((char *)w) - offsetof(struct inputattrib, widget)); - formsubmit(input->formptr); + formsubmit((struct inputattrib *) + (((char *)w) - offsetof(struct inputattrib, widget))); #endif /* WWW_CONF_FORMS */ } } else if(ev == ctk_signal_hyperlink_activate) { @@ -670,8 +676,6 @@ webclient_connected(void) { start_loading(); - clear_page(); - show_statustext("Request sent..."); set_url(webclient_hostname(), webclient_port(), webclient_filename()); @@ -731,6 +735,8 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type, char *wptr; static unsigned char maxwidth; + newlines = 0; + if(!loading) { return; } @@ -770,49 +776,50 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type, wptr[size + border] = ' '; switch(type) { - case CTK_WIDGET_HYPERLINK: { - struct linkattrib *linkptr = - (struct linkattrib *)add_pageattrib(sizeof(struct linkattrib) /* incl 1 attrib char */ + attriblen); - if(linkptr != NULL) { - CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url); - strcpy(linkptr->url, attrib); - CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE); - CTK_WIDGET_ADD(&mainwindow, &linkptr->hyperlink); - } - break; + case CTK_WIDGET_HYPERLINK: { + struct linkattrib *linkptr = + (struct linkattrib *)add_pageattrib(sizeof(struct linkattrib) /* incl 1 attrib char */ + attriblen); + if(linkptr != NULL) { + CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url); + strcpy(linkptr->url, attrib); + CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE); + CTK_WIDGET_ADD(&mainwindow, &linkptr->hyperlink); } + break; + } #if WWW_CONF_FORMS - case CTK_WIDGET_BUTTON: { - struct submitattrib *submitptr = - (struct submitattrib *)add_pageattrib(sizeof(struct submitattrib) /* incl 1 attrib char */ + attriblen); - if(submitptr != NULL) { - CTK_BUTTON_NEW((struct ctk_button *)&submitptr->button, x, y + 3, size, wptr); - add_forminput((struct inputattrib *)submitptr); - submitptr->formptr = formptr; - strcpy(submitptr->name, attrib); - CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE); - CTK_WIDGET_ADD(&mainwindow, &submitptr->button); - } - break; + case CTK_WIDGET_BUTTON: { + struct submitattrib *submitptr = + (struct submitattrib *)add_pageattrib(sizeof(struct submitattrib) /* incl 1 attrib char */ + attriblen); + if(submitptr != NULL) { + CTK_BUTTON_NEW((struct ctk_button *)&submitptr->button, x, y + 3, size, wptr); + add_forminput((struct inputattrib *)submitptr); + submitptr->formptr = formptr; + strcpy(submitptr->name, attrib); + CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE); + CTK_WIDGET_ADD(&mainwindow, &submitptr->button); } - case CTK_WIDGET_TEXTENTRY: { - struct textattrib *textptr = - (struct textattrib *)add_pageattrib(sizeof(struct textattrib) /* incl 1 attrib char */ + attriblen - + (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1); - if(textptr != NULL) { - CTK_TEXTENTRY_NEW((struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1, - textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN); - add_forminput((struct inputattrib *)textptr); - textptr->formptr = formptr; - strcpy(textptr->textentry.text, text); - strcpy(textptr->name, attrib); - if(size) { - CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE); - CTK_WIDGET_ADD(&mainwindow, &textptr->textentry); - } + break; + } + case CTK_WIDGET_TEXTENTRY: { + struct textattrib *textptr = + (struct textattrib *)add_pageattrib(sizeof(struct textattrib) /* incl 1 attrib char */ + attriblen + + (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1); + if(textptr != NULL) { + CTK_TEXTENTRY_NEW((struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1, + 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) { + CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE); + CTK_WIDGET_ADD(&mainwindow, &textptr->textentry); } - break; } + break; + } #endif /* WWW_CONF_FORMS */ } } @@ -837,6 +844,10 @@ htmlparser_newline(void) { char *wptr; + if(++newlines > 2) { + return; + } + if(pagey < firsty) { ++pagey; x = 0; @@ -863,6 +874,8 @@ htmlparser_newline(void) void htmlparser_word(char *word, unsigned char wordlen) { + newlines = 0; + if(loading) { if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) { htmlparser_newline(); @@ -886,7 +899,12 @@ htmlparser_word(char *word, unsigned char wordlen) void htmlparser_link(char *text, unsigned char textlen, char *url) { - add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0); + /* No link for https or fragment-only as we would't be able to handle it anyway. */ + if(url[0] == ISO_hash || strncmp(url, http_https, sizeof(http_https) - 1) == 0) { + htmlparser_word(text, textlen); + } else { + add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0); + } } /*-----------------------------------------------------------------------------------*/ #if WWW_CONF_FORMS @@ -946,23 +964,36 @@ add_query(char delimiter, char *string) } /*-----------------------------------------------------------------------------------*/ static void CC_FASTCALL -formsubmit(struct formattrib *form) +formsubmit(struct inputattrib *trigger) { - struct inputattrib *inputptr; + struct inputattrib *input; + struct formattrib *form = trigger->formptr; char delimiter = ISO_questionmark; set_link(form->action); - for(inputptr = form->nextptr; inputptr != NULL; inputptr = inputptr->nextptr) { + /* No button pressed so prepare to look for default button. */ + if(trigger->widget.type == CTK_WIDGET_TEXTENTRY) { + trigger = NULL; + } + + for(input = form->nextptr; input != NULL; input = input->nextptr) { char *name; char *value; - if(inputptr->widget.type == CTK_WIDGET_BUTTON) { - name = ((struct submitattrib *)inputptr)->name; - value = ((struct submitattrib *)inputptr)->button.text; + if(input->widget.type == CTK_WIDGET_TEXTENTRY) { + name = ((struct textattrib *)input)->name; + value = ((struct textattrib *)input)->textentry.text; } else { - name = ((struct textattrib *)inputptr)->name; - value = ((struct textattrib *)inputptr)->textentry.text; + /* Consider first button as default button. */ + if(trigger == NULL) { + trigger = input; + } + if(input != trigger) { + continue; + } + name = ((struct submitattrib *)input)->name; + value = ((struct submitattrib *)input)->button.text; } add_query(delimiter, name); diff --git a/apps/webbrowser/www.h b/apps/webbrowser/www.h index d7ffd6fd6..2b6e5f33e 100644 --- a/apps/webbrowser/www.h +++ b/apps/webbrowser/www.h @@ -44,7 +44,7 @@ #define WWW_CONF_HISTORY_SIZE 10 #endif #ifndef WWW_CONF_MAX_URLLEN -#define WWW_CONF_MAX_URLLEN 300 +#define WWW_CONF_MAX_URLLEN 255 #endif #ifndef WWW_CONF_PAGEATTRIB_SIZE #define WWW_CONF_PAGEATTRIB_SIZE 2000 diff --git a/apps/webserver/http-strings b/apps/webserver/http-strings index 4178cae2f..07d4eac8c 100644 --- a/apps/webserver/http-strings +++ b/apps/webserver/http-strings @@ -1,4 +1,5 @@ http_http "http://" +http_https "https://" http_200 "200 " http_301 "301 " http_302 "302 " @@ -32,4 +33,4 @@ http_gif ".gif" http_jpg ".jpg" http_text ".text" http_txt ".txt" - +http_redirect "Redirect to " diff --git a/apps/webserver/http-strings.c b/apps/webserver/http-strings.c index f1c55e621..40667d24c 100644 --- a/apps/webserver/http-strings.c +++ b/apps/webserver/http-strings.c @@ -1,6 +1,9 @@ const char http_http[8] = /* "http://" */ {0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, }; +const char http_https[9] = +/* "https://" */ +{0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, }; const char http_200[5] = /* "200 " */ {0x32, 0x30, 0x30, 0x20, }; @@ -100,3 +103,6 @@ const char http_text[6] = const char http_txt[5] = /* ".txt" */ {0x2e, 0x74, 0x78, 0x74, }; +const char http_redirect[19] = +/* "Redirect to " */ +{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, }; diff --git a/apps/webserver/http-strings.h b/apps/webserver/http-strings.h index 01fc8cd9d..58ae13be8 100644 --- a/apps/webserver/http-strings.h +++ b/apps/webserver/http-strings.h @@ -1,4 +1,5 @@ extern const char http_http[8]; +extern const char http_https[9]; extern const char http_200[5]; extern const char http_301[5]; extern const char http_302[5]; @@ -32,3 +33,4 @@ extern const char http_gif[5]; extern const char http_jpg[5]; extern const char http_text[6]; extern const char http_txt[5]; +extern const char http_redirect[19]; diff --git a/core/lib/aes-128.c b/core/lib/aes-128.c index 473adf6fc..59b16421e 100644 --- a/core/lib/aes-128.c +++ b/core/lib/aes-128.c @@ -80,7 +80,7 @@ galois_mul2(uint8_t value) } /*---------------------------------------------------------------------------*/ static void -set_key(uint8_t *key) +set_key(const uint8_t *key) { uint8_t i; uint8_t j; diff --git a/core/lib/aes-128.h b/core/lib/aes-128.h index a16155b4f..59a7f7c33 100644 --- a/core/lib/aes-128.h +++ b/core/lib/aes-128.h @@ -59,7 +59,7 @@ struct aes_128_driver { /** * \brief Sets the current key. */ - void (* set_key)(uint8_t *key); + void (* set_key)(const uint8_t *key); /** * \brief Encrypts. diff --git a/core/net/llsec/ccm-star.c b/core/lib/ccm-star.c similarity index 65% rename from core/net/llsec/ccm-star.c rename to core/lib/ccm-star.c index faf79ba28..e093c8703 100644 --- a/core/net/llsec/ccm-star.c +++ b/core/lib/ccm-star.c @@ -34,44 +34,37 @@ * \file * AES_128-based CCM* implementation. * \author - * Konrad Krentz + * Original: Konrad Krentz + * Generified version: Justin King-Lacroix */ -/** - * \addtogroup llsec802154 - * @{ - */ - -#include "net/llsec/ccm-star.h" -#include "net/llsec/llsec802154.h" -#include "net/packetbuf.h" +#include "ccm-star.h" #include "lib/aes-128.h" #include +/* see RFC 3610 */ +#define CCM_STAR_AUTH_FLAGS(Adata, M) ((Adata ? (1u << 6) : 0) | (((M - 2u) >> 1) << 3) | 1u) +#define CCM_STAR_ENCRYPTION_FLAGS 1 + /*---------------------------------------------------------------------------*/ static void -set_nonce(uint8_t *nonce, +set_nonce(uint8_t *iv, uint8_t flags, - const uint8_t *extended_source_address, + const uint8_t *nonce, uint8_t counter) { /* 1 byte|| 8 bytes || 4 bytes || 1 byte || 2 bytes */ /* flags || extended_source_address || frame_counter || sec_lvl || counter */ - - nonce[0] = flags; - memcpy(nonce + 1, extended_source_address, 8); - nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8; - nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff; - nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8; - nonce[12] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff; - nonce[13] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); - nonce[14] = 0; - nonce[15] = counter; + + iv[0] = flags; + memcpy(iv + 1, nonce, CCM_STAR_NONCE_LENGTH); + iv[14] = 0; + iv[15] = counter; } /*---------------------------------------------------------------------------*/ /* XORs the block m[pos] ... m[pos + 15] with K_{counter} */ static void -ctr_step(const uint8_t *extended_source_address, +ctr_step(const uint8_t *nonce, uint8_t pos, uint8_t *m_and_result, uint8_t m_len, @@ -80,7 +73,7 @@ ctr_step(const uint8_t *extended_source_address, uint8_t a[AES_128_BLOCK_SIZE]; uint8_t i; - set_nonce(a, CCM_STAR_ENCRYPTION_FLAGS, extended_source_address, counter); + set_nonce(a, CCM_STAR_ENCRYPTION_FLAGS, nonce, counter); AES_128.encrypt(a); for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) { @@ -89,43 +82,20 @@ ctr_step(const uint8_t *extended_source_address, } /*---------------------------------------------------------------------------*/ static void -mic(const uint8_t *extended_source_address, +mic(const uint8_t *m, uint8_t m_len, + const uint8_t *nonce, + const uint8_t *a, uint8_t a_len, uint8_t *result, uint8_t mic_len) { uint8_t x[AES_128_BLOCK_SIZE]; uint8_t pos; uint8_t i; - uint8_t a_len; - uint8_t *a; -#if LLSEC802154_USES_ENCRYPTION - uint8_t shall_encrypt; - uint8_t m_len; - uint8_t *m; - shall_encrypt = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & (1 << 2); - if(shall_encrypt) { - a_len = packetbuf_hdrlen(); - m_len = packetbuf_datalen(); - } else { - a_len = packetbuf_totlen(); - m_len = 0; - } - set_nonce(x, - CCM_STAR_AUTH_FLAGS(a_len, mic_len), - extended_source_address, - m_len); -#else /* LLSEC802154_USES_ENCRYPTION */ - a_len = packetbuf_totlen(); - set_nonce(x, - CCM_STAR_AUTH_FLAGS(a_len, mic_len), - extended_source_address, - 0); -#endif /* LLSEC802154_USES_ENCRYPTION */ + set_nonce(x, CCM_STAR_AUTH_FLAGS(a_len, mic_len), nonce, m_len); AES_128.encrypt(x); - a = packetbuf_hdrptr(); - if(a_len) { + if(a_len > 0) { x[1] = x[1] ^ a_len; for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) { x[i] ^= a[i - 2]; @@ -143,8 +113,7 @@ mic(const uint8_t *extended_source_address, } } -#if LLSEC802154_USES_ENCRYPTION - if(shall_encrypt) { + if(m_len > 0) { m = a + a_len; pos = 0; while(pos < m_len) { @@ -155,36 +124,33 @@ mic(const uint8_t *extended_source_address, AES_128.encrypt(x); } } -#endif /* LLSEC802154_USES_ENCRYPTION */ - ctr_step(extended_source_address, 0, x, AES_128_BLOCK_SIZE, 0); + ctr_step(nonce, 0, x, AES_128_BLOCK_SIZE, 0); memcpy(result, x, mic_len); } /*---------------------------------------------------------------------------*/ static void -ctr(const uint8_t *extended_source_address) +ctr(uint8_t *m, uint8_t m_len, const uint8_t* nonce) { - uint8_t m_len; - uint8_t *m; uint8_t pos; uint8_t counter; - m_len = packetbuf_datalen(); - m = (uint8_t *) packetbuf_dataptr(); - pos = 0; counter = 1; while(pos < m_len) { - ctr_step(extended_source_address, pos, m, m_len, counter++); + ctr_step(nonce, pos, m, m_len, counter++); pos += AES_128_BLOCK_SIZE; } } /*---------------------------------------------------------------------------*/ +static void set_key(const uint8_t *key) { + AES_128.set_key((uint8_t*)key); +} +/*---------------------------------------------------------------------------*/ const struct ccm_star_driver ccm_star_driver = { mic, - ctr + ctr, + set_key }; /*---------------------------------------------------------------------------*/ - -/** @} */ diff --git a/core/net/llsec/ccm-star.h b/core/lib/ccm-star.h similarity index 66% rename from core/net/llsec/ccm-star.h rename to core/lib/ccm-star.h index 89a486075..f0394e4ae 100644 --- a/core/net/llsec/ccm-star.h +++ b/core/lib/ccm-star.h @@ -34,23 +34,13 @@ * \file * CCM* header file. * \author - * Konrad Krentz + * Original: Konrad Krentz + * Generified version: Justin King-Lacroix */ - -/** - * \addtogroup llsec802154 - * @{ - */ - #ifndef CCM_STAR_H_ #define CCM_STAR_H_ #include "contiki.h" -#include "net/mac/frame802154.h" - -/* see RFC 3610 */ -#define CCM_STAR_AUTH_FLAGS(Adata, M) ((Adata ? (1 << 6) : 0) | (((M - 2) >> 1) << 3) | 1) -#define CCM_STAR_ENCRYPTION_FLAGS 1 #ifdef CCM_STAR_CONF #define CCM_STAR CCM_STAR_CONF @@ -58,28 +48,43 @@ #define CCM_STAR ccm_star_driver #endif /* CCM_STAR_CONF */ +#define CCM_STAR_NONCE_LENGTH 13 + /** * Structure of CCM* drivers. */ struct ccm_star_driver { /** - * \brief Generates a MIC over the frame in the packetbuf. - * \param result The generated MIC will be put here - * \param mic_len <= 16; set to LLSEC802154_MIC_LENGTH to be compliant + * \brief Generates a MIC over the data supplied. + * \param data The data buffer to read. + * \param data_length The data buffer length. + * \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long. + * \param result The generated MIC will be put here + * \param mic_len The size of the MIC to be generated. <= 16. */ - void (* mic)(const uint8_t *extended_source_address, + void (* mic)(const uint8_t* data, uint8_t data_length, + const uint8_t* nonce, + const uint8_t* add, uint8_t add_len, uint8_t *result, uint8_t mic_len); /** * \brief XORs the frame in the packetbuf with the key stream. + * \param data The data buffer to read. + * \param data_length The data buffer length. + * \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long. */ - void (* ctr)(const uint8_t *extended_source_address); + void (* ctr)( uint8_t* data, uint8_t data_length, + const uint8_t* nonce); + + /** + * \brief Sets the key in use. Default implementation calls AES_128.set_key() + * \param key The key to use. + */ + void (* set_key)(const uint8_t* key); }; extern const struct ccm_star_driver CCM_STAR; #endif /* CCM_STAR_H_ */ - -/** @} */ 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/resolv.c b/core/net/ip/resolv.c index 58bda004d..edf2a4815 100644 --- a/core/net/ip/resolv.c +++ b/core/net/ip/resolv.c @@ -394,7 +394,7 @@ dns_name_isequal(const unsigned char *queryptr, const char *name, return 0; } - if(tolower(*name++) != tolower(*queryptr++)) { + if(tolower((unsigned int)*name++) != tolower((unsigned int)*queryptr++)) { return 0; } } diff --git a/core/net/ip/uip-debug.c b/core/net/ip/uip-debug.c index 6460f2bb4..93e7edfe7 100644 --- a/core/net/ip/uip-debug.c +++ b/core/net/ip/uip-debug.c @@ -43,14 +43,16 @@ void uip_debug_ipaddr_print(const uip_ipaddr_t *addr) { - if(addr == NULL || addr->u8 == NULL) { - printf("(NULL IP addr)"); - return; - } #if NETSTACK_CONF_WITH_IPV6 uint16_t a; unsigned int i; int f; +#endif /* NETSTACK_CONF_WITH_IPV6 */ + if(addr == NULL) { + PRINTA("(NULL IP addr)"); + return; + } +#if NETSTACK_CONF_WITH_IPV6 for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) { a = (addr->u8[i] << 8) + addr->u8[i + 1]; if(a == 0 && f >= 0) { @@ -75,6 +77,10 @@ void uip_debug_lladdr_print(const uip_lladdr_t *addr) { unsigned int i; + if(addr == NULL) { + PRINTA("(NULL LL addr)"); + return; + } for(i = 0; i < sizeof(uip_lladdr_t); i++) { if(i > 0) { PRINTA(":"); diff --git a/core/net/ip/uip-nameserver.c b/core/net/ip/uip-nameserver.c index 367fe421d..6e34346b0 100644 --- a/core/net/ip/uip-nameserver.c +++ b/core/net/ip/uip-nameserver.c @@ -59,7 +59,7 @@ typedef struct uip_nameserver_record { #if UIP_NAMESERVER_POOL_SIZE > 1 /** \brief Initialization flag */ static uint8_t initialized = 0; -#endif +#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ /** \name List and memory block * @{ @@ -92,7 +92,7 @@ init(void) #endif /* UIP_NAMESERVER_POOL_SIZE > 1 */ /*----------------------------------------------------------------------------*/ void -uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime) +uip_nameserver_update(const uip_ipaddr_t *nameserver, uint32_t lifetime) { #if UIP_NAMESERVER_POOL_SIZE > 1 register uip_nameserver_record *e; diff --git a/core/net/ip/uip-nameserver.h b/core/net/ip/uip-nameserver.h index 41dcf58c8..6acf62290 100644 --- a/core/net/ip/uip-nameserver.h +++ b/core/net/ip/uip-nameserver.h @@ -74,7 +74,7 @@ * considered to remove an entry. Maximum is 0xFFFFFFFF which * is considered infinite. */ -void uip_nameserver_update(uip_ipaddr_t *nameserver, uint32_t lifetime); +void uip_nameserver_update(const uip_ipaddr_t *nameserver, uint32_t lifetime); /** * \brief Get a Nameserver ip address given in RA 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/ipv6/multicast/roll-tm.c b/core/net/ipv6/multicast/roll-tm.c index 20a562084..a6b1b8bff 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; } /*---------------------------------------------------------------------------*/ diff --git a/core/net/llsec/ccm-star-packetbuf.c b/core/net/llsec/ccm-star-packetbuf.c new file mode 100644 index 000000000..08087398e --- /dev/null +++ b/core/net/llsec/ccm-star-packetbuf.c @@ -0,0 +1,52 @@ +/** + * \file + * CCM* convenience functions for LLSEC use + * \author + * Justin King-Lacroix + */ + +#include "lib/ccm-star.h" +#include "net/packetbuf.h" +#include + +/*---------------------------------------------------------------------------*/ +void ccm_star_mic_packetbuf(const uint8_t *extended_source_address, + uint8_t *result, + uint8_t mic_len) +{ + uint8_t *dataptr = packetbuf_dataptr(); + uint8_t data_len = packetbuf_datalen(); + uint8_t *headerptr = packetbuf_hdrptr(); + uint8_t header_len = packetbuf_hdrlen(); + uint8_t nonce[CCM_STAR_NONCE_LENGTH]; + + memcpy(nonce, extended_source_address, 8); + nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8; + nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff; + nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8; + nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff; + nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); + + if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) & (1 << 2)) { + CCM_STAR.mic(dataptr, data_len, nonce, headerptr, header_len, result, mic_len); + } else { + CCM_STAR.mic(dataptr, 0, nonce, headerptr, packetbuf_totlen(), result, mic_len); + } +} +/*---------------------------------------------------------------------------*/ +void ccm_star_ctr_packetbuf(const uint8_t *extended_source_address) +{ + uint8_t *dataptr = packetbuf_dataptr(); + uint8_t data_len = packetbuf_datalen(); + uint8_t nonce[CCM_STAR_NONCE_LENGTH]; + + memcpy(nonce, extended_source_address, 8); + nonce[8] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8; + nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff; + nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) >> 8; + nonce[11] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1) & 0xff; + nonce[12] = packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL); + + CCM_STAR.ctr(dataptr, data_len, nonce); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/net/llsec/ccm-star-packetbuf.h b/core/net/llsec/ccm-star-packetbuf.h new file mode 100644 index 000000000..3b6c43472 --- /dev/null +++ b/core/net/llsec/ccm-star-packetbuf.h @@ -0,0 +1,24 @@ +/** + * \file + * CCM* convenience functions for MAC security + * \author + * Justin King-Lacroix + */ + +#ifndef CCM_STAR_PACKETBUF_H_ +#define CCM_STAR_PACKETBUF_H_ + +/** + * \brief Calls CCM_STAR.mic with parameters appropriate for LLSEC. + */ +void ccm_star_mic_packetbuf(const uint8_t *extended_source_address, + uint8_t *result, + uint8_t mic_len); + +/** + * \brief Calls CCM_STAR.ctr with parameters appropriate for LLSEC. + */ +void ccm_star_ctr_packetbuf(const uint8_t *extended_source_address); + +#endif /* CCM_STAR_PACKETBUF_H_ */ + diff --git a/core/net/llsec/noncoresec/noncoresec.c b/core/net/llsec/noncoresec/noncoresec.c index 8935d3375..e62ad2725 100644 --- a/core/net/llsec/noncoresec/noncoresec.c +++ b/core/net/llsec/noncoresec/noncoresec.c @@ -45,13 +45,13 @@ #include "net/llsec/noncoresec/noncoresec.h" #include "net/llsec/anti-replay.h" #include "net/llsec/llsec802154.h" -#include "net/llsec/ccm-star.h" +#include "net/llsec/ccm-star-packetbuf.h" #include "net/mac/frame802154.h" #include "net/netstack.h" #include "net/packetbuf.h" #include "net/nbr-table.h" #include "net/linkaddr.h" -#include "lib/aes-128.h" +#include "lib/ccm-star.h" #include #define WITH_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2)) @@ -110,15 +110,12 @@ send(mac_callback_t sent, void *ptr) static int on_frame_created(void) { - uint8_t *dataptr; - uint8_t data_len; - - dataptr = packetbuf_dataptr(); - data_len = packetbuf_datalen(); - - CCM_STAR.mic(get_extended_address(&linkaddr_node_addr), dataptr + data_len, LLSEC802154_MIC_LENGTH); + uint8_t *dataptr = packetbuf_dataptr(); + uint8_t data_len = packetbuf_datalen(); + + ccm_star_mic_packetbuf(get_extended_address(&linkaddr_node_addr), dataptr + data_len, LLSEC802154_MIC_LENGTH); #if WITH_ENCRYPTION - CCM_STAR.ctr(get_extended_address(&linkaddr_node_addr)); + ccm_star_ctr_packetbuf(get_extended_address(&linkaddr_node_addr)); #endif /* WITH_ENCRYPTION */ packetbuf_set_datalen(data_len + LLSEC802154_MIC_LENGTH); @@ -132,6 +129,8 @@ input(void) uint8_t *received_mic; const linkaddr_t *sender; struct anti_replay_info* info; + uint8_t *dataptr = packetbuf_dataptr(); + uint8_t data_len = packetbuf_datalen(); if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != LLSEC802154_SECURITY_LEVEL) { PRINTF("noncoresec: received frame with wrong security level\n"); @@ -143,14 +142,15 @@ input(void) return; } - packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH); + data_len -= LLSEC802154_MIC_LENGTH; + packetbuf_set_datalen(data_len); #if WITH_ENCRYPTION - CCM_STAR.ctr(get_extended_address(sender)); + ccm_star_ctr_packetbuf(get_extended_address(sender)); #endif /* WITH_ENCRYPTION */ - CCM_STAR.mic(get_extended_address(sender), generated_mic, LLSEC802154_MIC_LENGTH); + ccm_star_mic_packetbuf(get_extended_address(sender), generated_mic, LLSEC802154_MIC_LENGTH); - received_mic = ((uint8_t *) packetbuf_dataptr()) + packetbuf_datalen(); + received_mic = dataptr + data_len; if(memcmp(generated_mic, received_mic, LLSEC802154_MIC_LENGTH) != 0) { PRINTF("noncoresec: received nonauthentic frame %"PRIu32"\n", anti_replay_get_counter()); @@ -203,7 +203,7 @@ get_overhead(void) static void bootstrap(llsec_on_bootstrapped_t on_bootstrapped) { - AES_128.set_key(key); + CCM_STAR.set_key(key); nbr_table_register(anti_replay_table, NULL); on_bootstrapped(); } diff --git a/core/net/mac/contikimac/contikimac.c b/core/net/mac/contikimac/contikimac.c index 6bb6317ee..7362fb527 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 @@ -490,7 +504,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, int is_receiver_awake) { rtimer_clock_t t0; +#if WITH_PHASE_OPTIMIZATION rtimer_clock_t encounter_time = 0; +#endif int strobes; uint8_t got_strobe_ack = 0; int len; @@ -664,7 +680,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, { rtimer_clock_t wt; +#if WITH_PHASE_OPTIMIZATION rtimer_clock_t txtime = RTIMER_NOW(); +#endif #if RDC_CONF_HARDWARE_ACK int ret = NETSTACK_RADIO.transmit(transmit_len); #else @@ -677,7 +695,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, if(ret == RADIO_TX_OK) { if(!is_broadcast) { got_strobe_ack = 1; +#if WITH_PHASE_OPTIMIZATION encounter_time = txtime; +#endif break; } } else if (ret == RADIO_TX_NOACK) { @@ -702,7 +722,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr, len = NETSTACK_RADIO.read(ackbuf, ACK_LEN); if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) { got_strobe_ack = 1; +#if WITH_PHASE_OPTIMIZATION encounter_time = txtime; +#endif break; } else { PRINTF("contikimac: collisions while sending\n"); @@ -861,10 +883,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) { @@ -892,12 +930,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 @@ -915,7 +954,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/rime/collect-neighbor.c b/core/net/rime/collect-neighbor.c index dae9289ea..b033d3e05 100644 --- a/core/net/rime/collect-neighbor.c +++ b/core/net/rime/collect-neighbor.c @@ -254,13 +254,11 @@ collect_neighbor_list_remove(struct collect_neighbor_list *neighbors_list, struct collect_neighbor * collect_neighbor_list_best(struct collect_neighbor_list *neighbors_list) { - int found; struct collect_neighbor *n, *best; uint16_t rtmetric; rtmetric = RTMETRIC_MAX; best = NULL; - found = 0; if(neighbors_list == NULL) { return NULL; diff --git a/core/net/rime/collect.c b/core/net/rime/collect.c index 325996246..cdd2557c3 100644 --- a/core/net/rime/collect.c +++ b/core/net/rime/collect.c @@ -950,14 +950,18 @@ node_packet_received(struct unicast_conn *c, const linkaddr_t *from) if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == PACKETBUF_ATTR_PACKET_TYPE_DATA) { linkaddr_t ack_to; +#if DEBUG uint8_t packet_seqno; +#endif stats.datarecv++; /* Remember to whom we should send the ACK, since we reuse the packet buffer and its attributes when sending the ACK. */ linkaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER)); +#if DEBUG packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID); +#endif /* If the queue is more than half filled, we add the CONGESTED flag to our outgoing acks. */ diff --git a/core/net/rpl/rpl-conf.h b/core/net/rpl/rpl-conf.h index a2c0e6dd2..69199f9ac 100644 --- a/core/net/rpl/rpl-conf.h +++ b/core/net/rpl/rpl-conf.h @@ -105,6 +105,22 @@ #define RPL_MAX_DAG_PER_INSTANCE 2 #endif /* RPL_CONF_MAX_DAG_PER_INSTANCE */ +/* + * RPL Default route lifetime + * The RPL route lifetime is used for the downward routes and for the default + * route. In a high density network with DIO suppression activated it may happen + * that a node will never send a DIO once the DIO interval becomes high as it + * has heard DIO from many neighbors already. As the default route to the + * preferred parent has a lifetime reset by receiving DIO from the parent, it + * means that the default route can be destroyed after a while. Setting the + * default route with infinite lifetime secures the upstream route. + */ +#ifdef RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME +#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME +#else +#define RPL_DEFAULT_ROUTE_INFINITE_LIFETIME 0 +#endif /* RPL_CONF_DEFAULT_ROUTE_INFINITE_LIFETIME */ + /* * */ diff --git a/core/net/rpl/rpl-dag.c b/core/net/rpl/rpl-dag.c index 6c9b75b8f..767c58968 100644 --- a/core/net/rpl/rpl-dag.c +++ b/core/net/rpl/rpl-dag.c @@ -481,8 +481,7 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from) PRINT6ADDR(from); PRINTF("\n"); instance->def_route = uip_ds6_defrt_add(from, - RPL_LIFETIME(instance, - instance->default_lifetime)); + RPL_DEFAULT_ROUTE_INFINITE_LIFETIME ? 0 : RPL_LIFETIME(instance, instance->default_lifetime)); if(instance->def_route == NULL) { return 0; } @@ -814,6 +813,9 @@ rpl_select_parent(rpl_dag_t *dag) if(best != NULL) { rpl_set_preferred_parent(dag, best); + dag->rank = dag->instance->of->calculate_rank(dag->preferred_parent, 0); + } else { + dag->rank = INFINITE_RANK; } return best; @@ -1373,6 +1375,9 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } } + /* Parent info has been updated, trigger rank recalculation */ + p->flags |= RPL_PARENT_FLAG_UPDATED; + PRINTF("RPL: preferred DAG "); PRINT6ADDR(&instance->current_dag->dag_id); PRINTF(", rank %u, min_rank %u, ", @@ -1398,7 +1403,7 @@ rpl_process_dio(uip_ipaddr_t *from, rpl_dio_t *dio) } /* We received a new DIO from our preferred parent. * Call uip_ds6_defrt_add to set a fresh value for the lifetime counter */ - uip_ds6_defrt_add(from, RPL_LIFETIME(instance, instance->default_lifetime)); + uip_ds6_defrt_add(from, RPL_DEFAULT_ROUTE_INFINITE_LIFETIME ? 0 : RPL_LIFETIME(instance, instance->default_lifetime)); } p->dtsn = dio->dtsn; } diff --git a/core/net/rpl/rpl.c b/core/net/rpl/rpl.c index db5230611..dc66528d3 100644 --- a/core/net/rpl/rpl.c +++ b/core/net/rpl/rpl.c @@ -277,9 +277,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/cpu/6502/6502def.h b/cpu/6502/6502def.h index 1d7b5c440..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; @@ -72,7 +72,6 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_LLH_LEN 14 #define RESOLV_CONF_SUPPORTS_MDNS 0 #define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0 -#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 1 #define LOADER_CONF_ARCH "lib/unload.h" @@ -85,7 +84,7 @@ typedef unsigned short uip_stats_t; #if CONNECTIONS #define UIP_CONF_MAX_CONNECTIONS CONNECTIONS #else /* CONNECTIONS */ -#define UIP_CONF_MAX_CONNECTIONS 10 +#define UIP_CONF_MAX_CONNECTIONS 2 #endif /* CONNECTIONS */ #if WITH_LOGGING diff --git a/cpu/6502/Makefile.customrules-6502 b/cpu/6502/Makefile.customrules-6502 index d477a1d15..e0953362d 100644 --- a/cpu/6502/Makefile.customrules-6502 +++ b/cpu/6502/Makefile.customrules-6502 @@ -6,7 +6,7 @@ $(OBJECTDIR)/%.o: %.c | $(OBJECTDIR) CUSTOM_RULE_C_TO_CO = 1 %.co: %.c $(TRACE_CC) - $(Q)$(CC) -c -o $@ $(CFLAGS) -DAUTOSTART_ENABLE --create-dep $(@:.o=.d) $< + $(Q)$(CC) -c -o $@ $(CFLAGS) -DAUTOSTART_ENABLE $< CUSTOM_RULE_LINK = 1 %.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a diff --git a/cpu/6502/README.md b/cpu/6502/README.md index a928d81bd..3ab367a52 100644 --- a/cpu/6502/README.md +++ b/cpu/6502/README.md @@ -37,7 +37,7 @@ high-level configuration macros may be set: - Purpose: Set the Maximum Transfer Unit size. - CONNECTIONS - - Default: 10 + - Default: 2 - Purpose: Set the maximum number of concurrent TCP connections. - ETHERNET diff --git a/cpu/6502/ipconfig/ipconfig.c b/cpu/6502/ipconfig/ipconfig.c index 5452b735a..7c7584b67 100644 --- a/cpu/6502/ipconfig/ipconfig.c +++ b/cpu/6502/ipconfig/ipconfig.c @@ -177,9 +177,9 @@ app_quit(void) PROCESS_THREAD(ipconfig_process, ev, data) { PROCESS_BEGIN(); - + ctk_window_new(&window, 29, 14, "IP config"); - + CTK_WIDGET_ADD(&window, &requestbutton); CTK_WIDGET_ADD(&window, &statuslabel); CTK_WIDGET_ADD(&window, &ipaddrlabel); @@ -208,11 +208,11 @@ PROCESS_THREAD(ipconfig_process, ev, data) while(1) { PROCESS_WAIT_EVENT(); - + if(ev == PROCESS_EVENT_MSG) { makestrings(); ctk_window_redraw(&window); - } else if(ev == tcpip_event) { + } else if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) { dhcpc_appcall(ev, data); } else if(ev == ctk_signal_button_activate) { if(data == (process_data_t)&requestbutton) { diff --git a/cpu/6502/net/cs8900a.S b/cpu/6502/net/cs8900a.S index 9bc648704..e650f28c2 100644 --- a/cpu/6502/net/cs8900a.S +++ b/cpu/6502/net/cs8900a.S @@ -92,12 +92,13 @@ fixups = * - fixup ;--------------------------------------------------------------------- -rxtxreg := $FF00 ; High byte patched at runtime -txcmd := $FF04 ; High byte patched at runtime -txlen := $FF06 ; High byte patched at runtime -isq := $FF08 ; High byte patched at runtime -packetpp := $FF0A ; High byte patched at runtime -ppdata := $FF0C ; High byte patched at runtime +; 3 most significant nibbles are fixed up at runtime +rxtxreg := $FFF0 +txcmd := $FFF4 +txlen := $FFF6 +isq := $FFF8 +packetpp := $FFFA +ppdata := $FFFC .data @@ -117,8 +118,9 @@ init: ldy #$00 ; Fixup address at location -: lda reg - eor (ptr),y ; Use XOR to support C64 RR-Net +: lda (ptr),y + and #$0F + eor reg ; Use XOR to support C64 RR-Net sta (ptr),y iny lda reg+1 diff --git a/cpu/6502/net/lan91c96.S b/cpu/6502/net/lan91c96.S index e94fdda7c..ea0c80098 100644 --- a/cpu/6502/net/lan91c96.S +++ b/cpu/6502/net/lan91c96.S @@ -95,40 +95,41 @@ fixups = * - fixup ;--------------------------------------------------------------------- -ethbsr := $FF0E ; Bank select register R/W (2B) +; 3 most significant nibbles are fixed up at runtime +ethbsr := $FFFE ; Bank select register R/W (2B) ; Register bank 0 -ethtcr := $FF00 ; Transmition control register R/W (2B) -ethephsr := $FF02 ; EPH status register R/O (2B) -ethrcr := $FF04 ; Receive control register R/W (2B) -ethecr := $FF06 ; Counter register R/O (2B) -ethmir := $FF08 ; Memory information register R/O (2B) -ethmcr := $FF0A ; Memory Config. reg. +0 R/W +1 R/O (2B) +ethtcr := $FFF0 ; Transmition control register R/W (2B) +ethephsr := $FFF2 ; EPH status register R/O (2B) +ethrcr := $FFF4 ; Receive control register R/W (2B) +ethecr := $FFF6 ; Counter register R/O (2B) +ethmir := $FFF8 ; Memory information register R/O (2B) +ethmcr := $FFFA ; Memory Config. reg. +0 R/W +1 R/O (2B) ; Register bank 1 -ethcr := $FF00 ; Configuration register R/W (2B) -ethbar := $FF02 ; Base address register R/W (2B) -ethiar := $FF04 ; Individual address register R/W (6B) -ethgpr := $FF0A ; General address register R/W (2B) -ethctr := $FF0C ; Control register R/W (2B) +ethcr := $FFF0 ; Configuration register R/W (2B) +ethbar := $FFF2 ; Base address register R/W (2B) +ethiar := $FFF4 ; Individual address register R/W (6B) +ethgpr := $FFFA ; General address register R/W (2B) +ethctr := $FFFC ; Control register R/W (2B) ; Register bank 2 -ethmmucr := $FF00 ; MMU command register W/O (1B) -ethautotx := $FF01 ; AUTO TX start register R/W (1B) -ethpnr := $FF02 ; Packet number register R/W (1B) -etharr := $FF03 ; Allocation result register R/O (1B) -ethfifo := $FF04 ; FIFO ports register R/O (2B) -ethptr := $FF06 ; Pointer register R/W (2B) -ethdata := $FF08 ; Data register R/W (4B) -ethist := $FF0C ; Interrupt status register R/O (1B) -ethack := $FF0C ; Interrupt acknowledge register W/O (1B) -ethmsk := $FF0D ; Interrupt mask register R/W (1B) +ethmmucr := $FFF0 ; MMU command register W/O (1B) +ethautotx := $FFF1 ; AUTO TX start register R/W (1B) +ethpnr := $FFF2 ; Packet number register R/W (1B) +etharr := $FFF3 ; Allocation result register R/O (1B) +ethfifo := $FFF4 ; FIFO ports register R/O (2B) +ethptr := $FFF6 ; Pointer register R/W (2B) +ethdata := $FFF8 ; Data register R/W (4B) +ethist := $FFFC ; Interrupt status register R/O (1B) +ethack := $FFFC ; Interrupt acknowledge register W/O (1B) +ethmsk := $FFFD ; Interrupt mask register R/W (1B) ; Register bank 3 -ethmt := $FF00 ; Multicast table R/W (8B) -ethmgmt := $FF08 ; Management interface R/W (2B) -ethrev := $FF0A ; Revision register R/W (2B) -ethercv := $FF0C ; Early RCV register R/W (2B) +ethmt := $FFF0 ; Multicast table R/W (8B) +ethmgmt := $FFF8 ; Management interface R/W (2B) +ethrev := $FFFA ; Revision register R/W (2B) +ethercv := $FFFC ; Early RCV register R/W (2B) .data @@ -148,8 +149,9 @@ init: ldy #$00 ; Fixup address at location -: lda reg - ora (ptr),y +: lda (ptr),y + and #$0F + ora reg sta (ptr),y iny lda reg+1 diff --git a/cpu/6502/net/w5100.S b/cpu/6502/net/w5100.S index f200a31fb..8fb040b01 100644 --- a/cpu/6502/net/w5100.S +++ b/cpu/6502/net/w5100.S @@ -103,9 +103,10 @@ fixups = * - fixup ;--------------------------------------------------------------------- -mode := $FF00 ; High byte patched at runtime -addr := $FF01 ; High byte patched at runtime -data := $FF03 ; High byte patched at runtime +; 14 most significant bits are fixed up at runtime +mode := $FFFC|0 +addr := $FFFC|1 +data := $FFFC|3 .data @@ -125,8 +126,9 @@ init: ldy #$00 ; Fixup address at location -: lda reg - ora (ptr),y +: lda (ptr),y + and #$03 + ora reg sta (ptr),y iny lda reg+1 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/arm/common/CMSIS/core.txt b/cpu/arm/common/CMSIS/core.txt index 3ae0d00ff..b9270e199 100644 --- a/cpu/arm/common/CMSIS/core.txt +++ b/cpu/arm/common/CMSIS/core.txt @@ -34,17 +34,17 @@ */ /** - * @defgroup Cortex_M0 + * @defgroup Cortex_M0 Cortex-M0 * @ingroup cmsis */ /** - * @defgroup Cortex_M3 + * @defgroup Cortex_M3 Cortex-M3 * @ingroup cmsis */ /** - * @defgroup Cortex_M4 + * @defgroup Cortex_M4 Cortex-M4 * @ingroup cmsis */ diff --git a/cpu/avr/dev/lanc111.c b/cpu/avr/dev/lanc111.c index 28b793896..60cde63af 100644 --- a/cpu/avr/dev/lanc111.c +++ b/cpu/avr/dev/lanc111.c @@ -170,7 +170,7 @@ * \addtogroup avr * @{ */ /*! - * \defgroup xgSmscRegs + * \defgroup xgSmscRegs SMSC Registers * * @{ */ @@ -1203,6 +1203,7 @@ PROCESS_THREAD(lanc111_process, ev, data) PROCESS_END(); } #endif /* 0 */ +#if 0 /*! * \brief Send Ethernet packet. * @@ -1213,7 +1214,6 @@ PROCESS_THREAD(lanc111_process, ev, data) * * \return 0 on success, -1 in case of any errors. */ -#if 0 int LancOutput(NUTDEVICE * dev, NETBUF * nb) { static u_long mx_wait = 5000; diff --git a/cpu/avr/radio/rf230bb/halbb.c b/cpu/avr/radio/rf230bb/halbb.c index d37882d45..ae495d762 100644 --- a/cpu/avr/radio/rf230bb/halbb.c +++ b/cpu/avr/radio/rf230bb/halbb.c @@ -544,6 +544,7 @@ hal_frame_write(uint8_t *write_buffer, uint8_t length) } /*----------------------------------------------------------------------------*/ +#if 0 //Uses 80 bytes (on Raven) omit unless needed /** \brief Read SRAM * * This function reads from the SRAM of the radio transceiver. @@ -552,7 +553,6 @@ hal_frame_write(uint8_t *write_buffer, uint8_t length) * \param length Length of the read burst * \param data Pointer to buffer where data is stored. */ -#if 0 //Uses 80 bytes (on Raven) omit unless needed void hal_sram_read(uint8_t address, uint8_t length, uint8_t *data) { @@ -576,6 +576,7 @@ hal_sram_read(uint8_t address, uint8_t length, uint8_t *data) } #endif /*----------------------------------------------------------------------------*/ +#if 0 //omit unless needed /** \brief Write SRAM * * This function writes into the SRAM of the radio transceiver. It can reduce @@ -585,7 +586,6 @@ hal_sram_read(uint8_t address, uint8_t length, uint8_t *data) * \param length Length of the write burst * \param data Pointer to an array of bytes that should be written */ -#if 0 //omit unless needed void hal_sram_write(uint8_t address, uint8_t length, uint8_t *data) { diff --git a/cpu/cc2538/Makefile.cc2538 b/cpu/cc2538/Makefile.cc2538 index d4eafc93a..29795111c 100644 --- a/cpu/cc2538/Makefile.cc2538 +++ b/cpu/cc2538/Makefile.cc2538 @@ -49,6 +49,7 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm ### CPU-dependent source files CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c CONTIKI_CPU_SOURCEFILES += nvic.c cpu.c sys-ctrl.c gpio.c ioc.c spi.c adc.c +CONTIKI_CPU_SOURCEFILES += crypto.c aes.c ccm.c sha256.c CONTIKI_CPU_SOURCEFILES += cc2538-rf.c udma.c lpm.c CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c diff --git a/cpu/cc2538/cc2538.lds b/cpu/cc2538/cc2538.lds index 17b048778..cfd4cb48c 100644 --- a/cpu/cc2538/cc2538.lds +++ b/cpu/cc2538/cc2538.lds @@ -85,12 +85,13 @@ SECTIONS *(.udma_channel_control_table) } > SRAM - .data : + .data : ALIGN(4) { _data = .; *(.data*) _edata = .; } > SRAM AT > FLASH + _ldata = LOADADDR(.data); .ARM.exidx : { @@ -105,6 +106,11 @@ SECTIONS _ebss = .; } > SRAM + .stack (NOLOAD) : + { + *(.stack) + } > SRAM + #if (LPM_CONF_MAX_PM==2) && (LPM_CONF_ENABLE != 0) .nrdata (NOLOAD) : { diff --git a/cpu/cc2538/dev/aes.c b/cpu/cc2538/dev/aes.c new file mode 100644 index 000000000..1bd70690c --- /dev/null +++ b/cpu/cc2538/dev/aes.c @@ -0,0 +1,152 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538-aes + * @{ + * + * \file + * Implementation of the cc2538 AES driver + */ +#include "contiki.h" +#include "dev/rom-util.h" +#include "dev/aes.h" +#include "reg.h" + +#include +/*---------------------------------------------------------------------------*/ +uint8_t +aes_load_keys(const void *keys, uint8_t key_size, uint8_t count, + uint8_t start_area) +{ + uint32_t aes_key_store_size; + uint32_t areas; + uint64_t aligned_keys[16]; + int i; + + if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { + return CRYPTO_RESOURCE_IN_USE; + } + + /* 192-bit keys must be padded to 256 bits */ + if(key_size == AES_KEY_STORE_SIZE_KEY_SIZE_192) { + for(i = 0; i < count; i++) { + rom_util_memcpy(&aligned_keys[i << 2], &((uint64_t *)keys)[i * 3], 24); + aligned_keys[(i << 2) + 3] = 0; + } + } + + /* Change count to the number of 128-bit key areas */ + if(key_size != AES_KEY_STORE_SIZE_KEY_SIZE_128) { + count <<= 1; + } + + /* The keys base address needs to be 4-byte aligned */ + if(key_size != AES_KEY_STORE_SIZE_KEY_SIZE_192) { + rom_util_memcpy(aligned_keys, keys, count << 4); + } + + /* Workaround for AES registers not retained after PM2 */ + REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV; + + /* Configure master control module */ + REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_KEYSTORE; + + /* Clear any outstanding events */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + /* Configure key store module (areas, size) + * Note that writing AES_KEY_STORE_SIZE deletes all stored keys */ + aes_key_store_size = REG(AES_KEY_STORE_SIZE); + if((aes_key_store_size & AES_KEY_STORE_SIZE_KEY_SIZE_M) != key_size) { + REG(AES_KEY_STORE_SIZE) = (aes_key_store_size & + ~AES_KEY_STORE_SIZE_KEY_SIZE_M) | key_size; + } + + /* Free possibly already occupied key areas */ + areas = ((0x00000001 << count) - 1) << start_area; + REG(AES_KEY_STORE_WRITTEN_AREA) = areas; + + /* Enable key areas to write */ + REG(AES_KEY_STORE_WRITE_AREA) = areas; + + /* Configure DMAC + * Enable DMA channel 0 */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + + /* Base address of the keys in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)aligned_keys; + + /* Total keys length in bytes (e.g. 16 for 1 x 128-bit key) */ + REG(AES_DMAC_CH0_DMALENGTH) = (REG(AES_DMAC_CH0_DMALENGTH) & + ~AES_DMAC_CH_DMALENGTH_DMALEN_M) | + (count << (4 + AES_DMAC_CH_DMALENGTH_DMALEN_S)); + + /* Wait for operation to complete */ + while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)); + + /* Check for absence of errors in DMA and key store */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return CRYPTO_DMA_BUS_ERROR; + } + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) { + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_WR_ERR; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return AES_KEYSTORE_WRITE_ERROR; + } + + /* Acknowledge the interrupt */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + + /* Check status, if error return error code */ + if((REG(AES_KEY_STORE_WRITTEN_AREA) & areas) != areas) { + return AES_KEYSTORE_WRITE_ERROR; + } + + return CRYPTO_SUCCESS; +} + +/** @} */ diff --git a/cpu/cc2538/dev/aes.h b/cpu/cc2538/dev/aes.h new file mode 100644 index 000000000..39c794b51 --- /dev/null +++ b/cpu/cc2538/dev/aes.h @@ -0,0 +1,495 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538-crypto + * @{ + * + * \defgroup cc2538-aes cc2538 AES + * + * Driver for the cc2538 AES modes of the security core + * @{ + * + * \file + * Header file for the cc2538 AES driver + */ +#ifndef AES_H_ +#define AES_H_ + +#include "contiki.h" +#include "dev/crypto.h" + +#include +/*---------------------------------------------------------------------------*/ +/** \name AES register offsets + * @{ + */ +#define AES_DMAC_CH0_CTRL 0x4008B000 /**< Channel 0 control */ +#define AES_DMAC_CH0_EXTADDR 0x4008B004 /**< Channel 0 external address */ +#define AES_DMAC_CH0_DMALENGTH 0x4008B00C /**< Channel 0 DMA length */ +#define AES_DMAC_STATUS 0x4008B018 /**< DMAC status */ +#define AES_DMAC_SWRES 0x4008B01C /**< DMAC software reset */ +#define AES_DMAC_CH1_CTRL 0x4008B020 /**< Channel 1 control */ +#define AES_DMAC_CH1_EXTADDR 0x4008B024 /**< Channel 1 external address */ +#define AES_DMAC_CH1_DMALENGTH 0x4008B02C /**< Channel 1 DMA length */ +#define AES_DMAC_MST_RUNPARAMS 0x4008B078 /**< DMAC master run-time parameters */ +#define AES_DMAC_PERSR 0x4008B07C /**< DMAC port error raw status */ +#define AES_DMAC_OPTIONS 0x4008B0F8 /**< DMAC options */ +#define AES_DMAC_VERSION 0x4008B0FC /**< DMAC version */ +#define AES_KEY_STORE_WRITE_AREA \ + 0x4008B400 /**< Key store write area */ +#define AES_KEY_STORE_WRITTEN_AREA \ + 0x4008B404 /**< Key store written area */ +#define AES_KEY_STORE_SIZE 0x4008B408 /**< Key store size */ +#define AES_KEY_STORE_READ_AREA 0x4008B40C /**< Key store read area */ +#define AES_AES_KEY2_0 0x4008B500 /**< AES_KEY2_0 / AES_GHASH_H_IN_0 */ +#define AES_AES_KEY2_1 0x4008B504 /**< AES_KEY2_1 / AES_GHASH_H_IN_1 */ +#define AES_AES_KEY2_2 0x4008B508 /**< AES_KEY2_2 / AES_GHASH_H_IN_2 */ +#define AES_AES_KEY2_3 0x4008B50C /**< AES_KEY2_3 / AES_GHASH_H_IN_3 */ +#define AES_AES_KEY3_0 0x4008B510 /**< AES_KEY3_0 / AES_KEY2_4 */ +#define AES_AES_KEY3_1 0x4008B514 /**< AES_KEY3_1 / AES_KEY2_5 */ +#define AES_AES_KEY3_2 0x4008B518 /**< AES_KEY3_2 / AES_KEY2_6 */ +#define AES_AES_KEY3_3 0x4008B51C /**< AES_KEY3_3 / AES_KEY2_7 */ +#define AES_AES_IV_0 0x4008B540 /**< AES initialization vector */ +#define AES_AES_IV_1 0x4008B544 /**< AES initialization vector */ +#define AES_AES_IV_2 0x4008B548 /**< AES initialization vector */ +#define AES_AES_IV_3 0x4008B54C /**< AES initialization vector */ +#define AES_AES_CTRL 0x4008B550 /**< AES input/output buffer control and mode */ +#define AES_AES_C_LENGTH_0 0x4008B554 /**< AES crypto length (LSW) */ +#define AES_AES_C_LENGTH_1 0x4008B558 /**< AES crypto length (MSW) */ +#define AES_AES_AUTH_LENGTH 0x4008B55C /**< Authentication length */ +#define AES_AES_DATA_IN_OUT_0 0x4008B560 /**< Data input/output */ +#define AES_AES_DATA_IN_OUT_1 0x4008B564 /**< Data Input/Output */ +#define AES_AES_DATA_IN_OUT_2 0x4008B568 /**< Data Input/Output */ +#define AES_AES_DATA_IN_OUT_3 0x4008B56C /**< Data Input/Output */ +#define AES_AES_TAG_OUT_0 0x4008B570 /**< TAG */ +#define AES_AES_TAG_OUT_1 0x4008B574 /**< TAG */ +#define AES_AES_TAG_OUT_2 0x4008B578 /**< TAG */ +#define AES_AES_TAG_OUT_3 0x4008B57C /**< TAG */ +#define AES_HASH_DATA_IN_0 0x4008B600 /**< HASH data input */ +#define AES_HASH_DATA_IN_1 0x4008B604 /**< HASH data input */ +#define AES_HASH_DATA_IN_2 0x4008B608 /**< HASH data input */ +#define AES_HASH_DATA_IN_3 0x4008B60C /**< HASH data input */ +#define AES_HASH_DATA_IN_4 0x4008B610 /**< HASH data input */ +#define AES_HASH_DATA_IN_5 0x4008B614 /**< HASH data input */ +#define AES_HASH_DATA_IN_6 0x4008B618 /**< HASH data input */ +#define AES_HASH_DATA_IN_7 0x4008B61C /**< HASH data input */ +#define AES_HASH_DATA_IN_8 0x4008B620 /**< HASH data input */ +#define AES_HASH_DATA_IN_9 0x4008B624 /**< HASH data input */ +#define AES_HASH_DATA_IN_10 0x4008B628 /**< HASH data input */ +#define AES_HASH_DATA_IN_11 0x4008B62C /**< HASH data input */ +#define AES_HASH_DATA_IN_12 0x4008B630 /**< HASH data input */ +#define AES_HASH_DATA_IN_13 0x4008B634 /**< HASH data input */ +#define AES_HASH_DATA_IN_14 0x4008B638 /**< HASH data input */ +#define AES_HASH_DATA_IN_15 0x4008B63C /**< HASH data input */ +#define AES_HASH_IO_BUF_CTRL 0x4008B640 /**< Input/output buffer control and status */ +#define AES_HASH_MODE_IN 0x4008B644 /**< Hash mode */ +#define AES_HASH_LENGTH_IN_L 0x4008B648 /**< Hash length */ +#define AES_HASH_LENGTH_IN_H 0x4008B64C /**< Hash length */ +#define AES_HASH_DIGEST_A 0x4008B650 /**< Hash digest */ +#define AES_HASH_DIGEST_B 0x4008B654 /**< Hash digest */ +#define AES_HASH_DIGEST_C 0x4008B658 /**< Hash digest */ +#define AES_HASH_DIGEST_D 0x4008B65C /**< Hash digest */ +#define AES_HASH_DIGEST_E 0x4008B660 /**< Hash digest */ +#define AES_HASH_DIGEST_F 0x4008B664 /**< Hash digest */ +#define AES_HASH_DIGEST_G 0x4008B668 /**< Hash digest */ +#define AES_HASH_DIGEST_H 0x4008B66C /**< Hash digest */ +#define AES_CTRL_ALG_SEL 0x4008B700 /**< Algorithm select */ +#define AES_CTRL_PROT_EN 0x4008B704 /**< Master PROT privileged access enable */ +#define AES_CTRL_SW_RESET 0x4008B740 /**< Software reset */ +#define AES_CTRL_INT_CFG 0x4008B780 /**< Interrupt configuration */ +#define AES_CTRL_INT_EN 0x4008B784 /**< Interrupt enable */ +#define AES_CTRL_INT_CLR 0x4008B788 /**< Interrupt clear */ +#define AES_CTRL_INT_SET 0x4008B78C /**< Interrupt set */ +#define AES_CTRL_INT_STAT 0x4008B790 /**< Interrupt status */ +#define AES_CTRL_OPTIONS 0x4008B7F8 /**< Options */ +#define AES_CTRL_VERSION 0x4008B7FC /**< Version */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_CHx_CTRL registers bit fields + * @{ + */ +#define AES_DMAC_CH_CTRL_PRIO 0x00000002 /**< Channel priority 0: Low 1: High */ +#define AES_DMAC_CH_CTRL_EN 0x00000001 /**< Channel enable */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_CHx_DMALENGTH registers bit fields + * @{ + */ +#define AES_DMAC_CH_DMALENGTH_DMALEN_M \ + 0x0000FFFF /**< Channel DMA length in bytes mask */ +#define AES_DMAC_CH_DMALENGTH_DMALEN_S 0 /**< Channel DMA length in bytes shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_STATUS register bit fields + * @{ + */ +#define AES_DMAC_STATUS_PORT_ERR \ + 0x00020000 /**< AHB port transfer errors */ +#define AES_DMAC_STATUS_CH1_ACT 0x00000002 /**< Channel 1 active (DMA transfer on-going) */ +#define AES_DMAC_STATUS_CH0_ACT 0x00000001 /**< Channel 0 active (DMA transfer on-going) */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_SWRES register bit fields + * @{ + */ +#define AES_DMAC_SWRES_SWRES 0x00000001 /**< Software reset enable */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_MST_RUNPARAMS register bit fields + * @{ + */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_4 \ + (2 << 12) /**< Maximum burst size: 4 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_8 \ + (3 << 12) /**< Maximum burst size: 8 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_16 \ + (4 << 12) /**< Maximum burst size: 16 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_32 \ + (5 << 12) /**< Maximum burst size: 32 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_64 \ + (6 << 12) /**< Maximum burst size: 64 bytes */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_M \ + 0x0000F000 /**< Maximum burst size mask */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BURST_SIZE_S \ + 12 /**< Maximum burst size shift */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_IDLE_EN \ + 0x00000800 /**< Idle insertion between bursts */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_INCR_EN \ + 0x00000400 /**< Fixed-length burst or single transfers */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_LOCK_EN \ + 0x00000200 /**< Locked transfers */ +#define AES_DMAC_MST_RUNPARAMS_AHB_MST1_BIGEND \ + 0x00000100 /**< Big endian AHB master */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_PERSR register bit fields + * @{ + */ +#define AES_DMAC_PERSR_PORT1_AHB_ERROR \ + 0x00001000 /**< AHB bus error */ +#define AES_DMAC_PERSR_PORT1_CHANNEL \ + 0x00000200 /**< Last serviced channel (0 or 1) */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_OPTIONS register bit fields + * @{ + */ +#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_M \ + 0x00000F00 /**< Number of channels implemented mask */ +#define AES_DMAC_OPTIONS_NR_OF_CHANNELS_S \ + 8 /**< Number of channels implemented shift */ +#define AES_DMAC_OPTIONS_NR_OF_PORTS_M \ + 0x00000007 /**< Number of ports implemented mask */ +#define AES_DMAC_OPTIONS_NR_OF_PORTS_S 0 /**< Number of ports implemented shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_DMAC_VERSION register bit fields + * @{ + */ +#define AES_DMAC_VERSION_HW_MAJOR_VERSION_M \ + 0x0F000000 /**< Major version number mask */ +#define AES_DMAC_VERSION_HW_MAJOR_VERSION_S \ + 24 /**< Major version number shift */ +#define AES_DMAC_VERSION_HW_MINOR_VERSION_M \ + 0x00F00000 /**< Minor version number mask */ +#define AES_DMAC_VERSION_HW_MINOR_VERSION_S \ + 20 /**< Minor version number shift */ +#define AES_DMAC_VERSION_HW_PATCH_LEVEL_M \ + 0x000F0000 /**< Patch level mask */ +#define AES_DMAC_VERSION_HW_PATCH_LEVEL_S \ + 16 /**< Patch level shift */ +#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_M \ + 0x0000FF00 /**< EIP_NUMBER 1's complement mask */ +#define AES_DMAC_VERSION_EIP_NUMBER_COMPL_S \ + 8 /**< EIP_NUMBER 1's complement shift */ +#define AES_DMAC_VERSION_EIP_NUMBER_M \ + 0x000000FF /**< DMAC EIP-number mask */ +#define AES_DMAC_VERSION_EIP_NUMBER_S 0 /**< DMAC EIP-number shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_KEY_STORE_SIZE register bit fields + * @{ + */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_128 1 /**< Key size: 128 bits */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_192 2 /**< Key size: 192 bits */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_256 3 /**< Key size: 256 bits */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_M \ + 0x00000003 /**< Key size mask */ +#define AES_KEY_STORE_SIZE_KEY_SIZE_S 0 /**< Key size shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_KEY_STORE_READ_AREA register bit fields + * @{ + */ +#define AES_KEY_STORE_READ_AREA_BUSY \ + 0x80000000 /**< Key store operation busy */ +#define AES_KEY_STORE_READ_AREA_RAM_AREA_M \ + 0x0000000F /**< Key store RAM area select mask */ +#define AES_KEY_STORE_READ_AREA_RAM_AREA_S \ + 0 /**< Key store RAM area select shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_AES_CTRL register bit fields + * @{ + */ +#define AES_AES_CTRL_CONTEXT_READY \ + 0x80000000 /**< Context data registers can be overwritten */ +#define AES_AES_CTRL_SAVED_CONTEXT_READY \ + 0x40000000 /**< AES auth. TAG and/or IV block(s) available */ +#define AES_AES_CTRL_SAVE_CONTEXT \ + 0x20000000 /**< Auth. TAG or result IV needs to be stored */ +#define AES_AES_CTRL_CCM_M_M 0x01C00000 /**< CCM auth. field length mask */ +#define AES_AES_CTRL_CCM_M_S 22 /**< CCM auth. field length shift */ +#define AES_AES_CTRL_CCM_L_M 0x00380000 /**< CCM length field width mask */ +#define AES_AES_CTRL_CCM_L_S 19 /**< CCM length field width shift */ +#define AES_AES_CTRL_CCM 0x00040000 /**< AES-CCM mode */ +#define AES_AES_CTRL_GCM 0x00030000 /**< AES-GCM mode */ +#define AES_AES_CTRL_CBC_MAC 0x00008000 /**< AES-CBC MAC mode */ +#define AES_AES_CTRL_CTR_WIDTH_32 (0 << 7) /**< CTR counter width: 32 bits */ +#define AES_AES_CTRL_CTR_WIDTH_64 (1 << 7) /**< CTR counter width: 64 bits */ +#define AES_AES_CTRL_CTR_WIDTH_96 (2 << 7) /**< CTR counter width: 96 bits */ +#define AES_AES_CTRL_CTR_WIDTH_128 \ + (3 << 7) /**< CTR counter width: 128 bits */ +#define AES_AES_CTRL_CTR_WIDTH_M \ + 0x00000180 /**< CTR counter width mask */ +#define AES_AES_CTRL_CTR_WIDTH_S 7 /**< CTR counter width shift */ +#define AES_AES_CTRL_CTR 0x00000040 /**< AES-CTR mode */ +#define AES_AES_CTRL_CBC 0x00000020 /**< AES-CBC mode */ +#define AES_AES_CTRL_KEY_SIZE_128 (1 << 3) /**< Key size: 128 bits */ +#define AES_AES_CTRL_KEY_SIZE_192 (2 << 3) /**< Key size: 192 bits */ +#define AES_AES_CTRL_KEY_SIZE_256 (3 << 3) /**< Key size: 256 bits */ +#define AES_AES_CTRL_KEY_SIZE_M 0x00000018 /**< Key size mask */ +#define AES_AES_CTRL_KEY_SIZE_S 3 /**< Key size shift */ +#define AES_AES_CTRL_DIRECTION_ENCRYPT \ + 0x00000004 /**< Encrypt */ +#define AES_AES_CTRL_INPUT_READY \ + 0x00000002 /**< AES input buffer empty */ +#define AES_AES_CTRL_OUTPUT_READY \ + 0x00000001 /**< AES output block available */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_AES_C_LENGTH_1 register bit fields + * @{ + */ +#define AES_AES_C_LENGTH_1_C_LENGTH_M \ + 0x1FFFFFFF /**< Crypto length bits [60:32] mask */ +#define AES_AES_C_LENGTH_1_C_LENGTH_S 0 /**< Crypto length bits [60:32] shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_HASH_IO_BUF_CTRL register bit fields + * @{ + */ +#define AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE \ + 0x00000080 /**< Hash engine message padding required */ +#define AES_HASH_IO_BUF_CTRL_GET_DIGEST \ + 0x00000040 /**< Hash engine digest requested */ +#define AES_HASH_IO_BUF_CTRL_PAD_MESSAGE \ + 0x00000020 /**< Last message data in HASH_DATA_IN, apply hash padding */ +#define AES_HASH_IO_BUF_CTRL_RFD_IN \ + 0x00000004 /**< Hash engine input buffer can accept new data */ +#define AES_HASH_IO_BUF_CTRL_DATA_IN_AV \ + 0x00000002 /**< Start processing HASH_DATA_IN data */ +#define AES_HASH_IO_BUF_CTRL_OUTPUT_FULL \ + 0x00000001 /**< Output buffer registers available */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_HASH_MODE_IN register bit fields + * @{ + */ +#define AES_HASH_MODE_IN_SHA256_MODE \ + 0x00000008 /**< Hash mode */ +#define AES_HASH_MODE_IN_NEW_HASH \ + 0x00000001 /**< New hash session */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_ALG_SEL register bit fields + * @{ + */ +#define AES_CTRL_ALG_SEL_TAG 0x80000000 /**< DMA operation includes TAG */ +#define AES_CTRL_ALG_SEL_HASH 0x00000004 /**< Select hash engine as DMA destination */ +#define AES_CTRL_ALG_SEL_AES 0x00000002 /**< Select AES engine as DMA source/destination */ +#define AES_CTRL_ALG_SEL_KEYSTORE \ + 0x00000001 /**< Select Key Store as DMA destination */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_PROT_EN register bit fields + * @{ + */ +#define AES_CTRL_PROT_EN_PROT_EN \ + 0x00000001 /**< m_h_prot[1] asserted for DMA reads towards key store */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_SW_RESET register bit fields + * @{ + */ +#define AES_CTRL_SW_RESET_SW_RESET \ + 0x00000001 /**< Reset master control and key store */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_CFG register bit fields + * @{ + */ +#define AES_CTRL_INT_CFG_LEVEL 0x00000001 /**< Level interrupt type */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_EN register bit fields + * @{ + */ +#define AES_CTRL_INT_EN_DMA_IN_DONE \ + 0x00000002 /**< DMA input done interrupt enabled */ +#define AES_CTRL_INT_EN_RESULT_AV \ + 0x00000001 /**< Result available interrupt enabled */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_CLR register bit fields + * @{ + */ +#define AES_CTRL_INT_CLR_DMA_BUS_ERR \ + 0x80000000 /**< Clear DMA bus error status */ +#define AES_CTRL_INT_CLR_KEY_ST_WR_ERR \ + 0x40000000 /**< Clear key store write error status */ +#define AES_CTRL_INT_CLR_KEY_ST_RD_ERR \ + 0x20000000 /**< Clear key store read error status */ +#define AES_CTRL_INT_CLR_DMA_IN_DONE \ + 0x00000002 /**< Clear DMA in done interrupt */ +#define AES_CTRL_INT_CLR_RESULT_AV \ + 0x00000001 /**< Clear result available interrupt */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_SET register bit fields + * @{ + */ +#define AES_CTRL_INT_SET_DMA_IN_DONE \ + 0x00000002 /**< Set DMA data in done interrupt */ +#define AES_CTRL_INT_SET_RESULT_AV \ + 0x00000001 /**< Set result available interrupt */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_INT_STAT register bit fields + * @{ + */ +#define AES_CTRL_INT_STAT_DMA_BUS_ERR \ + 0x80000000 /**< DMA bus error detected */ +#define AES_CTRL_INT_STAT_KEY_ST_WR_ERR \ + 0x40000000 /**< Write error detected */ +#define AES_CTRL_INT_STAT_KEY_ST_RD_ERR \ + 0x20000000 /**< Read error detected */ +#define AES_CTRL_INT_STAT_DMA_IN_DONE \ + 0x00000002 /**< DMA data in done interrupt status */ +#define AES_CTRL_INT_STAT_RESULT_AV \ + 0x00000001 /**< Result available interrupt status */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_OPTIONS register bit fields + * @{ + */ +#define AES_CTRL_OPTIONS_TYPE_M 0xFF000000 /**< Device type mask */ +#define AES_CTRL_OPTIONS_TYPE_S 24 /**< Device type shift */ +#define AES_CTRL_OPTIONS_AHBINTERFACE \ + 0x00010000 /**< AHB interface available */ +#define AES_CTRL_OPTIONS_SHA_256 \ + 0x00000100 /**< The HASH core supports SHA-256 */ +#define AES_CTRL_OPTIONS_AES_CCM \ + 0x00000080 /**< AES-CCM available as single operation */ +#define AES_CTRL_OPTIONS_AES_GCM \ + 0x00000040 /**< AES-GCM available as single operation */ +#define AES_CTRL_OPTIONS_AES_256 \ + 0x00000020 /**< AES core supports 256-bit keys */ +#define AES_CTRL_OPTIONS_AES_128 \ + 0x00000010 /**< AES core supports 128-bit keys */ +#define AES_CTRL_OPTIONS_HASH 0x00000004 /**< HASH Core available */ +#define AES_CTRL_OPTIONS_AES 0x00000002 /**< AES core available */ +#define AES_CTRL_OPTIONS_KEYSTORE \ + 0x00000001 /**< KEY STORE available */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES_CTRL_VERSION register bit fields + * @{ + */ +#define AES_CTRL_VERSION_MAJOR_VERSION_M \ + 0x0F000000 /**< Major version number mask */ +#define AES_CTRL_VERSION_MAJOR_VERSION_S \ + 24 /**< Major version number shift */ +#define AES_CTRL_VERSION_MINOR_VERSION_M \ + 0x00F00000 /**< Minor version number mask */ +#define AES_CTRL_VERSION_MINOR_VERSION_S \ + 20 /**< Minor version number shift */ +#define AES_CTRL_VERSION_PATCH_LEVEL_M \ + 0x000F0000 /**< Patch level mask */ +#define AES_CTRL_VERSION_PATCH_LEVEL_S 16 /**< Patch level shift */ +#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_M \ + 0x0000FF00 /**< EIP_NUMBER 1's complement mask */ +#define AES_CTRL_VERSION_EIP_NUMBER_COMPL_S \ + 8 /**< EIP_NUMBER 1's complement shift */ +#define AES_CTRL_VERSION_EIP_NUMBER_M \ + 0x000000FF /**< EIP-120t EIP-number mask */ +#define AES_CTRL_VERSION_EIP_NUMBER_S 0 /**< EIP-120t EIP-number shift */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES drivers return codes + * @{ + */ +#define AES_KEYSTORE_READ_ERROR 5 +#define AES_KEYSTORE_WRITE_ERROR 6 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES functions + * @{ + */ + +/** \brief Writes keys into the Key RAM + * \param keys Pointer to AES Keys + * \param key_size Key size: \c AES_KEY_STORE_SIZE_KEY_SIZE_x + * \param count Number of keys (1 to 8 - \p start_area for 128-bit keys, 1 to + * (8 - \p start_area) / 2 for 192- and 256-bit keys) + * \param start_area Start area in Key RAM where to store the key (0 to 7, must + * be even for 192- and 256-bit keys) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES error code + * \note Calling this function with a value of \p key_size different from the + * one passed for the previous calls causes the deletion of all previously + * stored keys. + */ +uint8_t aes_load_keys(const void *keys, uint8_t key_size, uint8_t count, + uint8_t start_area); + +/** @} */ + +#endif /* AES_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/ccm.c b/cpu/cc2538/dev/ccm.c new file mode 100644 index 000000000..b25ef29b3 --- /dev/null +++ b/cpu/cc2538/dev/ccm.c @@ -0,0 +1,413 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538-ccm + * @{ + * + * \file + * Implementation of the cc2538 AES-CCM driver + */ +#include "contiki.h" +#include "sys/cc.h" +#include "dev/rom-util.h" +#include "dev/nvic.h" +#include "dev/ccm.h" +#include "reg.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_encrypt_start(uint8_t len_len, uint8_t key_area, const void *nonce, + const void *adata, uint16_t adata_len, void *pdata, + uint16_t pdata_len, uint8_t mic_len, + struct process *process) +{ + uint32_t iv[4]; + + if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { + return CRYPTO_RESOURCE_IN_USE; + } + + /* Workaround for AES registers not retained after PM2 */ + REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV; + + REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES; + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + REG(AES_KEY_STORE_READ_AREA) = key_area; + + /* Wait until key is loaded to the AES module */ + while(REG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY); + + /* Check for Key Store read error */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) { + /* Clear the Keystore Read error bit */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + /* Disable the master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return AES_KEYSTORE_READ_ERROR; + } + + /* Prepare the encryption initialization vector + * Flags: L' = L - 1 */ + ((uint8_t *)iv)[0] = len_len - 1; + /* Nonce */ + rom_util_memcpy(&((uint8_t *)iv)[1], nonce, 15 - len_len); + /* Initialize counter to 0 */ + rom_util_memset(&((uint8_t *)iv)[16 - len_len], 0, len_len); + + /* Write initialization vector */ + REG(AES_AES_IV_0) = iv[0]; + REG(AES_AES_IV_1) = iv[1]; + REG(AES_AES_IV_2) = iv[2]; + REG(AES_AES_IV_3) = iv[3]; + + /* Program AES-CCM encryption */ + REG(AES_AES_CTRL) = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */ + (((MAX(mic_len, 2) - 2) >> 1) << AES_AES_CTRL_CCM_M_S) | /* M */ + ((len_len - 1) << AES_AES_CTRL_CCM_L_S) | /* L */ + AES_AES_CTRL_CCM | /* CCM */ + AES_AES_CTRL_CTR_WIDTH_128 | /* CTR width 128 */ + AES_AES_CTRL_CTR | /* CTR */ + AES_AES_CTRL_DIRECTION_ENCRYPT; /* Encryption */ + + /* Write the length of the crypto block (lo) */ + REG(AES_AES_C_LENGTH_0) = pdata_len; + /* Write the length of the crypto block (hi) */ + REG(AES_AES_C_LENGTH_1) = 0; + + /* Write the length of the AAD data block (may be non-block size-aligned) */ + REG(AES_AES_AUTH_LENGTH) = adata_len; + + if(adata_len != 0) { + /* Configure DMAC to fetch the AAD data + * Enable DMA channel 0 */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the AAD input data in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)adata; + /* AAD data length in bytes */ + REG(AES_DMAC_CH0_DMALENGTH) = adata_len; + + /* Wait for completion of the AAD data transfer, DMA_IN_DONE */ + while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE)); + + /* Check for the absence of error */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + /* Clear the DMA error */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; + /* Disable the master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return CRYPTO_DMA_BUS_ERROR; + } + } + + /* Clear interrupt status */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + if(process != NULL) { + crypto_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_AES); + nvic_interrupt_enable(NVIC_INT_AES); + } + + /* Enable result available bit in interrupt enable */ + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV; + + if(pdata_len != 0) { + /* Configure DMAC + * Enable DMA channel 0 */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the payload data in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)pdata; + /* Payload data length in bytes */ + REG(AES_DMAC_CH0_DMALENGTH) = pdata_len; + + /* Enable DMA channel 1 */ + REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the output data buffer */ + REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)pdata; + /* Output data length in bytes */ + REG(AES_DMAC_CH1_DMALENGTH) = pdata_len; + } + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_encrypt_check_status(void) +{ + return !!(REG(AES_CTRL_INT_STAT) & + (AES_CTRL_INT_STAT_DMA_BUS_ERR | AES_CTRL_INT_STAT_KEY_ST_WR_ERR | + AES_CTRL_INT_STAT_KEY_ST_RD_ERR | AES_CTRL_INT_STAT_RESULT_AV)); +} +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_encrypt_get_result(void *mic, uint8_t mic_len) +{ + uint32_t aes_ctrl_int_stat; + uint32_t tag[4]; + + aes_ctrl_int_stat = REG(AES_CTRL_INT_STAT); + /* Clear the error bits */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR | + AES_CTRL_INT_CLR_KEY_ST_WR_ERR | + AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + + nvic_interrupt_disable(NVIC_INT_AES); + crypto_register_process_notification(NULL); + + /* Disable the master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + + if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + return CRYPTO_DMA_BUS_ERROR; + } + if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) { + return AES_KEYSTORE_WRITE_ERROR; + } + if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) { + return AES_KEYSTORE_READ_ERROR; + } + + /* Read tag + * Wait for the context ready bit */ + while(!(REG(AES_AES_CTRL) & AES_AES_CTRL_SAVED_CONTEXT_READY)); + + /* Read the tag registers */ + tag[0] = REG(AES_AES_TAG_OUT_0); + tag[1] = REG(AES_AES_TAG_OUT_1); + tag[2] = REG(AES_AES_TAG_OUT_2); + tag[3] = REG(AES_AES_TAG_OUT_3); + + /* Clear the interrupt status */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + /* Copy tag to MIC */ + rom_util_memcpy(mic, tag, mic_len); + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_decrypt_start(uint8_t len_len, uint8_t key_area, const void *nonce, + const void *adata, uint16_t adata_len, void *cdata, + uint16_t cdata_len, uint8_t mic_len, + struct process *process) +{ + uint16_t pdata_len = cdata_len - mic_len; + uint32_t iv[4]; + + if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { + return CRYPTO_RESOURCE_IN_USE; + } + + /* Workaround for AES registers not retained after PM2 */ + REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV; + + REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_AES; + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + REG(AES_KEY_STORE_READ_AREA) = key_area; + + /* Wait until key is loaded to the AES module */ + while(REG(AES_KEY_STORE_READ_AREA) & AES_KEY_STORE_READ_AREA_BUSY); + + /* Check for Key Store read error */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) { + /* Clear the Keystore Read error bit */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + /* Disable the master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return AES_KEYSTORE_READ_ERROR; + } + + /* Prepare the decryption initialization vector + * Flags: L' = L - 1 */ + ((uint8_t *)iv)[0] = len_len - 1; + /* Nonce */ + rom_util_memcpy(&((uint8_t *)iv)[1], nonce, 15 - len_len); + /* Initialize counter to 0 */ + rom_util_memset(&((uint8_t *)iv)[16 - len_len], 0, len_len); + + /* Write initialization vector */ + REG(AES_AES_IV_0) = iv[0]; + REG(AES_AES_IV_1) = iv[1]; + REG(AES_AES_IV_2) = iv[2]; + REG(AES_AES_IV_3) = iv[3]; + + /* Program AES-CCM decryption */ + REG(AES_AES_CTRL) = AES_AES_CTRL_SAVE_CONTEXT | /* Save context */ + (((MAX(mic_len, 2) - 2) >> 1) << AES_AES_CTRL_CCM_M_S) | /* M */ + ((len_len - 1) << AES_AES_CTRL_CCM_L_S) | /* L */ + AES_AES_CTRL_CCM | /* CCM */ + AES_AES_CTRL_CTR_WIDTH_128 | /* CTR width 128 */ + AES_AES_CTRL_CTR; /* CTR */ + + /* Write the length of the crypto block (lo) */ + REG(AES_AES_C_LENGTH_0) = pdata_len; + /* Write the length of the crypto block (hi) */ + REG(AES_AES_C_LENGTH_1) = 0; + + /* Write the length of the AAD data block (may be non-block size-aligned) */ + REG(AES_AES_AUTH_LENGTH) = adata_len; + + if(adata_len != 0) { + /* Configure DMAC to fetch the AAD data + * Enable DMA channel 0 */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the AAD input data in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)adata; + /* AAD data length in bytes */ + REG(AES_DMAC_CH0_DMALENGTH) = adata_len; + + /* Wait for completion of the AAD data transfer, DMA_IN_DONE */ + while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_IN_DONE)); + + /* Check for the absence of error */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + /* Clear the DMA error */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; + /* Disable the master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return CRYPTO_DMA_BUS_ERROR; + } + } + + /* Clear interrupt status */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + if(process != NULL) { + crypto_register_process_notification(process); + nvic_interrupt_unpend(NVIC_INT_AES); + nvic_interrupt_enable(NVIC_INT_AES); + } + + /* Enable result available bit in interrupt enable */ + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_RESULT_AV; + + if(pdata_len != 0) { + /* Configure DMAC + * Enable DMA channel 0 */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the payload data in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)cdata; + /* Payload data length in bytes */ + REG(AES_DMAC_CH0_DMALENGTH) = pdata_len; + + /* Enable DMA channel 1 */ + REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the output data buffer */ + REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)cdata; + /* Output data length in bytes */ + REG(AES_DMAC_CH1_DMALENGTH) = pdata_len; + } + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_decrypt_check_status(void) +{ + /* Check if result is available or some error has occured */ + return ccm_auth_encrypt_check_status(); +} +/*---------------------------------------------------------------------------*/ +uint8_t +ccm_auth_decrypt_get_result(const void *cdata, uint16_t cdata_len, + void *mic, uint8_t mic_len) +{ + uint32_t aes_ctrl_int_stat; + uint16_t pdata_len = cdata_len - mic_len; + uint32_t tag[4]; + + aes_ctrl_int_stat = REG(AES_CTRL_INT_STAT); + /* Clear the error bits */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR | + AES_CTRL_INT_CLR_KEY_ST_WR_ERR | + AES_CTRL_INT_CLR_KEY_ST_RD_ERR; + + nvic_interrupt_disable(NVIC_INT_AES); + crypto_register_process_notification(NULL); + + /* Disable the master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + + if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + return CRYPTO_DMA_BUS_ERROR; + } + if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_WR_ERR) { + return AES_KEYSTORE_WRITE_ERROR; + } + if(aes_ctrl_int_stat & AES_CTRL_INT_STAT_KEY_ST_RD_ERR) { + return AES_KEYSTORE_READ_ERROR; + } + + /* Read tag + * Wait for the context ready bit */ + while(!(REG(AES_AES_CTRL) & AES_AES_CTRL_SAVED_CONTEXT_READY)); + + /* Read the tag registers */ + tag[0] = REG(AES_AES_TAG_OUT_0); + tag[1] = REG(AES_AES_TAG_OUT_1); + tag[2] = REG(AES_AES_TAG_OUT_2); + tag[3] = REG(AES_AES_TAG_OUT_3); + + /* Clear the interrupt status */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + + /* Check MIC */ + if(rom_util_memcmp(tag, &((const uint8_t *)cdata)[pdata_len], mic_len)) { + return CCM_AUTHENTICATION_FAILED; + } + + /* Copy tag to MIC */ + rom_util_memcpy(mic, tag, mic_len); + + return CRYPTO_SUCCESS; +} + +/** @} */ diff --git a/cpu/cc2538/dev/ccm.h b/cpu/cc2538/dev/ccm.h new file mode 100644 index 000000000..1cab578af --- /dev/null +++ b/cpu/cc2538/dev/ccm.h @@ -0,0 +1,141 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538-aes + * @{ + * + * \defgroup cc2538-ccm cc2538 AES-CCM + * + * Driver for the cc2538 AES-CCM mode of the security core + * @{ + * + * \file + * Header file for the cc2538 AES-CCM driver + */ +#ifndef CCM_H_ +#define CCM_H_ + +#include "contiki.h" +#include "dev/aes.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +/** \name AES-CCM driver return codes + * @{ + */ +#define CCM_AUTHENTICATION_FAILED 7 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name AES-CCM functions + * @{ + */ + +/** \brief Starts the CCM authentication and encryption operation + * \param len_len Number of octets in length field (2, 4 or 8) + * \param key_area Area in Key RAM where the key is stored (0 to 7) + * \param nonce Pointer to nonce (15 - \p len_len octets) + * \param adata Pointer to additional authenticated data, or \c NULL + * \param adata_len Length of additional authenticated data in octets, or \c 0 + * \param pdata Pointer to message to authenticate and encrypt, or \c NULL + * \param pdata_len Length of message to authenticate and encrypt in octets, or \c 0 + * \param mic_len Number of octets in authentication field (even value between 0 and 16) + * \param process Process to be polled upon completion of the operation, or \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code + */ +uint8_t ccm_auth_encrypt_start(uint8_t len_len, uint8_t key_area, + const void *nonce, const void *adata, + uint16_t adata_len, void *pdata, + uint16_t pdata_len, uint8_t mic_len, + struct process *process); + +/** \brief Checks the status of the CCM authentication and encryption operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +uint8_t ccm_auth_encrypt_check_status(void); + +/** \brief Gets the result of the CCM authentication and encryption operation + * \param mic Pointer to authentication field, or \c NULL + * \param mic_len Number of octets in authentication field (even value between 0 and 16) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code + * \note This function must be called only after \c ccm_auth_encrypt_start(). + */ +uint8_t ccm_auth_encrypt_get_result(void *mic, uint8_t mic_len); + +/** \brief Starts the CCM authentication checking and decryption operation + * \param len_len Number of octets in length field (2, 4 or 8) + * \param key_area Area in Key RAM where the key is stored (0 to 7) + * \param nonce Pointer to nonce (15 - \p len_len octets) + * \param adata Pointer to additional authenticated data, or \c NULL + * \param adata_len Length of additional authenticated data in octets, or \c 0 + * \param cdata Pointer to encrypted and authenticated message + * \param cdata_len Length of encrypted and authenticated message in octets + * \param mic_len Number of octets in authentication field (even value between 0 and 16) + * \param process Process to be polled upon completion of the operation, or \c NULL + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code + */ +uint8_t ccm_auth_decrypt_start(uint8_t len_len, uint8_t key_area, + const void *nonce, const void *adata, + uint16_t adata_len, void *cdata, + uint16_t cdata_len, uint8_t mic_len, + struct process *process); + +/** \brief Checks the status of the CCM authentication checking and decryption operation + * \retval false Result not yet available, and no error occurred + * \retval true Result available, or error occurred + */ +uint8_t ccm_auth_decrypt_check_status(void); + +/** \brief Gets the result of the CCM authentication checking and decryption operation + * \param cdata Pointer to encrypted and authenticated message + * \param cdata_len Length of encrypted and authenticated message in octets + * \param mic Pointer to authentication field, or \c NULL + * \param mic_len Number of octets in authentication field (even value between 0 and 16) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES/CCM error code + * \note This function must be called only after \c ccm_auth_decrypt_start(). + */ +uint8_t ccm_auth_decrypt_get_result(const void *cdata, uint16_t cdata_len, + void *mic, uint8_t mic_len); + +/** @} */ + +#endif /* CCM_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/crypto.c b/cpu/cc2538/dev/crypto.c new file mode 100644 index 000000000..7dc5d3342 --- /dev/null +++ b/cpu/cc2538/dev/crypto.c @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538-crypto + * @{ + * + * \file + * Implementation of the cc2538 AES/SHA cryptoprocessor driver + */ +#include "contiki.h" +#include "sys/energest.h" +#include "dev/sys-ctrl.h" +#include "dev/nvic.h" +#include "dev/crypto.h" +#include "dev/aes.h" +#include "reg.h" +#include "lpm.h" + +#include +/*---------------------------------------------------------------------------*/ +static volatile struct process *notification_process = NULL; +/*---------------------------------------------------------------------------*/ +/** \brief The AES/SHA cryptoprocessor ISR + * + * This is the interrupt service routine for the AES/SHA + * cryptoprocessor. + * + * This ISR is called at worst from PM0, so lpm_exit() does not need + * to be called. + */ +void +crypto_isr(void) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + nvic_interrupt_unpend(NVIC_INT_AES); + nvic_interrupt_disable(NVIC_INT_AES); + + if(notification_process != NULL) { + process_poll((struct process *)notification_process); + notification_process = NULL; + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +static bool +permit_pm1(void) +{ + return REG(AES_CTRL_ALG_SEL) == 0; +} +/*---------------------------------------------------------------------------*/ +void +crypto_init(void) +{ + volatile int i; + + lpm_register_peripheral(permit_pm1); + + crypto_enable(); + + /* Reset the AES/SHA cryptoprocessor */ + REG(SYS_CTRL_SRSEC) |= SYS_CTRL_SRSEC_AES; + for(i = 0; i < 16; i++); + REG(SYS_CTRL_SRSEC) &= ~SYS_CTRL_SRSEC_AES; +} +/*---------------------------------------------------------------------------*/ +void +crypto_enable(void) +{ + /* Enable the clock for the AES/SHA cryptoprocessor */ + REG(SYS_CTRL_RCGCSEC) |= SYS_CTRL_RCGCSEC_AES; + REG(SYS_CTRL_SCGCSEC) |= SYS_CTRL_SCGCSEC_AES; + REG(SYS_CTRL_DCGCSEC) |= SYS_CTRL_DCGCSEC_AES; +} +/*---------------------------------------------------------------------------*/ +void +crypto_disable(void) +{ + /* Gate the clock for the AES/SHA cryptoprocessor */ + REG(SYS_CTRL_RCGCSEC) &= ~SYS_CTRL_RCGCSEC_AES; + REG(SYS_CTRL_SCGCSEC) &= ~SYS_CTRL_SCGCSEC_AES; + REG(SYS_CTRL_DCGCSEC) &= ~SYS_CTRL_DCGCSEC_AES; +} +/*---------------------------------------------------------------------------*/ +void +crypto_register_process_notification(struct process *p) +{ + notification_process = p; +} + +/** @} */ diff --git a/cpu/cc2538/dev/crypto.h b/cpu/cc2538/dev/crypto.h new file mode 100644 index 000000000..ad06ef343 --- /dev/null +++ b/cpu/cc2538/dev/crypto.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538 + * @{ + * + * \defgroup cc2538-crypto cc2538 AES/SHA cryptoprocessor + * + * Driver for the cc2538 AES/SHA cryptoprocessor + * @{ + * + * \file + * Header file for the cc2538 AES/SHA cryptoprocessor driver + */ +#ifndef CRYPTO_H_ +#define CRYPTO_H_ + +#include "contiki.h" +/*---------------------------------------------------------------------------*/ +/** \name Crypto drivers return codes + * @{ + */ +#define CRYPTO_SUCCESS 0 +#define CRYPTO_INVALID_PARAM 1 +#define CRYPTO_NULL_ERROR 2 +#define CRYPTO_RESOURCE_IN_USE 3 +#define CRYPTO_DMA_BUS_ERROR 4 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Crypto functions + * @{ + */ + +/** \brief Enables and resets the AES/SHA cryptoprocessor + */ +void crypto_init(void); + +/** \brief Enables the AES/SHA cryptoprocessor + */ +void crypto_enable(void); + +/** \brief Disables the AES/SHA cryptoprocessor + * \note Call this function to save power when the cryptoprocessor is unused. + */ +void crypto_disable(void); + +/** \brief Registers a process to be notified of the completion of a crypto + * operation + * \param p Process to be polled upon IRQ + * \note This function is only supposed to be called by the crypto drivers. + */ +void crypto_register_process_notification(struct process *p); + +/** @} */ + +#endif /* CRYPTO_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/sha256.c b/cpu/cc2538/dev/sha256.c new file mode 100644 index 000000000..347c54081 --- /dev/null +++ b/cpu/cc2538/dev/sha256.c @@ -0,0 +1,356 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538-sha256 + * @{ + * + * \file + * Implementation of the cc2538 SHA-256 driver + */ +#include "contiki.h" +#include "sys/cc.h" +#include "dev/rom-util.h" +#include "dev/aes.h" +#include "dev/sha256.h" +#include "reg.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define BLOCK_SIZE 64 +#define OUTPUT_LEN 32 +/*---------------------------------------------------------------------------*/ +/** \brief Starts a new hash session in hardware + * \param state Hash state + * \param data Pointer to input message + * \param hash Destination of the hash (32 bytes) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + */ +static uint8_t +new_hash(sha256_state_t *state, const void *data, void *hash) +{ + /* Workaround for AES registers not retained after PM2 */ + REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV; + + /* Configure master control module and enable DMA path to the SHA-256 engine + * + Digest readout */ + REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_TAG | AES_CTRL_ALG_SEL_HASH; + + /* Clear any outstanding events */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV; + + /* Configure hash engine + * Indicate start of a new hash session and SHA-256 */ + REG(AES_HASH_MODE_IN) = AES_HASH_MODE_IN_SHA256_MODE | + AES_HASH_MODE_IN_NEW_HASH; + + /* If the final digest is required (pad the input DMA data), write the + * following register */ + if(state->final_digest) { + /* Write length of the message (lo) */ + REG(AES_HASH_LENGTH_IN_L) = (uint32_t)state->length; + /* Write length of the message (hi) */ + REG(AES_HASH_LENGTH_IN_H) = (uint32_t)(state->length >> 32); + /* Pad the DMA-ed data */ + REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE; + } + + /* Enable DMA channel 0 for message data */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the data in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data; + if(state->final_digest) { + /* Input data length in bytes, equal to the message */ + REG(AES_DMAC_CH0_DMALENGTH) = state->curlen; + } else { + REG(AES_DMAC_CH0_DMALENGTH) = BLOCK_SIZE; + } + + /* Enable DMA channel 1 for result digest */ + REG(AES_DMAC_CH1_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the digest buffer */ + REG(AES_DMAC_CH1_EXTADDR) = (uint32_t)hash; + /* Length of the result digest */ + REG(AES_DMAC_CH1_DMALENGTH) = OUTPUT_LEN; + + /* Wait for completion of the operation */ + while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)); + + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + /* Clear the DMA error */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return CRYPTO_DMA_BUS_ERROR; + } + + /* Clear the interrupt */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + /* Clear mode */ + REG(AES_AES_CTRL) = 0x00000000; + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +/** \brief Resumes an already started hash session in hardware + * \param state Hash state + * \param data Pointer to the input message + * \param hash Pointer to the destination of the hash (32 bytes) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + */ +static uint8_t +resume_hash(sha256_state_t *state, const void *data, void *hash) +{ + /* Workaround for AES registers not retained after PM2 */ + REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL; + REG(AES_CTRL_INT_EN) = AES_CTRL_INT_EN_DMA_IN_DONE | + AES_CTRL_INT_EN_RESULT_AV; + + /* Configure master control module and enable the DMA path to the SHA-256 + * engine */ + REG(AES_CTRL_ALG_SEL) = AES_CTRL_ALG_SEL_HASH; + + /* Clear any outstanding events */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_RESULT_AV; + + /* Configure hash engine + * Indicate the start of a resumed hash session and SHA-256 */ + REG(AES_HASH_MODE_IN) = AES_HASH_MODE_IN_SHA256_MODE; + + /* If the final digest is required (pad the input DMA data) */ + if(state->final_digest) { + /* Write length of the message (lo) */ + REG(AES_HASH_LENGTH_IN_L) = (uint32_t)state->length; + /* Write length of the message (hi) */ + REG(AES_HASH_LENGTH_IN_H) = (uint32_t)(state->length >> 32); + } + + /* Write the initial digest */ + REG(AES_HASH_DIGEST_A) = (uint32_t)state->state[0]; + REG(AES_HASH_DIGEST_B) = (uint32_t)state->state[1]; + REG(AES_HASH_DIGEST_C) = (uint32_t)state->state[2]; + REG(AES_HASH_DIGEST_D) = (uint32_t)state->state[3]; + REG(AES_HASH_DIGEST_E) = (uint32_t)state->state[4]; + REG(AES_HASH_DIGEST_F) = (uint32_t)state->state[5]; + REG(AES_HASH_DIGEST_G) = (uint32_t)state->state[6]; + REG(AES_HASH_DIGEST_H) = (uint32_t)state->state[7]; + + /* If final digest, pad the DMA-ed data */ + if(state->final_digest) { + REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_PAD_DMA_MESSAGE; + } + + /* Enable DMA channel 0 for message data */ + REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN; + /* Base address of the data in ext. memory */ + REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)data; + /* Input data length in bytes, equal to the message */ + if(state->final_digest) { + REG(AES_DMAC_CH0_DMALENGTH) = state->curlen; + } else { + REG(AES_DMAC_CH0_DMALENGTH) = BLOCK_SIZE; + } + + /* Wait for completion of the operation */ + while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV)); + + /* Check for any DMA Bus errors */ + if(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_DMA_BUS_ERR) { + /* Clear the DMA error */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_BUS_ERR; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + return CRYPTO_DMA_BUS_ERROR; + } + + /* Read digest */ + ((uint32_t *)hash)[0] = REG(AES_HASH_DIGEST_A); + ((uint32_t *)hash)[1] = REG(AES_HASH_DIGEST_B); + ((uint32_t *)hash)[2] = REG(AES_HASH_DIGEST_C); + ((uint32_t *)hash)[3] = REG(AES_HASH_DIGEST_D); + ((uint32_t *)hash)[4] = REG(AES_HASH_DIGEST_E); + ((uint32_t *)hash)[5] = REG(AES_HASH_DIGEST_F); + ((uint32_t *)hash)[6] = REG(AES_HASH_DIGEST_G); + ((uint32_t *)hash)[7] = REG(AES_HASH_DIGEST_H); + + /* Acknowledge reading of the digest */ + REG(AES_HASH_IO_BUF_CTRL) = AES_HASH_IO_BUF_CTRL_OUTPUT_FULL; + + /* Clear the interrupt */ + REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE | + AES_CTRL_INT_CLR_RESULT_AV; + /* Disable master control / DMA clock */ + REG(AES_CTRL_ALG_SEL) = 0x00000000; + /* Clear mode */ + REG(AES_AES_CTRL) = 0x00000000; + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +sha256_init(sha256_state_t *state) +{ + if(state == NULL) { + return CRYPTO_NULL_ERROR; + } + + state->curlen = 0; + state->length = 0; + state->new_digest = true; + state->final_digest = false; + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +sha256_process(sha256_state_t *state, const void *data, uint32_t len) +{ + uint32_t n; + uint8_t ret; + + if(state == NULL || data == NULL) { + return CRYPTO_NULL_ERROR; + } + + if(state->curlen > sizeof(state->buf)) { + return CRYPTO_INVALID_PARAM; + } + + if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { + return CRYPTO_RESOURCE_IN_USE; + } + + if(len > 0 && state->new_digest) { + if(state->curlen == 0 && len > BLOCK_SIZE) { + rom_util_memcpy(state->buf, data, BLOCK_SIZE); + ret = new_hash(state, state->buf, state->state); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + state->new_digest = false; + state->length += BLOCK_SIZE << 3; + data += BLOCK_SIZE; + len -= BLOCK_SIZE; + } else { + n = MIN(len, BLOCK_SIZE - state->curlen); + rom_util_memcpy(&state->buf[state->curlen], data, n); + state->curlen += n; + data += n; + len -= n; + if(state->curlen == BLOCK_SIZE && len > 0) { + ret = new_hash(state, state->buf, state->state); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + state->new_digest = false; + state->length += BLOCK_SIZE << 3; + state->curlen = 0; + } + } + } + + while(len > 0 && !state->new_digest) { + if(state->curlen == 0 && len > BLOCK_SIZE) { + rom_util_memcpy(state->buf, data, BLOCK_SIZE); + ret = resume_hash(state, state->buf, state->state); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + state->length += BLOCK_SIZE << 3; + data += BLOCK_SIZE; + len -= BLOCK_SIZE; + } else { + n = MIN(len, BLOCK_SIZE - state->curlen); + rom_util_memcpy(&state->buf[state->curlen], data, n); + state->curlen += n; + data += n; + len -= n; + if(state->curlen == BLOCK_SIZE && len > 0) { + ret = resume_hash(state, state->buf, state->state); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + state->length += BLOCK_SIZE << 3; + state->curlen = 0; + } + } + } + + return CRYPTO_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +uint8_t +sha256_done(sha256_state_t *state, void *hash) +{ + uint8_t ret; + + if(state == NULL || hash == NULL) { + return CRYPTO_NULL_ERROR; + } + + if(state->curlen > sizeof(state->buf)) { + return CRYPTO_INVALID_PARAM; + } + + if(REG(AES_CTRL_ALG_SEL) != 0x00000000) { + return CRYPTO_RESOURCE_IN_USE; + } + + /* Increase the length of the message */ + state->length += state->curlen << 3; + state->final_digest = true; + if(state->new_digest) { + ret = new_hash(state, state->buf, hash); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + } else { + ret = resume_hash(state, state->buf, hash); + if(ret != CRYPTO_SUCCESS) { + return ret; + } + } + state->new_digest = false; + state->final_digest = false; + + return CRYPTO_SUCCESS; +} + +/** @} */ diff --git a/cpu/cc2538/dev/sha256.h b/cpu/cc2538/dev/sha256.h new file mode 100644 index 000000000..b2e799bd8 --- /dev/null +++ b/cpu/cc2538/dev/sha256.h @@ -0,0 +1,103 @@ +/* + * Original file: + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538-crypto + * @{ + * + * \defgroup cc2538-sha526 cc2538 SHA-256 + * + * Driver for the cc2538 SHA-256 mode of the security core + * @{ + * + * \file + * Header file for the cc2538 SHA-256 driver + */ +#ifndef SHA256_H_ +#define SHA256_H_ + +#include "contiki.h" +#include "dev/crypto.h" + +#include +/*---------------------------------------------------------------------------*/ +/** \name SHA-256 structures + * @{ + */ +typedef struct { + uint64_t length; + uint32_t state[8]; + uint32_t curlen; + uint8_t buf[64]; + uint8_t new_digest; + uint8_t final_digest; +} sha256_state_t; +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name SHA-256 functions + * @{ + */ + +/** \brief Initializes the hash state + * \param state Pointer to hash state to initialize + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + */ +uint8_t sha256_init(sha256_state_t *state); + +/** \brief Processes a block of memory through the hash + * \param state Pointer to hash state + * \param data Pointer to the data to hash + * \param len Length of the data to hash in bytes (octets) + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + * \note This function must be called only after \c sha256_init(). + */ +uint8_t sha256_process(sha256_state_t *state, const void *data, uint32_t len); + +/** \brief Terminates hash session to get the digest + * \param state Pointer to hash state + * \param hash Pointer to hash + * \return \c CRYPTO_SUCCESS if successful, or CRYPTO/SHA256 error code + * \note This function must be called only after \c sha256_process(). + */ +uint8_t sha256_done(sha256_state_t *state, void *hash); + +/** @} */ + +#endif /* SHA256_H_ */ + +/** + * @} + * @} + */ diff --git a/cpu/cc2538/dev/sys-ctrl.h b/cpu/cc2538/dev/sys-ctrl.h index a8b61932e..3fda071fe 100644 --- a/cpu/cc2538/dev/sys-ctrl.h +++ b/cpu/cc2538/dev/sys-ctrl.h @@ -161,6 +161,34 @@ #define SYS_CTRL_SRGPT_GPT0 0x00000001 /**< GPT0 is reset */ /** @} */ /*---------------------------------------------------------------------------*/ +/** \name SYS_CTRL_RCGCSEC register bit masks + * @{ + */ +#define SYS_CTRL_RCGCSEC_AES 0x00000002 /**< AES clock enable, CPU running */ +#define SYS_CTRL_RCGCSEC_PKA 0x00000001 /**< PKA clock enable, CPU running */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name SYS_CTRL_SCGCSEC register bit masks + * @{ + */ +#define SYS_CTRL_SCGCSEC_AES 0x00000002 /**< AES clock enable, CPU IDLE */ +#define SYS_CTRL_SCGCSEC_PKA 0x00000001 /**< PKA clock enable, CPU IDLE */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name SYS_CTRL_DCGCSEC register bit masks + * @{ + */ +#define SYS_CTRL_DCGCSEC_AES 0x00000002 /**< AES clock enable, PM0 */ +#define SYS_CTRL_DCGCSEC_PKA 0x00000001 /**< PKA clock enable, PM0 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name SYS_CTRL_SRSEC register bits + * @{ + */ +#define SYS_CTRL_SRSEC_AES 0x00000002 /**< AES is reset */ +#define SYS_CTRL_SRSEC_PKA 0x00000001 /**< PKA is reset */ +/** @} */ +/*---------------------------------------------------------------------------*/ /** \name SYS_CTRL_PWRDBG register bits * @{ */ diff --git a/cpu/cc2538/dev/uart.c b/cpu/cc2538/dev/uart.c index fbcc3c56c..cefbecf82 100644 --- a/cpu/cc2538/dev/uart.c +++ b/cpu/cc2538/dev/uart.c @@ -359,7 +359,7 @@ uart_write_byte(uint8_t uart, uint8_t b) REG(uart_base + UART_DR) = b; } /*---------------------------------------------------------------------------*/ -void +static void uart_isr(uint8_t uart) { uint32_t uart_base; diff --git a/cpu/cc2538/dev/watchdog.c b/cpu/cc2538/dev/watchdog.c index e67015943..9f306e586 100644 --- a/cpu/cc2538/dev/watchdog.c +++ b/cpu/cc2538/dev/watchdog.c @@ -88,15 +88,6 @@ watchdog_periodic(void) REG(SMWDTHROSC_WDCTL) = (SMWDTHROSC_WDCTL_CLR_2 | SMWDTHROSC_WDCTL_CLR_0); } /*---------------------------------------------------------------------------*/ -/** \brief In watchdog mode, the WDT can not be stopped. This function is - * defined here to satisfy API requirements. - */ -void -watchdog_stop(void) -{ - return; -} -/*---------------------------------------------------------------------------*/ /** \brief Keeps control until the WDT throws a reset signal. Starts the WDT * if not already started. */ void diff --git a/cpu/cc2538/lpm.c b/cpu/cc2538/lpm.c index abe75c02e..91d67acc9 100644 --- a/cpu/cc2538/lpm.c +++ b/cpu/cc2538/lpm.c @@ -101,7 +101,7 @@ static uint8_t max_pm; #ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #else -#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 2 +#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 3 #endif static lpm_periph_permit_pm1_func_t diff --git a/cpu/cc2538/startup-gcc.c b/cpu/cc2538/startup-gcc.c index 99a624a7d..2aa82894e 100644 --- a/cpu/cc2538/startup-gcc.c +++ b/cpu/cc2538/startup-gcc.c @@ -40,6 +40,7 @@ #include "reg.h" #include "flash-cca.h" #include "sys-ctrl.h" +#include "rom-util.h" #include /*---------------------------------------------------------------------------*/ @@ -66,6 +67,7 @@ void udma_err_isr(void); void usb_isr(void) WEAK_ALIAS(default_handler); void uart0_isr(void) WEAK_ALIAS(default_handler); void uart1_isr(void) WEAK_ALIAS(default_handler); +void crypto_isr(void); /* Boot Loader Backdoor selection */ #if FLASH_CCA_CONF_BOOTLDR_BACKDOOR @@ -89,7 +91,7 @@ void uart1_isr(void) WEAK_ALIAS(default_handler); #endif /*---------------------------------------------------------------------------*/ /* Allocate stack space */ -static unsigned long stack[512]; +static unsigned long stack[512] __attribute__ ((section(".stack"))); /*---------------------------------------------------------------------------*/ /* Linker construct indicating .text section location */ extern uint8_t _text[0]; @@ -268,18 +270,18 @@ void(*const vectors[])(void) = usb_isr, /* 156 USB */ cc2538_rf_rx_tx_isr, /* 157 RFCORE RX/TX */ cc2538_rf_err_isr, /* 158 RFCORE Error */ - default_handler, /* 159 AES */ + crypto_isr, /* 159 AES */ default_handler, /* 160 PKA */ rtimer_isr, /* 161 SM Timer */ default_handler, /* 162 MACTimer */ }; /*---------------------------------------------------------------------------*/ /* Linker constructs indicating .data and .bss segment locations */ -extern unsigned long _etext; -extern unsigned long _data; -extern unsigned long _edata; -extern unsigned long _bss; -extern unsigned long _ebss; +extern uint8_t _ldata; +extern uint8_t _data; +extern uint8_t _edata; +extern uint8_t _bss; +extern uint8_t _ebss; /*---------------------------------------------------------------------------*/ /* Weak interrupt handlers. */ void @@ -298,26 +300,13 @@ default_handler(void) void reset_handler(void) { - unsigned long *pul_src, *pul_dst; - REG(SYS_CTRL_EMUOVR) = 0xFF; /* Copy the data segment initializers from flash to SRAM. */ - pul_src = &_etext; - - for(pul_dst = &_data; pul_dst < &_edata;) { - *pul_dst++ = *pul_src++; - } + rom_util_memcpy(&_data, &_ldata, &_edata - &_data); /* Zero-fill the bss segment. */ - __asm(" ldr r0, =_bss\n" - " ldr r1, =_ebss\n" - " mov r2, #0\n" - " .thumb_func\n" - "zero_loop:\n" - " cmp r0, r1\n" - " it lt\n" - " strlt r2, [r0], #4\n" " blt zero_loop"); + rom_util_memset(&_bss, 0, &_ebss - &_bss); /* call the application's entry point. */ main(); diff --git a/cpu/cc2538/usb/usb-arch.c b/cpu/cc2538/usb/usb-arch.c index c209d7778..ed771ce83 100644 --- a/cpu/cc2538/usb/usb-arch.c +++ b/cpu/cc2538/usb/usb-arch.c @@ -872,7 +872,7 @@ fill_buffers(usb_buffer *buffer, uint8_t hw_ep, unsigned int len, static uint8_t ep0_get_setup_pkt(void) { - uint8_t res; + uint8_t res = 0; usb_buffer *buffer = skip_buffers_until(usb_endpoints[0].buffer, USB_BUFFER_SETUP, USB_BUFFER_SETUP, &res); @@ -916,8 +916,6 @@ ep0_get_data_pkt(void) } if(buffer->flags & (USB_BUFFER_SETUP | USB_BUFFER_IN)) { - uint8_t temp; - buffer->flags |= USB_BUFFER_FAILED; buffer->flags &= ~USB_BUFFER_SUBMITTED; if(buffer->flags & USB_BUFFER_NOTIFY) { @@ -925,7 +923,7 @@ ep0_get_data_pkt(void) } /* Flush the fifo */ while(len--) { - temp = REG(USB_F0); + REG(USB_F0); } usb_endpoints[0].buffer = buffer->next; /* Force data stage end */ diff --git a/cpu/cc253x/8051def.h b/cpu/cc253x/8051def.h index 03dfc810e..eb794e754 100644 --- a/cpu/cc253x/8051def.h +++ b/cpu/cc253x/8051def.h @@ -14,11 +14,6 @@ #include -/* In watchdog mode, our WDT can't be stopped once started - * Include watchdog_stop()'s declaration and then trash it */ -#include "dev/watchdog.h" -#define watchdog_stop() watchdog_periodic() - /* This port no longer implements the legacy clock_delay. Hack its usages * outta the way till it gets phased out completely * NB: This also overwrites the prototype so delay_usec() is declared twice */ 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 34e8d492a..000000000 --- a/cpu/cc26xx/dev/cc26xx-rf.c +++ /dev/null @@ -1,2147 +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, 0) | - 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, 0) | - BITVALUE(CMD_IEEE_RX, ccaOpt, ccaEnSync, 0) | - BITVALUE(CMD_IEEE_RX, ccaOpt, ccaCorrOp, 0) | - BITVALUE(CMD_IEEE_RX, ccaOpt, ccaSyncOp, 0); - /* 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/stm32w108/hal/error-def.h b/cpu/stm32w108/hal/error-def.h index 908b60ae5..a3a38ed21 100644 --- a/cpu/stm32w108/hal/error-def.h +++ b/cpu/stm32w108/hal/error-def.h @@ -363,9 +363,9 @@ DEFINE_ERROR(MAC_INDIRECT_TIMEOUT, 0x42) /** * @brief The Simulated EEPROM is telling the application that there * is at least one flash page to be erased. The GREEN status means the - * current page has not filled above the ::ERASE_CRITICAL_THRESHOLD. + * current page has not filled above the ERASE_CRITICAL_THRESHOLD. * - * The application should call the function ::halSimEepromErasePage() when it can + * The application should call the function halSimEepromErasePage() when it can * to erase a page. */ #define ST_SIM_EEPROM_ERASE_PAGE_GREEN(0x43) @@ -378,10 +378,10 @@ DEFINE_ERROR(SIM_EEPROM_ERASE_PAGE_GREEN, 0x43) /** * @brief The Simulated EEPROM is telling the application that there * is at least one flash page to be erased. The RED status means the - * current page has filled above the ::ERASE_CRITICAL_THRESHOLD. + * current page has filled above the ERASE_CRITICAL_THRESHOLD. * * Due to the shrinking availablity of write space, there is a danger of - * data loss. The application must call the function ::halSimEepromErasePage() + * data loss. The application must call the function halSimEepromErasePage() * as soon as possible to erase a page. */ #define ST_SIM_EEPROM_ERASE_PAGE_RED(0x44) @@ -394,9 +394,9 @@ DEFINE_ERROR(SIM_EEPROM_ERASE_PAGE_RED, 0x44) /** * @brief The Simulated EEPROM has run out of room to write any new data * and the data trying to be set has been lost. This error code is the - * result of ignoring the ::SIM_EEPROM_ERASE_PAGE_RED error code. + * result of ignoring the ::ST_SIM_EEPROM_ERASE_PAGE_RED error code. * - * The application must call the function ::halSimEepromErasePage() to make room for + * The application must call the function halSimEepromErasePage() to make room for * any further calls to set a token. */ #define ST_SIM_EEPROM_FULL(0x45) @@ -440,8 +440,8 @@ DEFINE_ERROR(SIM_EEPROM_INIT_2_FAILED, 0x49) /** * @brief Attempt 3 to initialize the Simulated EEPROM has failed. * - * This failure means one or both of the tokens ::TOKEN_MFG_NVDATA_VERSION or - * ::TOKEN_STACK_NVDATA_VERSION were incorrect and the token system failed to + * This failure means one or both of the tokens TOKEN_MFG_NVDATA_VERSION or + * TOKEN_STACK_NVDATA_VERSION were incorrect and the token system failed to * properly reload default tokens and reset the Simulated EEPROM. */ #define ST_SIM_EEPROM_INIT_3_FAILED(0x4A) @@ -486,7 +486,7 @@ DEFINE_ERROR(ERR_FLASH_VERIFY_FAILED, 0x47) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** - * @description A fatal error has occured while trying to write data to the + * @brief A fatal error has occured while trying to write data to the * flash, possibly due to write protection or an invalid address. The data in * the flash cannot be trusted after this error, and it is possible this error * is the result of exceeding the life cycles of the flash. @@ -499,7 +499,7 @@ DEFINE_ERROR(ERR_FLASH_PROG_FAIL, 0x4B) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** - * @description A fatal error has occured while trying to erase flash, possibly + * @brief A fatal error has occured while trying to erase flash, possibly * due to write protection. The data in the flash cannot be trusted after * this error, and it is possible this error is the result of exceeding the * life cycles of the flash. @@ -626,7 +626,7 @@ DEFINE_ERROR(COST_NOT_KNOWN, 0x71) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** * @brief The maximum number of in-flight messages (i.e. - * ::ST_APS_UNICAST_MESSAGE_COUNT) has been reached. + * ST_APS_UNICAST_MESSAGE_COUNT) has been reached. */ #define ST_MAX_MESSAGE_LIMIT_REACHED(0x72) #else @@ -820,7 +820,7 @@ DEFINE_ERROR(PHY_ACK_RECEIVED, 0x8F) /** * @name Return Codes Passed to stStackStatusHandler() - * See also ::stStackStatusHandler(). + * See also stStackStatusHandler(). * * @{ */ @@ -882,7 +882,7 @@ DEFINE_ERROR(CANNOT_JOIN_AS_ROUTER, 0x98) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief The local node ID has changed. The application can obtain the new - * node ID by calling ::stGetNodeId(). + * node ID by calling stGetNodeId(). */ #define ST_NODE_ID_CHANGED(0x99) #else @@ -892,7 +892,7 @@ DEFINE_ERROR(NODE_ID_CHANGED, 0x99) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief The local PAN ID has changed. The application can obtain the new PAN - * ID by calling ::stGetPanId(). + * ID by calling stGetPanId(). */ #define ST_PAN_ID_CHANGED(0x9A) #else @@ -920,7 +920,7 @@ DEFINE_ERROR(NO_BEACONS, 0xAB) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief An attempt was made to join a Secured Network using a pre-configured * key, but the Trust Center sent back a Network Key in-the-clear when - * an encrypted Network Key was required. (::ST_REQUIRE_ENCRYPTED_KEY). + * an encrypted Network Key was required. (ST_REQUIRE_ENCRYPTED_KEY). */ #define ST_RECEIVED_KEY_IN_THE_CLEAR(0xAC) #else @@ -940,7 +940,7 @@ DEFINE_ERROR(NO_NETWORK_KEY_RECEIVED, 0xAD) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief After a device joined a Secured Network, a Link Key was requested - * (::ST_GET_LINK_KEY_WHEN_JOINING) but no response was ever received. + * (ST_GET_LINK_KEY_WHEN_JOINING) but no response was ever received. */ #define ST_NO_LINK_KEY_RECEIVED(0xAE) #else @@ -978,7 +978,7 @@ DEFINE_ERROR(KEY_INVALID, 0xB2) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** - * @brief The chosen security level (the value of ::ST_SECURITY_LEVEL) + * @brief The chosen security level (the value of ST_SECURITY_LEVEL) * is not supported by the stack. */ #define ST_INVALID_SECURITY_LEVEL(0x95) @@ -1011,7 +1011,7 @@ DEFINE_ERROR(INVALID_SECURITY_LEVEL, 0x95) #ifdef DOXYGEN_SHOULD_SKIP_THIS /** @brief There was an attempt to form or join a network with security - * without calling ::stSetInitialSecurityState() first. + * without calling stSetInitialSecurityState() first. */ #define ST_SECURITY_STATE_NOT_SET(0xA8) #else @@ -1274,7 +1274,9 @@ DEFINE_ERROR( APPLICATION_ERROR_14, 0xFE) DEFINE_ERROR( APPLICATION_ERROR_15, 0xFF) #endif //DOXYGEN_SHOULD_SKIP_THIS -/** @} */ // END name group +/** @} */ + +/** @} END defgroup */ /** @} END addtogroup */ diff --git a/cpu/stm32w108/hal/micro/cortexm3/compiler/gnu.h b/cpu/stm32w108/hal/micro/cortexm3/compiler/gnu.h index 7783c0f96..ccdfa6199 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/compiler/gnu.h +++ b/cpu/stm32w108/hal/micro/cortexm3/compiler/gnu.h @@ -7,7 +7,7 @@ * @addtogroup stm32w-cpu * @{ */ -/** @defgroup gnu +/** @defgroup gnu GNU * @brief Compiler and Platform specific definitions and typedefs for the * GNU C ARM compiler. * diff --git a/cpu/stm32w108/hal/micro/cortexm3/compiler/iar.h b/cpu/stm32w108/hal/micro/cortexm3/compiler/iar.h index c4492dd61..a057d48ca 100644 --- a/cpu/stm32w108/hal/micro/cortexm3/compiler/iar.h +++ b/cpu/stm32w108/hal/micro/cortexm3/compiler/iar.h @@ -8,7 +8,7 @@ * @addtogroup stm32w-cpu * @{ */ -/** @defgroup iar +/** @defgroup iar IAR * @brief Compiler and Platform specific definitions and typedefs for the * IAR ARM C compiler. * diff --git a/cpu/stm32w108/hal/micro/micro-common.h b/cpu/stm32w108/hal/micro/micro-common.h index db12908bf..9cba68903 100644 --- a/cpu/stm32w108/hal/micro/micro-common.h +++ b/cpu/stm32w108/hal/micro/micro-common.h @@ -9,7 +9,7 @@ * @addtogroup stm32w-cpu * @{ */ -/** @defgroup micro +/** @defgroup micro Micro * Many of the supplied example applications use these microcontroller functions. * See hal/micro/micro-common.h for source code. * 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 a9c714d73..e0b0d232e 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/* # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the @@ -1918,14 +1919,14 @@ MACRO_EXPANSION = YES # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -EXPAND_ONLY_PREDEF = NO +EXPAND_ONLY_PREDEF = YES # If the SEARCH_INCLUDES tag is set to YES the includes files in the # INCLUDE_PATH will be searched if a #include is found. # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -SEARCH_INCLUDES = YES +SEARCH_INCLUDES = NO # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the @@ -1950,17 +1951,23 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = CC_FUNCTION_POINTER_ARGS \ - NETSTACK_CONF_WITH_RIME \ - NETSTACK_CONF_WITH_IPV4 \ - NETSTACK_CONF_WITH_IPV6 \ - UIP_CONF_IPV6_RPL \ - UIP_TCP \ - UIP_UDP \ - UIP_CONF_ICMP6 \ - WITH_LOADER_ARCH \ - DOXYGEN \ - "ASCCMD(name, flags, args)=void CMD_ASCII(name)" +PREDEFINED = CC_FUNCTION_POINTER_ARGS:=1 \ + NETSTACK_CONF_WITH_RIME:=1 \ + NETSTACK_CONF_WITH_IPV4:=1 \ + NETSTACK_CONF_WITH_IPV6:=1 \ + UIP_CONF_IPV6_RPL:=1 \ + UIP_TCP:=1 \ + UIP_UDP:=1 \ + UIP_CONF_ICMP6:=1 \ + WITH_LOADER_ARCH:=1 \ + __attribute__(x):= \ + CC_ALIGN_ATTR(n):= \ + HTTPD_STRING_ATTR:= \ + PROGMEM:= \ + EEMEM:= \ + DOXYGEN:=1 \ + DOXYGEN_SHOULD_SKIP_THIS:=1 \ + "ASCCMD(name, flags, args):=void CMD_ASCII(name)" # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The 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/cc2538dk/crypto/Makefile b/examples/cc2538dk/crypto/Makefile new file mode 100644 index 000000000..513e37676 --- /dev/null +++ b/examples/cc2538dk/crypto/Makefile @@ -0,0 +1,6 @@ +CONTIKI_PROJECT = ccm-test sha256-test + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/cc2538dk/crypto/Makefile.target b/examples/cc2538dk/crypto/Makefile.target new file mode 100644 index 000000000..777593c88 --- /dev/null +++ b/examples/cc2538dk/crypto/Makefile.target @@ -0,0 +1 @@ +TARGET = cc2538dk diff --git a/examples/cc2538dk/crypto/ccm-test.c b/examples/cc2538dk/crypto/ccm-test.c new file mode 100644 index 000000000..64c4fcf18 --- /dev/null +++ b/examples/cc2538dk/crypto/ccm-test.c @@ -0,0 +1,733 @@ +/* + * Original file: + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538-examples + * @{ + * + * \defgroup cc2538-ccm-test cc2538dk AES-CCM Test Project + * + * AES-CCM access example for CC2538 on SmartRF06EB. + * + * This example shows how AES-CCM should be used. The example also verifies + * the AES-CCM functionality. + * + * @{ + * + * \file + * Example demonstrating AES-CCM on the cc2538dk platform + */ +#include "contiki.h" +#include "sys/rtimer.h" +#include "dev/rom-util.h" +#include "dev/ccm.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +PROCESS(ccm_test_process, "ccm test process"); +AUTOSTART_PROCESSES(&ccm_test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(ccm_test_process, ev, data) +{ + static const char *const str_res[] = { + "success", + "invalid param", + "NULL error", + "resource in use", + "DMA bus error", + "keystore read error", + "keystore write error", + "authentication failed" + }; + static const uint8_t keys128[][16] = { + { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, + { 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf } + }; + static const uint8_t keys192[][24] = { + { 0x26, 0x51, 0x1f, 0xb5, 0x1f, 0xcf, 0xa7, 0x5c, + 0xb4, 0xb4, 0x4d, 0xa7, 0x5a, 0x6e, 0x5a, 0x0e, + 0xb8, 0xd9, 0xc8, 0xf3, 0xb9, 0x06, 0xf8, 0x86 }, + { 0x08, 0x6e, 0x29, 0x67, 0xcd, 0xe9, 0x9e, 0x90, + 0xfa, 0xae, 0xa8, 0xa9, 0x4e, 0x16, 0x8b, 0xf0, + 0xe0, 0x66, 0xc5, 0x03, 0xa8, 0x49, 0xa9, 0xf3 }, + { 0xce, 0xb0, 0x09, 0xae, 0xa4, 0x45, 0x44, 0x51, + 0xfe, 0xad, 0xf0, 0xe6, 0xb3, 0x6f, 0x45, 0x55, + 0x5d, 0xd0, 0x47, 0x23, 0xba, 0xa4, 0x48, 0xe8 }, + { 0x11, 0xfd, 0x45, 0x74, 0x3d, 0x94, 0x6e, 0x6d, + 0x37, 0x34, 0x1f, 0xec, 0x49, 0x94, 0x7e, 0x8c, + 0x70, 0x48, 0x24, 0x94, 0xa8, 0xf0, 0x7f, 0xcc } + }; + static const uint8_t keys256[][32] = { + { 0x26, 0x51, 0x1f, 0xb5, 0x1f, 0xcf, 0xa7, 0x5c, + 0xb4, 0xb4, 0x4d, 0xa7, 0x5a, 0x6e, 0x5a, 0x0e, + 0xb8, 0xd9, 0xc8, 0xf3, 0xb9, 0x06, 0xf8, 0x86, + 0xdf, 0x3b, 0xa3, 0xe6, 0xda, 0x3a, 0x13, 0x89 }, + { 0xc6, 0xc1, 0x4c, 0x65, 0x5e, 0x52, 0xc8, 0xa4, + 0xc7, 0xe8, 0xd5, 0x4e, 0x97, 0x4d, 0x69, 0x8e, + 0x1f, 0x21, 0xee, 0x3b, 0xa7, 0x17, 0xa0, 0xad, + 0xfa, 0x61, 0x36, 0xd0, 0x26, 0x68, 0xc4, 0x76 }, + { 0x55, 0x35, 0x21, 0xa7, 0x65, 0xab, 0x0c, 0x3f, + 0xd2, 0x03, 0x65, 0x4e, 0x99, 0x16, 0x33, 0x0e, + 0x18, 0x9b, 0xdf, 0x95, 0x1f, 0xee, 0xe9, 0xb4, + 0x4b, 0x10, 0xda, 0x20, 0x8f, 0xee, 0x7a, 0xcf }, + { 0x90, 0x74, 0xb1, 0xae, 0x4c, 0xa3, 0x34, 0x2f, + 0xe5, 0xbf, 0x6f, 0x14, 0xbc, 0xf2, 0xf2, 0x79, + 0x04, 0xf0, 0xb1, 0x51, 0x79, 0xd9, 0x5a, 0x65, + 0x4f, 0x61, 0xe6, 0x99, 0x69, 0x2e, 0x6f, 0x71 } + }; + static const struct { + const void *keys; + uint8_t key_size; + uint8_t count; + } keys[] = { + { keys128, AES_KEY_STORE_SIZE_KEY_SIZE_128, + sizeof(keys128) / sizeof(keys128[0]) }, + { keys192, AES_KEY_STORE_SIZE_KEY_SIZE_192, + sizeof(keys192) / sizeof(keys192[0]) }, + { keys256, AES_KEY_STORE_SIZE_KEY_SIZE_256, + sizeof(keys256) / sizeof(keys256[0]) } + }; + static struct { + bool encrypt; + uint8_t len_len; + uint8_t key_size_index; + uint8_t key_area; + uint8_t nonce[13]; + uint8_t adata[32]; + uint16_t adata_len; + uint8_t mdata[40]; + uint16_t mdata_len; + uint8_t mic[16]; + uint8_t mic_len; + uint8_t expected[40]; + } vectors[] = { + { + true, /* encrypt */ + 2, /* len_len */ + 0, /* key_size_index */ + 0, /* key_area */ + { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */ + {}, /* adata */ + 0, /* adata_len */ + { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, /* mdata */ + 20, /* mdata_len */ + {}, /* mic */ + 0, /* mic_len */ + { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, + 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, + 0x2c, 0x61, 0x01, 0x4e } /* expected */ + }, { + true, /* encrypt */ + 2, /* len_len */ + 0, /* key_size_index */ + 1, /* key_area */ + { 0xac, 0xde, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x05, 0x02 }, /* nonce */ + { 0x08, 0xd0, 0x84, 0x21, 0x43, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xde, 0xac, 0x02, 0x05, 0x00, + 0x00, 0x00, 0x55, 0xcf, 0x00, 0x00, 0x51, 0x52, + 0x53, 0x54 }, /* adata */ + 26, /* adata_len */ + {}, /* mdata */ + 0, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 8, /* mic_len */ + { 0x22, 0x3b, 0xc1, 0xec, 0x84, 0x1a, 0xb5, 0x53 } /* expected */ + }, { + true, /* encrypt */ + 2, /* len_len */ + 0, /* key_size_index */ + 0, /* key_area */ + { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */ + { 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03 }, /* adata */ + 15, /* adata_len */ + { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f }, /* mdata */ + 20, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 4, /* mic_len */ + { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, + 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, + 0x2c, 0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09 } /* expected */ + }, { + false, /* decrypt */ + 2, /* len_len */ + 0, /* key_size_index */ + 0, /* key_area */ + { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */ + {}, /* adata */ + 0, /* adata_len */ + { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, + 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, + 0x2c, 0x61, 0x01, 0x4e }, /* mdata */ + 20, /* mdata_len */ + {}, /* mic */ + 0, /* mic_len */ + { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f } /* expected */ + }, { + false, /* decrypt */ + 2, /* len_len */ + 0, /* key_size_index */ + 1, /* key_area */ + { 0xac, 0xde, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x00, 0x05, 0x02 }, /* nonce */ + { 0x08, 0xd0, 0x84, 0x21, 0x43, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x48, 0xde, 0xac, 0x02, 0x05, 0x00, + 0x00, 0x00, 0x55, 0xcf, 0x00, 0x00, 0x51, 0x52, + 0x53, 0x54 }, /* adata */ + 26, /* adata_len */ + { 0x22, 0x3b, 0xc1, 0xec, 0x84, 0x1a, 0xb5, 0x53 }, /* mdata */ + 8, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 8, /* mic_len */ + {} /* expected */ + }, { + false, /* decrypt */ + 2, /* len_len */ + 0, /* key_size_index */ + 0, /* key_area */ + { 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0, + 0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */ + { 0x69, 0x98, 0x03, 0x33, 0x63, 0xbb, 0xaa, 0x01, + 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x03 }, /* adata */ + 15, /* adata_len */ + { 0x92, 0xe8, 0xad, 0xca, 0x53, 0x81, 0xbf, 0xd0, + 0x5b, 0xdd, 0xf3, 0x61, 0x09, 0x09, 0x82, 0xe6, + 0x2c, 0x61, 0x01, 0x4e, 0x7b, 0x34, 0x4f, 0x09 }, /* mdata */ + 24, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 4, /* mic_len */ + { 0x14, 0xaa, 0xbb, 0x00, 0x00, 0x01, 0x02, 0x03, + 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f } /* expected */ + }, { + true, /* encrypt */ + 2, /* len_len */ + 1, /* key_size_index */ + 0, /* key_area */ + { 0x15, 0xb3, 0x69, 0x88, 0x96, 0x99, 0xb6, 0xde, + 0x1f, 0xa3, 0xee, 0x73, 0xe5 }, /* nonce */ + {}, /* adata */ + 0, /* adata_len */ + { 0x39, 0xf0, 0x8a, 0x2a, 0xf1, 0xd8, 0xda, 0x62, + 0x12, 0x55, 0x06, 0x39, 0xb9, 0x1f, 0xb2, 0x57, + 0x3e, 0x39, 0xa8, 0xeb, 0x5d, 0x80, 0x1d, 0xe8 }, /* mdata */ + 24, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0x63, 0x42, 0xb8, 0x70, 0x0e, 0xde, 0xc9, 0x7a, + 0x96, 0x0e, 0xb1, 0x6e, 0x7c, 0xb1, 0xeb, 0x44, + 0x12, 0xfb, 0x4e, 0x26, 0x3d, 0xdd, 0x22, 0x06, + 0xb0, 0x90, 0x15, 0x5d, 0x34, 0xa7, 0x6c, 0x83, + 0x24, 0xe5, 0x55, 0x0c, 0x3e, 0xf4, 0x26, 0xed } /* expected */ + }, { + true, /* encrypt */ + 2, /* len_len */ + 1, /* key_size_index */ + 2, /* key_area */ + { 0x92, 0x95, 0x42, 0xcd, 0x69, 0x0f, 0x1b, 0xab, + 0xcf, 0x16, 0x96, 0xcb, 0x03 }, /* nonce */ + { 0x58, 0xf7, 0x0b, 0xab, 0x24, 0xe0, 0xa6, 0x13, + 0x7e, 0x5c, 0xd3, 0xeb, 0x18, 0x65, 0x6f, 0x2b, + 0x5c, 0xcd, 0xdc, 0x3f, 0x53, 0x8a, 0x00, 0x00, + 0xc6, 0x51, 0x90, 0xe4, 0xa3, 0x66, 0x8e, 0x71 }, /* adata */ + 32, /* adata_len */ + {}, /* mdata */ + 0, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0x3b, 0xf9, 0xd9, 0x3a, 0xf6, 0xff, 0xac, 0x9a, + 0xc8, 0x4c, 0xd3, 0x20, 0x2d, 0x4e, 0x0c, 0xc8 } /* expected */ + }, { + true, /* encrypt */ + 8, /* len_len */ + 1, /* key_size_index */ + 4, /* key_area */ + { 0x76, 0x40, 0x43, 0xc4, 0x94, 0x60, 0xb7 }, /* nonce */ + { 0x6e, 0x80, 0xdd, 0x7f, 0x1b, 0xad, 0xf3, 0xa1, + 0xc9, 0xab, 0x25, 0xc7, 0x5f, 0x10, 0xbd, 0xe7, + 0x8c, 0x23, 0xfa, 0x0e, 0xb8, 0xf9, 0xaa, 0xa5, + 0x3a, 0xde, 0xfb, 0xf4, 0xcb, 0xf7, 0x8f, 0xe4 }, /* adata */ + 32, /* adata_len */ + { 0xc8, 0xd2, 0x75, 0xf9, 0x19, 0xe1, 0x7d, 0x7f, + 0xe6, 0x9c, 0x2a, 0x1f, 0x58, 0x93, 0x9d, 0xfe, + 0x4d, 0x40, 0x37, 0x91, 0xb5, 0xdf, 0x13, 0x10 }, /* mdata */ + 24, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0x8a, 0x0f, 0x3d, 0x82, 0x29, 0xe4, 0x8e, 0x74, + 0x87, 0xfd, 0x95, 0xa2, 0x8a, 0xd3, 0x92, 0xc8, + 0x0b, 0x36, 0x81, 0xd4, 0xfb, 0xc7, 0xbb, 0xfd, + 0x2d, 0xd6, 0xef, 0x1c, 0x45, 0xd4, 0xcc, 0xb7, + 0x23, 0xdc, 0x07, 0x44, 0x14, 0xdb, 0x50, 0x6d } /* expected */ + }, { + true, /* encrypt */ + 2, /* len_len */ + 1, /* key_size_index */ + 6, /* key_area */ + { 0xc6, 0xae, 0xeb, 0xcb, 0x14, 0x6c, 0xfa, 0xfa, + 0xae, 0x66, 0xf7, 0x8a, 0xab }, /* nonce */ + { 0x7d, 0xc8, 0xc5, 0x21, 0x44, 0xa7, 0xcb, 0x65, + 0xb3, 0xe5, 0xa8, 0x46, 0xe8, 0xfd, 0x7e, 0xae, + 0x37, 0xbf, 0x69, 0x96, 0xc2, 0x99, 0xb5, 0x6e, + 0x49, 0x14, 0x4e, 0xbf, 0x43, 0xa1, 0x77, 0x0f }, /* adata */ + 32, /* adata_len */ + { 0xee, 0x7e, 0x60, 0x75, 0xba, 0x52, 0x84, 0x6d, + 0xe5, 0xd6, 0x25, 0x49, 0x59, 0xa1, 0x8a, 0xff, + 0xc4, 0xfa, 0xf5, 0x9c, 0x8e, 0xf6, 0x34, 0x89 }, /* mdata */ + 24, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 4, /* mic_len */ + { 0x13, 0x7d, 0x9d, 0xa5, 0x9b, 0xaf, 0x5c, 0xbf, + 0xd4, 0x66, 0x20, 0xc5, 0xf2, 0x98, 0xfc, 0x76, + 0x6d, 0xe1, 0x0a, 0xc6, 0x8e, 0x77, 0x4e, 0xdf, + 0x1f, 0x2c, 0x5b, 0xad } /* expected */ + }, { + false, /* decrypt */ + 2, /* len_len */ + 1, /* key_size_index */ + 0, /* key_area */ + { 0x15, 0xb3, 0x69, 0x88, 0x96, 0x99, 0xb6, 0xde, + 0x1f, 0xa3, 0xee, 0x73, 0xe5 }, /* nonce */ + {}, /* adata */ + 0, /* adata_len */ + { 0x63, 0x42, 0xb8, 0x70, 0x0e, 0xde, 0xc9, 0x7a, + 0x96, 0x0e, 0xb1, 0x6e, 0x7c, 0xb1, 0xeb, 0x44, + 0x12, 0xfb, 0x4e, 0x26, 0x3d, 0xdd, 0x22, 0x06, + 0xb0, 0x90, 0x15, 0x5d, 0x34, 0xa7, 0x6c, 0x83, + 0x24, 0xe5, 0x55, 0x0c, 0x3e, 0xf4, 0x26, 0xed }, /* mdata */ + 40, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0x39, 0xf0, 0x8a, 0x2a, 0xf1, 0xd8, 0xda, 0x62, + 0x12, 0x55, 0x06, 0x39, 0xb9, 0x1f, 0xb2, 0x57, + 0x3e, 0x39, 0xa8, 0xeb, 0x5d, 0x80, 0x1d, 0xe8 } /* expected */ + }, { + false, /* decrypt */ + 2, /* len_len */ + 1, /* key_size_index */ + 2, /* key_area */ + { 0x92, 0x95, 0x42, 0xcd, 0x69, 0x0f, 0x1b, 0xab, + 0xcf, 0x16, 0x96, 0xcb, 0x03 }, /* nonce */ + { 0x58, 0xf7, 0x0b, 0xab, 0x24, 0xe0, 0xa6, 0x13, + 0x7e, 0x5c, 0xd3, 0xeb, 0x18, 0x65, 0x6f, 0x2b, + 0x5c, 0xcd, 0xdc, 0x3f, 0x53, 0x8a, 0x00, 0x00, + 0xc6, 0x51, 0x90, 0xe4, 0xa3, 0x66, 0x8e, 0x71 }, /* adata */ + 32, /* adata_len */ + { 0x3b, 0xf9, 0xd9, 0x3a, 0xf6, 0xff, 0xac, 0x9a, + 0xc8, 0x4c, 0xd3, 0x20, 0x2d, 0x4e, 0x0c, 0xc8 }, /* mdata */ + 16, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + {} /* expected */ + }, { + false, /* decrypt */ + 8, /* len_len */ + 1, /* key_size_index */ + 4, /* key_area */ + { 0x76, 0x40, 0x43, 0xc4, 0x94, 0x60, 0xb7 }, /* nonce */ + { 0x6e, 0x80, 0xdd, 0x7f, 0x1b, 0xad, 0xf3, 0xa1, + 0xc9, 0xab, 0x25, 0xc7, 0x5f, 0x10, 0xbd, 0xe7, + 0x8c, 0x23, 0xfa, 0x0e, 0xb8, 0xf9, 0xaa, 0xa5, + 0x3a, 0xde, 0xfb, 0xf4, 0xcb, 0xf7, 0x8f, 0xe4 }, /* adata */ + 32, /* adata_len */ + { 0x8a, 0x0f, 0x3d, 0x82, 0x29, 0xe4, 0x8e, 0x74, + 0x87, 0xfd, 0x95, 0xa2, 0x8a, 0xd3, 0x92, 0xc8, + 0x0b, 0x36, 0x81, 0xd4, 0xfb, 0xc7, 0xbb, 0xfd, + 0x2d, 0xd6, 0xef, 0x1c, 0x45, 0xd4, 0xcc, 0xb7, + 0x23, 0xdc, 0x07, 0x44, 0x14, 0xdb, 0x50, 0x6d }, /* mdata */ + 40, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0xc8, 0xd2, 0x75, 0xf9, 0x19, 0xe1, 0x7d, 0x7f, + 0xe6, 0x9c, 0x2a, 0x1f, 0x58, 0x93, 0x9d, 0xfe, + 0x4d, 0x40, 0x37, 0x91, 0xb5, 0xdf, 0x13, 0x10 } /* expected */ + }, { + false, /* decrypt */ + 2, /* len_len */ + 1, /* key_size_index */ + 6, /* key_area */ + { 0xc6, 0xae, 0xeb, 0xcb, 0x14, 0x6c, 0xfa, 0xfa, + 0xae, 0x66, 0xf7, 0x8a, 0xab }, /* nonce */ + { 0x7d, 0xc8, 0xc5, 0x21, 0x44, 0xa7, 0xcb, 0x65, + 0xb3, 0xe5, 0xa8, 0x46, 0xe8, 0xfd, 0x7e, 0xae, + 0x37, 0xbf, 0x69, 0x96, 0xc2, 0x99, 0xb5, 0x6e, + 0x49, 0x14, 0x4e, 0xbf, 0x43, 0xa1, 0x77, 0x0f }, /* adata */ + 32, /* adata_len */ + { 0x13, 0x7d, 0x9d, 0xa5, 0x9b, 0xaf, 0x5c, 0xbf, + 0xd4, 0x66, 0x20, 0xc5, 0xf2, 0x98, 0xfc, 0x76, + 0x6d, 0xe1, 0x0a, 0xc6, 0x8e, 0x77, 0x4e, 0xdf, + 0x1f, 0x2c, 0x5b, 0xad }, /* mdata */ + 28, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 4, /* mic_len */ + { 0xee, 0x7e, 0x60, 0x75, 0xba, 0x52, 0x84, 0x6d, + 0xe5, 0xd6, 0x25, 0x49, 0x59, 0xa1, 0x8a, 0xff, + 0xc4, 0xfa, 0xf5, 0x9c, 0x8e, 0xf6, 0x34, 0x89 } /* expected */ + }, { + true, /* encrypt */ + 2, /* len_len */ + 2, /* key_size_index */ + 0, /* key_area */ + { 0x72, 0xa6, 0x0f, 0x34, 0x5a, 0x19, 0x78, 0xfb, + 0x40, 0xf2, 0x8a, 0x2f, 0xa4 }, /* nonce */ + {}, /* adata */ + 0, /* adata_len */ + { 0x30, 0xd5, 0x6f, 0xf2, 0xa2, 0x5b, 0x83, 0xfe, + 0xe7, 0x91, 0x11, 0x0f, 0xca, 0xea, 0x48, 0xe4, + 0x1d, 0xb7, 0xc7, 0xf0, 0x98, 0xa8, 0x10, 0x00 }, /* mdata */ + 24, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0x55, 0xf0, 0x68, 0xc0, 0xbb, 0xba, 0x8b, 0x59, + 0x80, 0x13, 0xdd, 0x18, 0x41, 0xfd, 0x74, 0x0f, + 0xda, 0x29, 0x02, 0x32, 0x21, 0x48, 0xab, 0x5e, + 0x93, 0x57, 0x53, 0xe6, 0x01, 0xb7, 0x9d, 0xb4, + 0xae, 0x73, 0x0b, 0x6a, 0xe3, 0x50, 0x07, 0x31 } /* expected */ + }, { + true, /* encrypt */ + 2, /* len_len */ + 2, /* key_size_index */ + 2, /* key_area */ + { 0x29, 0x1e, 0x91, 0xb1, 0x9d, 0xe5, 0x18, 0xcd, + 0x78, 0x06, 0xde, 0x44, 0xf6 }, /* nonce */ + { 0xb4, 0xf8, 0x32, 0x69, 0x44, 0xa4, 0x5d, 0x95, + 0xf9, 0x18, 0x87, 0xc2, 0xa6, 0xac, 0x36, 0xb6, + 0x0e, 0xea, 0x5e, 0xde, 0xf8, 0x4c, 0x1c, 0x35, + 0x81, 0x46, 0xa6, 0x66, 0xb6, 0x87, 0x83, 0x35 }, /* adata */ + 32, /* adata_len */ + {}, /* mdata */ + 0, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0xca, 0x48, 0x2c, 0x67, 0x4b, 0x59, 0x90, 0x46, + 0xcc, 0x7d, 0x7e, 0xe0, 0xd0, 0x0e, 0xec, 0x1e } /* expected */ + }, { + true, /* encrypt */ + 8, /* len_len */ + 2, /* key_size_index */ + 4, /* key_area */ + { 0xaa, 0xa2, 0x3f, 0x10, 0x16, 0x47, 0xd8 }, /* nonce */ + { 0xa3, 0x55, 0xd4, 0xc6, 0x11, 0x81, 0x2e, 0x5f, + 0x92, 0x58, 0xd7, 0x18, 0x8b, 0x3d, 0xf8, 0x85, + 0x14, 0x77, 0x09, 0x4f, 0xfc, 0x2a, 0xf2, 0xcf, + 0x0c, 0x86, 0x70, 0xdb, 0x90, 0x3f, 0xbb, 0xe0 }, /* adata */ + 32, /* adata_len */ + { 0x64, 0x4e, 0xb3, 0x4b, 0x9a, 0x12, 0x6e, 0x43, + 0x7b, 0x5e, 0x01, 0x5e, 0xea, 0x14, 0x1c, 0xa1, + 0xa8, 0x80, 0x20, 0xf2, 0xd5, 0xd6, 0xcc, 0x2c }, /* mdata */ + 24, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0x27, 0xed, 0x90, 0x66, 0x81, 0x74, 0xeb, 0xf8, + 0x24, 0x1a, 0x3c, 0x74, 0xb3, 0x5e, 0x12, 0x46, + 0xb6, 0x61, 0x7e, 0x41, 0x23, 0x57, 0x8f, 0x15, + 0x3b, 0xdb, 0x67, 0x06, 0x2a, 0x13, 0xef, 0x4e, + 0x98, 0x6f, 0x5b, 0xb3, 0xd0, 0xbb, 0x43, 0x07 } /* expected */ + }, { + true, /* encrypt */ + 2, /* len_len */ + 2, /* key_size_index */ + 6, /* key_area */ + { 0x2e, 0x1e, 0x01, 0x32, 0x46, 0x85, 0x00, 0xd4, + 0xbd, 0x47, 0x86, 0x25, 0x63 }, /* nonce */ + { 0x3c, 0x5f, 0x54, 0x04, 0x37, 0x0a, 0xbd, 0xcb, + 0x1e, 0xdd, 0xe9, 0x9d, 0xe6, 0x0d, 0x06, 0x82, + 0xc6, 0x00, 0xb0, 0x34, 0xe0, 0x63, 0xb7, 0xd3, + 0x23, 0x77, 0x23, 0xda, 0x70, 0xab, 0x75, 0x52 }, /* adata */ + 32, /* adata_len */ + { 0x23, 0x90, 0x29, 0xf1, 0x50, 0xbc, 0xcb, 0xd6, + 0x7e, 0xdb, 0xb6, 0x7f, 0x8a, 0xe4, 0x56, 0xb4, + 0xea, 0x06, 0x6a, 0x4b, 0xee, 0xe0, 0x65, 0xf9 }, /* mdata */ + 24, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 4, /* mic_len */ + { 0x9c, 0x8d, 0x5d, 0xd2, 0x27, 0xfd, 0x9f, 0x81, + 0x23, 0x76, 0x01, 0x83, 0x0a, 0xfe, 0xe4, 0xf0, + 0x11, 0x56, 0x36, 0xc8, 0xe5, 0xd5, 0xfd, 0x74, + 0x3c, 0xb9, 0xaf, 0xed } /* expected */ + }, { + false, /* decrypt */ + 2, /* len_len */ + 2, /* key_size_index */ + 0, /* key_area */ + { 0x72, 0xa6, 0x0f, 0x34, 0x5a, 0x19, 0x78, 0xfb, + 0x40, 0xf2, 0x8a, 0x2f, 0xa4 }, /* nonce */ + {}, /* adata */ + 0, /* adata_len */ + { 0x55, 0xf0, 0x68, 0xc0, 0xbb, 0xba, 0x8b, 0x59, + 0x80, 0x13, 0xdd, 0x18, 0x41, 0xfd, 0x74, 0x0f, + 0xda, 0x29, 0x02, 0x32, 0x21, 0x48, 0xab, 0x5e, + 0x93, 0x57, 0x53, 0xe6, 0x01, 0xb7, 0x9d, 0xb4, + 0xae, 0x73, 0x0b, 0x6a, 0xe3, 0x50, 0x07, 0x31 }, /* mdata */ + 40, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0x30, 0xd5, 0x6f, 0xf2, 0xa2, 0x5b, 0x83, 0xfe, + 0xe7, 0x91, 0x11, 0x0f, 0xca, 0xea, 0x48, 0xe4, + 0x1d, 0xb7, 0xc7, 0xf0, 0x98, 0xa8, 0x10, 0x00 } /* expected */ + }, { + false, /* decrypt */ + 2, /* len_len */ + 2, /* key_size_index */ + 2, /* key_area */ + { 0x29, 0x1e, 0x91, 0xb1, 0x9d, 0xe5, 0x18, 0xcd, + 0x78, 0x06, 0xde, 0x44, 0xf6 }, /* nonce */ + { 0xb4, 0xf8, 0x32, 0x69, 0x44, 0xa4, 0x5d, 0x95, + 0xf9, 0x18, 0x87, 0xc2, 0xa6, 0xac, 0x36, 0xb6, + 0x0e, 0xea, 0x5e, 0xde, 0xf8, 0x4c, 0x1c, 0x35, + 0x81, 0x46, 0xa6, 0x66, 0xb6, 0x87, 0x83, 0x35 }, /* adata */ + 32, /* adata_len */ + { 0xca, 0x48, 0x2c, 0x67, 0x4b, 0x59, 0x90, 0x46, + 0xcc, 0x7d, 0x7e, 0xe0, 0xd0, 0x0e, 0xec, 0x1e }, /* mdata */ + 16, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + {} /* expected */ + }, { + false, /* decrypt */ + 8, /* len_len */ + 2, /* key_size_index */ + 4, /* key_area */ + { 0xaa, 0xa2, 0x3f, 0x10, 0x16, 0x47, 0xd8 }, /* nonce */ + { 0xa3, 0x55, 0xd4, 0xc6, 0x11, 0x81, 0x2e, 0x5f, + 0x92, 0x58, 0xd7, 0x18, 0x8b, 0x3d, 0xf8, 0x85, + 0x14, 0x77, 0x09, 0x4f, 0xfc, 0x2a, 0xf2, 0xcf, + 0x0c, 0x86, 0x70, 0xdb, 0x90, 0x3f, 0xbb, 0xe0 }, /* adata */ + 32, /* adata_len */ + { 0x27, 0xed, 0x90, 0x66, 0x81, 0x74, 0xeb, 0xf8, + 0x24, 0x1a, 0x3c, 0x74, 0xb3, 0x5e, 0x12, 0x46, + 0xb6, 0x61, 0x7e, 0x41, 0x23, 0x57, 0x8f, 0x15, + 0x3b, 0xdb, 0x67, 0x06, 0x2a, 0x13, 0xef, 0x4e, + 0x98, 0x6f, 0x5b, 0xb3, 0xd0, 0xbb, 0x43, 0x07 }, /* mdata */ + 40, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 16, /* mic_len */ + { 0x64, 0x4e, 0xb3, 0x4b, 0x9a, 0x12, 0x6e, 0x43, + 0x7b, 0x5e, 0x01, 0x5e, 0xea, 0x14, 0x1c, 0xa1, + 0xa8, 0x80, 0x20, 0xf2, 0xd5, 0xd6, 0xcc, 0x2c } /* expected */ + }, { + false, /* decrypt */ + 2, /* len_len */ + 2, /* key_size_index */ + 6, /* key_area */ + { 0x2e, 0x1e, 0x01, 0x32, 0x46, 0x85, 0x00, 0xd4, + 0xbd, 0x47, 0x86, 0x25, 0x63 }, /* nonce */ + { 0x3c, 0x5f, 0x54, 0x04, 0x37, 0x0a, 0xbd, 0xcb, + 0x1e, 0xdd, 0xe9, 0x9d, 0xe6, 0x0d, 0x06, 0x82, + 0xc6, 0x00, 0xb0, 0x34, 0xe0, 0x63, 0xb7, 0xd3, + 0x23, 0x77, 0x23, 0xda, 0x70, 0xab, 0x75, 0x52 }, /* adata */ + 32, /* adata_len */ + { 0x9c, 0x8d, 0x5d, 0xd2, 0x27, 0xfd, 0x9f, 0x81, + 0x23, 0x76, 0x01, 0x83, 0x0a, 0xfe, 0xe4, 0xf0, + 0x11, 0x56, 0x36, 0xc8, 0xe5, 0xd5, 0xfd, 0x74, + 0x3c, 0xb9, 0xaf, 0xed }, /* mdata */ + 28, /* mdata_len */ + { 0x00, 0x00, 0x00, 0x00 }, /* mic */ + 4, /* mic_len */ + { 0x23, 0x90, 0x29, 0xf1, 0x50, 0xbc, 0xcb, 0xd6, + 0x7e, 0xdb, 0xb6, 0x7f, 0x8a, 0xe4, 0x56, 0xb4, + 0xea, 0x06, 0x6a, 0x4b, 0xee, 0xe0, 0x65, 0xf9 } /* expected */ + } + }; + static int i; + static uint8_t key_size_index = -1, ret; + static rtimer_clock_t time, time2, total_time; + + PROCESS_BEGIN(); + + puts("-----------------------------------------\n" + "Initializing cryptoprocessor..."); + crypto_init(); + + for(i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) { + if(key_size_index != vectors[i].key_size_index) { + key_size_index = vectors[i].key_size_index; + printf("-----------------------------------------\n" + "Filling %d-bit key store...\n", 128 + (key_size_index << 6)); + time = RTIMER_NOW(); + ret = aes_load_keys(keys[key_size_index].keys, + keys[key_size_index].key_size, keys[key_size_index].count, 0); + time = RTIMER_NOW() - time; + printf("aes_load_keys(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + break; + } + } + + printf("-----------------------------------------\n" + "Test vector #%d: %s\n" + "len_len=%d key_area=%d\n" + "adata_len=%d mdata_len=%d mic_len=%d\n", + i, vectors[i].encrypt ? "encrypt" : "decrypt", + vectors[i].len_len, vectors[i].key_area, + vectors[i].adata_len, vectors[i].mdata_len, vectors[i].mic_len); + + time = RTIMER_NOW(); + if(vectors[i].encrypt) { + ret = ccm_auth_encrypt_start(vectors[i].len_len, vectors[i].key_area, + vectors[i].nonce, vectors[i].adata, + vectors[i].adata_len, vectors[i].mdata, + vectors[i].mdata_len, vectors[i].mic_len, + &ccm_test_process); + time2 = RTIMER_NOW(); + time = time2 - time; + total_time = time; + if(ret == CRYPTO_SUCCESS) { + PROCESS_WAIT_EVENT_UNTIL(ccm_auth_encrypt_check_status()); + time2 = RTIMER_NOW() - time2; + total_time += time2; + } + printf("ccm_auth_encrypt_start(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + if(ret != CRYPTO_SUCCESS) { + PROCESS_PAUSE(); + continue; + } + printf("ccm_auth_encrypt_check_status() wait: %lu us\n", + (uint32_t)((uint64_t)time2 * 1000000 / RTIMER_SECOND)); + + time = RTIMER_NOW(); + ret = ccm_auth_encrypt_get_result(vectors[i].mic, vectors[i].mic_len); + time = RTIMER_NOW() - time; + total_time += time; + printf("ccm_auth_encrypt_get_result(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + continue; + } + + if(rom_util_memcmp(vectors[i].mdata, vectors[i].expected, + vectors[i].mdata_len)) { + puts("Encrypted message does not match expected one"); + } else { + puts("Encrypted message OK"); + } + + if(rom_util_memcmp(vectors[i].mic, + vectors[i].expected + vectors[i].mdata_len, + vectors[i].mic_len)) { + puts("MIC does not match expected one"); + } else { + puts("MIC OK"); + } + } else { + ret = ccm_auth_decrypt_start(vectors[i].len_len, vectors[i].key_area, + vectors[i].nonce, vectors[i].adata, + vectors[i].adata_len, vectors[i].mdata, + vectors[i].mdata_len, vectors[i].mic_len, + &ccm_test_process); + time2 = RTIMER_NOW(); + time = time2 - time; + total_time = time; + if(ret == CRYPTO_SUCCESS) { + PROCESS_WAIT_EVENT_UNTIL(ccm_auth_decrypt_check_status()); + time2 = RTIMER_NOW() - time2; + total_time += time2; + } + printf("ccm_auth_decrypt_start(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + if(ret != CRYPTO_SUCCESS) { + PROCESS_PAUSE(); + continue; + } + printf("ccm_auth_decrypt_check_status() wait: %lu us\n", + (uint32_t)((uint64_t)time2 * 1000000 / RTIMER_SECOND)); + + time = RTIMER_NOW(); + ret = ccm_auth_decrypt_get_result(vectors[i].mdata, vectors[i].mdata_len, + vectors[i].mic, vectors[i].mic_len); + time = RTIMER_NOW() - time; + total_time += time; + printf("ccm_auth_decrypt_get_result(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + continue; + } + + if(rom_util_memcmp(vectors[i].mdata, vectors[i].expected, + vectors[i].mdata_len - vectors[i].mic_len)) { + puts("Decrypted message does not match expected one"); + } else { + puts("Decrypted message OK"); + } + } + + printf("Total duration: %lu us\n", + (uint32_t)((uint64_t)total_time * 1000000 / RTIMER_SECOND)); + } + + puts("-----------------------------------------\n" + "Disabling cryptoprocessor..."); + crypto_disable(); + + puts("Done!"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/examples/cc2538dk/crypto/sha256-test.c b/examples/cc2538dk/crypto/sha256-test.c new file mode 100644 index 000000000..f690ed27d --- /dev/null +++ b/examples/cc2538dk/crypto/sha256-test.c @@ -0,0 +1,261 @@ +/* + * Original file: + * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/ + * All rights reserved. + * + * Port to Contiki: + * Copyright (c) 2013, ADVANSEE - http://www.advansee.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 cc2538-examples + * @{ + * + * \defgroup cc2538-sha256-test cc2538dk SHA-256 Test Project + * + * SHA-256 access example for CC2538 on SmartRF06EB. + * + * This example shows how SHA-256 should be used. The example also verifies + * the SHA-256 functionality. + * + * @{ + * + * \file + * Example demonstrating SHA-256 on the cc2538dk platform + */ +#include "contiki.h" +#include "sys/rtimer.h" +#include "dev/rom-util.h" +#include "dev/sha256.h" + +#include +#include +#include +#include +/*---------------------------------------------------------------------------*/ +PROCESS(sha256_test_process, "sha256 test process"); +AUTOSTART_PROCESSES(&sha256_test_process); +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(sha256_test_process, ev, data) +{ + static const char *const str_res[] = { + "success", + "invalid param", + "NULL error", + "resource in use", + "DMA bus error" + }; + static const struct { + const char *data[3]; + uint8_t sha256[32]; + } vectors[] = { + { /* Simple */ + { + "abc", + NULL, + NULL + }, { + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad + } + }, { /* Simple */ + { + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + NULL, + NULL, + }, { + 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 + } + }, { /* Message of length 130 */ + { + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklabcd" + "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn", + NULL, + NULL + }, { + 0x15, 0xd2, 0x3e, 0xea, 0x57, 0xb3, 0xd4, 0x61, + 0xbf, 0x38, 0x91, 0x12, 0xab, 0x4c, 0x43, 0xce, + 0x85, 0xe1, 0x68, 0x23, 0x8a, 0xaa, 0x54, 0x8e, + 0xc8, 0x6f, 0x0c, 0x9d, 0x65, 0xf9, 0xb9, 0x23 + } + }, { /* Message of length 128 */ + { + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklabcd" + "efghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl", + NULL, + NULL + }, { + 0xf8, 0xa3, 0xf2, 0x26, 0xfc, 0x42, 0x10, 0xe9, + 0x0d, 0x13, 0x0c, 0x7f, 0x41, 0xf2, 0xbe, 0x66, + 0x45, 0x53, 0x85, 0xd2, 0x92, 0x0a, 0xda, 0x78, + 0x15, 0xf8, 0xf7, 0x95, 0xd9, 0x44, 0x90, 0x5f + } + }, { /* Message of length 64 */ + { + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl", + NULL, + NULL + }, { + 0x2f, 0xcd, 0x5a, 0x0d, 0x60, 0xe4, 0xc9, 0x41, + 0x38, 0x1f, 0xcc, 0x4e, 0x00, 0xa4, 0xbf, 0x8b, + 0xe4, 0x22, 0xc3, 0xdd, 0xfa, 0xfb, 0x93, 0xc8, + 0x09, 0xe8, 0xd1, 0xe2, 0xbf, 0xff, 0xae, 0x8e + } + }, { /* Message of length 66 */ + { + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmn", + NULL, + NULL + }, { + 0x92, 0x90, 0x1c, 0x85, 0x82, 0xe3, 0x1c, 0x05, + 0x69, 0xb5, 0x36, 0x26, 0x9c, 0xe2, 0x2c, 0xc8, + 0x30, 0x8b, 0xa4, 0x17, 0xab, 0x36, 0xc1, 0xbb, + 0xaf, 0x08, 0x4f, 0xf5, 0x8b, 0x18, 0xdc, 0x6a + } + }, { + { + "abcdbcdecdefde", + "fgefghfghighijhijkijkljklmklmnlmnomnopnopq", + NULL + }, { + 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 + } + }, { + { + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl", + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl", + NULL + }, { + 0xf8, 0xa3, 0xf2, 0x26, 0xfc, 0x42, 0x10, 0xe9, + 0x0d, 0x13, 0x0c, 0x7f, 0x41, 0xf2, 0xbe, 0x66, + 0x45, 0x53, 0x85, 0xd2, 0x92, 0x0a, 0xda, 0x78, + 0x15, 0xf8, 0xf7, 0x95, 0xd9, 0x44, 0x90, 0x5f + } + }, { + { + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefgh", + "ijkl", + "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl" + }, { + 0xf8, 0xa3, 0xf2, 0x26, 0xfc, 0x42, 0x10, 0xe9, + 0x0d, 0x13, 0x0c, 0x7f, 0x41, 0xf2, 0xbe, 0x66, + 0x45, 0x53, 0x85, 0xd2, 0x92, 0x0a, 0xda, 0x78, + 0x15, 0xf8, 0xf7, 0x95, 0xd9, 0x44, 0x90, 0x5f + } + } + }; + static sha256_state_t state; + static uint8_t sha256[32]; + static int i, j; + static uint8_t ret; + static rtimer_clock_t total_time; + rtimer_clock_t time; + size_t len; + + PROCESS_BEGIN(); + + puts("-----------------------------------------\n" + "Initializing cryptoprocessor..."); + crypto_init(); + + for(i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) { + printf("-----------------------------------------\n" + "Test vector #%d:\n", i); + + time = RTIMER_NOW(); + ret = sha256_init(&state); + time = RTIMER_NOW() - time; + total_time = time; + printf("sha256_init(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + continue; + } + + for(j = 0; j < sizeof(vectors[i].data) / sizeof(vectors[i].data[0]) && + vectors[i].data[j] != NULL; j++) { + len = strlen(vectors[i].data[j]); + printf("Buffer #%d (length: %u):\n", j, len); + time = RTIMER_NOW(); + ret = sha256_process(&state, vectors[i].data[j], len); + time = RTIMER_NOW() - time; + total_time += time; + printf("sha256_process(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + break; + } + } + if(ret != CRYPTO_SUCCESS) { + continue; + } + + time = RTIMER_NOW(); + ret = sha256_done(&state, sha256); + time = RTIMER_NOW() - time; + total_time += time; + printf("sha256_done(): %s, %lu us\n", str_res[ret], + (uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND)); + PROCESS_PAUSE(); + if(ret != CRYPTO_SUCCESS) { + continue; + } + + if(rom_util_memcmp(sha256, vectors[i].sha256, sizeof(sha256))) { + puts("Computed SHA-256 hash does not match expected hash"); + } else { + puts("Computed SHA-256 hash OK"); + } + printf("Total duration: %lu us\n", + (uint32_t)((uint64_t)total_time * 1000000 / RTIMER_SECOND)); + } + + puts("-----------------------------------------\n" + "Disabling cryptoprocessor..."); + crypto_disable(); + + puts("Done!"); + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ 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/examples/cc26xx/very-sleepy-demo/project-conf.h b/examples/cc26xx/very-sleepy-demo/project-conf.h new file mode 100644 index 000000000..477a535bf --- /dev/null +++ b/examples/cc26xx/very-sleepy-demo/project-conf.h @@ -0,0 +1,51 @@ +/* + * 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 PROJECT_CONF_H_ +#define PROJECT_CONF_H_ +/*---------------------------------------------------------------------------*/ +/* Change to match your configuration */ +#define IEEE802154_CONF_PANID 0xABCD +#define RF_CORE_CONF_CHANNEL 25 +/*---------------------------------------------------------------------------*/ +/* 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 + +/* + * 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/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/llsec/ccm-star-tests/encryption/tests.c b/examples/llsec/ccm-star-tests/encryption/tests.c index 99999f819..b9cc58782 100644 --- a/examples/llsec/ccm-star-tests/encryption/tests.c +++ b/examples/llsec/ccm-star-tests/encryption/tests.c @@ -41,9 +41,9 @@ #include "net/packetbuf.h" #include "net/netstack.h" #include "net/llsec/llsec802154.h" -#include "net/llsec/ccm-star.h" +#include "lib/ccm-star.h" +#include "net/llsec/ccm-star-packetbuf.h" #include "net/mac/frame802154.h" -#include "lib/aes-128.h" #include #include @@ -86,8 +86,8 @@ test_sec_lvl_6() packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL); packetbuf_hdrreduce(29); - AES_128.set_key(key); - CCM_STAR.mic(extended_source_address, mic, LLSEC802154_MIC_LENGTH); + CCM_STAR.set_key(key); + ccm_star_mic_packetbuf(extended_source_address, mic, LLSEC802154_MIC_LENGTH); if(memcmp(mic, oracle, LLSEC802154_MIC_LENGTH) == 0) { printf("Success\n"); @@ -97,7 +97,7 @@ test_sec_lvl_6() printf("Testing encryption ... "); - CCM_STAR.ctr(extended_source_address); + ccm_star_ctr_packetbuf(extended_source_address); if(((uint8_t *) packetbuf_hdrptr())[29] == 0xD8) { printf("Success\n"); } else { @@ -105,7 +105,7 @@ test_sec_lvl_6() } printf("Testing decryption ... "); - CCM_STAR.ctr(extended_source_address); + ccm_star_ctr_packetbuf(extended_source_address); if(((uint8_t *) packetbuf_hdrptr())[29] == 0xCE) { printf("Success\n"); } else { diff --git a/examples/llsec/ccm-star-tests/verification/tests.c b/examples/llsec/ccm-star-tests/verification/tests.c index 86d5952fc..d768ddeb6 100644 --- a/examples/llsec/ccm-star-tests/verification/tests.c +++ b/examples/llsec/ccm-star-tests/verification/tests.c @@ -41,9 +41,10 @@ #include "net/packetbuf.h" #include "net/netstack.h" #include "net/llsec/llsec802154.h" -#include "net/llsec/ccm-star.h" +#include "net/llsec/ccm-star-packetbuf.h" #include "net/mac/frame802154.h" #include "lib/aes-128.h" +#include "lib/ccm-star.h" #include #include @@ -112,8 +113,8 @@ test_sec_lvl_2() packetbuf_set_attr(PACKETBUF_ATTR_SECURITY_LEVEL, LLSEC802154_SECURITY_LEVEL); packetbuf_hdrreduce(18); - AES_128.set_key(key); - CCM_STAR.mic(extended_source_address, mic, LLSEC802154_MIC_LENGTH); + CCM_STAR.set_key(key); + ccm_star_mic_packetbuf(extended_source_address,mic, LLSEC802154_MIC_LENGTH); if(memcmp(mic, oracle, LLSEC802154_MIC_LENGTH) == 0) { printf("Success\n"); diff --git a/examples/remote/Makefile b/examples/remote/Makefile new file mode 100644 index 000000000..289f7e330 --- /dev/null +++ b/examples/remote/Makefile @@ -0,0 +1,9 @@ +DEFINES+=PROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = remote-demo test-tsl2563 test-sht25 +CONTIKI_TARGET_SOURCEFILES += tsl2563.c sht25.c + +all: $(CONTIKI_PROJECT) + +CONTIKI = ../.. +CONTIKI_WITH_RIME = 1 +include $(CONTIKI)/Makefile.include diff --git a/examples/remote/Makefile.target b/examples/remote/Makefile.target new file mode 100644 index 000000000..fe36b5539 --- /dev/null +++ b/examples/remote/Makefile.target @@ -0,0 +1 @@ +TARGET = remote diff --git a/examples/remote/node-red/README.md b/examples/remote/node-red/README.md new file mode 100644 index 000000000..0e8fc7b74 --- /dev/null +++ b/examples/remote/node-red/README.md @@ -0,0 +1,38 @@ +Re-Mote + Node Red README +======================== + +A very basic example of how to use MQTT-Demo + Mosquitto + Node Red + +Install Mosquitto +----------------- +* Install and run [mosquitto](http://mosquitto.org/). Default configuration + options should work. + +Fire up a Re-Mote +----------------- +* Compile the MQTT demo example from `../../cc2538dk/mqtt-demo.c` following + the instructions of the README.md therein. +* Program your Re-Mote. +* If you are running mosquitto with `-v`, a few seconds later you should see + the Re-Mote connect, subscribe and start publishing. + +Deploy your Node Red +-------------------- +* Install and run [Node Red](https://github.com/node-red/node-red) as per the + instructions +* Open `mqtt-remote-demo.json` from this directory with your favourite text + editor, select all and copy. +* Once you have the opened the Node Red page, click the menu icon on the top + right and go to Import -> Clipboard. Paste the copied text. +* Double click the `MQTT input from Re-Mote` box on the top left. Set `Broker` + IP and port to those corresponding to your running mosquitto. +* Hit Deploy +* Optionally, export the flow to a file for future use + +Browse +------ +Fire up a browser and browse to `http:///remote` + +Do more cool stuff +------------------ +Come up with more cool flows and share! diff --git a/examples/remote/node-red/mqtt-remote-demo.json b/examples/remote/node-red/mqtt-remote-demo.json new file mode 100644 index 000000000..a121cc6c2 --- /dev/null +++ b/examples/remote/node-red/mqtt-remote-demo.json @@ -0,0 +1,2 @@ +[{"id":"d95a1e7f.43a","type":"mqtt-broker","broker":"localhost","port":"1883","clientid":""},{"id":"ddd5cc1c.723e18","type":"mqtt in","name":"MQTT input from Re-Mote","topic":"iot-2/evt/status/fmt/json","broker":"d95a1e7f.43a","x":131.11109924316406,"y":98.88890075683594,"z":"9b2868a4.2cef5","wires":[["12ea094e.3c2447"]]},{"id":"7728d120.25c64","type":"function","name":"Parse and Store Data","func":"var dat = msg.payload.d;\n\nif(dat) {\n var ret = [\n {\n name: \"Name\",\n value: dat.myName,\n unit: \"\",\n },\n {\n name: \"Seq #\",\n value: dat[\"Seq #\"],\n unit: \"\",\n },\n {\n name: \"Uptime\",\n value: dat[\"Uptime (sec)\"],\n unit: \"sec\",\n },\n {\n name: \"On-Chip Temp\",\n value: dat[\"On-Chip Temp (mC)\"],\n unit: \"C\",\n },\n {\n name: \"VDD/3\",\n value: dat[\"VDD3 (mV)\"],\n unit: \"V\",\n },\n {\n name: \"Parent RSSI\",\n value: dat[\"RSSI (dBm)\"],\n unit: \"dBm\",\n },\n ];\n \n context.ret = ret;\n} else {\n if(context.ret) {\n msg.has_data = true;\n msg.payload = context.ret;\n } else {\n msg.payload = \"No Data!\";\n }\n return [msg, msg];\n}\nreturn [msg, null];","outputs":"2","x":545.1110992431641,"y":346.38890075683594,"z":"9b2868a4.2cef5","wires":[["4249c5c.35b5c3c"],["dacab617.9133c8"]]},{"id":"12ea094e.3c2447","type":"json","name":"Convert to JS Object","x":305.61109924316406,"y":263.13890075683594,"z":"9b2868a4.2cef5","wires":[["7728d120.25c64"]]},{"id":"e5e8271c.99c2d","type":"http response","name":"Send HTTP Reponse","x":1252.2220611572266,"y":488.38890075683594,"z":"9b2868a4.2cef5","wires":[]},{"id":"4b2260f8.436808","type":"http in","name":"","url":"/remote","method":"get","x":327.11109924316406,"y":429.88890075683594,"z":"9b2868a4.2cef5","wires":[["8a3f88a9.ec77d8","7728d120.25c64"]]},{"id":"8a3f88a9.ec77d8","type":"debug","name":"","active":false,"console":"false","complete":"req","x":459.61109924316406,"y":522.3889007568359,"z":"9b2868a4.2cef5","wires":[]},{"id":"ac349e33.beb47","type":"template","name":"Render HTML from Data","field":"payload","template":"\n\n
      \n {{#payload}}\n
    • {{name}}: {{value}}{{#unit}} {{unit}}{{/unit}}
    • \n {{/payload}}\n
    \n\n","x":1046.361099243164,"y":347.13890075683594,"z":"9b2868a4.2cef5","wires":[["e5e8271c.99c2d","530bf522.d773dc"]]},{"id":"4249c5c.35b5c3c","type":"debug","name":"","active":false,"console":"false","complete":"false","x":620.1110992431641,"y":247.88890075683594,"z":"9b2868a4.2cef5","wires":[]},{"id":"dacab617.9133c8","type":"switch","name":"","property":"has_data","rules":[{"t":"true"},{"t":"else"}],"checkall":"false","outputs":2,"x":765.1110992431641,"y":352.88890075683594,"z":"9b2868a4.2cef5","wires":[["124554c4.5b82b3","ac349e33.beb47"],["e5e8271c.99c2d"]]},{"id":"530bf522.d773dc","type":"debug","name":"","active":false,"console":"false","complete":"payload","x":1228.361099243164,"y":217.88890075683594,"z":"9b2868a4.2cef5","wires":[]},{"id":"124554c4.5b82b3","type":"debug","name":"","active":false,"console":"false","complete":"payload","x":898.1110992431641,"y":220.88890075683594,"z":"9b2868a4.2cef5","wires":[]}] + diff --git a/examples/remote/project-conf.h b/examples/remote/project-conf.h new file mode 100644 index 000000000..1f2f9adf4 --- /dev/null +++ b/examples/remote/project-conf.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2012, 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 remote-examples + * @{ + * + * \file + * Project specific configuration defines for the basic Re-Mote examples + */ +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define NETSTACK_CONF_RDC nullrdc_driver + +#endif /* PROJECT_CONF_H_ */ + +/** @} */ diff --git a/examples/remote/remote-demo.c b/examples/remote/remote-demo.c new file mode 100644 index 000000000..929726871 --- /dev/null +++ b/examples/remote/remote-demo.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2012, 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 remote + * @{ + * + * \defgroup remote-examples Re-Mote Example Projects + * @{ + * + * \defgroup remote-demo Re-Mote Demo Project + * + * Example project demonstrating the Re-Mote functionality + * + * - Boot sequence: LEDs flashing (Red, then yellow, finally green) + * + * - etimer/clock : Every LOOP_INTERVAL clock ticks (LOOP_PERIOD secs) the LED + * defined as LEDS_PERIODIC will turn on + * - rtimer : Exactly LEDS_OFF_HYSTERISIS rtimer ticks later, + * LEDS_PERIODIC will turn back off + * - ADC sensors : On-chip VDD / 3, temperature, and Phidget sensor + * values are printed over UART periodically. + * - UART : Every LOOP_INTERVAL the Remote will print something over + * the UART. Receiving an entire line of text over UART (ending + * in \\r) will cause LEDS_SERIAL_IN to toggle + * - Radio comms : BTN_USER sends a rime broadcast. Reception of a rime + * packet will toggle LEDs defined as LEDS_RF_RX + * - Button : Keeping the button pressed will print a counter that + * increments every BUTTON_PRESS_EVENT_INTERVAL ticks + * - TMP102 : Built-in digital temperature sensor, every LOOP_INTERVAL + * clock ticks a sensor reading will be taken + * + * @{ + * + * \file + * Example demonstrating the Re-Mote platform + */ +#include "contiki.h" +#include "cpu.h" +#include "sys/etimer.h" +#include "sys/rtimer.h" +#include "dev/leds.h" +#include "dev/uart.h" +#include "dev/button-sensor.h" +#include "dev/remote-sensors.h" +#include "dev/watchdog.h" +#include "dev/serial-line.h" +#include "dev/sys-ctrl.h" +#include "net/rime/broadcast.h" +#include "dev/antenna-sw.h" +#include "dev/tmp102.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define LOOP_PERIOD 8 +#define LOOP_INTERVAL (CLOCK_SECOND * LOOP_PERIOD) +#define LEDS_OFF_HYSTERISIS ((RTIMER_SECOND * LOOP_PERIOD) >> 1) +#define LEDS_PERIODIC LEDS_BLUE +#define LEDS_BUTTON LEDS_RED +#define LEDS_SERIAL_IN LEDS_GREEN +#define LEDS_REBOOT LEDS_ALL +#define LEDS_RF_RX (LEDS_YELLOW | LEDS_RED) +#define BROADCAST_CHANNEL 129 + +#define BUTTON_PRESS_EVENT_INTERVAL (CLOCK_SECOND) +/*---------------------------------------------------------------------------*/ +static struct etimer et; +static struct rtimer rt; +static uint16_t counter, temperature; +/*---------------------------------------------------------------------------*/ +PROCESS(cc2538_demo_process, "cc2538 demo process"); +AUTOSTART_PROCESSES(&cc2538_demo_process); +/*---------------------------------------------------------------------------*/ +static void +broadcast_recv(struct broadcast_conn *c, const linkaddr_t *from) +{ + leds_toggle(LEDS_RF_RX); + printf("*** Received %u bytes from %u:%u: '0x%04x'\n", packetbuf_datalen(), + from->u8[0], from->u8[1], *(uint16_t *)packetbuf_dataptr()); +} +/*---------------------------------------------------------------------------*/ +static const struct broadcast_callbacks bc_rx = { broadcast_recv }; +static struct broadcast_conn bc; +/*---------------------------------------------------------------------------*/ +void +rt_callback(struct rtimer *t, void *ptr) +{ + leds_off(LEDS_PERIODIC); +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(cc2538_demo_process, ev, data) +{ + PROCESS_EXITHANDLER(broadcast_close(&bc)) + + PROCESS_BEGIN(); + + counter = 0; + broadcast_open(&bc, BROADCAST_CHANNEL, &bc_rx); + + /* Enable antenna */ + antenna_sw_select(ANTENNA_SW_SELECT_INTERNAL); + + button_sensor.configure(BUTTON_SENSOR_CONFIG_TYPE_INTERVAL, + BUTTON_PRESS_EVENT_INTERVAL); + + tmp102_init(); + + printf("Re-Mote test application, initial values:\n"); + + etimer_set(&et, LOOP_INTERVAL); + + while(1) { + + PROCESS_YIELD(); + + if(ev == PROCESS_EVENT_TIMER) { + leds_on(LEDS_PERIODIC); + + printf("-----------------------------------------\n" + "Counter = 0x%08x\n", counter); + + printf("VDD = %d mV\n", + vdd3_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); + + printf("Temperature = %d mC\n", + cc2538_temp_sensor.value(CC2538_SENSORS_VALUE_TYPE_CONVERTED)); + + printf("Phidget ADC2 = %d raw\n", + phidget_sensor.value(PHIDGET_SENSORS_ADC2)); + + printf("Phidget ADC3 = %d raw\n", + phidget_sensor.value(PHIDGET_SENSORS_ADC3)); + + tmp102_read(&temperature); + printf("TMP102 sensor = %u mC\n", temperature); + + etimer_set(&et, LOOP_INTERVAL); + rtimer_set(&rt, RTIMER_NOW() + LEDS_OFF_HYSTERISIS, 1, + rt_callback, NULL); + counter++; + } else if(ev == sensors_event) { + if(data == &button_sensor) { + if(button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == + BUTTON_SENSOR_PRESSED_LEVEL) { + printf("Press\n"); + packetbuf_copyfrom(&counter, sizeof(counter)); + broadcast_send(&bc); + } else { + printf("Release\n"); + } + } + } else if(ev == serial_line_event_message) { + leds_toggle(LEDS_SERIAL_IN); + } else if(ev == button_press_duration_exceeded) { + printf("Button pressed for %d ticks [%u events]\n", + (*((uint8_t *)data) * BUTTON_PRESS_EVENT_INTERVAL), + button_sensor.value(BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION)); + } + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + * @} + */ diff --git a/examples/remote/test-sht25.c b/examples/remote/test-sht25.c new file mode 100644 index 000000000..3ff4316bd --- /dev/null +++ b/examples/remote/test-sht25.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015, Zolertia + * 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 + * A quick program for testing the SHT25 temperature and humidity sensor + * \author + * Antonio Lignan + */ +#include +#include "contiki.h" +#include "dev/sht25.h" + +PROCESS(test_sht25_process, "SHT25 test"); +AUTOSTART_PROCESSES(&test_sht25_process); + +static struct etimer et; + +PROCESS_THREAD(test_sht25_process, ev, data) +{ + int16_t temperature, humidity; + + PROCESS_BEGIN(); + SENSORS_ACTIVATE(sht25); + + while(1) { + etimer_set(&et, CLOCK_SECOND); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + temperature = sht25.value(SHT25_VAL_TEMP); + printf("Temperature %d.%d ºC\n", temperature / 100, temperature % 100); + humidity = sht25.value(SHT25_VAL_HUM); + printf("Humidity %d.%d RH\n", humidity / 100, humidity % 100); + } + PROCESS_END(); +} diff --git a/examples/remote/test-tsl2563.c b/examples/remote/test-tsl2563.c new file mode 100644 index 000000000..88f3cbe2d --- /dev/null +++ b/examples/remote/test-tsl2563.c @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-examples + * @{ + * + * \defgroup remote-tsl2563-test Re-Mote TSL2563 light sensor test + * + * Demonstrates the use of the TSL2563 digital ambient light sensor + * @{ + * + * \file + * Driver for the Re-Mote external TSL2563 light sensor (Ziglet) + * + * \author + * Antonio Lignan + * Toni Lozano + */ + +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/tsl2563.h" + +#if 1 +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define SENSOR_READ_INTERVAL (CLOCK_SECOND / 2) + +PROCESS(test_process, "Test TSL2563 light ziglet process"); +AUTOSTART_PROCESSES(&test_process); +/*---------------------------------------------------------------------------*/ +static struct etimer et; +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(test_process, ev, data) +{ + PROCESS_BEGIN(); + int light; + SENSORS_ACTIVATE(tsl2563); + + while(1) { + etimer_set(&et, SENSOR_READ_INTERVAL); + PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et)); + light = tsl2563.value(TSL2563_VAL_READ); + PRINTF("Light = %u\n", light); + } + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ + diff --git a/examples/telnet-server/Makefile.apple2enh.defines b/examples/telnet-server/Makefile.apple2enh.defines index 3dbfd3e2f..64d673103 100644 --- a/examples/telnet-server/Makefile.apple2enh.defines +++ b/examples/telnet-server/Makefile.apple2enh.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS +DEFINES = CONNECTIONS=3,WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_REBOOT diff --git a/examples/telnet-server/Makefile.atarixl.defines b/examples/telnet-server/Makefile.atarixl.defines index 405794c09..bcd39d550 100644 --- a/examples/telnet-server/Makefile.atarixl.defines +++ b/examples/telnet-server/Makefile.atarixl.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS +DEFINES = CONNECTIONS=3,WITH_LOGGING,WITH_CLIENT,WITH_DNS diff --git a/examples/telnet-server/Makefile.c128.defines b/examples/telnet-server/Makefile.c128.defines index 84c86ef72..5e74716aa 100644 --- a/examples/telnet-server/Makefile.c128.defines +++ b/examples/telnet-server/Makefile.c128.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS,CONNECTIONS=2,MTU_SIZE=500 +DEFINES = WITH_LOGGING diff --git a/examples/telnet-server/Makefile.c64.defines b/examples/telnet-server/Makefile.c64.defines index 3dbfd3e2f..bcd39d550 100644 --- a/examples/telnet-server/Makefile.c64.defines +++ b/examples/telnet-server/Makefile.c64.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_CLIENT,WITH_DNS,WITH_PFS +DEFINES = CONNECTIONS=3,WITH_LOGGING,WITH_CLIENT,WITH_DNS diff --git a/examples/telnet-server/telnet-server.c b/examples/telnet-server/telnet-server.c index a0862886e..0164d2744 100644 --- a/examples/telnet-server/telnet-server.c +++ b/examples/telnet-server/telnet-server.c @@ -48,21 +48,18 @@ PROCESS_THREAD(shell_init_process, ev, data) { PROCESS_BEGIN(); -#ifdef __CC65__ - shell_ps_init(); - shell_netstat_init(); - shell_wget_init(); - shell_memdebug_init(); -#else /* __CC65__ */ shell_file_init(); +#ifndef __CC65__ shell_httpd_init(); shell_irc_init(); shell_ps_init(); shell_run_init(); shell_text_init(); shell_time_init(); +#endif /* !__CC65__ */ +#ifndef __C128__ shell_wget_init(); -#endif /* __CC65__ */ +#endif /* !__C128__ */ PROCESS_END(); } diff --git a/examples/webserver/Makefile.apple2enh.defines b/examples/webserver/Makefile.apple2enh.defines index 70fa579ff..461a038bb 100644 --- a/examples/webserver/Makefile.apple2enh.defines +++ b/examples/webserver/Makefile.apple2enh.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_BOOST,CONNECTIONS=5 +DEFINES = CONNECTIONS=4,WITH_LOGGING,WITH_BOOST diff --git a/examples/webserver/Makefile.atarixl.defines b/examples/webserver/Makefile.atarixl.defines index a17e2c1c1..461a038bb 100644 --- a/examples/webserver/Makefile.atarixl.defines +++ b/examples/webserver/Makefile.atarixl.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_BOOST +DEFINES = CONNECTIONS=4,WITH_LOGGING,WITH_BOOST diff --git a/examples/webserver/Makefile.c128.defines b/examples/webserver/Makefile.c128.defines index ac4b8c2d8..43f7fe613 100644 --- a/examples/webserver/Makefile.c128.defines +++ b/examples/webserver/Makefile.c128.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_BOOST,WITH_PFS,CONNECTIONS=5 +DEFINES = CONNECTIONS=4,WITH_LOGGING,WITH_BOOST,WITH_PFS diff --git a/examples/webserver/Makefile.c64.defines b/examples/webserver/Makefile.c64.defines index 0c6ef3678..43f7fe613 100644 --- a/examples/webserver/Makefile.c64.defines +++ b/examples/webserver/Makefile.c64.defines @@ -1 +1 @@ -DEFINES = WITH_LOGGING,WITH_BOOST,WITH_PFS +DEFINES = CONNECTIONS=4,WITH_LOGGING,WITH_BOOST,WITH_PFS 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/Makefile.apple2enh b/platform/apple2enh/Makefile.apple2enh index 2bc8c4626..b59c82e44 100644 --- a/platform/apple2enh/Makefile.apple2enh +++ b/platform/apple2enh/Makefile.apple2enh @@ -41,7 +41,7 @@ LC_SOURCEFILES = process.c tcpip.c ifeq ($(findstring WITH_REBOOT,$(DEFINES)),WITH_REBOOT) LDFLAGS += -D __LCADDR__=0xD000 -D __LCSIZE__=0x1000 - LC_SOURCEFILES += etimer.c + LC_SOURCEFILES += autostart.c timer.c uip_arch.c uiplib.c endif # Set a target-specific variable value diff --git a/platform/apple2enh/contiki-conf.h b/platform/apple2enh/contiki-conf.h index 4326efe2d..2ad5ceb7f 100644 --- a/platform/apple2enh/contiki-conf.h +++ b/platform/apple2enh/contiki-conf.h @@ -55,15 +55,12 @@ #define IRC_CONF_WIDTH 80 #define IRC_CONF_HEIGHT 23 -#define WWW_CONF_WEBPAGE_WIDTH 80 -#define WWW_CONF_WEBPAGE_HEIGHT 19 -#define WWW_CONF_HISTORY_SIZE 4 -#define WWW_CONF_MAX_URLLEN 78 -#define WWW_CONF_MAX_NUMPAGEWIDGETS 20 -#define WWW_CONF_FORMS 1 -#define WWW_CONF_MAX_FORMACTIONLEN 20 -#define WWW_CONF_MAX_INPUTNAMELEN 20 -#define WWW_CONF_MAX_INPUTVALUELEN 20 -#define WWW_CONF_WGET_EXEC(url) exec("wget", url) +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME 300 +#endif + +#define WWW_CONF_WEBPAGE_HEIGHT 19 +#define WWW_CONF_HISTORY_SIZE 4 +#define WWW_CONF_WGET_EXEC(url) exec("wget", url) #endif /* CONTIKI_CONF_H_ */ 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/atarixl/contiki-conf.h b/platform/atarixl/contiki-conf.h index 047e473ed..8c43fdcae 100644 --- a/platform/atarixl/contiki-conf.h +++ b/platform/atarixl/contiki-conf.h @@ -60,14 +60,12 @@ #define IRC_CONF_WIDTH 40 #define IRC_CONF_HEIGHT 23 -#define WWW_CONF_WEBPAGE_WIDTH 40 -#define WWW_CONF_WEBPAGE_HEIGHT 19 -#define WWW_CONF_HISTORY_SIZE 4 -#define WWW_CONF_MAX_URLLEN 80 -#define WWW_CONF_MAX_NUMPAGEWIDGETS 20 -#define WWW_CONF_FORMS 1 -#define WWW_CONF_MAX_FORMACTIONLEN 20 -#define WWW_CONF_MAX_INPUTNAMELEN 20 -#define WWW_CONF_MAX_INPUTVALUELEN 20 +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME 300 +#endif + +#define WWW_CONF_WEBPAGE_WIDTH 40 +#define WWW_CONF_WEBPAGE_HEIGHT 19 +#define WWW_CONF_HISTORY_SIZE 4 #endif /* CONTIKI_CONF_H_ */ diff --git a/platform/c128/Makefile.c128 b/platform/c128/Makefile.c128 index 6b73ff04c..b186fac60 100644 --- a/platform/c128/Makefile.c128 +++ b/platform/c128/Makefile.c128 @@ -31,7 +31,7 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += pfs.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += lseek.c pfs.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 diff --git a/platform/c128/contiki-conf.h b/platform/c128/contiki-conf.h index 8aabcca03..53a6878f9 100644 --- a/platform/c128/contiki-conf.h +++ b/platform/c128/contiki-conf.h @@ -65,11 +65,12 @@ #define IRC_CONF_WIDTH 80 #define IRC_CONF_HEIGHT 24 -#define WWW_CONF_WEBPAGE_WIDTH 80 -#define WWW_CONF_WEBPAGE_HEIGHT 20 -#define WWW_CONF_HISTORY_SIZE 0 -#define WWW_CONF_MAX_URLLEN 78 -#define WWW_CONF_MAX_NUMPAGEWIDGETS 20 -#define WWW_CONF_FORMS 0 +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME 300 +#endif + +#define WWW_CONF_HISTORY_SIZE 0 +#define WWW_CONF_FORMS 0 +#define WWW_CONF_PAGEATTRIB_SIZE 1500 #endif /* CONTIKI_CONF_H_ */ diff --git a/platform/c128/lib/lseek.c b/platform/c128/lib/lseek.c new file mode 100644 index 000000000..d79f9e529 --- /dev/null +++ b/platform/c128/lib/lseek.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2007, 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. + * + * Author: Oliver Schmidt + * + */ + +#include + +/*-----------------------------------------------------------------------------------*/ +off_t +__fastcall__ lseek(int fd, off_t offset, int whence) +{ + return (off_t)-1; +} +/*-----------------------------------------------------------------------------------*/ 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/Makefile.c64 b/platform/c64/Makefile.c64 index ddc94d586..ed548463b 100644 --- a/platform/c64/Makefile.c64 +++ b/platform/c64/Makefile.c64 @@ -31,7 +31,7 @@ # Author: Oliver Schmidt # -CONTIKI_TARGET_SOURCEFILES += pfs.S pfs_write.S +CONTIKI_TARGET_SOURCEFILES += lseek.c pfs.S pfs_write.S CONTIKI_CPU = $(CONTIKI)/cpu/6502 include $(CONTIKI_CPU)/Makefile.6502 diff --git a/platform/c64/contiki-conf.h b/platform/c64/contiki-conf.h index 0e5581aae..bfaf1c956 100644 --- a/platform/c64/contiki-conf.h +++ b/platform/c64/contiki-conf.h @@ -65,15 +65,12 @@ #define IRC_CONF_WIDTH 40 #define IRC_CONF_HEIGHT 24 -#define WWW_CONF_WEBPAGE_WIDTH 40 -#define WWW_CONF_WEBPAGE_HEIGHT 20 -#define WWW_CONF_HISTORY_SIZE 4 -#define WWW_CONF_MAX_URLLEN 80 -#define WWW_CONF_MAX_NUMPAGEWIDGETS 20 -#define WWW_CONF_FORMS 1 -#define WWW_CONF_MAX_FORMACTIONLEN 20 -#define WWW_CONF_MAX_INPUTNAMELEN 20 -#define WWW_CONF_MAX_INPUTVALUELEN 20 -#define WWW_CONF_WGET_EXEC(url) exec("wget", url) +#ifndef TELNETD_CONF_MAX_IDLE_TIME +#define TELNETD_CONF_MAX_IDLE_TIME 300 +#endif + +#define WWW_CONF_WEBPAGE_WIDTH 40 +#define WWW_CONF_HISTORY_SIZE 4 +#define WWW_CONF_WGET_EXEC(url) exec("wget", url) #endif /* CONTIKI_CONF_H_ */ diff --git a/platform/c64/lib/lseek.c b/platform/c64/lib/lseek.c new file mode 100644 index 000000000..d79f9e529 --- /dev/null +++ b/platform/c64/lib/lseek.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2007, 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. + * + * Author: Oliver Schmidt + * + */ + +#include + +/*-----------------------------------------------------------------------------------*/ +off_t +__fastcall__ lseek(int fd, off_t offset, int whence) +{ + return (off_t)-1; +} +/*-----------------------------------------------------------------------------------*/ 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/cc2538dk/README.md b/platform/cc2538dk/README.md index e5fc755c0..dde73842e 100644 --- a/platform/cc2538dk/README.md +++ b/platform/cc2538dk/README.md @@ -29,6 +29,7 @@ In terms of hardware support, the following drivers have been implemented: * Low Power Modes * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. * ADC + * Cryptoprocessor (AES-CCM-256, SHA-256) * SmartRF06 EB and BB peripherals * LEDs * Buttons @@ -146,10 +147,14 @@ The CC2538 EM's USB Vendor and Product IDs are the following: The implementation in Contiki is pure CDC-ACM: The Linux and OS X kernels know exactly what to do and drivers are not required. -On windows, you will need to provide a driver: +On windows, you will need to provide a driver. You have two options: - * Download this LUFA CDC-ACM driver: - + * Use the signed or unsigned driver provided by TI in [CC2538 Foundation Firmware](http://www.ti.com/tool/cc2538-sw). You will find them both under the `drivers` directory. + * Download a generic Virtual Serial Port driver and modify it so it works for the CC2538. + +For the latter option: + + * Download this [LUFA CDC-ACM driver](https://raw.githubusercontent.com/abcminiuser/lufa/master/Demos/Device/LowLevel/VirtualSerial/LUFA%20VirtualSerial.inf). * Adjust the VID and PID near the end with the values at the start of this section. * Next time you get prompted for the driver, include the directory containing the .inf file in the search path and the driver will be installed. diff --git a/platform/remote/Makefile.remote b/platform/remote/Makefile.remote new file mode 100644 index 000000000..a9acc1dbc --- /dev/null +++ b/platform/remote/Makefile.remote @@ -0,0 +1,46 @@ +# Remote platform makefile + +ifndef CONTIKI + $(error CONTIKI not defined! You must specify where CONTIKI resides!) +endif + +PYTHON = python +BSL_FLAGS += -e -w -v -b 115200 + +ifdef PORT + BSL_FLAGS += -p $(PORT) +endif + +CONTIKI_TARGET_DIRS = . dev + +CONTIKI_TARGET_SOURCEFILES += leds.c leds-arch.c +CONTIKI_TARGET_SOURCEFILES += contiki-main.c +CONTIKI_TARGET_SOURCEFILES += sensors.c remote-sensors.c +CONTIKI_TARGET_SOURCEFILES += button-sensor.c antenna-sw.c +CONTIKI_TARGET_SOURCEFILES += phidget-sensor.c tmp102.c + +CONTIKI_SOURCEFILES += $(CONTIKI_TARGET_SOURCEFILES) + +CLEAN += *.remote + +### Unless the example dictates otherwise, build with code size optimisations +ifndef SMALL + SMALL = 1 +endif + +### Define the CPU directory +CONTIKI_CPU=$(CONTIKI)/cpu/cc2538 +include $(CONTIKI_CPU)/Makefile.cc2538 + +MODULES += core/net core/net/mac \ + core/net/mac/contikimac \ + core/net/llsec + +BSL = $(CONTIKI)/tools/cc2538-bsl/cc2538-bsl.py + +%.upload: %.bin +ifeq ($(wildcard $(BSL)), ) + @echo "ERROR: Could not find the cc2538-bsl script. Did you run 'git submodule update --init' ?" +else + $(PYTHON) $(BSL) $(BSL_FLAGS) $< +endif diff --git a/platform/remote/README.md b/platform/remote/README.md new file mode 100644 index 000000000..7172ebd02 --- /dev/null +++ b/platform/remote/README.md @@ -0,0 +1,283 @@ +Zolertia Re-Mote platform +============================================ + + + +The Re-Mote platform is a IoT Hardware development platform based on TI's CC2538 +system on chip (SoC), featuring an ARM Cortex-M3 with 512KB flash, 32Kb RAM, +double RF interface, and the following goodies: + +* ISM 2.4-GHz IEEE 802.15.4 & Zigbee compliant. +* ISM 868-, 915-, 920-, 950-MHz ISM/SRD Band. +* AES-128/256, SHA2 Hardware Encryption Engine. +* ECC-128/256, RSA Hardware Acceleration Engine for Secure Key Exchange. +* Power consumption down to 3uA using our shutdown mode. +* Co-Processor to allow peripheral management, programming over BSL without requiring to press any button to enter bootloader mode. +* Built-in battery charger (500mA), Energy Harvesting and Solar Panels to be connected to standards LiPo batteries. +* Power input with wide range 2-26VDC. +* Built-in TMP102 temperature sensor +* Small form-factor (as the Z1 mote, half the size of an Arduino) 57x35 mm. + + +Port Features +============= +The platform has the following key features: + + * Deep Sleep support with RAM retention for ultra-low energy consumption. + * Native USB support (CDC-ACM). SLIP over UART for border routers is no longer a bottleneck. + * DMA transfers for increased performance (RAM to/from RF, RAM to/from USB). + * Shutdown mode controlled externally by the Co-processor, completely power the + platform OFF, further reducing current consumption. + +In terms of hardware support, the following drivers have been implemented: + + * CC2538 System-on-Chip: + * Standard Cortex M3 peripherals (NVIC, SCB, SysTick) + * Sleep Timer (underpins rtimers) + * SysTick (underpins the platform clock and Contiki's timers infrastructure) + * RF + * UART + * Watchdog (in watchdog mode) + * USB (in CDC-ACM) + * uDMA Controller (RAM to/from USB and RAM to/from RF) + * Random number generator + * Low Power Modes + * General-Purpose Timers. NB: GPT0 is in use by the platform code, the remaining GPTs are available for application development. + * ADC + * Cryptoprocessor (AES-CCM-256, SHA-256) + * LEDs + * Buttons + * Internal/external 2.4GHz antenna switch controllable by SW. + * Built-in core temperature and battery sensor. + * TMP102 temperature sensor driver. + * CC1120 sub-1GHz radio interface: + * Ported in Contiki, SPI based. + * Micro-SD external storage: + * Pending to port, SPI based. + +Requirements +============ +To start using Contiki, the following is required: + + * A toolchain to compile Contiki for the CC2538. + * Drivers so that your OS can communicate with your hardware. + * Software to upload images to the CC2538. + + +Install a Toolchain +------------------- +Forked from `platform/cc2538dk/README.md`. +The toolchain used to build contiki is arm-gcc, also used by other arm-based Contiki ports. If you are using Instant Contiki, you will have a version pre-installed in your system. To find out if this is the case, try this: + + $ arm-none-eabi-gcc -v + Using built-in specs. + Target: arm-none-eabi + Configured with: /scratch/julian/lite-respin/eabi/src/gcc-4.3/configure + ... + (skip) + ... + Thread model: single + gcc version 4.3.2 (Sourcery G++ Lite 2008q3-66) + +The platform is currently being used/tested with the following toolchains: + +* GNU Tools for ARM Embedded Processors. This is the recommended version. Works nicely on OS X. +* Alternatively, you can use this older version for Linux. At the time of writing, this is the version used by Contiki's regression tests. + +Drivers +------- +The Re-Mote features a FTDI serial-to-USB module, the driver is commonly found in most OS, but if required it can be downloaded +from + + +### For the CC2538EM (USB CDC-ACM) +The Re-Mote has built-in support for USB 2.0 USB, Vendor and Product IDs are the following: + + * VID 0x0451 + * PID 0x16C8 + +The implementation in Contiki is pure CDC-ACM: The Linux and OS X kernels know exactly what to do and drivers are not required. + +On windows, you will need to provide a driver: + + * Download this LUFA CDC-ACM driver: + + * Adjust the VID and PID near the end with the values at the start of this section. + * Next time you get prompted for the driver, include the directory containing the .inf file in the search path and the driver will be installed. + +### Device Enumerations +For the UART, serial line settings are 115200 8N1, no flow control. + +Once all drivers have been installed correctly: + +On windows, devices will appear as a virtual COM port. + +On Linux and OS X, devices will appear under `/dev/`. + +On OS X: + +* XDS backchannel: `tty.usbserial-` +* EM in CDC-ACM: `tty.usbmodemf` (X a letter, ABC a number e.g. `tty.usbmodemfd121`) + +On Linux: + +* Re-Mote over FTDI: `ttyUSB1` +* Re-Mote over USB driver (in CDC-ACM): `ttyACMn` (n=0, 1, ....) + +Software to Program the Nodes +----------------------------- +The Re-Mote can be programmed via the jtag interface or via the serial boot loader on the chip. + +* On Windows: + * Nodes can be programmed with TI's ArmProgConsole or the [SmartRF Flash Programmer 2][smart-rf-flashprog]. The README should be self-explanatory. With ArmProgConsole, upload the file with a `.bin` extension. (jtag + serial) + * Nodes can also be programmed via the serial boot loader in the cc2538. In `tools/cc2538-bsl/` you can find `cc2538-bsl.py` this is a python script that can download firmware to your node via a serial connection. If you use this option you just need to make sure you have a working version of python installed. You can read the README in the same directory for more info. (serial) + +* On Linux: + * Nodes can be programmed with TI's [UniFlash] tool. With UniFlash, use the file with `.elf` extension. (jtag + serial) + * Nodes can also be programmed via the serial boot loader in the cc2538. No extra software needs to be installed. (serial) + +* On OSX: + * The `cc2538-bsl.py` script in `tools/cc2538-bsl/` is the only option. No extra software needs to be installed. (serial) + +The file with a `.remote` extension is a copy of the `.elf` file. + +Use the Port +============ +The following examples are intended to work off-the-shelf: + +* Examples under `examples/remote` +* MQTT example `examples/cc2538dk/mqtt-demo` +* Border router: `examples/ipv6/rpl-border-router` +* Webserver: `examples/webserver-ipv6` +* CoAP example: `examples/er-rest-example/` + +Build your First Examples +------------------------- +It is recommended to start with the `remote-demo`, it is a simple example that walkthroughs the platform features, such as +the built-in sensors, LEDs, user button operation modes (press, release, hold-press), radio (Rime broadcast). + +The `Makefile.target` includes the `TARGET=` argument, predefining which is the target platform to compile for, it is automatically included at compilation. To generate or override an existing one, you can run: + +`make TARGET=remote savetarget` + +Then you can just run `make` to compile an application, otherwise you will need to do `make TARGET=remote`. + +If you want to upload the compiled firmware to a node via the serial boot loader you need first to either manually enable the boot loader, or just let the Co-Processor detect the flash sequence and do it on your behalf, as simple as not pressing anything at all! + +Then use `make remote-demo.upload PORT=/dev/ttyUSB1`. + +The `PORT` argument is used to specify in which port the device is connected, as we are currently using a dual-channel FTDI chip, at the moment the programming channel is always assigned to the second FTDI channel, so the FTDI will enumerate as `/dev/ttyUSB0`, `/dev/ttyUSB1`, and we would need to use the later one and specify when flashing using the `cc2538-bsl` script, as it will use the first port found by default. This will be improved in the next release. + +To manually enable the boot loader, press the `reset` button on the board while holding the `user` button. (The boot loader backdoor needs to be enabled on the chip for this to work, see README in the `tools/cc2538-bsl` directory for more info) + +To generate an assembly listing of the compiled firmware, run `make remote-demo.lst`. This may be useful for debugging or optimizing your application code. To intersperse the C source code within the assembly listing, you must instruct the compiler to include debugging information by adding `CFLAGS += -g` to the project Makefile and rebuild by running `make clean remote-demo.lst`. + +Node IEEE/RIME/IPv6 Addresses +----------------------------- + +Nodes will generally autoconfigure their IPv6 address based on their IEEE address. The IEEE address can be read directly from the CC2538 Info Page, or it can be hard-coded. Additionally, the user may specify a 2-byte value at build time, which will be used as the IEEE address' 2 LSBs. + +To configure the IEEE address source location (Info Page or hard-coded), use the `IEEE_ADDR_CONF_HARDCODED` define in contiki-conf.h: + +* 0: Info Page +* 1: Hard-coded + +If `IEEE_ADDR_CONF_HARDCODED` is defined as 1, the IEEE address will take its value from the `IEEE_ADDR_CONF_ADDRESS` define. If `IEEE_ADDR_CONF_HARDCODED` is defined as 0, the IEEE address can come from either the primary or secondary location in the Info Page. To use the secondary address, define `IEEE_ADDR_CONF_USE_SECONDARY_LOCATION` as 1. + +Additionally, you can override the IEEE's 2 LSBs, by using the `NODEID` make variable. The value of `NODEID` will become the value of the `IEEE_ADDR_NODE_ID` pre-processor define. If `NODEID` is not defined, `IEEE_ADDR_NODE_ID` will not get defined either. For example: + + make NODEID=0x79ab + +This will result in the 2 last bytes of the IEEE address getting set to 0x79 0xAB + +Note: Some early production devices do not have am IEEE address written on the Info Page. For those devices, using value 0 above will result in a Rime address of all 0xFFs. If your device is in this category, define `IEEE_ADDR_CONF_HARDCODED` to 1 and specify `NODEID` to differentiate between devices. + + + +Low-Power Modes +--------------- +The CC2538 port supports power modes for low energy consumption. The SoC will enter a low power mode as part of the main loop when there are no more events to service. + +LPM support can be disabled in its entirety by setting `LPM_CONF_ENABLE` to 0 in `contiki-conf.h` or `project-conf.h`. + +NOTE: If you are using PG2 version of the Evaluation Module, the SoC will refuse to enter Power Modes 1+ if the debugger is connected and will always enter PM0 regardless of configuration. In order to get real low power mode functionality, make sure the debugger is disconnected. The Battery Board is ideal to test this. + +The Low-Power module uses a simple heuristic to determine the best power mode, depending on anticipated Deep Sleep duration and the state of various peripherals. + +In a nutshell, the algorithm first answers the following questions: + +* Is the RF off? +* Are all registered peripherals permitting PM1+? +* Is the Sleep Timer scheduled to fire an interrupt? + +If the answer to any of the above question is "No", the SoC will enter PM0. If the answer to all questions is "Yes", the SoC will enter one of PMs 0/1/2 depending on the expected Deep Sleep duration and subject to user configuration and application requirements. + +At runtime, the application may enable/disable some Power Modes by making calls to `lpm_set_max_pm()`. For example, to avoid PM2 an application could call `lpm_set_max_pm(1)`. Subsequently, to re-enable PM2 the application would call `lpm_set_max_pm(2)`. + +The LPM module can be configured with a hard maximum permitted power mode. + + #define LPM_CONF_MAX_PM N + +Where N corresponds to the PM number. Supported values are 0, 1, 2. PM3 is not supported. Thus, if the value of the define is 1, the SoC will only ever enter PMs 0 or 1 but never 2 and so on. + +The configuration directive `LPM_CONF_MAX_PM` sets a hard upper boundary. For instance, if `LPM_CONF_MAX_PM` is defined as 1, calls to `lpm_set_max_pm()` can only enable/disable PM1. In this scenario, PM2 can not be enabled at runtime. + +When setting `LPM_CONF_MAX_PM` to 0 or 1, the entire SRAM will be available. Crucially, when value 2 is used the linker will automatically stop using the SoC's SRAM non-retention area, resulting in a total available RAM of 16MB instead of 32MB. + +### LPM and Duty Cycling Driver +LPM is highly related to the operations of the Radio Duty Cycling (RDC) driver of the Contiki network stack and will work correctly with ContikiMAC and NullRDC. + +* With ContikiMAC, PMs 0/1/2 are supported subject to user configuration. +* When NullRDC is in use, the radio will be always on. As a result, the algorithm discussed above will always choose PM0 and will never attempt to drop to PM1/2. + +### Shutdown Mode +The Re-Mote allows to further reduce power consumption by shutting down entirely all the components but the Co-Processor, powering completely of the CC2538 and CC1120 even preventing quiescent current from being drawn, allowing the platform to awake after a given period governed by the Co-Processor and the built-in battery management IC. This effectively reduces the power consumption down to 3-4uA. + +Build headless nodes +-------------------- +It is possible to turn off all character I/O for nodes not connected to a PC. Doing this will entirely disable the UART as well as the USB controller, preserving energy in the long term. The define used to achieve this is (1: Quiet, 0: Normal output): + + #define CC2538_CONF_QUIET 0 + +Setting this define to 1 will automatically set the following to 0: + +* `USB_SERIAL_CONF_ENABLE` +* `UART_CONF_ENABLE` +* `STARTUP_CONF_VERBOSE` + +Code Size Optimisations +----------------------- +The build system currently uses optimization level `-Os`, which is controlled indirectly through the value of the `SMALL` make variable. This value can be overridden by example makefiles, or it can be changed directly in `platform/remote/Makefile.remote`. + +Historically, the `-Os` flag has caused problems with some toolchains. If you are using one of the toolchains documented in this README, you should be able to use it without issues. If for whatever reason you do come across problems, try setting `SMALL=0` or replacing `-Os` with `-O2` in `cpu/cc2538/Makefile.cc2538`. + +Doxygen Documentation +===================== +This port's code has been documented with doxygen. To build the documentation, navigate to `$(CONTIKI)/doc` and run `make`. This will build the entire contiki documentation and may take a while. + +If you want to build this platform's documentation only and skip the remaining platforms, run this: + + make basedirs="platform/remote core cpu/cc2538 examples/remote examples/cc2538dk" + +Once you've built the docs, open `$(CONTIKI)/doc/html/index.html` and enjoy. + +Other Versions of this Guide +============================ +If you prefer this guide in other formats, use the excellent [pandoc] to convert it. + +* **pdf**: `pandoc -s --toc README.md -o README.pdf` +* **html**: `pandoc -s --toc README.md -o README.html` + +More Reading +============ +1. [Zolertia Re-Mote website][remote-site] +2. [CC2538 System-on-Chip Solution for 2.4-GHz IEEE 802.15.4 and ZigBee®/ZigBee IP® Applications, (SWRU319B)][cc2538] +3. [CC1120 sub-1GHz RF transceiver][cc1120] + +[remote-site]: http://www.zolertia.io/products "Zolertia Re-Mote" +[cc1120]: http://www.ti.com/cc1120 "CC1120" +[smart-rf-studio]: http://www.ti.com/tool/smartrftm-studio "SmartRF Studio" +[smart-rf-flashprog]: http://www.ti.com/tool/flash-programmer "SmartRF Flash Programmer" +[cc2538]: http://www.ti.com/product/cc2538 "CC2538" +[uniflash]: http://processors.wiki.ti.com/index.php/Category:CCS_UniFlash "UniFlash" +[pandoc]: http://johnmacfarlane.net/pandoc/ "Pandoc - a universal document converter" diff --git a/platform/remote/contiki-conf.h b/platform/remote/contiki-conf.h new file mode 100644 index 000000000..959e5fe4b --- /dev/null +++ b/platform/remote/contiki-conf.h @@ -0,0 +1,525 @@ +/** + * \addtogroup remote + * @{ + * + * \file + * Configuration for the Re-Mote platform + */ +#ifndef CONTIKI_CONF_H_ +#define CONTIKI_CONF_H_ + +#include +#include +/*---------------------------------------------------------------------------*/ +/* Include Project Specific conf */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ +/*---------------------------------------------------------------------------*/ +/** + * \name Compiler configuration and platform-specific type definitions + * + * Those values are not meant to be modified by the user + * @{ + */ +#define CLOCK_CONF_SECOND 128 + +/* Compiler configurations */ +#define CCIF +#define CLIF + +/* Platform typedefs */ +typedef uint32_t clock_time_t; +typedef uint32_t uip_stats_t; + +/* + * rtimer.h typedefs rtimer_clock_t as unsigned short. We need to define + * RTIMER_CLOCK_LT to override this + */ +typedef uint32_t rtimer_clock_t; +#define RTIMER_CLOCK_LT(a,b) ((int32_t)((a)-(b)) < 0) +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Serial Boot Loader Backdoor configuration + * + * @{ + */ +#ifndef FLASH_CCA_CONF_BOOTLDR_BACKDOOR +#define FLASH_CCA_CONF_BOOTLDR_BACKDOOR 1 /** RAM DMA channel */ +#define USB_ARCH_CONF_TX_DMA_CHAN 1 /**< RAM -> USB DMA channel */ +#define CC2538_RF_CONF_TX_DMA_CHAN 2 /**< RF -> RAM DMA channel */ +#define CC2538_RF_CONF_RX_DMA_CHAN 3 /**< RAM -> RF DMA channel */ +#define UDMA_CONF_MAX_CHANNEL CC2538_RF_CONF_RX_DMA_CHAN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Character I/O Configuration + * + * @{ + */ +#ifndef UART_CONF_ENABLE +#define UART_CONF_ENABLE 1 /**< Enable/Disable UART I/O */ +#endif + +#ifndef UART0_CONF_BAUD_RATE +#define UART0_CONF_BAUD_RATE 115200 /**< Default UART0 baud rate */ +#endif + +#ifndef UART1_CONF_BAUD_RATE +#define UART1_CONF_BAUD_RATE 115200 /**< Default UART1 baud rate */ +#endif + +#ifndef SLIP_ARCH_CONF_USB +#define SLIP_ARCH_CONF_USB 0 /**< SLIP over UART by default */ +#endif + +#ifndef CC2538_RF_CONF_SNIFFER_USB +#define CC2538_RF_CONF_SNIFFER_USB 0 /**< Sniffer out over UART by default */ +#endif + +#ifndef DBG_CONF_USB +#define DBG_CONF_USB 0 /**< All debugging over UART by default */ +#endif + +#ifndef SERIAL_LINE_CONF_UART +#define SERIAL_LINE_CONF_UART 0 /**< UART to use with serial line */ +#endif + +#if !SLIP_ARCH_CONF_USB +#ifndef SLIP_ARCH_CONF_UART +#define SLIP_ARCH_CONF_UART 0 /**< UART to use with SLIP */ +#endif +#endif + +#if !CC2538_RF_CONF_SNIFFER_USB +#ifndef CC2538_RF_CONF_SNIFFER_UART +#define CC2538_RF_CONF_SNIFFER_UART 0 /**< UART to use with sniffer */ +#endif +#endif + +#if !DBG_CONF_USB +#ifndef DBG_CONF_UART +#define DBG_CONF_UART 0 /**< UART to use for debugging */ +#endif +#endif + +#ifndef UART1_CONF_UART +#define UART1_CONF_UART 0 /**< UART to use for examples relying on + the uart1_* API */ +#endif + +/* Turn off example-provided putchars */ +#define SLIP_BRIDGE_CONF_NO_PUTCHAR 1 +#define SLIP_RADIO_CONF_NO_PUTCHAR 1 + +#ifndef SLIP_ARCH_CONF_ENABLED +/* + * Determine whether we need SLIP + * This will keep working while UIP_FALLBACK_INTERFACE and CMD_CONF_OUTPUT + * keep using SLIP + */ +#if defined (UIP_FALLBACK_INTERFACE) || defined (CMD_CONF_OUTPUT) +#define SLIP_ARCH_CONF_ENABLED 1 +#endif +#endif + +/* + * When set, the radio turns off address filtering and sends all captured + * frames down a peripheral (UART or USB, depending on the value of + * CC2538_RF_CONF_SNIFFER_USB) + */ +#ifndef CC2538_RF_CONF_SNIFFER +#define CC2538_RF_CONF_SNIFFER 0 +#endif + +/** + * \brief Define this as 1 to build a headless node. + * + * The UART will not be initialised its clock will be gated, offering some + * energy savings. The USB will not be initialised either + */ +#ifndef CC2538_CONF_QUIET +#define CC2538_CONF_QUIET 0 +#endif + +/* CC2538_CONF_QUIET is hard and overrides all other related defines */ +#if CC2538_CONF_QUIET +#undef USB_SERIAL_CONF_ENABLE +#define USB_SERIAL_CONF_ENABLE 0 + +#undef UART_CONF_ENABLE +#define UART_CONF_ENABLE 0 + +#undef STARTUP_CONF_VERBOSE +#define STARTUP_CONF_VERBOSE 0 + +/* Little sanity check: We can't have quiet sniffers */ +#if CC2538_RF_CONF_SNIFFER +#error "CC2538_RF_CONF_SNIFFER == 1 and CC2538_CONF_QUIET == 1" +#error "These values are conflicting. Please set either to 0" +#endif +#endif /* CC2538_CONF_QUIET */ + +/** + * \brief Enable the USB core only if we need it + */ +#ifndef USB_SERIAL_CONF_ENABLE +#define USB_SERIAL_CONF_ENABLE \ + ((SLIP_ARCH_CONF_USB & SLIP_ARCH_CONF_ENABLED) | \ + DBG_CONF_USB | \ + (CC2538_RF_CONF_SNIFFER & CC2538_RF_CONF_SNIFFER_USB)) +#endif + +/* + * If debugging and SLIP use the same peripheral, this will be 1. Don't modify + * this + */ +#if SLIP_ARCH_CONF_ENABLED +#define DBG_CONF_SLIP_MUX (SLIP_ARCH_CONF_USB == DBG_CONF_USB && \ + (SLIP_ARCH_CONF_USB || \ + SLIP_ARCH_CONF_UART == DBG_CONF_UART)) +#endif + +/* + * Automatic detection of whether a specific UART is in use + */ +#define UART_IN_USE_BY_SERIAL_LINE(u) (SERIAL_LINE_CONF_UART == (u)) +#define UART_IN_USE_BY_SLIP(u) (SLIP_ARCH_CONF_ENABLED && \ + !SLIP_ARCH_CONF_USB && \ + SLIP_ARCH_CONF_UART == (u)) +#define UART_IN_USE_BY_RF_SNIFFER(u) (CC2538_RF_CONF_SNIFFER && \ + !CC2538_RF_CONF_SNIFFER_USB && \ + CC2538_RF_CONF_SNIFFER_UART == (u)) +#define UART_IN_USE_BY_DBG(u) (!DBG_CONF_USB && DBG_CONF_UART == (u)) +#define UART_IN_USE_BY_UART1(u) (UART1_CONF_UART == (u)) + +#define UART_IN_USE(u) ( \ + UART_CONF_ENABLE && \ + (UART_IN_USE_BY_SERIAL_LINE(u) || \ + UART_IN_USE_BY_SLIP(u) || \ + UART_IN_USE_BY_RF_SNIFFER(u) || \ + UART_IN_USE_BY_DBG(u) || \ + UART_IN_USE_BY_UART1(u)) \ +) +/** @} */ +/*---------------------------------------------------------------------------*/ +/* board.h assumes that basic configuration is done */ +#include "board.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Network Stack Configuration + * + * @{ + */ +#ifndef NETSTACK_CONF_NETWORK +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_NETWORK sicslowpan_driver +#else +#define NETSTACK_CONF_NETWORK rime_driver +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_NETWORK */ + +#ifndef NETSTACK_CONF_MAC +#define NETSTACK_CONF_MAC csma_driver +#endif + +#ifndef NETSTACK_CONF_RDC +#define NETSTACK_CONF_RDC contikimac_driver +#endif + +/* Configure NullRDC for when it's selected */ +#define NULLRDC_802154_AUTOACK 1 +#define NULLRDC_802154_AUTOACK_HW 1 + +/* Configure ContikiMAC for when it's selected */ +#define CONTIKIMAC_CONF_WITH_PHASE_OPTIMIZATION 0 +#define WITH_FAST_SLEEP 1 + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif + +#ifndef NETSTACK_CONF_FRAMER +#if NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_FRAMER framer_802154 +#else /* NETSTACK_CONF_WITH_IPV6 */ +#define NETSTACK_CONF_FRAMER contikimac_framer +#endif /* NETSTACK_CONF_WITH_IPV6 */ +#endif /* NETSTACK_CONF_FRAMER */ + +/* This can be overriden to use the cc1120_driver instead */ +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc2538_rf_driver +#endif + +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name LPM configuration + * @{ + */ +#ifndef LPM_CONF_ENABLE +#define LPM_CONF_ENABLE 1 /**< Set to 0 to disable LPM entirely */ +#endif + +/** + * \brief Maximum PM + * + * The SoC will never drop to a Power Mode deeper than the one specified here. + * 0 for PM0, 1 for PM1 and 2 for PM2 + */ +#ifndef LPM_CONF_MAX_PM +#define LPM_CONF_MAX_PM 2 +#endif + +#ifndef LPM_CONF_STATS +#define LPM_CONF_STATS 0 /**< Set to 1 to enable LPM-related stats */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IEEE address configuration + * + * Used to generate our RIME & IPv6 address + * @{ + */ +/** + * \brief Location of the IEEE address + * 0 => Read from InfoPage, + * 1 => Use a hardcoded address, configured by IEEE_ADDR_CONF_ADDRESS + */ +#ifndef IEEE_ADDR_CONF_HARDCODED +#define IEEE_ADDR_CONF_HARDCODED 0 +#endif + +/** + * \brief The hardcoded IEEE address to be used when IEEE_ADDR_CONF_HARDCODED + * is defined as 1 + */ +#ifndef IEEE_ADDR_CONF_ADDRESS +#define IEEE_ADDR_CONF_ADDRESS { 0x00, 0x12, 0x4B, 0x00, 0x89, 0xAB, 0xCD, 0xEF } +#endif + +/** + * \brief Location of the IEEE address in the InfoPage when + * IEEE_ADDR_CONF_HARDCODED is defined as 0 + * 0 => Use the primary address location + * 1 => Use the secondary address location + */ +#ifndef IEEE_ADDR_CONF_USE_SECONDARY_LOCATION +#define IEEE_ADDR_CONF_USE_SECONDARY_LOCATION 0 +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name RF configuration + * + * @{ + */ +/* RF Config */ +#ifndef IEEE802154_CONF_PANID +#define IEEE802154_CONF_PANID 0xABCD +#endif + +#ifndef CC2538_RF_CONF_CHANNEL +#define CC2538_RF_CONF_CHANNEL 25 +#endif /* CC2538_RF_CONF_CHANNEL */ + +#ifndef CC2538_RF_CONF_AUTOACK +#define CC2538_RF_CONF_AUTOACK 1 /**< RF H/W generates ACKs */ +#endif /* CC2538_CONF_AUTOACK */ + +#ifndef CC2538_RF_CONF_TX_USE_DMA +#define CC2538_RF_CONF_TX_USE_DMA 1 /**< RF TX over DMA */ +#endif + +#ifndef CC2538_RF_CONF_RX_USE_DMA +#define CC2538_RF_CONF_RX_USE_DMA 1 /**< RF RX over DMA */ +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name IPv6, RIME and network buffer configuration + * + * @{ + */ + +/* Don't let contiki-default-conf.h decide if we are an IPv6 build */ +#ifndef NETSTACK_CONF_WITH_IPV6 +#define NETSTACK_CONF_WITH_IPV6 0 +#endif + +#if NETSTACK_CONF_WITH_IPV6 +/* Addresses, Sizes and Interfaces */ +/* 8-byte addresses here, 2 otherwise */ +#define LINKADDR_CONF_SIZE 8 +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 +#define UIP_CONF_NETIF_MAX_ADDRESSES 3 + +/* TCP, UDP, ICMP */ +#ifndef UIP_CONF_TCP +#define UIP_CONF_TCP 1 +#endif +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 64 +#endif +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_ICMP6 1 + +/* ND and Routing */ +#ifndef UIP_CONF_ROUTER +#define UIP_CONF_ROUTER 1 +#endif + +#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 + +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#ifndef NBR_TABLE_CONF_MAX_NEIGHBORS +#define NBR_TABLE_CONF_MAX_NEIGHBORS 20 +#endif +#ifndef UIP_CONF_MAX_ROUTES +#define UIP_CONF_MAX_ROUTES 20 +#endif + +/* uIP */ +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 1300 +#endif + +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 +#define UIP_CONF_MAX_LISTENPORTS 8 + +/* 6lowpan */ +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_COMPRESSION_THRESHOLD +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 +#endif +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#endif +#define SICSLOWPAN_CONF_MAXAGE 8 + +/* Define our IPv6 prefixes/contexts here */ +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 1 +#ifndef SICSLOWPAN_CONF_ADDR_CONTEXT_0 +#define SICSLOWPAN_CONF_ADDR_CONTEXT_0 { \ + addr_contexts[0].prefix[0] = 0xaa; \ + addr_contexts[0].prefix[1] = 0xaa; \ +} +#endif + +#define MAC_CONF_CHANNEL_CHECK_RATE 8 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif +/*---------------------------------------------------------------------------*/ +#else /* NETSTACK_CONF_WITH_IPV6 */ +/* Network setup for non-IPv6 (rime). */ +#define UIP_CONF_IP_FORWARD 1 + +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 108 +#endif + +#define RIME_CONF_NO_POLITE_ANNOUCEMENTS 0 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif + +#endif /* NETSTACK_CONF_WITH_IPV6 */ +/** @} */ +/*---------------------------------------------------------------------------*/ + +#endif /* CONTIKI_CONF_H_ */ + +/** @} */ diff --git a/platform/remote/contiki-main.c b/platform/remote/contiki-main.c new file mode 100644 index 000000000..562af4e66 --- /dev/null +++ b/platform/remote/contiki-main.c @@ -0,0 +1,244 @@ +/* + * Copyright (c) 2012, 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 platform + * @{ + * + * \defgroup remote Zolertia Re-Mote platform + * + * The Re-Mote is the new platform by Zolertia based on the cc2538, featuring a + * cc2538 SoC with an ARM Cortex-M3 core plus the CC1120 Sub-1Ghz transceiver + * @{ + * + * \file + * Main module for the Re-Mote platform + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/leds.h" +#include "dev/sys-ctrl.h" +#include "dev/scb.h" +#include "dev/nvic.h" +#include "dev/uart.h" +#include "dev/watchdog.h" +#include "dev/ioc.h" +#include "dev/button-sensor.h" +#include "dev/serial-line.h" +#include "dev/slip.h" +#include "dev/cc2538-rf.h" +#include "dev/udma.h" +#include "usb/usb-serial.h" +#include "lib/random.h" +#include "net/netstack.h" +#include "net/queuebuf.h" +#include "net/ip/tcpip.h" +#include "net/ip/uip.h" +#include "net/mac/frame802154.h" +#include "cpu.h" +#include "reg.h" +#include "ieee-addr.h" +#include "lpm.h" +#include "dev/antenna-sw.h" + +#include +#include +#include +/*---------------------------------------------------------------------------*/ +#if STARTUP_CONF_VERBOSE +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#if UART_CONF_ENABLE +#define PUTS(s) puts(s) +#else +#define PUTS(s) +#endif +/*---------------------------------------------------------------------------*/ +static void +fade(unsigned char l) +{ + volatile int i; + int k, j; + for(k = 0; k < 800; ++k) { + j = k > 400 ? 800 - k : k; + + leds_on(l); + for(i = 0; i < j; ++i) { + asm("nop"); + } + leds_off(l); + for(i = 0; i < 400 - j; ++i) { + asm("nop"); + } + } +} +/*---------------------------------------------------------------------------*/ +static void +set_rf_params(void) +{ + uint16_t short_addr; + uint8_t ext_addr[8]; + + ieee_addr_cpy_to(ext_addr, 8); + + short_addr = ext_addr[7]; + short_addr |= ext_addr[6] << 8; + + /* Populate linkaddr_node_addr. Maintain endianness */ + memcpy(&linkaddr_node_addr, &ext_addr[8 - LINKADDR_SIZE], LINKADDR_SIZE); + +#if STARTUP_CONF_VERBOSE + { + int i; + printf("Rime configured with address "); + for(i = 0; i < LINKADDR_SIZE - 1; i++) { + printf("%02x:", linkaddr_node_addr.u8[i]); + } + printf("%02x\n", linkaddr_node_addr.u8[i]); + } +#endif + + 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, CC2538_RF_CHANNEL); + NETSTACK_RADIO.set_object(RADIO_PARAM_64BIT_ADDR, ext_addr, 8); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Main routine for the Re-Mote platform + */ +int +main(void) +{ + nvic_init(); + ioc_init(); + sys_ctrl_init(); + clock_init(); + lpm_init(); + rtimer_init(); + gpio_init(); + + leds_init(); + fade(LEDS_RED); + + process_init(); + + watchdog_init(); + SENSORS_ACTIVATE(button_sensor); + + /* + * Character I/O Initialisation. + * When the UART receives a character it will call serial_line_input_byte to + * notify the core. The same applies for the USB driver. + * + * If slip-arch is also linked in afterwards (e.g. if we are a border router) + * it will overwrite one of the two peripheral input callbacks. Characters + * received over the relevant peripheral will be handled by + * slip_input_byte instead + */ +#if UART_CONF_ENABLE + uart_init(0); + uart_init(1); + uart_set_input(SERIAL_LINE_CONF_UART, serial_line_input_byte); +#endif + +#if USB_SERIAL_CONF_ENABLE + usb_serial_init(); + usb_serial_set_input(serial_line_input_byte); +#endif + + serial_line_init(); + + INTERRUPTS_ENABLE(); + fade(LEDS_BLUE); + + PUTS(CONTIKI_VERSION_STRING); + PUTS(BOARD_STRING); + + PRINTF(" Net: "); + PRINTF("%s\n", NETSTACK_NETWORK.name); + PRINTF(" MAC: "); + PRINTF("%s\n", NETSTACK_MAC.name); + PRINTF(" RDC: "); + PRINTF("%s\n", NETSTACK_RDC.name); + + /* Initialise the H/W RNG engine. */ + random_init(0); + + udma_init(); + + process_start(&etimer_process, NULL); + ctimer_init(); + + set_rf_params(); + netstack_init(); + +#if NETSTACK_CONF_WITH_IPV6 + memcpy(&uip_lladdr.addr, &linkaddr_node_addr, sizeof(uip_lladdr.addr)); + queuebuf_init(); + process_start(&tcpip_process, NULL); +#endif /* NETSTACK_CONF_WITH_IPV6 */ + + antenna_sw_config(); + + process_start(&sensors_process, NULL); + + SENSORS_ACTIVATE(button_sensor); + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + autostart_start(autostart_processes); + + watchdog_start(); + fade(LEDS_GREEN); + + while(1) { + uint8_t r; + do { + /* Reset watchdog and handle polls and events */ + watchdog_periodic(); + + r = process_run(); + } while(r > 0); + + /* We have serviced all pending events. Enter a Low-Power mode. */ + lpm_enter(); + } +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/platform/remote/dev/antenna-sw.c b/platform/remote/dev/antenna-sw.c new file mode 100644 index 000000000..6d320fedc --- /dev/null +++ b/platform/remote/dev/antenna-sw.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015, Zolertia + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-antenna + * @{ + * + * Driver for the Re-Mote 2.4Ghz antenna switch, to enable either the internal + * ceramic antenna or an external one connected to the uFL connector + * @{ + * + * \file + * Driver for the Re-Mote 2.4Ghz antenna switch + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/gpio.h" +#include "antenna-sw.h" + +#include +/*---------------------------------------------------------------------------*/ +#define ANTENNA_2_4GHZ_SW_PORT_BASE GPIO_PORT_TO_BASE(ANTENNA_2_4GHZ_SW_PORT) +#define ANTENNA_2_4GHZ_SW_PIN_MASK GPIO_PIN_MASK(ANTENNA_2_4GHZ_SW_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t initialized = 0; +/*---------------------------------------------------------------------------*/ +void +antenna_sw_config(void) +{ + /* Software controlled */ + GPIO_SOFTWARE_CONTROL(ANTENNA_2_4GHZ_SW_PORT_BASE, + ANTENNA_2_4GHZ_SW_PIN_MASK); + + /* Set pin to output */ + GPIO_SET_OUTPUT(ANTENNA_2_4GHZ_SW_PORT_BASE, ANTENNA_2_4GHZ_SW_PIN_MASK); + + /* Set the antenna selector to a default position */ + GPIO_CLR_PIN(ANTENNA_2_4GHZ_SW_PORT_BASE, ANTENNA_2_4GHZ_SW_PIN_MASK); + + initialized = 1; +} +/*---------------------------------------------------------------------------*/ +int +antenna_sw_select(uint8_t val) +{ + if(!initialized) { + return ANTENNA_SW_SELECT_ERROR; + } + + if(val != ANTENNA_SW_SELECT_INTERNAL && val != ANTENNA_SW_SELECT_EXTERNAL) { + return ANTENNA_SW_SELECT_ERROR; + } + + /* Set the antenna selector */ + GPIO_WRITE_PIN(ANTENNA_2_4GHZ_SW_PORT_BASE, ANTENNA_2_4GHZ_SW_PIN_MASK, val); + + return val; +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/platform/remote/dev/antenna-sw.h b/platform/remote/dev/antenna-sw.h new file mode 100644 index 000000000..a93f580d3 --- /dev/null +++ b/platform/remote/dev/antenna-sw.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2015, Zolertia + * 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. + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup remote + * @{ + * + * \defgroup remote-antenna Re-Mote Antenna switch + * + * Driver for the Re-Mote 2.4Ghz antenna switch, to enable either the internal + * ceramic antenna or an external one connected to the uFL connector + * @{ + * + * \file + * Header file for the Re-Mote 2.4Ghz antenna switch Driver + */ +/* -------------------------------------------------------------------------- */ +#ifndef ANTENNA_SW_H_ +#define ANTENNA_SW_H_ +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ +#define ANTENNA_SW_SELECT_EXTERNAL 0xFF +#define ANTENNA_SW_SELECT_INTERNAL 0x00 + +#define ANTENNA_SW_SELECT_ERROR -1 +/* -------------------------------------------------------------------------- */ +/** + * \brief Init function for the antenna switch + * + * The Re-Mote platform allows to programatically select between the 2.4Ghz + * internal or external antenna. + * The function is set to enable using the internal ceramic antenna as default, + * it should be called from the contiki-main initialization process. + * + * \return ignored + */ +void antenna_sw_config(void); + +/** + * \brief Function to select between the internal or external 2.4Ghz antenna + * + * \param val Select antenna. + * External: ANTENNA_SW_SELECT_EXTERNAL or + * Internal (ceramic): ANTENNA_SW_SELECT_INTERNAL + * \return the selected antenna position, or ANTENNA_SW_SELECT_ERROR if not + * previously configured + */ +int antenna_sw_select(uint8_t val); +/* -------------------------------------------------------------------------- */ +#endif /* ifndef ANTENNA_SW_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/remote/dev/board.h b/platform/remote/dev/board.h new file mode 100644 index 000000000..71c9b28c3 --- /dev/null +++ b/platform/remote/dev/board.h @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2012, 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 remote + * @{ + * + * \defgroup remote-peripherals Re-Mote Peripherals + * + * Defines related to the Re-Mote + * + * This file provides connectivity information on LEDs, Buttons, UART and + * other Re-Mote peripherals + * + * This file can be used as the basis to configure other platforms using the + * cc2538 SoC. + * @{ + * + * \file + * Header file with definitions related to the I/O connections on the Zolertia's + * Re-Mote platform, cc2538-based + * + * \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 "dev/gpio.h" +#include "dev/nvic.h" +/*---------------------------------------------------------------------------*/ +/** \name Re-Mote LED configuration + * + * LEDs on the Re-mote are connected as follows: + * - LED1 (Red) -> PD2 + * - LED2 (Blue) -> PC3 + * - LED3 (Green) -> PD5 + * + * LED1 routed also to JP5 connector + * LED2 shares the same pin with Watchdog WDI pulse and routed to JP8 connector + * LED3 routed also to JP5 connector + * @{ + */ +/*---------------------------------------------------------------------------*/ +/* 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_BLUE +#undef LEDS_RED +#undef LEDS_CONF_ALL + +/* In leds.h the LEDS_BLUE is defined by LED_YELLOW definition */ +#define LEDS_GREEN 1 /**< LED1 (Green) -> PD5 */ +#define LEDS_BLUE 2 /**< LED2 (Blue) -> PC3 */ +#define LEDS_RED 4 /**< LED3 (Red) -> PD2 */ + +#define LEDS_CONF_ALL 7 + +#define LEDS_LIGHT_BLUE (LEDS_GREEN | LEDS_BLUE) /**< Green + Blue (3) */ +#define LEDS_YELLOW (LEDS_GREEN | LEDS_RED) /**< Green + Red (5) */ +#define LEDS_PURPLE (LEDS_BLUE | LEDS_RED) /**< Blue + Red (6) */ +#define LEDS_WHITE LEDS_ALL /**< Green + Blue + Red (7) */ + +/* Notify various examples that we have LEDs */ +#define PLATFORM_HAS_LEDS 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name USB configuration + * + * The USB pullup is enabled by an external resistor, not mapped to a GPIO + */ +#ifdef USB_PULLUP_PORT +#undef USB_PULLUP_PORT +#endif +#ifdef USB_PULLUP_PIN +#undef USB_PULLUP_PIN +#endif +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name UART configuration + * + * On the Re-Mote, the UART is connected to the following ports/pins + * - UART0: + * - RX: PA0 + * - TX: PA1 + * - UART1: + * - RX: PC6 + * - TX: PC5 + * - CTS: + * - RTS: + * We configure the port to use UART0 and UART1, CTS/RTS only for UART1, + * both without a HW pull-up resistor + * @{ + */ +#define UART0_RX_PORT GPIO_A_NUM +#define UART0_RX_PIN 0 +#define UART0_TX_PORT GPIO_A_NUM +#define UART0_TX_PIN 1 + +#define UART1_RX_PORT GPIO_C_NUM +#define UART1_RX_PIN 6 +#define UART1_TX_PORT GPIO_C_NUM +#define UART1_TX_PIN 5 +#define UART1_CTS_PORT GPIO_C_NUM +#define UART1_CTS_PIN 1 +#define UART1_RTS_PORT GPIO_C_NUM +#define UART1_RTS_PIN 2 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** \name Re-Mote Button configuration + * + * Buttons on the Re-Mote are connected as follows: + * - BUTTON_USER -> PA3, S1 user button, shared with bootloader + * - BUTTON_RESET -> RESET_N line, S2 reset both CC2538 and CoP + * - BUTTON_VBAT -> Power switch, not mounted by default + * @{ + */ +/** BUTTON_USER -> PA3 */ +#define BUTTON_USER_PORT GPIO_A_NUM +#define BUTTON_USER_PIN 3 +#define BUTTON_USER_VECTOR NVIC_INT_GPIO_PORT_A + +/* Notify various examples that we have Buttons */ +#define PLATFORM_HAS_BUTTON 1 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name ADC configuration + * + * These values configure which CC2538 pins and ADC channels to use for the ADC + * inputs. By default the Re-Mote allows two out-of-the-box ADC ports with a + * phidget-like 3-pin connector (GND/3V3/ADC) + * + * ADC inputs can only be on port A. + * @{ + */ +#define ADC_PHIDGET_PORT GPIO_A_NUM /**< Phidget GPIO control port */ +#define ADC_PHIDGET_ADC2_PIN 6 /**< ADC2 to PA6, 3V3 */ +#define ADC_PHIDGET_ADC3_PIN 7 /**< ADC3 to PA7, 3V3 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI0) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI0) lines, + * shared with the CC1120 RF transceiver + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI0_CLK_PORT GPIO_D_NUM +#define SPI0_CLK_PIN 1 +#define SPI0_TX_PORT GPIO_D_NUM +#define SPI0_TX_PIN 0 +#define SPI0_RX_PORT GPIO_C_NUM +#define SPI0_RX_PIN 4 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name SPI (SSI1) configuration + * + * These values configure which CC2538 pins to use for the SPI (SSI1) lines, + * shared with the microSD, not routed anywhere. + * TX -> MOSI, RX -> MISO + * @{ + */ +#define SPI1_CLK_PORT GPIO_B_NUM +#define SPI1_CLK_PIN 5 +#define SPI1_TX_PORT GPIO_C_NUM +#define SPI1_TX_PIN 7 +#define SPI1_RX_PORT GPIO_A_NUM +#define SPI1_RX_PIN 4 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name I2C configuration + * + * These values configure which CC2538 pins to use for the I2C lines, shared + * with the TMP102 built-in temperature sensor + * @{ + */ +#define I2C_SCL_PORT GPIO_B_NUM +#define I2C_SCL_PIN 1 +#define I2C_SDA_PORT GPIO_B_NUM +#define I2C_SDA_PIN 0 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Antenna switch configuration + * + * These values configure the required pin to drive the antenna switch, to + * use either the built-in ceramic antenna or an external one over the uFL + * connector + * - Internal antenna: LOW + * - External antenna: HIGH + * @{ + */ +#define ANTENNA_2_4GHZ_SW_PORT GPIO_D_NUM +#define ANTENNA_2_4GHZ_SW_PIN 4 +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name CC1120/CC1200 configuration + * + * These values configure the required pins to drive the CC1120/CC1200 + * @{ + */ +#define CC1120_SPI_SCLK_PORT SPI0_CLK_PORT +#define CC1120_SPI_SCLK_PIN SPI0_CLK_PIN +#define CC1120_SPI_MOSI_PORT SPIO0_TX_PORT +#define CC1120_SPI_MOSI_PIN SPIO0_TX_PIN +#define CC1120_SPI_MISO_PORT SPIO0_RX_PORT +#define CC1120_SPI_MISO_PIN SPIO0_RX_PIN +#define CC1120_SPI_CSN_PORT GPIO_D_NUM +#define CC1120_SPI_CSN_PIN 3 +#define CC1120_GDO0_PORT GPIO_B_NUM +#define CC1120_GDO0_PIN 4 +#define CC1120_GDO2_PORT GPIO_B_NUM +#define CC1120_GDO2_PIN 3 +#define CC1120_RESET_PORT GPIO_B_NUM +#define CC1120_RESET_PIN 2 +#define CC1120_GPIO0_VECTOR NVIC_INT_GPIO_PORT_B +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name microSD configuration + * + * These values configure the required pins to drive the built-in microSD + * external module, to be used with SSI1 + * @{ + */ +#define USD_CLK_PORT SPI1_CLK_PORT +#define USD_CLK_PIN SPI1_CLK_PIN +#define USD_MOSI_PORT SPI1_TX_PORT +#define USD_MOSI_PIN SPI1_TX_PIN +#define USD_MISO_PORT SPI1_RX_PORT +#define USD_MISO_PIN SPI1_RX_PIN +/** @} */ +/*---------------------------------------------------------------------------*/ +/** + * \name Device string used on startup + * @{ + */ +#define BOARD_STRING "Zolertia Re-Mote platform" +/** @} */ + +#endif /* BOARD_H_ */ + +/** + * @} + * @} + */ diff --git a/platform/remote/dev/button-sensor.c b/platform/remote/dev/button-sensor.c new file mode 100644 index 000000000..4433f3e06 --- /dev/null +++ b/platform/remote/dev/button-sensor.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * 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 remote-button-sensor + * @{ + * + * \file + * Driver for the Re-Mote user button + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/nvic.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/button-sensor.h" +#include "sys/timer.h" +#include "sys/ctimer.h" +#include "sys/process.h" + +#include +#include +/*---------------------------------------------------------------------------*/ +#define BUTTON_USER_PORT_BASE GPIO_PORT_TO_BASE(BUTTON_USER_PORT) +#define BUTTON_USER_PIN_MASK GPIO_PIN_MASK(BUTTON_USER_PIN) +/*---------------------------------------------------------------------------*/ +#define DEBOUNCE_DURATION (CLOCK_SECOND >> 4) + +static struct timer debouncetimer; +/*---------------------------------------------------------------------------*/ +static clock_time_t press_duration = 0; +static struct ctimer press_counter; +static uint8_t press_event_counter; + +process_event_t button_press_duration_exceeded; +/*---------------------------------------------------------------------------*/ +static void +duration_exceeded_callback(void *data) +{ + press_event_counter++; + process_post(PROCESS_BROADCAST, button_press_duration_exceeded, + &press_event_counter); + ctimer_set(&press_counter, press_duration, duration_exceeded_callback, + NULL); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Retrieves the value of the button pin + * \param type Returns the pin level or the counter of press duration events. + * type == BUTTON_SENSOR_VALUE_TYPE_LEVEL or + * type == BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION + * respectively + */ +static int +value(int type) +{ + switch(type) { + case BUTTON_SENSOR_VALUE_TYPE_LEVEL: + return GPIO_READ_PIN(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + case BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION: + return press_event_counter; + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Callback registered with the GPIO module. Gets fired with a button + * port/pin generates an interrupt + * \param port The port number that generated the interrupt + * \param pin The pin number that generated the interrupt. This is the pin + * absolute number (i.e. 0, 1, ..., 7), not a mask + */ +static void +btn_callback(uint8_t port, uint8_t pin) +{ + if(!timer_expired(&debouncetimer)) { + return; + } + + timer_set(&debouncetimer, DEBOUNCE_DURATION); + + if(press_duration) { + press_event_counter = 0; + if(value(BUTTON_SENSOR_VALUE_TYPE_LEVEL) == BUTTON_SENSOR_PRESSED_LEVEL) { + ctimer_set(&press_counter, press_duration, duration_exceeded_callback, + NULL); + } else { + ctimer_stop(&press_counter); + } + } + + sensors_changed(&button_sensor); +} +/*---------------------------------------------------------------------------*/ +/** + * \brief Init function for the User button. + * \param type SENSORS_ACTIVE: Activate / Deactivate the sensor (value == 1 + * or 0 respectively) + * + * \param value Depends on the value of the type argument + * \return Depends on the value of the type argument + */ +static int +config_user(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + button_press_duration_exceeded = process_alloc_event(); + + /* Software controlled */ + GPIO_SOFTWARE_CONTROL(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Set pin to input */ + GPIO_SET_INPUT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Enable edge detection */ + GPIO_DETECT_EDGE(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + /* Both Edges */ + GPIO_TRIGGER_BOTH_EDGES(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + + ioc_set_over(BUTTON_USER_PORT, BUTTON_USER_PIN, IOC_OVERRIDE_PUE); + + gpio_register_callback(btn_callback, BUTTON_USER_PORT, BUTTON_USER_PIN); + break; + case SENSORS_ACTIVE: + if(value) { + GPIO_ENABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + nvic_interrupt_enable(BUTTON_USER_VECTOR); + } else { + GPIO_DISABLE_INTERRUPT(BUTTON_USER_PORT_BASE, BUTTON_USER_PIN_MASK); + nvic_interrupt_disable(BUTTON_USER_VECTOR); + } + return value; + case BUTTON_SENSOR_CONFIG_TYPE_INTERVAL: + press_duration = (clock_time_t)value; + break; + default: + break; + } + + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, value, config_user, NULL); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/remote/dev/button-sensor.h b/platform/remote/dev/button-sensor.h new file mode 100644 index 000000000..817769591 --- /dev/null +++ b/platform/remote/dev/button-sensor.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2012, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * 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 remote-sensors + * @{ + * + * \defgroup remote-button-sensor Re-Mote User Button Driver + * + * Driver for the Re-Mote user button + * + * The Re-Mote button will generate a sensors_changed event on press as well + * as on release. + * + * Unlike many other platforms, the Re-Mote user button has the ability to + * generate events when the user keeps the button pressed. The user can + * configure the button driver with a timer interval in clock ticks. When the + * button is kept pressed, the driver will then generate a broadcast event + * each time the interval passes. For example the driver can be configured to + * generate an event every second while the button is kept pressed. This + * functionality can be enabled through the configure() function, by passing + * BUTTON_SENSOR_CONFIG_TYPE_INTERVAL as the type argument. + * @{ + * + * \file + * Header file for the Re-Mote User Button Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef BUTTON_SENSOR_H_ +#define BUTTON_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR "Button" + +extern const struct sensors_sensor button_sensor; +/*---------------------------------------------------------------------------*/ +extern process_event_t button_press_duration_exceeded; +/*---------------------------------------------------------------------------*/ +#define BUTTON_SENSOR_CONFIG_TYPE_INTERVAL 0x0100 + +#define BUTTON_SENSOR_VALUE_TYPE_LEVEL 0 +#define BUTTON_SENSOR_VALUE_TYPE_PRESS_DURATION 1 + +#define BUTTON_SENSOR_PRESSED_LEVEL 0 +#define BUTTON_SENSOR_RELEASED_LEVEL 8 +/*---------------------------------------------------------------------------*/ +#endif /* BUTTON_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/remote/dev/led-strip.c b/platform/remote/dev/led-strip.c new file mode 100644 index 000000000..a13ad23a8 --- /dev/null +++ b/platform/remote/dev/led-strip.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2015, Zolertia + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-led-strip + * @{ + * + * Driver to control a bright LED strip powered at 3VDC, drawing power directly + * from the battery power supply. An example on how to adapt 12VDC LED strips + * to 3VDC is provided at http://www.hackster.io/zolertia + * @{ + * + * \file + * Driver for the Re-Mote bright LED strip Driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/gpio.h" +#include "led-strip.h" + +#include +/*---------------------------------------------------------------------------*/ +#ifndef LED_STRIP_PORT +#define LED_STRIP_PORT GPIO_A_NUM +#endif +#ifndef LED_STRIP_PIN +#define LED_STRIP_PIN 6 +#endif +#define LED_STRIP_PORT_BASE GPIO_PORT_TO_BASE(LED_STRIP_PORT) +#define LED_STRIP_PIN_MASK GPIO_PIN_MASK(LED_STRIP_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t initialized = 0; +/*---------------------------------------------------------------------------*/ +void +led_strip_config(void) +{ + /* Software controlled */ + GPIO_SOFTWARE_CONTROL(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK); + /* Set pin to output */ + GPIO_SET_OUTPUT(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK); + /* Set the antenna selector to a default position */ + GPIO_SET_PIN(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK); + + initialized = 1; +} +/*---------------------------------------------------------------------------*/ +int +led_strip_switch(uint8_t val) +{ + if(!initialized) { + return LED_STRIP_ERROR; + } + + if(val != LED_STRIP_ON && val != LED_STRIP_OFF) { + return LED_STRIP_ERROR; + } + + /* Set the LED to ON or OFF */ + GPIO_WRITE_PIN(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK, val); + + return val; +} +/*---------------------------------------------------------------------------*/ +int +led_strip_get(void) +{ + if(!initialized) { + return LED_STRIP_ERROR; + } + + /* Inverse logic, return ON if the pin is low */ + if(GPIO_READ_PIN(LED_STRIP_PORT_BASE, LED_STRIP_PIN_MASK)) { + return LED_STRIP_OFF; + } + return LED_STRIP_ON; +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ + diff --git a/platform/remote/dev/led-strip.h b/platform/remote/dev/led-strip.h new file mode 100644 index 000000000..27880668a --- /dev/null +++ b/platform/remote/dev/led-strip.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2015, Zolertia + * 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. + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup remote-sensors + * @{ + * + * \defgroup remote-led-strip Re-Mote LED strip driver + * + * Driver to control a bright LED strip powered at 3VDC, drawing power directly + * from the battery power supply. An example on how to adapt 12VDC LED strips + * to 3VDC is provided at http://www.hackster.io/zolertia + * @{ + * + * \file + * Header file for the Re-Mote bright LED strip Driver + */ +/* -------------------------------------------------------------------------- */ +#ifndef LED_STRIP_H_ +#define LED_STRIP_H_ +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ +#define LED_STRIP_OFF 0xFF +#define LED_STRIP_ON 0x00 + +#define LED_STRIP_ERROR -1 +/* -------------------------------------------------------------------------- */ +/** + * \brief Init function for the bright LED strip driver + * + * The LED strip driver allows to lighten up any application using up to 4 + * LEDs 3VDC-powered per strip + * The function is set to power OFF the LEDs as default, + * it should be called from the contiki-main initialization process. + * + * \return ignored + */ +void led_strip_config(void); + +/** + * \brief Function to turn ON/OFF the LED strip + * + * \param val Set ON/OFF (LED_STRIP_ON or LED_STRIP_OFF) + * \return the selected antenna position, or LED_STRIP_ERROR if not + * previously configured + */ +int led_strip_switch(uint8_t val); + +/** + * \brief Function to get the LED strip current state + * + * \return Current LED strip state or LED_STRIP_ERROR if not + * previously configured + */ +int led_strip_get(void); +/* -------------------------------------------------------------------------- */ +#endif /* ifndef LED_STRIP_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ + diff --git a/platform/remote/dev/leds-arch.c b/platform/remote/dev/leds-arch.c new file mode 100644 index 000000000..a120e4144 --- /dev/null +++ b/platform/remote/dev/leds-arch.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * 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 remote + * @{ + * + * \defgroup remote-leds Re-Mote LED driver + * + * LED driver implementation for the Re-Mote platform + * @{ + * + * \file + * LED driver implementation for the Re-Mote platform + */ +#include "contiki.h" +#include "reg.h" +#include "dev/leds.h" +#include "dev/gpio.h" +/*---------------------------------------------------------------------------*/ +#define LED_GREEN_PORT GPIO_D_BASE +#define LED_GREEN_PIN (1 << 5) + +#define LED_BLUE_PORT GPIO_C_BASE +#define LED_BLUE_PIN (1 << 3) + +#define LED_RED_PORT GPIO_D_BASE +#define LED_RED_PIN (1 << 2) + +#define PORT_D_LEDS (LED_RED_PIN | LED_GREEN_PIN) +#define PORT_C_LEDS LED_BLUE_PIN +/*---------------------------------------------------------------------------*/ +void +leds_arch_init(void) +{ + /* Initialize LED1 (Red) and LED3 (Green) */ + GPIO_SET_OUTPUT(GPIO_D_BASE, PORT_D_LEDS); + GPIO_SET_PIN(GPIO_D_BASE, PORT_D_LEDS); + + /* Initialize LED2 - Blue */ + GPIO_SET_OUTPUT(GPIO_C_BASE, PORT_C_LEDS); + GPIO_SET_PIN(GPIO_C_BASE, PORT_C_LEDS); +} +/*---------------------------------------------------------------------------*/ +unsigned char +leds_arch_get(void) +{ + uint8_t mask_leds; + + mask_leds = GPIO_READ_PIN(LED_GREEN_PORT, LED_GREEN_PIN) == 0? LEDS_GREEN : 0; + mask_leds |= GPIO_READ_PIN(LED_BLUE_PORT, LED_BLUE_PIN) == 0? LEDS_BLUE : 0; + mask_leds |= GPIO_READ_PIN(LED_RED_PORT, LED_RED_PIN) == 0? LEDS_RED : 0; + + return mask_leds; +} +/*---------------------------------------------------------------------------*/ +void +leds_arch_set(unsigned char leds) +{ + if(leds & LEDS_GREEN) { + GPIO_CLR_PIN(LED_GREEN_PORT, LED_GREEN_PIN); + } else { + GPIO_SET_PIN(LED_GREEN_PORT, LED_GREEN_PIN); + } + + if(leds & LEDS_BLUE) { + GPIO_CLR_PIN(LED_BLUE_PORT, LED_BLUE_PIN); + } else { + GPIO_SET_PIN(LED_BLUE_PORT, LED_BLUE_PIN); + } + + if(leds & LEDS_RED) { + GPIO_CLR_PIN(LED_RED_PORT, LED_RED_PIN); + } else { + GPIO_SET_PIN(LED_RED_PORT, LED_RED_PIN); + } +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/platform/remote/dev/mp3-wtv020sd.c b/platform/remote/dev/mp3-wtv020sd.c new file mode 100644 index 000000000..7897c3d33 --- /dev/null +++ b/platform/remote/dev/mp3-wtv020sd.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2015, Zolertia + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-mp3-wtv020sd + * @{ + * + * Driver to control the MP3 WTV020SD board in MP3 mode (GPIO based) and the + * 2-line serial mode (CLK/DI). Loop Mode and Key Modes not implemented. + * More product information available at: + * http://avrproject.ru/chasy-budilnik/WTV020SD.pdf + * An example on how to wire with a sound power amplifier and speakers at + * http://www.hackster.io/zolertia + * @{ + * + * \file + * Header file for the MP3 WTV020SD driver + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "dev/gpio.h" +#include "mp3-wtv020sd.h" + +#include +/*---------------------------------------------------------------------------*/ + +/* + * The WTV020SD can be used in MP3 mode (GPIO-controlled) or 2-line mode (CLK + * and DATA line). The following pin-out can be implemented without reusing + * the pins as below (in 2-line mode the CLK/DATA functions replace the VOL+/- + * keys, others remain the same), but this would require more GPIOs to + * interface all functions, so we chose the configuration that uses the less + * number of GPIOs, and emulate all functions available in each mode + */ +#ifndef MP3_WTV020SD_P07_PORT +#define MP3_WTV020SD_P07_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_P07_PIN +#define MP3_WTV020SD_P07_PIN 0 +#endif +#ifndef MP3_WTV020SD_P02_PORT +#define MP3_WTV020SD_P02_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_P02_PIN +#define MP3_WTV020SD_P02_PIN 1 +#endif +#ifndef MP3_WTV020SD_P06_PORT +#define MP3_WTV020SD_P06_PORT GPIO_C_NUM +#endif +#ifndef MP3_WTV020SD_P06_PIN +#define MP3_WTV020SD_P06_PIN 1 +#endif +#ifndef MP3_WTV020SD_P04_PORT +#define MP3_WTV020SD_P04_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_P04_PIN +#define MP3_WTV020SD_P04_PIN 0 +#endif +#ifndef MP3_WTV020SD_P05_PORT +#define MP3_WTV020SD_P05_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_P05_PIN +#define MP3_WTV020SD_P05_PIN 1 +#endif +#ifndef MP3_WTV020SD_RESET_PORT +#define MP3_WTV020SD_RESET_PORT GPIO_B_NUM +#endif +#ifndef MP3_WTV020SD_RESET_PIN +#define MP3_WTV020SD_RESET_PIN 1 +#endif + +/* The BUSY pin is shared between operation modes */ +#define MP3_BUSY_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P06_PORT) +#define MP3_BUSY_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P06_PIN) + +#define MP3_PLAY_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P07_PORT) +#define MP3_PLAY_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P07_PIN) +#define MP3_NEXT_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P02_PORT) +#define MP3_NEXT_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P02_PIN) + +#define MP3_RESET_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_RESET_PORT) +#define MP3_RESET_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_RESET_PIN) +#define MP3_CLK_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P04_PORT) +#define MP3_CLK_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P04_PIN) +#define MP3_DATA_PORT_BASE GPIO_PORT_TO_BASE(MP3_WTV020SD_P05_PORT) +#define MP3_DATA_PIN_MASK GPIO_PIN_MASK(MP3_WTV020SD_P05_PIN) + +/*---------------------------------------------------------------------------*/ +static uint8_t initialized = 0; +static int mp3_line_command(uint16_t cmd); +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_config(uint8_t mode) +{ + if(mode != MP3_WTV020SD_GPIO_MODE && mode != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + + if(mode == MP3_WTV020SD_GPIO_MODE) { + GPIO_SOFTWARE_CONTROL(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + GPIO_SET_OUTPUT(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + GPIO_SET_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + GPIO_SOFTWARE_CONTROL(MP3_NEXT_PORT_BASE, MP3_NEXT_PIN_MASK); + GPIO_SET_OUTPUT(MP3_NEXT_PORT_BASE, MP3_NEXT_PIN_MASK); + GPIO_SET_PIN(MP3_NEXT_PORT_BASE, MP3_NEXT_PIN_MASK); + } else { + GPIO_SOFTWARE_CONTROL(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_SET_OUTPUT(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_SET_PIN(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_SOFTWARE_CONTROL(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + GPIO_SET_OUTPUT(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + GPIO_SET_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + GPIO_SOFTWARE_CONTROL(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + GPIO_SET_OUTPUT(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + GPIO_SET_PIN(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + } + + GPIO_SOFTWARE_CONTROL(MP3_BUSY_PORT_BASE, MP3_BUSY_PIN_MASK); + GPIO_SET_INPUT(MP3_BUSY_PORT_BASE, MP3_BUSY_PIN_MASK); + + initialized = mode; + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_gpio_play(void) +{ + if(initialized != MP3_WTV020SD_GPIO_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_CLR_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_gpio_stop(void) +{ + if(initialized != MP3_WTV020SD_GPIO_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_SET_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_gpio_next(void) +{ + if(initialized != MP3_WTV020SD_GPIO_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_CLR_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + clock_delay_usec(MP3_USEC_DELAY); + GPIO_SET_PIN(MP3_PLAY_PORT_BASE, MP3_PLAY_PIN_MASK); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_busy(void) +{ + if((initialized != MP3_WTV020SD_GPIO_MODE) && + (initialized != MP3_WTV020SD_LINE_MODE)) { + return MP3_WTV020SD_ERROR; + } + if(GPIO_READ_PIN(MP3_BUSY_PORT_BASE, MP3_BUSY_PIN_MASK)) { + return MP3_WTV020SD_BUSY; + } + return MP3_WTV020SD_IDLE; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_reset(void) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_CLR_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + GPIO_SET_PIN(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_CLR_PIN(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + clock_delay_usec(MP3_USEC_DELAY); + GPIO_SET_PIN(MP3_RESET_PORT_BASE, MP3_RESET_PIN_MASK); + GPIO_SET_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + clock_delay_usec(MP3_USEC_RESET_DELAY); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_sync_play(uint16_t track) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + mp3_line_command(track); + while(mp3_wtv020sd_busy()); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_async_play(uint16_t track) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + mp3_line_command(track); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_stop(void) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + mp3_line_command(MP3_WTV020SD_STOP_VAL); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_wtv020sd_pause(void) +{ + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + mp3_line_command(MP3_WTV020SD_PLAY_PAUSE_VAL); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +int +mp3_line_command(uint16_t cmd) +{ + uint16_t mask; + if(initialized != MP3_WTV020SD_LINE_MODE) { + return MP3_WTV020SD_ERROR; + } + GPIO_CLR_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + clock_delay_usec(MP3_USEC_CMD_DELAY / 10); + for(mask = 0x8000; mask > 0; mask >> 1) { + GPIO_CLR_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + clock_delay_usec(MP3_USEC_CMD_DELAY / 2); + if(cmd & mask) { + GPIO_SET_PIN(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + } else { + GPIO_CLR_PIN(MP3_DATA_PORT_BASE, MP3_DATA_PIN_MASK); + } + clock_delay_usec(MP3_USEC_CMD_DELAY / 2); + GPIO_SET_PIN(MP3_CLK_PORT_BASE, MP3_CLK_PIN_MASK); + clock_delay_usec(MP3_USEC_CMD_DELAY); + if(mask > 0x0001) { + clock_delay_usec(MP3_USEC_CMD_DELAY / 10); + } + } + clock_delay_usec(MP3_USEC_CMD_DELAY / 8); + return MP3_WTV020SD_SUCCESS; +} +/*---------------------------------------------------------------------------*/ + +/** + * @} + * @} + */ diff --git a/platform/remote/dev/mp3-wtv020sd.h b/platform/remote/dev/mp3-wtv020sd.h new file mode 100644 index 000000000..15ec2c526 --- /dev/null +++ b/platform/remote/dev/mp3-wtv020sd.h @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2015, Zolertia + * 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. + */ +/* -------------------------------------------------------------------------- */ +/** + * \addtogroup remote-sensors + * @{ + * + * \defgroup remote-mp3-wtv020sd Re-Mote MP3 WTV020SD driver + * + * Driver to control the MP3 WTV020SD board in MP3 mode (GPIO based) and the + * 2-line serial mode (CLK/DI). Loop Mode and Key Modes not implemented. + * More product information available at: + * http://avrproject.ru/chasy-budilnik/WTV020SD.pdf + * An example on how to wire with a sound power amplifier and speakers at + * http://www.hackster.io/zolertia + * Based on the Arduino Wtv020sd16p library + * @{ + * + * \file + * Header file for the MP3 WTV020SD driver + */ +/* -------------------------------------------------------------------------- */ +#ifndef MP3_WTV020SD_H_ +#define MP3_WTV020SD_H_ +/* -------------------------------------------------------------------------- */ +#include +/* -------------------------------------------------------------------------- */ +#define MP3_WTV020SD_ERROR -1 +#define MP3_WTV020SD_SUCCESS 0x00 +#define MP3_WTV020SD_GPIO_MODE 0x01 +#define MP3_WTV020SD_LINE_MODE 0x02 +#define MP3_WTV020SD_IDLE 0x00 +#define MP3_WTV020SD_BUSY 0x0F +/* -------------------------------------------------------------------------- */ +#define MP3_WTV020SD_PLAY_PAUSE_VAL 0xFFFE +#define MP3_WTV020SD_STOP_VAL 0xFFFF +#define MP3_WTV020SD_VOLUME_MIN 0xFFF0 +#define MP3_WTV020SD_VOLUME_MAX 0xFFF7 +/* -------------------------------------------------------------------------- */ +#define MP3_USEC_DELAY 1000 +#define MP3_USEC_CMD_DELAY 100 +#define MP3_USEC_RESET_DELAY ((MP3_USEC_DELAY) * 30) +/* -------------------------------------------------------------------------- */ +#define MP3_TRACK_BASE 0 /* 0000.ad4 */ +/* -------------------------------------------------------------------------- */ +/** + * \brief Init function for the MP3 driver + * + * Configures the pins required to operate in either driver mode + * + * \param mode drive the board using GPIOs or the two-line mode, using + * either MP3_WTV020SD_GPIO_MODE or MP3_WTV020SD_LINE_MODE + * \return MP3_WTV020SD_ERROR if invalid mode selected, otherwise it + * will return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_config(uint8_t mode); +/** + * \brief Function to play a current track + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_gpio_play(void); +/** + * \brief Function to stop a current track + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_gpio_stop(void); +/** + * \brief Advances and play the next track, wraps over the playlist + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_gpio_next(void); +/** + * \brief Get the current status of the device (playing/stopped) + * + * \return MP3_WTV020SD_BUSY if a track is playing, otherwise it will + * return MP3_WTV020SD_IDLE + */ +int mp3_wtv020sd_busy(void); +/** + * \brief Trigger a module reset + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_reset(void); +/** + * \brief Plays the selected track and waits until it stops + * + * \param track forwards and play the selected track, starting from + * MP3_TRACK_BASE (0000.ad4) up to MP3_TRACK_BASE + 511 + * (0511.ad4) + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_sync_play(uint16_t track); +/** + * \brief Plays the selected track and returns immediately + * + * \param track forwards and play the selected track, starting from + * MP3_TRACK_BASE (0000.ad4) up to MP3_TRACK_BASE + 511 + * (0511.ad4) + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_async_play(uint16_t track); +/** + * \brief Stops the current track + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_stop(void); +/** + * \brief Pauses the current track + * + * \return MP3_WTV020SD_ERROR if invalid mode used, otherwise it will + * return MP3_WTV020SD_SUCCESS + */ +int mp3_wtv020sd_pause(void); + +/* -------------------------------------------------------------------------- */ +#endif /* ifndef MP3_WTV020SD_H_ */ +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ diff --git a/platform/remote/dev/phidget-sensor.c b/platform/remote/dev/phidget-sensor.c new file mode 100644 index 000000000..c400b8ad1 --- /dev/null +++ b/platform/remote/dev/phidget-sensor.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * 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 remote-phidget-sensor + * @{ + * + * \file + * Generic driver for the Re-Mote Phidget/ADC sensors + */ +/*---------------------------------------------------------------------------*/ +#include "contiki.h" +#include "sys/clock.h" +#include "dev/ioc.h" +#include "dev/gpio.h" +#include "dev/adc.h" +#include "dev/phidget-sensor.h" +#include "dev/remote-sensors.h" + +#include +/*---------------------------------------------------------------------------*/ +#define ADC_PHIDGET_PORT_BASE GPIO_PORT_TO_BASE(ADC_PHIDGET_PORT) +#define ADC_PHIDGET_ADC2_PIN_MASK GPIO_PIN_MASK(ADC_PHIDGET_ADC2_PIN) +#define ADC_PHIDGET_ADC3_PIN_MASK GPIO_PIN_MASK(ADC_PHIDGET_ADC3_PIN) +/*---------------------------------------------------------------------------*/ +static uint8_t decimation_rate; +/*---------------------------------------------------------------------------*/ +static int +set_decimation_rate(uint8_t rate) +{ + switch(rate) { + case SOC_ADC_ADCCON_DIV_64: + case SOC_ADC_ADCCON_DIV_128: + case SOC_ADC_ADCCON_DIV_256: + case SOC_ADC_ADCCON_DIV_512: + decimation_rate = rate; + break; + default: + return REMOTE_SENSORS_ERROR; + } + + return decimation_rate; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint8_t channel; + int16_t res; + + switch(type) { + case PHIDGET_SENSORS_ADC2: + channel = SOC_ADC_ADCCON_CH_AIN0 + ADC_PHIDGET_ADC2_PIN; + break; + case PHIDGET_SENSORS_ADC3: + channel = SOC_ADC_ADCCON_CH_AIN0 + ADC_PHIDGET_ADC3_PIN; + break; + default: + return REMOTE_SENSORS_ERROR; + } + + res = adc_get(channel, SOC_ADC_ADCCON_REF_INT, decimation_rate); + + return res; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + switch(type) { + case SENSORS_HW_INIT: + GPIO_SOFTWARE_CONTROL(GPIO_A_BASE, ADC_PHIDGET_ADC2_PIN_MASK); + GPIO_SET_INPUT(GPIO_A_BASE, ADC_PHIDGET_ADC2_PIN_MASK); + ioc_set_over(GPIO_A_NUM, ADC_PHIDGET_ADC2_PIN, IOC_OVERRIDE_ANA); + + GPIO_SOFTWARE_CONTROL(GPIO_A_BASE, ADC_PHIDGET_ADC3_PIN_MASK); + GPIO_SET_INPUT(GPIO_A_BASE, ADC_PHIDGET_ADC3_PIN_MASK); + ioc_set_over(GPIO_A_NUM, ADC_PHIDGET_ADC3_PIN, IOC_OVERRIDE_ANA); + adc_init(); + set_decimation_rate(SOC_ADC_ADCCON_DIV_512); + break; + case REMOTE_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE: + return set_decimation_rate((uint8_t)value); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 1; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(phidget_sensor, PHIDGET_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/remote/dev/phidget-sensor.h b/platform/remote/dev/phidget-sensor.h new file mode 100644 index 000000000..577c8f2c7 --- /dev/null +++ b/platform/remote/dev/phidget-sensor.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * 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 remote-sensors + * @{ + * + * \defgroup remote-phidget-sensor Re-Mote Generic Phidget Sensor + * + * Driver for the Re-Mote phidget ADC sensor + * + * This driver supports phidgets connected to both the ADC2 and AND3 channels. + * This is controlled by the type argument of the value() function. Possible + * choices are: + * - PHIDGET_SENSORS_ADC2 (channel 2) + * - PHIDGET_SENSORS_ADC3 (channel 3) + * + * The decimation rate can be set by passing + * REMOTE_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE as the type argument to the + * configure() function and then specifying the rate through the value + * argument. Valid values are: + * - SOC_ADC_ADCCON_DIV_64 (64 bit rate) + * - SOC_ADC_ADCCON_DIV_128 (128 bit rate) + * - SOC_ADC_ADCCON_DIV_256 (256 bit rate) + * - SOC_ADC_ADCCON_DIV_512 (512 bit rate) + * @{ + * + * \file + * Header file for the Re-Mote Generic Driver for Phidget/ADC sensors + */ +/*---------------------------------------------------------------------------*/ +#ifndef PHIDGET_SENSOR_H_ +#define PHIDGET_SENSOR_H_ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" +#include "dev/soc-adc.h" +/*---------------------------------------------------------------------------*/ +/** + * \name Generic phidget sensor + * @{ + */ +#define PHIDGET_SENSOR "Phidget ADC" + +#define PHIDGET_SENSORS_ADC2 2 /**< 3V3 ADC phidget-like connector ADC2 */ +#define PHIDGET_SENSORS_ADC3 3 /**< 3V3 ADC phidget-like connector ADC3 */ +/** @} */ +/*---------------------------------------------------------------------------*/ +extern const struct sensors_sensor phidget_sensor; +/*---------------------------------------------------------------------------*/ +#endif /* PHIDGET_SENSOR_H_ */ +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/platform/remote/dev/remote-sensors.c b/platform/remote/dev/remote-sensors.c new file mode 100644 index 000000000..88daaa0cf --- /dev/null +++ b/platform/remote/dev/remote-sensors.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk + * 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 remote-sensors + * @{ + * + * Generic module controlling sensors on the Re-Mote platform + * @{ + * + * \file + * Implementation of a generic module controlling Re-Mote sensors + */ +#include "contiki.h" +#include "dev/cc2538-sensors.h" +#include "dev/button-sensor.h" +#include "dev/phidget-sensor.h" + +#include +/*---------------------------------------------------------------------------*/ +/* TODO: include the tmp102 sensor as well */ +/*---------------------------------------------------------------------------*/ +/** \brief Exports global symbols for the sensor API */ +SENSORS(&button_sensor, &vdd3_sensor, &cc2538_temp_sensor, &phidget_sensor); +/*---------------------------------------------------------------------------*/ +/** + * @} + * @} + */ diff --git a/cpu/cc26xx/cc26xx-model.h b/platform/remote/dev/remote-sensors.h similarity index 68% rename from cpu/cc26xx/cc26xx-model.h rename to platform/remote/dev/remote-sensors.h index 44ee1cfe3..aa0ee03d8 100644 --- a/cpu/cc26xx/cc26xx-model.h +++ b/platform/remote/dev/remote-sensors.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2015, Texas Instruments Incorporated - http://www.ti.com/ + * Copyright (c) 2015, Zolertia - http://www.zolertia.com + * Copyright (c) 2015, University of Bristol - http://www.bristol.ac.uk * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,43 +31,39 @@ */ /*---------------------------------------------------------------------------*/ /** - * \addtogroup cc26xx + * \addtogroup remote * @{ * - * \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. + * \defgroup remote-sensors Re-Mote Sensors * + * Generic module controlling sensors on the Re-Mote platform * @{ - */ -/** + * * \file - * Header file with definitions relating to various CC26xx variants + * Implementation of a generic module controlling Re-Mote sensors */ /*---------------------------------------------------------------------------*/ -#ifndef CC26XX_MODEL_H_ -#define CC26XX_MODEL_H_ +#ifndef REMOTE_SENSORS_H_ +#define REMOTE_SENSORS_H_ /*---------------------------------------------------------------------------*/ -#include "contiki-conf.h" +#include "lib/sensors.h" +#include "dev/cc2538-sensors.h" +#include "dev/button-sensor.h" +#include "dev/phidget-sensor.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 +/** + * \name ReMote sensor constants + * + * These constants are used by various sensors on the ReMote. They can be used + * to configure ADC decimation rate (where applicable). + * @{ + */ +#define REMOTE_SENSORS_CONFIGURE_TYPE_DECIMATION_RATE 0x0100 /**< Change decimation rate (used with configure()) */ -#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 +#define REMOTE_SENSORS_ERROR CC2538_SENSORS_ERROR /**< Error */ +/** @} */ /*---------------------------------------------------------------------------*/ -#endif /* CC26XX_MODEL_H_ */ +#endif /* REMOTE_SENSORS_H_ */ /*---------------------------------------------------------------------------*/ /** * @} diff --git a/platform/remote/dev/sht25.c b/platform/remote/dev/sht25.c new file mode 100644 index 000000000..0bc34f7c5 --- /dev/null +++ b/platform/remote/dev/sht25.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2015, Zolertia + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-sht25-sensor + * @{ + * + * \file + * SHT25 temperature and humidity sensor driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "dev/sht25.h" +#include "lib/sensors.h" +/*---------------------------------------------------------------------------*/ +#warning I2C SDA AND SCL are inverted in JP8 connector, inverted in init() call +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return SHT25_ERROR; + } + if(value) { + i2c_init(I2C_SCL_PORT, I2C_SCL_PIN, I2C_SDA_PORT, I2C_SDA_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + } + enabled = value; + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static uint16_t +sht25_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum) +{ + if(i2c_single_send(SHT25_ADDR, reg) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(SHT25_ADDR, buf, regNum) == I2C_MASTER_ERR_NONE) { + return SHT25_SUCCESS; + } + } + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int16_t +sht25_convert(uint8_t variable, uint16_t value) +{ + int16_t rd; + uint32_t buff; + buff = (uint32_t)value; + if(variable == SHT25_VAL_TEMP) { + buff *= 17572; + buff = buff >> 16; + rd = (int16_t)buff - 4685; + } else { + buff *= 12500; + buff = buff >> 16; + rd = (int16_t)buff - 600; + rd = (rd > 10000) ? 10000 : rd; + } + return rd; +} +/*---------------------------------------------------------------------------*/ +static int16_t +sht25_read(uint8_t variable, uint16_t *rd) +{ + uint8_t buf[2]; + uint16_t raw; + + if((variable != SHT25_VAL_TEMP) && (variable != SHT25_VAL_HUM)) { + return SHT25_ERROR; + } + + if (sht25_read_reg(variable, buf, 2) == SHT25_SUCCESS){ + raw = (buf[0] << 8) + buf[1]; + *rd = sht25_convert(variable, raw); + return SHT25_SUCCESS; + } + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint16_t val; + if (sht25_read(type, &val) == SHT25_SUCCESS){ + return val; + } + return SHT25_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(sht25, SHT25_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/remote/dev/sht25.h b/platform/remote/dev/sht25.h new file mode 100644 index 000000000..c1ee19391 --- /dev/null +++ b/platform/remote/dev/sht25.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2015, Zolertia + * 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-sensors + * @{ + * + * \defgroup remote-sht25-sensor Re-Mote SHT25 digital temperature sensor + * @{ + * + * \file + * SHT25 temperature and humidity sensor driver + * \author + * Antonio Lignan + */ +/*---------------------------------------------------------------------------*/ +#include "lib/sensors.h" + +#ifndef SHT25_H_ +#define SHT25_H_ + +/* -------------------------------------------------------------------------- */ +#define SHT25_ADDR 0x40 +#define SHT25_TEMP_HOLD 0xE3 +#define SHT25_HUM_HOLD 0xE5 +#define SHT25_TEMP_NO_HOLD 0xF3 +#define SHT25_HUM_NO_HOLD 0xF5 +#define SHT2X_UREG_WRITE 0xE6 +#define SHT2X_UREG_READ 0xE7 +#define SHT2X_SOFT_RESET 0XFE +#define SHT2X_NULL 0x00 +/* -------------------------------------------------------------------------- */ +#define SHT2X_RES_14T_12RH 0x00 +#define SHT2X_RES_12T_08RH 0x01 +#define SHT2X_RES_13T_10RH 0x80 +#define SHT2X_RES_11T_11RH 0x81 +#define SHT2X_HEATER_ON 0x04 +#define SHT2X_HEATER_OFF 0x00 +#define SHT2X_OTP_RELOAD_EN 0x00 +#define SHT2X_OTP_RELOAD_DIS 0x02 +/* -------------------------------------------------------------------------- */ +#define SHT25_VAL_TEMP SHT25_TEMP_HOLD +#define SHT25_VAL_HUM SHT25_HUM_HOLD +#define SHT25_ERROR -1 +#define SHT25_SUCCESS 0x00 +/* -------------------------------------------------------------------------- */ +#define SHT25_SENSOR "SHT25 Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor sht25; +/* -------------------------------------------------------------------------- */ +#endif /* ifndef SHT25_H_ */ +/** + * @} + * @} + */ diff --git a/platform/remote/dev/tmp102.c b/platform/remote/dev/tmp102.c new file mode 100644 index 000000000..bdea73e87 --- /dev/null +++ b/platform/remote/dev/tmp102.c @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-tmp102-sensor + * @{ + * + * \file + * Driver for the Re-Mote TMP102 temperature sensor + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "tmp102.h" + +void +tmp102_init(void) +{ + i2c_init(I2C_SDA_PORT, I2C_SDA_PIN, I2C_SCL_PORT, I2C_SCL_PIN, I2C_SCL_NORMAL_BUS_SPEED); +} +/*---------------------------------------------------------------------------*/ + +uint8_t +tmp102_read(uint16_t *data) +{ + uint8_t buf[2]; + uint16_t temp; + + /* Write to the temperature register to trigger a reading */ + if(i2c_single_send(TMP102_ADDR, TMP102_TEMP) == I2C_MASTER_ERR_NONE) { + /* Read two bytes only */ + if(i2c_burst_receive(TMP102_ADDR, buf, 2) == I2C_MASTER_ERR_NONE) { + temp = (buf[0] << 8) + buf[1]; + if(temp > 2047) { + temp -= (1 << 12); + } + temp *= 0.625; + *data = temp; + return I2C_MASTER_ERR_NONE; + } + } + return i2c_master_error(); +} +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/remote/dev/tmp102.h b/platform/remote/dev/tmp102.h new file mode 100644 index 000000000..39da4408b --- /dev/null +++ b/platform/remote/dev/tmp102.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-sensors + * @{ + * + * \defgroup remote-tmp102-sensor Re-Mote TMP102 Sensor + * + * Driver for the Re-Mote TMP102 sensor + * + * The TMP102 driver returns the converted temperature value in centiCelsius + * with 2 digits precision, to get Celsius just divide by 100. + * @{ + * + * \file + * Header file for the Re-Mote TMP102 Sensor Driver + */ +/*---------------------------------------------------------------------------*/ +#ifndef TMP102_H_ +#define TMP102_H_ +#include +#include "i2c.h" +/* -------------------------------------------------------------------------- */ +/** + * \name Generic TMP102 sensor + * @{ + */ +/* -------------------------------------------------------------------------- */ +#define TMP102_ADDR 0x48 /**< TMP102 slave address */ +#define TMP102_TEMP 0x00 /**< TMP102 temperature data register */ +/** @} */ +/* -------------------------------------------------------------------------- */ +#endif /* ifndef TMP102_H_ */ +/*---------------------------------------------------------------------------*/ + +/** \brief Initialiser for the TMP102 sensor driver */ +void tmp102_init(void); + +/** \brief Get a temperature reading from the TMP102 sensor */ +uint8_t tmp102_read(uint16_t *data); + +/** + * @} + * @} + */ diff --git a/platform/remote/dev/tsl2563.c b/platform/remote/dev/tsl2563.c new file mode 100644 index 000000000..c7e57f7ee --- /dev/null +++ b/platform/remote/dev/tsl2563.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-tsl2563-sensor + * @{ + * + * \file + * Driver for the Re-Mote external TSL2563 light sensor (Ziglet) + * + * \author + * Antonio Lignan + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#include +#include "contiki.h" +#include "dev/i2c.h" +#include "lib/sensors.h" +#include "tsl2563.h" +/*---------------------------------------------------------------------------*/ +#warning I2C SDA AND SCL are inverted in JP8 connector, inverted in init() call +/*---------------------------------------------------------------------------*/ +static uint8_t enabled; +/*---------------------------------------------------------------------------*/ +static uint16_t +calculateLux(uint8_t *buf) +{ + uint32_t ch0, ch1 = 0; + uint32_t aux = (1 << 14); + uint32_t ratio, lratio, tmp = 0; + uint16_t buffer[2]; + + buffer[0] = (buf[1] << 8 | (buf[0])); + buffer[1] = (buf[3] << 8 | (buf[2])); + ch0 = (buffer[0] * aux) >> 10; + ch1 = (buffer[1] * aux) >> 10; + ratio = (ch1 << 10); + ratio = ratio / ch0; + lratio = (ratio + 1) >> 1; + + if((lratio >= 0) && (lratio <= K1T)) { + tmp = (ch0 * B1T) - (ch1 * M1T); + } else if(lratio <= K2T) { + tmp = (ch0 * B2T) - (ch1 * M2T); + } else if(lratio <= K3T) { + tmp = (ch0 * B3T) - (ch1 * M3T); + } else if(lratio <= K4T) { + tmp = (ch0 * B4T) - (ch1 * M4T); + } else if(lratio <= K5T) { + tmp = (ch0 * B5T) - (ch1 * M5T); + } else if(lratio <= K6T) { + tmp = (ch0 * B6T) - (ch1 * M6T); + } else if(lratio <= K7T) { + tmp = (ch0 * B7T) - (ch1 * M7T); + } else if(lratio > K8T) { + tmp = (ch0 * B8T) - (ch1 * M8T); + } + + if(tmp < 0) { + tmp = 0; + } + + tmp += (1 << 13); + return tmp >> 14; +} +/*---------------------------------------------------------------------------*/ +static int +tsl2563_read_reg(uint8_t reg, uint8_t *buf, uint8_t regNum) +{ + if(i2c_single_send(TSL2563_ADDR, reg) == I2C_MASTER_ERR_NONE) { + if(i2c_burst_receive(TSL2563_ADDR, buf, regNum) == I2C_MASTER_ERR_NONE) { + return TSL2563_SUCCESS; + } + } + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +light_ziglet_on(void) +{ + if(i2c_single_send(TSL2563_ADDR, (uint8_t)TSL2563_PWRN) == I2C_MASTER_ERR_NONE) { + return TSL2563_SUCCESS; + } + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +light_ziglet_off(void) +{ + if(i2c_single_send(TSL2563_ADDR, (uint8_t)TSL2563_PWROFF) == I2C_MASTER_ERR_NONE) { + return TSL2563_SUCCESS; + } + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +light_ziglet_read(uint16_t *lux) +{ + uint8_t buf[4]; + if(light_ziglet_on() == TSL2563_SUCCESS) { + if(tsl2563_read_reg(TSL2563_READ, buf, 4) == TSL2563_SUCCESS) { + *lux = calculateLux(buf); + return light_ziglet_off(); + } + } + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int value) +{ + if(type != SENSORS_ACTIVE) { + return TSL2563_ERROR; + } + enabled = value; + if(value) { + i2c_init(I2C_SCL_PORT, I2C_SCL_PIN, I2C_SDA_PORT, I2C_SDA_PIN, + I2C_SCL_NORMAL_BUS_SPEED); + } else { + light_ziglet_off(); + } + return TSL2563_SUCCESS; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return enabled; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + uint16_t lux; + if(type == TSL2563_VAL_READ) { + if(light_ziglet_read(&lux) != TSL2563_ERROR) { + return lux; + } + } + return TSL2563_ERROR; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(tsl2563, TSL2563_SENSOR, value, configure, status); +/*---------------------------------------------------------------------------*/ +/** @} */ diff --git a/platform/remote/dev/tsl2563.h b/platform/remote/dev/tsl2563.h new file mode 100644 index 000000000..6cd2d14dc --- /dev/null +++ b/platform/remote/dev/tsl2563.h @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2015, Zolertia - http://www.zolertia.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 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. + * + */ +/*---------------------------------------------------------------------------*/ +/** + * \addtogroup remote-sensors + * @{ + * + * \defgroup remote-tsl2563-sensor Re-Mote TSL2563 Sensor + * + * Driver for the Re-Mote TSL2563 sensor + * + * The TSL2563 driver returns the converted light value value in lux + * @{ + * + * \file + * Header file for the Re-Mote external TSL2563 Sensor Driver + * + * \author + * Antonio Lignan + * Toni Lozano + */ +/*---------------------------------------------------------------------------*/ +#ifndef LIGHT_SENSOR_H_ +#define LIGHT_SENSOR_H_ +#include +#include "lib/sensors.h" +#include "i2c.h" +/* -------------------------------------------------------------------------- */ +/** + * \name TSL2563 digital Light sensor + * @{ + */ +/* -------------------------------------------------------------------------- */ +#define TSL2563_ADDR 0x39 /**< TSL2563 slave address */ +/* -------------------------------------------------------------------------- */ +#define TSL2563_READ 0xAC /**< TSL2563 read register */ +#define TSL2563_PWRN 0x03 /**< TSL2563 enable register */ +#define TSL2563_PWROFF 0x00 /**< TSL2563 Power OFF */ +/* -------------------------------------------------------------------------- */ +#define K1T 0X0040 /**< Calibration values (hardcoded) */ +#define B1T 0x01f2 +#define M1T 0x01b2 +#define K2T 0x0080 +#define B2T 0x0214 +#define M2T 0x02d1 +#define K3T 0x00c0 +#define B3T 0x023f +#define M3T 0x037b +#define K4T 0x0100 +#define B4T 0x0270 +#define M4T 0x03fe +#define K5T 0x0138 +#define B5T 0x016f +#define M5T 0x01fc +#define K6T 0x019a +#define B6T 0x00d2 +#define M6T 0x00fb +#define K7T 0x029a +#define B7T 0x0018 +#define M7T 0x0012 +#define K8T 0x029a +#define B8T 0x0000 +#define M8T 0x0000 +/** @} */ +/* -------------------------------------------------------------------------- */ +#define TSL2563_SUCCESS 0x00 +#define TSL2563_LIGHT 0x01 +#define TSL2563_ERROR -1 +/* -------------------------------------------------------------------------- */ +#define TSL2563_VAL_READ 0x01 +/* -------------------------------------------------------------------------- */ +#define TSL2563_SENSOR "TSL2563 Light Sensor" +/* -------------------------------------------------------------------------- */ +extern const struct sensors_sensor tsl2563; +/* -------------------------------------------------------------------------- */ +#endif +/* -------------------------------------------------------------------------- */ +/** + * @} + * @} + */ + 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..02f982854 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 /** @} */ /*---------------------------------------------------------------------------*/ @@ -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/win32/contiki-conf.h b/platform/win32/contiki-conf.h index 9c2e81be7..060648c36 100644 --- a/platform/win32/contiki-conf.h +++ b/platform/win32/contiki-conf.h @@ -56,16 +56,13 @@ typedef long s32_t; typedef unsigned short uip_stats_t; -#define UIP_CONF_MAX_CONNECTIONS 40 -#define UIP_CONF_MAX_LISTENPORTS 40 #define UIP_CONF_LLH_LEN 14 #define UIP_CONF_BUFFER_SIZE 1514 -#define UIP_CONF_BYTE_ORDER UIP_LITTLE_ENDIAN #define UIP_CONF_TCP_SPLIT 1 #define UIP_CONF_LOGGING 1 #define UIP_CONF_UDP_CHECKSUMS 1 -#if NETSTACK_CONF_WITH_IPV6 #define UIP_CONF_IP_FORWARD 0 +#if NETSTACK_CONF_WITH_IPV6 #define NBR_TABLE_CONF_MAX_NEIGHBORS 100 #define UIP_CONF_DS6_DEFRT_NBU 2 #define UIP_CONF_DS6_PREFIX_NBU 5 @@ -73,10 +70,10 @@ typedef unsigned short uip_stats_t; #define UIP_CONF_DS6_ADDR_NBU 10 #define UIP_CONF_DS6_MADDR_NBU 0 //VC++ does not allow zero length arrays #define UIP_CONF_DS6_AADDR_NBU 0 //inside a struct -#else -#define UIP_CONF_IP_FORWARD 1 #endif +#define RESOLV_CONF_SUPPORTS_MDNS 0 +#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0 #include #define ctk_arch_isprint isprint @@ -174,8 +171,9 @@ typedef unsigned short uip_stats_t; #define SHELL_GUI_CONF_YSIZE 30 +#define TELNETD_CONF_MAX_IDLE_TIME 300 #ifdef PLATFORM_BUILD -#define TELNETD_CONF_GUI 1 +#define TELNETD_CONF_GUI 1 #endif /* PLATFORM_BUILD */ diff --git a/platform/win32/contiki-main.c b/platform/win32/contiki-main.c index 5ced80992..0472bfbcc 100644 --- a/platform/win32/contiki-main.c +++ b/platform/win32/contiki-main.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "contiki-net.h" @@ -101,6 +102,8 @@ char **contiki_argv; int main(int argc, char **argv) { + _set_fmode(O_BINARY); + contiki_argc = argc; contiki_argv = argv; 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..f8b33d94a 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(); 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/dev/tmp102.c b/platform/z1/dev/tmp102.c index 11844acb0..cc9394b7b 100644 --- a/platform/z1/dev/tmp102.c +++ b/platform/z1/dev/tmp102.c @@ -185,5 +185,6 @@ tmp102_read_temp_x100(void) int8_t tmp102_read_temp_simple(void) { - return (int8_t)tmp102_read_temp_x100() / 100; + /* Casted to int8_t: We don't expect temperatures outside -128 to 127 C */ + return tmp102_read_temp_x100() / 100; } diff --git a/regression-tests/00-doxygen/doxyerrors.cnt b/regression-tests/00-doxygen/doxyerrors.cnt index 360b9e4ba..405e2afe8 100644 --- a/regression-tests/00-doxygen/doxyerrors.cnt +++ b/regression-tests/00-doxygen/doxyerrors.cnt @@ -1,2 +1 @@ -209 - +134 diff --git a/regression-tests/12-rpl/01-rpl-up-route.csc b/regression-tests/12-rpl/01-rpl-up-route.csc index 7c515b24b..bcefd4128 100644 --- a/regression-tests/12-rpl/01-rpl-up-route.csc +++ b/regression-tests/12-rpl/01-rpl-up-route.csc @@ -312,7 +312,7 @@ while(true) { } } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -323,7 +323,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/02-rpl-root-reboot.csc b/regression-tests/12-rpl/02-rpl-root-reboot.csc index eda75d60b..2ab456726 100644 --- a/regression-tests/12-rpl/02-rpl-root-reboot.csc +++ b/regression-tests/12-rpl/02-rpl-root-reboot.csc @@ -312,7 +312,7 @@ while(true) { } } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -323,7 +323,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/03-rpl-28-hours.csc b/regression-tests/12-rpl/03-rpl-28-hours.csc index d107f13b4..383b636fa 100644 --- a/regression-tests/12-rpl/03-rpl-28-hours.csc +++ b/regression-tests/12-rpl/03-rpl-28-hours.csc @@ -261,7 +261,7 @@ while(true) { } } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -272,7 +272,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/04-rpl-large-network.csc b/regression-tests/12-rpl/04-rpl-large-network.csc index 50b1cfad4..30944240a 100644 --- a/regression-tests/12-rpl/04-rpl-large-network.csc +++ b/regression-tests/12-rpl/04-rpl-large-network.csc @@ -7027,7 +7027,7 @@ while(true) { } } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -7038,7 +7038,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc b/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc index 7191e79ad..ba409e4fb 100644 --- a/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc +++ b/regression-tests/12-rpl/05-rpl-up-and-down-routes.csc @@ -310,7 +310,7 @@ while(true) { } } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -321,7 +321,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc b/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc index f4c132c4d..6884c9fc5 100644 --- a/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc +++ b/regression-tests/12-rpl/06-rpl-temporary-root-loss.csc @@ -287,9 +287,14 @@ GENERATE_MSG(2000000, "add-sink"); lostMsgs = 0; -TIMEOUT(2000000, if(lostMsgs == 0) { log.testOK(); } ); +// we check that we got up to at least message 62 and +// (the simulation is 4000000ms = 66 minutes long) +// that we did not lose anything since 34 +// (the sink is back at 2000000ms = 33 minutes) +TIMEOUT(4000000, if(lastMsg >= 62 && lastMissed <= 34) { log.testOK(); } ); lastMsg = -1; +lastMissed = -1; packets = "_________"; hops = 0; @@ -310,7 +315,7 @@ while(true) { } } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -321,7 +326,8 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + lastMissed = num; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc index 7f63864a2..66e890394 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-0.csc @@ -327,7 +327,7 @@ while(true) { node8.getInterfaces().getPosition().setCoordinates(58, 108, 0); } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -339,7 +339,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc index 9468dd53e..57b426ab2 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-1.csc @@ -327,7 +327,7 @@ while(true) { node8.getInterfaces().getPosition().setCoordinates(58, 108, 0); } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -339,7 +339,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc index 130eef941..2f42e92ea 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-2.csc @@ -327,7 +327,7 @@ while(true) { node8.getInterfaces().getPosition().setCoordinates(58, 108, 0); } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -339,7 +339,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc index d67d25f01..63fb1e042 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-3.csc @@ -327,7 +327,7 @@ while(true) { node8.getInterfaces().getPosition().setCoordinates(58, 108, 0); } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -339,7 +339,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc index bef4be8b8..8b33f560a 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-4.csc @@ -327,7 +327,7 @@ while(true) { node8.getInterfaces().getPosition().setCoordinates(58, 108, 0); } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -339,7 +339,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc b/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc index c2623f780..56925381b 100644 --- a/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc +++ b/regression-tests/12-rpl/08-rpl-dao-route-loss-5.csc @@ -327,7 +327,7 @@ while(true) { node8.getInterfaces().getPosition().setCoordinates(58, 108, 0); } else if(msg.startsWith("Sending")) { hops = 0; - } else if(msg.startsWith("#L")) { + } else if(msg.startsWith("#L") && msg.endsWith("1; red")) { hops++; } else if(msg.startsWith("Data")) { // log.log("" + msg + "\n"); @@ -339,7 +339,7 @@ while(true) { // log.log("Num " + num + "\n"); if(lastMsg != -1) { if(num != lastMsg + 1) { - numMissed = num - lastMsg; + numMissed = num - lastMsg - 1; lostMsgs += numMissed; log.log("Missed messages " + numMissed + " before " + num + "\n"); for(i = 0; i < numMissed; i++) { diff --git a/regression-tests/18-compile-arm-ports/Makefile b/regression-tests/18-compile-arm-ports/Makefile index 217b5eef9..222474b13 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/tools/6502/Makefile b/tools/6502/Makefile index 143393cf0..e409bf389 100644 --- a/tools/6502/Makefile +++ b/tools/6502/Makefile @@ -60,16 +60,13 @@ $1-makes: $(MAKE) -C ../../examples/webbrowser TARGET=$1 $(MAKE) -C ../../examples/wget TARGET=$1 $(MAKE) -C ../../examples/irc TARGET=$1 - $(MAKE) -C ../../../contikiprojects/vandenbrande.com/twitter/platform/$1 - $(MAKE) -C ../../examples/email TARGET=$1 - $(MAKE) -C ../../examples/ftp TARGET=$1 $(MAKE) -C ../../examples/webserver TARGET=$1 HTTPD-CFS=1 $(MAKE) -C ../../examples/telnet-server TARGET=$1 endef $(eval $(call makes,apple2enh)) -apple2: contiki-apple2-1.dsk contiki-apple2-2.dsk contiki-apple2-3.dsk contiki-apple2-4.dsk contiki-apple2.2mg +apple2: contiki-apple2-1.dsk contiki-apple2-2.dsk contiki-apple2-3.dsk contiki-apple2.po contiki-apple2-1.dsk: apple2enh-makes cp ../apple2enh/prodos.dsk $@ @@ -97,8 +94,6 @@ contiki-apple2-2.dsk: apple2enh-makes java -jar $(AC) -cc65 $@ ipconfig bin < ../../cpu/6502/ipconfig/ipconfig.apple2enh java -jar $(AC) -p $@ irc.system sys < $(CC65_HOME)/targetutil/loader.system java -jar $(AC) -cc65 $@ irc bin < ../../examples/irc/irc-client.apple2enh - java -jar $(AC) -p $@ breadbox.system sys < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ breadbox bin < ../../../contikiprojects/vandenbrande.com/twitter/platform/apple2enh/breadbox64.apple2enh java -jar $(AC) -p $@ contiki.cfg bin 0 < ../apple2enh/default.cfg java -jar $(AC) -p $@ cs8900a.eth rel 0 < ../../cpu/6502/ethconfig/cs8900a.eth java -jar $(AC) -p $@ lan91c96.eth rel 0 < ../../cpu/6502/ethconfig/lan91c96.eth @@ -106,23 +101,6 @@ contiki-apple2-2.dsk: apple2enh-makes java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65_HOME)/mou/a2e.stdmou.mou contiki-apple2-3.dsk: apple2enh-makes - cp ../apple2enh/prodos.dsk $@ - java -jar $(AC) -p $@ menu.system sys < ../apple2enh/menu.system - java -jar $(AC) -p $@ ethconfi.system sys < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ethconfi bin < ../../cpu/6502/ethconfig/ethconfig.apple2enh - java -jar $(AC) -p $@ ipconfig.system sys < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ipconfig bin < ../../cpu/6502/ipconfig/ipconfig.apple2enh - java -jar $(AC) -p $@ email.system sys < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ email bin < ../../examples/email/email-client.apple2enh - java -jar $(AC) -p $@ ftp.system sys < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ftp bin < ../../examples/ftp/ftp-client.apple2enh - java -jar $(AC) -p $@ contiki.cfg bin 0 < ../apple2enh/default.cfg - java -jar $(AC) -p $@ cs8900a.eth rel 0 < ../../cpu/6502/ethconfig/cs8900a.eth - java -jar $(AC) -p $@ lan91c96.eth rel 0 < ../../cpu/6502/ethconfig/lan91c96.eth - java -jar $(AC) -p $@ w5100.eth rel 0 < ../../cpu/6502/ethconfig/w5100.eth - java -jar $(AC) -p $@ contiki.mou rel 0 < $(CC65_HOME)/mou/a2e.stdmou.mou - -contiki-apple2-4.dsk: apple2enh-makes cp ../apple2enh/prodos.dsk $@ java -jar $(AC) -p $@ menu.system sys < ../apple2enh/menu.system java -jar $(AC) -p $@ ethconfi.system sys < $(CC65_HOME)/targetutil/loader.system @@ -143,8 +121,8 @@ contiki-apple2-4.dsk: apple2enh-makes java -jar $(AC) -p $@ contiki.gif bin 0 < ../../examples/webserver/httpd-cfs/contiki.gif java -jar $(AC) -p $@ notfound.htm bin 0 < ../../examples/webserver/httpd-cfs/notfound.htm -contiki-apple2.2mg: apple2enh-makes - cp ../apple2enh/prodos.2mg $@ +contiki-apple2.po: apple2enh-makes + cp ../apple2enh/prodos.po $@ java -jar $(AC) -p $@ menu.system sys < ../apple2enh/menu.system java -jar $(AC) -p $@ ethconfi.system sys < $(CC65_HOME)/targetutil/loader.system java -jar $(AC) -cc65 $@ ethconfi bin < ../../cpu/6502/ethconfig/ethconfig.apple2enh @@ -156,12 +134,6 @@ contiki-apple2.2mg: apple2enh-makes java -jar $(AC) -cc65 $@ wget bin < ../../examples/wget/wget.apple2enh java -jar $(AC) -p $@ irc.system sys < $(CC65_HOME)/targetutil/loader.system java -jar $(AC) -cc65 $@ irc bin < ../../examples/irc/irc-client.apple2enh - java -jar $(AC) -p $@ breadbox.system sys < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ breadbox bin < ../../../contikiprojects/vandenbrande.com/twitter/platform/apple2enh/breadbox64.apple2enh - java -jar $(AC) -p $@ email.system sys < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ email bin < ../../examples/email/email-client.apple2enh - java -jar $(AC) -p $@ ftp.system sys < $(CC65_HOME)/targetutil/loader.system - java -jar $(AC) -cc65 $@ ftp bin < ../../examples/ftp/ftp-client.apple2enh java -jar $(AC) -p $@ webserv.system sys < $(CC65_HOME)/targetutil/loader.system java -jar $(AC) -cc65 $@ webserv bin < ../../examples/webserver/webserver-example.apple2enh java -jar $(AC) -p $@ telnetd.system sys < $(CC65_HOME)/targetutil/loader.system @@ -178,7 +150,7 @@ contiki-apple2.2mg: apple2enh-makes $(eval $(call makes,atarixl)) -atari: contiki-atari-1.atr contiki-atari-2.atr contiki-atari-3.atr contiki-atari-4.atr contiki-atari.atr +atari: contiki-atari-1.atr contiki-atari-2.atr contiki-atari-3.atr contiki-atari.atr contiki-atari-1.atr: atarixl-makes mkdir atr @@ -199,39 +171,21 @@ contiki-atari-1.atr: atarixl-makes contiki-atari-2.atr: atarixl-makes mkdir atr - cp ../atarixl/dos25/dos.sys atr/dos.sys - cp ../atarixl/dos25/dup.sys atr/dup.sys - cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com - cp ../../examples/irc/irc-client.atarixl atr/irc.com - cp ../../../contikiprojects/vandenbrande.com/twitter/platform/atarixl/breadbox64.atarixl atr/breadbox.com - cp ../atarixl/default.cfg atr/contiki.cfg - cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth - cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou - cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou - cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou - cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou - cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou + cp ../atarixl/dos25/dos.sys atr/dos.sys + cp ../atarixl/dos25/dup.sys atr/dup.sys + cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com + cp ../../examples/irc/irc-client.atarixl atr/irc.com + cp ../atarixl/default.cfg atr/contiki.cfg + cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth + cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou + cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou + cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou + cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou + cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou $(DIR2ATR) -b Dos25 1040 $@ atr rm -r atr contiki-atari-3.atr: atarixl-makes - mkdir atr - cp ../atarixl/dos25/dos.sys atr/dos.sys - cp ../atarixl/dos25/dup.sys atr/dup.sys - cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com - cp ../../examples/email/email-client.atarixl atr/email.com - cp ../../examples/ftp/ftp-client.atarixl atr/ftp.com - cp ../atarixl/default.cfg atr/contiki.cfg - cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth - cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou - cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou - cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou - cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou - cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou - $(DIR2ATR) -b Dos25 1040 $@ atr - rm -r atr - -contiki-atari-4.atr: atarixl-makes mkdir atr cp ../atarixl/dos25/dos.sys atr/dos.sys cp ../atarixl/dos25/dup.sys atr/dup.sys @@ -254,34 +208,31 @@ contiki-atari-4.atr: atarixl-makes contiki-atari.atr: atarixl-makes mkdir atr - cp ../atarixl/mydos4534/dos.sys atr/dos.sys - cp ../atarixl/mydos4534/dup.sys atr/dup.sys - cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com - cp ../../examples/webbrowser/webbrowser.atarixl atr/webbrows.com - cp ../../examples/wget/wget.atarixl atr/wget.com - cp ../../examples/irc/irc-client.atarixl atr/irc.com - cp ../../../contikiprojects/vandenbrande.com/twitter/platform/atarixl/breadbox64.atarixl atr/breadbox.com - cp ../../examples/email/email-client.atarixl atr/email.com - cp ../../examples/ftp/ftp-client.atarixl atr/ftp.com - cp ../../examples/webserver/webserver-example.atarixl atr/webserv.com - cp ../../examples/telnet-server/telnet-server.atarixl atr/telnetd.com - cp ../atarixl/default.cfg atr/contiki.cfg - cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth - cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou - cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou - cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou - cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou - cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou - cp ../../examples/webserver/httpd-cfs/index.htm atr/index.htm - cp ../../examples/webserver/httpd-cfs/backgrnd.gif atr/backgrnd.gif - cp ../../examples/webserver/httpd-cfs/contiki.gif atr/contiki.gif - cp ../../examples/webserver/httpd-cfs/notfound.htm atr/notfound.htm + cp ../atarixl/mydos4534/dos.sys atr/dos.sys + cp ../atarixl/mydos4534/dup.sys atr/dup.sys + cp ../../cpu/6502/ipconfig/ipconfig.atarixl atr/ipconfig.com + cp ../../examples/webbrowser/webbrowser.atarixl atr/webbrows.com + cp ../../examples/wget/wget.atarixl atr/wget.com + cp ../../examples/irc/irc-client.atarixl atr/irc.com + cp ../../examples/webserver/webserver-example.atarixl atr/webserv.com + cp ../../examples/telnet-server/telnet-server.atarixl atr/telnetd.com + cp ../atarixl/default.cfg atr/contiki.cfg + cp ../../cpu/6502/ethconfig/cs8900a.eth atr/cs8900a.eth + cp $(CC65_HOME)/mou/atrxst.mou atr/contiki.mou + cp $(CC65_HOME)/mou/atrxami.mou atr/ami.mou + cp $(CC65_HOME)/mou/atrxjoy.mou atr/joy.mou + cp $(CC65_HOME)/mou/atrxtrk.mou atr/trk.mou + cp $(CC65_HOME)/mou/atrxtt.mou atr/tt.mou + cp ../../examples/webserver/httpd-cfs/index.htm atr/index.htm + cp ../../examples/webserver/httpd-cfs/backgrnd.gif atr/backgrnd.gif + cp ../../examples/webserver/httpd-cfs/contiki.gif atr/contiki.gif + cp ../../examples/webserver/httpd-cfs/notfound.htm atr/notfound.htm $(DIR2ATR) -d -b MyDos4534 3200 $@ atr rm -r atr $(eval $(call makes,c64)) -c64: contiki-c64-1.d64 contiki-c64-2.d64 contiki-c64-3.d64 contiki-c64.d71 contiki-c64.d81 +c64: contiki-c64-1.d64 contiki-c64-2.d64 contiki-c64.d71 contiki-c64.d81 contiki-c64-1.d64: c64-makes $(C1541) -format contiki-1,00 d64 $@ @@ -299,21 +250,6 @@ contiki-c64-1.d64: c64-makes $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s contiki-c64-2.d64: c64-makes - $(C1541) -format contiki-2,00 d64 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c64/breadbox64.c64 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c64 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c64 ftp,p - $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s - -contiki-c64-3.d64: c64-makes $(C1541) -format contiki-3,00 d64 $@ $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p @@ -333,55 +269,49 @@ contiki-c64-3.d64: c64-makes contiki-c64.d71: c64-makes $(C1541) -format contiki,00 d71 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c64/breadbox64.c64 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c64 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c64 ftp,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p - $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p + $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p + $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p + $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p + $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s + $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s + $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s + $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s + $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s contiki-c64.d81: c64-makes $(C1541) -format contiki,00 d81 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c64/breadbox64.c64 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c64 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c64 ftp,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p - $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s - $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c64 ethconfig,p + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c64 ipconfig,p + $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c64 webbrowser,p + $(C1541) -attach $@ -write ../../examples/wget/wget.c64 wget,p + $(C1541) -attach $@ -write ../../examples/irc/irc-client.c64 irc,p + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c64 webserver,p + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c64 telnetd,p + $(C1541) -attach $@ -write ../c64/default.cfg contiki.cfg,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s + $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-1351.mou contiki.mou,s + $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-inkwell.mou inkwell.mou,s + $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-joy.mou joy.mou,s + $(C1541) -attach $@ -write $(CC65_HOME)/mou/c64-pot.mou pot.mou,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s $(eval $(call makes,c128)) -c128: contiki-c128-1.d64 contiki-c128-2.d64 contiki-c128-3.d64 contiki-c128.d71 contiki-c128.d81 +c128: contiki-c128-1.d64 contiki-c128-2.d64 contiki-c128.d71 contiki-c128.d81 contiki-c128-1.d64: c128-makes $(C1541) -format contiki-1,00 d64 $@ @@ -395,17 +325,6 @@ contiki-c128-1.d64: c128-makes $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s contiki-c128-2.d64: c128-makes - $(C1541) -format contiki-2,00 d64 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c128/breadbox64.c128 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c128 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c128 ftp,p - $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - -contiki-c128-3.d64: c128-makes $(C1541) -format contiki-3,00 d64 $@ $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p @@ -421,40 +340,34 @@ contiki-c128-3.d64: c128-makes contiki-c128.d71: c128-makes $(C1541) -format contiki,00 d71 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c128 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c128 irc,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c128/breadbox64.c128 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c128 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c128 ftp,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p - $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p + $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c128 webbrowser,p + $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p + $(C1541) -attach $@ -write ../../examples/irc/irc-client.c128 irc,p + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p + $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s contiki-c128.d81: c128-makes $(C1541) -format contiki,00 d81 $@ - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p - $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p - $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c128 webbrowser,p - $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p - $(C1541) -attach $@ -write ../../examples/irc/irc-client.c128 irc,p - $(C1541) -attach $@ -write ../../../contikiprojects/vandenbrande.com/twitter/platform/c128/breadbox64.c128 breadbox64,p - $(C1541) -attach $@ -write ../../examples/email/email-client.c128 email,p - $(C1541) -attach $@ -write ../../examples/ftp/ftp-client.c128 ftp,p - $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p - $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p - $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s - $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s - $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/ethconfig.c128 ethconfig,p + $(C1541) -attach $@ -write ../../cpu/6502/ipconfig/ipconfig.c128 ipconfig,p + $(C1541) -attach $@ -write ../../examples/webbrowser/webbrowser.c128 webbrowser,p + $(C1541) -attach $@ -write ../../examples/wget/wget.c128 wget,p + $(C1541) -attach $@ -write ../../examples/irc/irc-client.c128 irc,p + $(C1541) -attach $@ -write ../../examples/webserver/webserver-example.c128 webserver,p + $(C1541) -attach $@ -write ../../examples/telnet-server/telnet-server.c128 telnetd,p + $(C1541) -attach $@ -write ../c128/default.cfg contiki.cfg,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/cs8900a.eth cs8900a.eth,s + $(C1541) -attach $@ -write ../../cpu/6502/ethconfig/lan91c96.eth lan91c96.eth,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/index.htm index.htm,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/backgrnd.gif backgrnd.gif,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/contiki.gif contiki.gif,s + $(C1541) -attach $@ -write ../../examples/webserver/httpd-cfs/notfound.htm notfound.htm,s diff --git a/tools/apple2enh/prodos.2mg b/tools/apple2enh/prodos.po similarity index 100% rename from tools/apple2enh/prodos.2mg rename to tools/apple2enh/prodos.po diff --git a/tools/z1/z1-bsl-nopic b/tools/z1/z1-bsl-nopic index db2435b92..802c84642 100755 --- a/tools/z1/z1-bsl-nopic +++ b/tools/z1/z1-bsl-nopic @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python2 # Serial Bootstrap Loader software for the MSP430 embedded proccessor. # # (C) 2001-2003 Chris Liechti @@ -293,9 +293,9 @@ class LowLevel: #used for some hardware self.invertRST = 0 self.invertTEST = 0 - self.swapRSTTEST = 0 - self.telosLatch = 0 - self.telosI2C = 0 + self.swapRSTTEST = 0 + self.telosLatch = 0 + self.telosI2C = 0 self.z1 = 0 @@ -581,22 +581,22 @@ class LowLevel: self.serialport.setDTR(not level) def telosI2CStart(self): - self.telosSetSDA(1) - self.telosSetSCL(1) - self.telosSetSDA(0) + self.telosSetSDA(1) + self.telosSetSCL(1) + self.telosSetSDA(0) def telosI2CStop(self): - self.telosSetSDA(0) - self.telosSetSCL(1) - self.telosSetSDA(1) + self.telosSetSDA(0) + self.telosSetSCL(1) + self.telosSetSDA(1) def telosI2CWriteBit(self, bit): - self.telosSetSCL(0) - self.telosSetSDA(bit) + self.telosSetSCL(0) + self.telosSetSDA(bit) time.sleep(2e-6) - self.telosSetSCL(1) + self.telosSetSCL(1) time.sleep(1e-6) - self.telosSetSCL(0) + self.telosSetSCL(0) def telosI2CWriteByte(self, byte): self.telosI2CWriteBit( byte & 0x80 ); @@ -610,34 +610,34 @@ class LowLevel: self.telosI2CWriteBit( 0 ); # "acknowledge" def telosI2CWriteCmd(self, addr, cmdbyte): - self.telosI2CStart() + self.telosI2CStart() self.telosI2CWriteByte( 0x90 | (addr << 1) ) - self.telosI2CWriteByte( cmdbyte ) - self.telosI2CStop() + self.telosI2CWriteByte( cmdbyte ) + self.telosI2CStop() def telosBReset(self,invokeBSL=0): - # "BSL entry sequence at dedicated JTAG pins" + # "BSL entry sequence at dedicated JTAG pins" # rst !s0: 0 0 0 0 1 1 - # tck !s1: 1 0 1 0 0 1 + # tck !s1: 1 0 1 0 0 1 # s0|s1: 1 3 1 3 2 0 - # "BSL entry sequence at shared JTAG pins" + # "BSL entry sequence at shared JTAG pins" # rst !s0: 0 0 0 0 1 1 - # tck !s1: 0 1 0 1 1 0 + # tck !s1: 0 1 0 1 1 0 # s0|s1: 3 1 3 1 0 2 - if invokeBSL: - self.telosI2CWriteCmd(0,1) - self.telosI2CWriteCmd(0,3) - self.telosI2CWriteCmd(0,1) - self.telosI2CWriteCmd(0,3) - self.telosI2CWriteCmd(0,2) - self.telosI2CWriteCmd(0,0) - else: - self.telosI2CWriteCmd(0,3) - self.telosI2CWriteCmd(0,2) - self.telosI2CWriteCmd(0,0) + if invokeBSL: + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,1) + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + self.telosI2CWriteCmd(0,0) + else: + self.telosI2CWriteCmd(0,3) + self.telosI2CWriteCmd(0,2) + self.telosI2CWriteCmd(0,0) time.sleep(0.250) #give MSP430's oscillator time to stabilize - self.serialport.flushInput() #clear buffers + self.serialport.flushInput() #clear buffers def bslReset(self, invokeBSL=0): """Applies BSL entry sequence on RST/NMI and TEST/VPP pins @@ -651,9 +651,9 @@ class LowLevel: #print 'goint to reset!' - if self.telosI2C: - self.telosBReset(invokeBSL) - return + if self.telosI2C: + self.telosBReset(invokeBSL) + return if self.z1: if DEBUG > 1: sys.stderr.write("* entering bsl with z1\n") @@ -665,10 +665,10 @@ class LowLevel: self.SetTESTpin(1) #power suply time.sleep(0.250) #charge capacitor on boot loader hardware - if self.telosLatch: - self.SetTESTpin(0) - self.SetRSTpin(0) - self.SetTESTpin(1) + if self.telosLatch: + self.SetTESTpin(0) + self.SetRSTpin(0) + self.SetTESTpin(1) self.SetRSTpin(0) #RST pin: GND if invokeBSL: @@ -1599,11 +1599,11 @@ def main(itest=1): "upload=", "download=", "size=", "hex", "bin", "intelhex", "titext", "notimeout", "bsl=", "speed=", "bslversion", "f1x", "f2x", "f4x", "invert-reset", "invert-test", - "swap-reset-test", "telos-latch", "telos-i2c", "telos", "telosb", + "swap-reset-test", "telos-latch", "telos-i2c", "telos", "telosb", "tmote","no-BSL-download", "force-BSL-download", "slow", "dumpivt", "dumpinfo", "fromweb", - "goodfet30", "goodfet20", "goodfet10", "z1", "mainerase" - ] + "goodfet30", "goodfet20", "goodfet10", "z1", "mainerase" + ] ) except getopt.GetoptError: # print help information and exit: @@ -1755,15 +1755,15 @@ def main(itest=1): bsl.invertTEST = 1 bsl.swapRSTTEST = 1 bsl.telosLatch = 1 - elif o in ("--goodfet10", ): - bsl.invertRST = 1 - bsl.invertTEST = 1 - elif o in ("--goodfet20", ): - bsl.invertRST = 1 - bsl.invertTEST = 1 - elif o in ("--goodfet30", ): - bsl.invertRST = 1 - bsl.invertTEST = 0 + elif o in ("--goodfet10", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + elif o in ("--goodfet20", ): + bsl.invertRST = 1 + bsl.invertTEST = 1 + elif o in ("--goodfet30", ): + bsl.invertRST = 1 + bsl.invertTEST = 0 elif o in ("--telosb", ): bsl.swapRSTTEST = 1 bsl.telosI2C = 1