update to contiki 3.0

This commit is contained in:
Harald Pichler 2015-08-26 16:01:57 +02:00
commit 500078ef9a
271 changed files with 21417 additions and 8647 deletions

3
.gitignore vendored
View file

@ -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

7
.gitmodules vendored
View file

@ -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

View file

@ -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

View file

@ -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
---------------------------

View file

@ -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)

View file

@ -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

View file

@ -116,7 +116,6 @@ PROCESS_THREAD(dhcp_process, ev, data)
ctk_window_open(&window);
dhcpc_init(uip_lladdr.addr, sizeof(uip_lladdr.addr));
while(1) {
PROCESS_WAIT_EVENT();
@ -125,7 +124,7 @@ PROCESS_THREAD(dhcp_process, ev, data)
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) {

View file

@ -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;
}

View file

@ -51,7 +51,7 @@
PROCESS(shell_ls_process, "ls");
SHELL_COMMAND(ls_command,
"ls",
"ls: list files",
"ls <dirname>: list files",
&shell_ls_process);
PROCESS(shell_append_process, "append");
SHELL_COMMAND(append_command,
@ -82,7 +82,8 @@ PROCESS_THREAD(shell_ls_process, ev, data)
char buf[32];
PROCESS_BEGIN();
if(cfs_opendir(&dir, "/") != 0) {
if(data != NULL) {
if(cfs_opendir(&dir, data) != 0) {
shell_output_str(&ls_command, "Cannot open directory", "");
} else {
totsize = 0;
@ -96,6 +97,7 @@ PROCESS_THREAD(shell_ls_process, ev, data)
sprintf(buf, "%lu", (unsigned long)totsize);
shell_output_str(&ls_command, "Total size: ", buf);
}
}
PROCESS_END();
}
/*---------------------------------------------------------------------------*/

View file

@ -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 */
}
}
/*---------------------------------------------------------------------------*/

View file

@ -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"

View file

@ -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, };

View file

@ -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];

View file

@ -119,9 +119,6 @@ G * (<br>, <p>, <h>), the <li> 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 * (<br>, <p>, <h>), the <li> 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 <script> we mustn't interpret any tags
(inside JavaScript strings) but wait for the </script>. */
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:
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 <srcipt> 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 </script>. */
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

View file

@ -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 "<body>Redirect to "

View file

@ -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] =
/* "<body>Redirect to " */
{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, };

View file

@ -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];

View file

@ -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://<host>/"
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,6 +341,9 @@ parse_headers(uint16_t len)
return len;
}
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,
@ -358,7 +360,9 @@ parse_headers(uint16_t len)
cptr = s.httpheaderline +
sizeof(http_location) - 1;
if(strncmp(cptr, http_http, 7) == 0) {
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 ||
@ -375,15 +379,17 @@ parse_headers(uint16_t len)
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 {
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;
}
}
}

View file

@ -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,6 +170,7 @@ 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_slash 0x2f
@ -181,6 +182,7 @@ 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;
}
@ -804,6 +810,7 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type,
textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN);
add_forminput((struct inputattrib *)textptr);
textptr->formptr = formptr;
petsciiconv_topetscii(text, strlen(text));
strcpy(textptr->textentry.text, text);
strcpy(textptr->name, attrib);
if(size) {
@ -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)
{
/* 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);

View file

@ -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

View file

@ -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 "<body>Redirect to "

View file

@ -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] =
/* "<body>Redirect to " */
{0x3c, 0x62, 0x6f, 0x64, 0x79, 0x3e, 0x52, 0x65, 0x64, 0x69, 0x72, 0x65, 0x63, 0x74, 0x20, 0x74, 0x6f, 0x20, };

View file

@ -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];

View file

@ -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;

View file

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

View file

@ -34,44 +34,37 @@
* \file
* AES_128-based CCM* implementation.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
* Original: Konrad Krentz <konrad.krentz@gmail.com>
* Generified version: Justin King-Lacroix <justin.kinglacroix@gmail.com>
*/
/**
* \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 <string.h>
/* 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
};
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -34,23 +34,13 @@
* \file
* CCM* header file.
* \author
* Konrad Krentz <konrad.krentz@gmail.com>
* Original: Konrad Krentz <konrad.krentz@gmail.com>
* Generified version: Justin King-Lacroix <justin.kinglacroix@gmail.com>
*/
/**
* \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.
* \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 <= 16; set to LLSEC802154_MIC_LENGTH to be compliant
* \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_ */
/** @} */

View file

@ -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);

View file

@ -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;
}
}

View file

@ -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(":");

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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;
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,52 @@
/**
* \file
* CCM* convenience functions for LLSEC use
* \author
* Justin King-Lacroix <justin.kinglacroix@gmail.com>
*/
#include "lib/ccm-star.h"
#include "net/packetbuf.h"
#include <string.h>
/*---------------------------------------------------------------------------*/
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);
}
/*---------------------------------------------------------------------------*/

View file

@ -0,0 +1,24 @@
/**
* \file
* CCM* convenience functions for MAC security
* \author
* Justin King-Lacroix <justin.kinglacroix@gmail.com>
*/
#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_ */

View file

@ -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 <string.h>
#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;
uint8_t *dataptr = packetbuf_dataptr();
uint8_t data_len = packetbuf_datalen();
dataptr = packetbuf_dataptr();
data_len = packetbuf_datalen();
CCM_STAR.mic(get_extended_address(&linkaddr_node_addr), dataptr + data_len, LLSEC802154_MIC_LENGTH);
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();
}

View file

@ -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 <stdio.h>
@ -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();
}
#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());
#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");

View file

@ -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;

View file

@ -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. */

View file

@ -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 */
/*
*
*/

View file

@ -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;
}

View file

@ -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);

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -212,7 +212,7 @@ PROCESS_THREAD(ipconfig_process, ev, data)
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) {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);
}
/*---------------------------------------------------------------------------*/

View file

@ -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
*/

View file

@ -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;

View file

@ -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)
{

View file

@ -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

View file

@ -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) :
{

152
cpu/cc2538/dev/aes.c Normal file
View file

@ -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 <stdint.h>
/*---------------------------------------------------------------------------*/
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;
}
/** @} */

495
cpu/cc2538/dev/aes.h Normal file
View file

@ -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 <stdint.h>
/*---------------------------------------------------------------------------*/
/** \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_ */
/**
* @}
* @}
*/

413
cpu/cc2538/dev/ccm.c Normal file
View file

@ -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 <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
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;
}
/** @} */

141
cpu/cc2538/dev/ccm.h Normal file
View file

@ -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 <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
/** \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_ */
/**
* @}
* @}
*/

120
cpu/cc2538/dev/crypto.c Normal file
View file

@ -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 <stdbool.h>
/*---------------------------------------------------------------------------*/
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;
}
/** @} */

89
cpu/cc2538/dev/crypto.h Normal file
View file

@ -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_ */
/**
* @}
* @}
*/

356
cpu/cc2538/dev/sha256.c Normal file
View file

@ -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 <stdbool.h>
#include <stdint.h>
/*---------------------------------------------------------------------------*/
#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;
}
/** @} */

103
cpu/cc2538/dev/sha256.h Normal file
View file

@ -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 <stdint.h>
/*---------------------------------------------------------------------------*/
/** \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_ */
/**
* @}
* @}
*/

View file

@ -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
* @{
*/

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -40,6 +40,7 @@
#include "reg.h"
#include "flash-cca.h"
#include "sys-ctrl.h"
#include "rom-util.h"
#include <stdint.h>
/*---------------------------------------------------------------------------*/
@ -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();

View file

@ -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 */

View file

@ -14,11 +14,6 @@
#include <stdint.h>
/* 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 */

View file

@ -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);

View file

@ -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

View file

@ -0,0 +1,3 @@
TI_XXWARE_PATH = lib/cc26xxware
include $(CONTIKI_CPU)/Makefile.cc26xx-cc13xx

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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_

View file

@ -33,7 +33,7 @@
* @{
*
* \file
* Driver for the CC26xx AON battery monitor
* Driver for the CC13xx/CC26xx AON battery monitor
*/
/*---------------------------------------------------------------------------*/
#include "contiki-conf.h"

View file

@ -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_

View file

@ -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 <stdint.h>
#include <stdbool.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
/* 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);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -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_

View file

@ -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
*/

View file

@ -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);
}
/*---------------------------------------------------------------------------*/
/** @} */

View file

@ -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_

View file

@ -166,7 +166,4 @@ oscillators_switch_to_hf_rc(void)
osc_interface_dis(smph_clk_state);
}
/*---------------------------------------------------------------------------*/
/**
* @}
* @}
*/
/** @} */

View file

@ -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_

View file

@ -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 <stdint.h>
#include <stdbool.h>
/*---------------------------------------------------------------------------*/
#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);

View file

@ -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 <stdint.h>
/*---------------------------------------------------------------------------*/
/**
* \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_ */
/*---------------------------------------------------------------------------*/
/**
* @}

View file

@ -34,7 +34,7 @@
* @{
*
* \file
* Driver for the CC26xx IEEE addresses
* Driver for the CC13xx/CC26xx IEEE addresses
*/
/*---------------------------------------------------------------------------*/
#include "contiki-conf.h"

View file

@ -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
*

@ -0,0 +1 @@
Subproject commit 63ed52888467ea7d403b0c743852162395232c9e

@ -0,0 +1 @@
Subproject commit 0e82b18bf2c69fb0a40af4d2496db2a3dc721cec

View file

@ -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 <stdint.h>
#include <string.h>
/*---------------------------------------------------------------------------*/
#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

View file

@ -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_

Some files were not shown because too many files have changed in this diff Show more