update to contiki 3.0
This commit is contained in:
commit
500078ef9a
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -24,6 +24,7 @@
|
||||||
*.c128
|
*.c128
|
||||||
*.c64
|
*.c64
|
||||||
*.cc2538dk
|
*.cc2538dk
|
||||||
|
*.remote
|
||||||
*.srf06-cc26xx
|
*.srf06-cc26xx
|
||||||
*.ev-aducrf101mkxz
|
*.ev-aducrf101mkxz
|
||||||
*.report
|
*.report
|
||||||
|
@ -79,7 +80,7 @@ contiki-cc2530dk.lib
|
||||||
*.S
|
*.S
|
||||||
*.eth
|
*.eth
|
||||||
*.dsk
|
*.dsk
|
||||||
*.2mg
|
*.po
|
||||||
*.atr
|
*.atr
|
||||||
*.d64
|
*.d64
|
||||||
*.d71
|
*.d71
|
||||||
|
|
7
.gitmodules
vendored
7
.gitmodules
vendored
|
@ -7,7 +7,10 @@
|
||||||
[submodule "platform/osd-merkur/dev/LED_Strip_Suli"]
|
[submodule "platform/osd-merkur/dev/LED_Strip_Suli"]
|
||||||
path = platform/osd-merkur/dev/LED_Strip_Suli
|
path = platform/osd-merkur/dev/LED_Strip_Suli
|
||||||
url = https://github.com/osdomotics/LED_Strip_Suli.git
|
url = https://github.com/osdomotics/LED_Strip_Suli.git
|
||||||
[submodule "cpu/cc26xx/lib/cc26xxware"]
|
[submodule "cpu/cc26xx-cc13xx/lib/cc26xxware"]
|
||||||
path = cpu/cc26xx/lib/cc26xxware
|
path = cpu/cc26xx-cc13xx/lib/cc26xxware
|
||||||
url = https://github.com/g-oikonomou/cc26xxware.git
|
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
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ before_script:
|
||||||
|
|
||||||
## Install doxygen
|
## Install doxygen
|
||||||
- if [ ${BUILD_CATEGORY:-0} = doxygen ] ; then
|
- 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 &&
|
sudo apt-get --no-install-suggests --no-install-recommends -qq install doxygen &&
|
||||||
doxygen --version ;
|
doxygen --version ;
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -136,7 +136,7 @@ Contiki maintainers to look at!
|
||||||
All code contributions to Contiki are submitted as [Github pull
|
All code contributions to Contiki are submitted as [Github pull
|
||||||
requests](https://help.github.com/articles/using-pull-requests). Pull
|
requests](https://help.github.com/articles/using-pull-requests). Pull
|
||||||
requests will be reviewed and accepted according to the guidelines
|
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:
|
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.
|
* 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.
|
* 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
|
Travis / Regression testing
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,6 @@ endif
|
||||||
|
|
||||||
ifdef MODULES
|
ifdef MODULES
|
||||||
UNIQUEMODULES = $(call uniq,$(MODULES))
|
UNIQUEMODULES = $(call uniq,$(MODULES))
|
||||||
MODULESSUBST = ${subst /,-,$(UNIQUEMODULES)}
|
|
||||||
MODULEDIRS = ${wildcard ${addprefix $(CONTIKI)/, $(UNIQUEMODULES)}}
|
MODULEDIRS = ${wildcard ${addprefix $(CONTIKI)/, $(UNIQUEMODULES)}}
|
||||||
MODULES_SOURCES = ${foreach d, $(MODULEDIRS), ${subst ${d}/,,${wildcard $(d)/*.c}}}
|
MODULES_SOURCES = ${foreach d, $(MODULEDIRS), ${subst ${d}/,,${wildcard $(d)/*.c}}}
|
||||||
CONTIKI_SOURCEFILES += $(MODULES_SOURCES)
|
CONTIKI_SOURCEFILES += $(MODULES_SOURCES)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
The Contiki Operating System
|
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
|
Contiki is an open source operating system that runs on tiny low-power
|
||||||
microcontrollers and makes it possible to develop applications that
|
microcontrollers and makes it possible to develop applications that
|
||||||
|
|
|
@ -97,9 +97,9 @@ makestrings(void)
|
||||||
PROCESS_THREAD(dhcp_process, ev, data)
|
PROCESS_THREAD(dhcp_process, ev, data)
|
||||||
{
|
{
|
||||||
PROCESS_BEGIN();
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
ctk_window_new(&window, 28, 7, "DHCP");
|
ctk_window_new(&window, 28, 7, "DHCP");
|
||||||
|
|
||||||
CTK_WIDGET_ADD(&window, &getbutton);
|
CTK_WIDGET_ADD(&window, &getbutton);
|
||||||
CTK_WIDGET_ADD(&window, &statuslabel);
|
CTK_WIDGET_ADD(&window, &statuslabel);
|
||||||
CTK_WIDGET_ADD(&window, &ipaddrlabel);
|
CTK_WIDGET_ADD(&window, &ipaddrlabel);
|
||||||
|
@ -110,22 +110,21 @@ PROCESS_THREAD(dhcp_process, ev, data)
|
||||||
CTK_WIDGET_ADD(&window, &gatewayentry);
|
CTK_WIDGET_ADD(&window, &gatewayentry);
|
||||||
CTK_WIDGET_ADD(&window, &dnsserverlabel);
|
CTK_WIDGET_ADD(&window, &dnsserverlabel);
|
||||||
CTK_WIDGET_ADD(&window, &dnsserverentry);
|
CTK_WIDGET_ADD(&window, &dnsserverentry);
|
||||||
|
|
||||||
CTK_WIDGET_FOCUS(&window, &getbutton);
|
CTK_WIDGET_FOCUS(&window, &getbutton);
|
||||||
|
|
||||||
ctk_window_open(&window);
|
ctk_window_open(&window);
|
||||||
dhcpc_init(uip_lladdr.addr, sizeof(uip_lladdr.addr));
|
dhcpc_init(uip_lladdr.addr, sizeof(uip_lladdr.addr));
|
||||||
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
PROCESS_WAIT_EVENT();
|
PROCESS_WAIT_EVENT();
|
||||||
|
|
||||||
if(ev == ctk_signal_widget_activate) {
|
if(ev == ctk_signal_widget_activate) {
|
||||||
if(data == (process_data_t)&getbutton) {
|
if(data == (process_data_t)&getbutton) {
|
||||||
dhcpc_request();
|
dhcpc_request();
|
||||||
set_statustext("Requesting...");
|
set_statustext("Requesting...");
|
||||||
}
|
}
|
||||||
} else if(ev == tcpip_event) {
|
} else if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) {
|
||||||
dhcpc_appcall(ev, data);
|
dhcpc_appcall(ev, data);
|
||||||
} else if(ev == PROCESS_EVENT_EXIT ||
|
} else if(ev == PROCESS_EVENT_EXIT ||
|
||||||
ev == ctk_signal_window_close) {
|
ev == ctk_signal_window_close) {
|
||||||
|
|
|
@ -104,7 +104,7 @@ coap_receive(void)
|
||||||
coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr,
|
coap_new_transaction(message->mid, &UIP_IP_BUF->srcipaddr,
|
||||||
UIP_UDP_BUF->srcport))) {
|
UIP_UDP_BUF->srcport))) {
|
||||||
uint32_t block_num = 0;
|
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;
|
uint32_t block_offset = 0;
|
||||||
int32_t new_offset = 0;
|
int32_t new_offset = 0;
|
||||||
|
|
||||||
|
@ -125,8 +125,8 @@ coap_receive(void)
|
||||||
if(coap_get_header_block2
|
if(coap_get_header_block2
|
||||||
(message, &block_num, NULL, &block_size, &block_offset)) {
|
(message, &block_num, NULL, &block_size, &block_offset)) {
|
||||||
PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n",
|
PRINTF("Blockwise: block request %lu (%u/%u) @ %lu bytes\n",
|
||||||
block_num, block_size, REST_MAX_CHUNK_SIZE, block_offset);
|
block_num, block_size, COAP_MAX_BLOCK_SIZE, block_offset);
|
||||||
block_size = MIN(block_size, REST_MAX_CHUNK_SIZE);
|
block_size = MIN(block_size, COAP_MAX_BLOCK_SIZE);
|
||||||
new_offset = block_offset;
|
new_offset = block_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
PROCESS(shell_ls_process, "ls");
|
PROCESS(shell_ls_process, "ls");
|
||||||
SHELL_COMMAND(ls_command,
|
SHELL_COMMAND(ls_command,
|
||||||
"ls",
|
"ls",
|
||||||
"ls: list files",
|
"ls <dirname>: list files",
|
||||||
&shell_ls_process);
|
&shell_ls_process);
|
||||||
PROCESS(shell_append_process, "append");
|
PROCESS(shell_append_process, "append");
|
||||||
SHELL_COMMAND(append_command,
|
SHELL_COMMAND(append_command,
|
||||||
|
@ -82,19 +82,21 @@ PROCESS_THREAD(shell_ls_process, ev, data)
|
||||||
char buf[32];
|
char buf[32];
|
||||||
PROCESS_BEGIN();
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
if(cfs_opendir(&dir, "/") != 0) {
|
if(data != NULL) {
|
||||||
shell_output_str(&ls_command, "Cannot open directory", "");
|
if(cfs_opendir(&dir, data) != 0) {
|
||||||
} else {
|
shell_output_str(&ls_command, "Cannot open directory", "");
|
||||||
totsize = 0;
|
} else {
|
||||||
while(cfs_readdir(&dir, &dirent) == 0) {
|
totsize = 0;
|
||||||
totsize += dirent.size;
|
while(cfs_readdir(&dir, &dirent) == 0) {
|
||||||
sprintf(buf, "%lu ", (unsigned long)dirent.size);
|
totsize += dirent.size;
|
||||||
/* printf("'%s'\n", dirent.name);*/
|
sprintf(buf, "%lu ", (unsigned long)dirent.size);
|
||||||
shell_output_str(&ls_command, buf, dirent.name);
|
/* printf("'%s'\n", dirent.name);*/
|
||||||
|
shell_output_str(&ls_command, buf, dirent.name);
|
||||||
|
}
|
||||||
|
cfs_closedir(&dir);
|
||||||
|
sprintf(buf, "%lu", (unsigned long)totsize);
|
||||||
|
shell_output_str(&ls_command, "Total size: ", buf);
|
||||||
}
|
}
|
||||||
cfs_closedir(&dir);
|
|
||||||
sprintf(buf, "%lu", (unsigned long)totsize);
|
|
||||||
shell_output_str(&ls_command, "Total size: ", buf);
|
|
||||||
}
|
}
|
||||||
PROCESS_END();
|
PROCESS_END();
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,10 @@ static char telnetd_reject_text[] =
|
||||||
"Too many connections, please try again later.";
|
"Too many connections, please try again later.";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef TELNETD_CONF_MAX_IDLE_TIME
|
||||||
|
#define TELNETD_CONF_MAX_IDLE_TIME (CLOCK_SECOND * 30)
|
||||||
|
#endif
|
||||||
|
|
||||||
struct telnetd_state {
|
struct telnetd_state {
|
||||||
char buf[TELNETD_CONF_LINELEN + 1];
|
char buf[TELNETD_CONF_LINELEN + 1];
|
||||||
char bufptr;
|
char bufptr;
|
||||||
|
@ -74,7 +78,9 @@ struct telnetd_state {
|
||||||
#define STATE_DO 4
|
#define STATE_DO 4
|
||||||
#define STATE_DONT 5
|
#define STATE_DONT 5
|
||||||
#define STATE_CLOSE 6
|
#define STATE_CLOSE 6
|
||||||
|
#if TELNETD_CONF_MAX_IDLE_TIME
|
||||||
struct timer silence_timer;
|
struct timer silence_timer;
|
||||||
|
#endif /* TELNETD_CONF_MAX_IDLE_TIME */
|
||||||
};
|
};
|
||||||
static struct telnetd_state s;
|
static struct telnetd_state s;
|
||||||
|
|
||||||
|
@ -102,8 +108,6 @@ static struct telnetd_buf buf;
|
||||||
|
|
||||||
static uint8_t connected;
|
static uint8_t connected;
|
||||||
|
|
||||||
#define MAX_SILENCE_TIME (CLOCK_SECOND * 30)
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
buf_init(struct telnetd_buf *buf)
|
buf_init(struct telnetd_buf *buf)
|
||||||
|
@ -169,6 +173,8 @@ shell_prompt(char *str)
|
||||||
void
|
void
|
||||||
shell_default_output(const char *str1, int len1, const char *str2, int len2)
|
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') {
|
if(len1 > 0 && str1[len1 - 1] == '\n') {
|
||||||
--len1;
|
--len1;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +189,7 @@ shell_default_output(const char *str1, int len1, const char *str2, int len2)
|
||||||
#endif /* TELNETD_CONF_GUI */
|
#endif /* TELNETD_CONF_GUI */
|
||||||
buf_append(&buf, str1, len1);
|
buf_append(&buf, str1, len1);
|
||||||
buf_append(&buf, str2, len2);
|
buf_append(&buf, str2, len2);
|
||||||
buf_append(&buf, "\r\n", 2);
|
buf_append(&buf, crnl, sizeof(crnl));
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
|
@ -359,7 +365,9 @@ telnetd_appcall(void *ts)
|
||||||
s.state = STATE_NORMAL;
|
s.state = STATE_NORMAL;
|
||||||
connected = 1;
|
connected = 1;
|
||||||
shell_start();
|
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;
|
ts = (char *)0;
|
||||||
} else {
|
} else {
|
||||||
uip_send(telnetd_reject_text, strlen(telnetd_reject_text));
|
uip_send(telnetd_reject_text, strlen(telnetd_reject_text));
|
||||||
|
@ -381,11 +389,15 @@ telnetd_appcall(void *ts)
|
||||||
connected = 0;
|
connected = 0;
|
||||||
}
|
}
|
||||||
if(uip_acked()) {
|
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();
|
acked();
|
||||||
}
|
}
|
||||||
if(uip_newdata()) {
|
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();
|
newdata();
|
||||||
}
|
}
|
||||||
if(uip_rexmit() ||
|
if(uip_rexmit() ||
|
||||||
|
@ -394,16 +406,20 @@ telnetd_appcall(void *ts)
|
||||||
uip_connected() ||
|
uip_connected() ||
|
||||||
uip_poll()) {
|
uip_poll()) {
|
||||||
senddata();
|
senddata();
|
||||||
|
#if TELNETD_CONF_MAX_IDLE_TIME
|
||||||
if(s.numsent > 0) {
|
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(uip_poll()) {
|
||||||
if(timer_expired(&s.silence_timer)) {
|
if(timer_expired(&s.silence_timer)) {
|
||||||
uip_close();
|
uip_close();
|
||||||
tcp_markconn(uip_conn, NULL);
|
tcp_markconn(uip_conn, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* TELNETD_CONF_MAX_IDLE_TIME */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -9,7 +9,6 @@ html_a "a\0"
|
||||||
html_body "body\0"
|
html_body "body\0"
|
||||||
html_br "br\0"
|
html_br "br\0"
|
||||||
html_form "form\0"
|
html_form "form\0"
|
||||||
html_frame "frame\0"
|
|
||||||
html_h1 "h1\0"
|
html_h1 "h1\0"
|
||||||
html_h2 "h2\0"
|
html_h2 "h2\0"
|
||||||
html_h3 "h3\0"
|
html_h3 "h3\0"
|
||||||
|
|
|
@ -31,9 +31,6 @@ const char html_br[4] =
|
||||||
const char html_form[6] =
|
const char html_form[6] =
|
||||||
/* "form\0" */
|
/* "form\0" */
|
||||||
{0x66, 0x6f, 0x72, 0x6d, 00, };
|
{0x66, 0x6f, 0x72, 0x6d, 00, };
|
||||||
const char html_frame[7] =
|
|
||||||
/* "frame\0" */
|
|
||||||
{0x66, 0x72, 0x61, 0x6d, 0x65, 00, };
|
|
||||||
const char html_h1[4] =
|
const char html_h1[4] =
|
||||||
/* "h1\0" */
|
/* "h1\0" */
|
||||||
{0x68, 0x31, 00, };
|
{0x68, 0x31, 00, };
|
||||||
|
|
|
@ -9,7 +9,6 @@ extern const char html_a[3];
|
||||||
extern const char html_body[6];
|
extern const char html_body[6];
|
||||||
extern const char html_br[4];
|
extern const char html_br[4];
|
||||||
extern const char html_form[6];
|
extern const char html_form[6];
|
||||||
extern const char html_frame[7];
|
|
||||||
extern const char html_h1[4];
|
extern const char html_h1[4];
|
||||||
extern const char html_h2[4];
|
extern const char html_h2[4];
|
||||||
extern const char html_h3[4];
|
extern const char html_h3[4];
|
||||||
|
|
|
@ -119,9 +119,6 @@ G * (<br>, <p>, <h>), the <li> tag (but does not even try to
|
||||||
#define ISO_eq 0x3d
|
#define ISO_eq 0x3d
|
||||||
#define ISO_gt 0x3e
|
#define ISO_gt 0x3e
|
||||||
|
|
||||||
#define ISO_rbrack 0x5b
|
|
||||||
#define ISO_lbrack 0x5d
|
|
||||||
|
|
||||||
#define MINORSTATE_NONE 0
|
#define MINORSTATE_NONE 0
|
||||||
#define MINORSTATE_TEXT 1 /* Parse normal text */
|
#define MINORSTATE_TEXT 1 /* Parse normal text */
|
||||||
#define MINORSTATE_EXTCHAR 2 /* Check for semi-colon */
|
#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_LINK 2
|
||||||
#define MAJORSTATE_FORM 3
|
#define MAJORSTATE_FORM 3
|
||||||
#define MAJORSTATE_DISCARD 4
|
#define MAJORSTATE_DISCARD 4
|
||||||
|
#define MAJORSTATE_SCRIPT 5
|
||||||
|
|
||||||
struct htmlparser_state {
|
struct htmlparser_state {
|
||||||
|
|
||||||
|
@ -151,7 +148,7 @@ struct htmlparser_state {
|
||||||
unsigned char tagattrptr;
|
unsigned char tagattrptr;
|
||||||
char tagattrparam[WWW_CONF_MAX_URLLEN + 1];
|
char tagattrparam[WWW_CONF_MAX_URLLEN + 1];
|
||||||
unsigned char tagattrparamptr;
|
unsigned char tagattrparamptr;
|
||||||
unsigned char lastchar, quotechar;
|
unsigned char quotechar;
|
||||||
unsigned char majorstate, lastmajorstate;
|
unsigned char majorstate, lastmajorstate;
|
||||||
char linkurl[WWW_CONF_MAX_URLLEN + 1];
|
char linkurl[WWW_CONF_MAX_URLLEN + 1];
|
||||||
|
|
||||||
|
@ -196,33 +193,31 @@ static const char *tags[] = {
|
||||||
html_br,
|
html_br,
|
||||||
#define TAG_FORM 10
|
#define TAG_FORM 10
|
||||||
html_form,
|
html_form,
|
||||||
#define TAG_FRAME 11
|
#define TAG_H1 11
|
||||||
html_frame,
|
|
||||||
#define TAG_H1 12
|
|
||||||
html_h1,
|
html_h1,
|
||||||
#define TAG_H2 13
|
#define TAG_H2 12
|
||||||
html_h2,
|
html_h2,
|
||||||
#define TAG_H3 14
|
#define TAG_H3 13
|
||||||
html_h3,
|
html_h3,
|
||||||
#define TAG_H4 15
|
#define TAG_H4 14
|
||||||
html_h4,
|
html_h4,
|
||||||
#define TAG_IMG 16
|
#define TAG_IMG 15
|
||||||
html_img,
|
html_img,
|
||||||
#define TAG_INPUT 17
|
#define TAG_INPUT 16
|
||||||
html_input,
|
html_input,
|
||||||
#define TAG_LI 18
|
#define TAG_LI 17
|
||||||
html_li,
|
html_li,
|
||||||
#define TAG_P 19
|
#define TAG_P 18
|
||||||
html_p,
|
html_p,
|
||||||
#define TAG_SCRIPT 20
|
#define TAG_SCRIPT 19
|
||||||
html_script,
|
html_script,
|
||||||
#define TAG_SELECT 21
|
#define TAG_SELECT 20
|
||||||
html_select,
|
html_select,
|
||||||
#define TAG_STYLE 22
|
#define TAG_STYLE 21
|
||||||
html_style,
|
html_style,
|
||||||
#define TAG_TR 23
|
#define TAG_TR 22
|
||||||
html_tr,
|
html_tr,
|
||||||
#define TAG_LAST 24
|
#define TAG_LAST 23
|
||||||
last,
|
last,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -254,7 +249,7 @@ htmlparser_init(void)
|
||||||
{
|
{
|
||||||
s.majorstate = s.lastmajorstate = MAJORSTATE_DISCARD;
|
s.majorstate = s.lastmajorstate = MAJORSTATE_DISCARD;
|
||||||
s.minorstate = MINORSTATE_TEXT;
|
s.minorstate = MINORSTATE_TEXT;
|
||||||
s.lastchar = 0;
|
s.wordlen = 0;
|
||||||
#if WWW_CONF_FORMS
|
#if WWW_CONF_FORMS
|
||||||
s.formaction[0] = 0;
|
s.formaction[0] = 0;
|
||||||
#endif /* WWW_CONF_FORMS */
|
#endif /* WWW_CONF_FORMS */
|
||||||
|
@ -305,10 +300,10 @@ do_word(void)
|
||||||
{
|
{
|
||||||
if(s.wordlen > 0) {
|
if(s.wordlen > 0) {
|
||||||
if(s.majorstate == MAJORSTATE_LINK) {
|
if(s.majorstate == MAJORSTATE_LINK) {
|
||||||
if(s.word[s.wordlen] != ISO_space) {
|
if(s.word[s.wordlen - 1] != ISO_space) {
|
||||||
add_char(ISO_space);
|
add_char(ISO_space);
|
||||||
}
|
}
|
||||||
} else if(s.majorstate == MAJORSTATE_DISCARD) {
|
} else if(s.majorstate >= MAJORSTATE_DISCARD) {
|
||||||
s.wordlen = 0;
|
s.wordlen = 0;
|
||||||
} else {
|
} else {
|
||||||
s.word[s.wordlen] = '\0';
|
s.word[s.wordlen] = '\0';
|
||||||
|
@ -368,13 +363,19 @@ static void
|
||||||
parse_tag(void)
|
parse_tag(void)
|
||||||
{
|
{
|
||||||
static char *tagattrparam;
|
static char *tagattrparam;
|
||||||
|
static unsigned char tag;
|
||||||
static unsigned char size;
|
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));
|
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_P:
|
||||||
case TAG_H1:
|
case TAG_H1:
|
||||||
case TAG_H2:
|
case TAG_H2:
|
||||||
|
@ -386,15 +387,18 @@ parse_tag(void)
|
||||||
case TAG_TR:
|
case TAG_TR:
|
||||||
case TAG_SLASHDIV:
|
case TAG_SLASHDIV:
|
||||||
case TAG_SLASHH:
|
case TAG_SLASHH:
|
||||||
dummy = 0;
|
|
||||||
newline();
|
newline();
|
||||||
break;
|
break;
|
||||||
case TAG_LI:
|
case TAG_LI:
|
||||||
newline();
|
if(s.tagattr[0] == 0) {
|
||||||
add_char(ISO_asterisk);
|
newline();
|
||||||
add_char(ISO_space);
|
add_char(ISO_asterisk);
|
||||||
|
add_char(ISO_space);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TAG_SCRIPT:
|
case TAG_SCRIPT:
|
||||||
|
switch_majorstate(MAJORSTATE_SCRIPT);
|
||||||
|
break;
|
||||||
case TAG_STYLE:
|
case TAG_STYLE:
|
||||||
case TAG_SELECT:
|
case TAG_SELECT:
|
||||||
switch_majorstate(MAJORSTATE_DISCARD);
|
switch_majorstate(MAJORSTATE_DISCARD);
|
||||||
|
@ -408,18 +412,6 @@ parse_tag(void)
|
||||||
case TAG_BODY:
|
case TAG_BODY:
|
||||||
s.majorstate = s.lastmajorstate = MAJORSTATE_BODY;
|
s.majorstate = s.lastmajorstate = MAJORSTATE_BODY;
|
||||||
break;
|
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:
|
case TAG_IMG:
|
||||||
if(strncmp(s.tagattr, html_alt, sizeof(html_alt)) == 0 && s.tagattrparam[0] != 0) {
|
if(strncmp(s.tagattr, html_alt, sizeof(html_alt)) == 0 && s.tagattrparam[0] != 0) {
|
||||||
add_char(ISO_lt);
|
add_char(ISO_lt);
|
||||||
|
@ -572,6 +564,15 @@ parse_word(char *data, uint8_t dlen)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MINORSTATE_TAG:
|
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
|
/* We are currently parsing within the name of a tag. We check
|
||||||
for the end of a tag (the '>' character) or whitespace (which
|
for the end of a tag (the '>' character) or whitespace (which
|
||||||
indicates that we should parse a tag attr argument
|
indicates that we should parse a tag attr argument
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
http_http "http://"
|
http_http "http://"
|
||||||
|
http_https "https://"
|
||||||
http_200 "200 "
|
http_200 "200 "
|
||||||
http_301 "301 "
|
http_301 "301 "
|
||||||
http_302 "302 "
|
http_302 "302 "
|
||||||
|
@ -10,3 +11,4 @@ http_location "location: "
|
||||||
http_host "Host: "
|
http_host "Host: "
|
||||||
http_crnl "\r\n"
|
http_crnl "\r\n"
|
||||||
http_html ".html"
|
http_html ".html"
|
||||||
|
http_redirect "<body>Redirect to "
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
const char http_http[8] =
|
const char http_http[8] =
|
||||||
/* "http://" */
|
/* "http://" */
|
||||||
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
|
{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] =
|
const char http_200[5] =
|
||||||
/* "200 " */
|
/* "200 " */
|
||||||
{0x32, 0x30, 0x30, 0x20, };
|
{0x32, 0x30, 0x30, 0x20, };
|
||||||
|
@ -34,3 +37,6 @@ const char http_crnl[3] =
|
||||||
const char http_html[6] =
|
const char http_html[6] =
|
||||||
/* ".html" */
|
/* ".html" */
|
||||||
{0x2e, 0x68, 0x74, 0x6d, 0x6c, };
|
{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, };
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
extern const char http_http[8];
|
extern const char http_http[8];
|
||||||
|
extern const char http_https[9];
|
||||||
extern const char http_200[5];
|
extern const char http_200[5];
|
||||||
extern const char http_301[5];
|
extern const char http_301[5];
|
||||||
extern const char http_302[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_host[7];
|
||||||
extern const char http_crnl[3];
|
extern const char http_crnl[3];
|
||||||
extern const char http_html[6];
|
extern const char http_html[6];
|
||||||
|
extern const char http_redirect[19];
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
#define HTTPFLAG_NONE 0
|
#define HTTPFLAG_NONE 0
|
||||||
#define HTTPFLAG_OK 1
|
#define HTTPFLAG_OK 1
|
||||||
#define HTTPFLAG_MOVED 2
|
#define HTTPFLAG_MOVED 2
|
||||||
#define HTTPFLAG_ERROR 3
|
#define HTTPFLAG_HTTPS 3
|
||||||
|
|
||||||
|
|
||||||
#define ISO_nl 0x0a
|
#define ISO_nl 0x0a
|
||||||
|
@ -63,11 +63,11 @@ struct webclient_state {
|
||||||
|
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
char host[40];
|
char host[40];
|
||||||
char file[WWW_CONF_MAX_URLLEN];
|
char file[WWW_CONF_MAX_URLLEN - 10]; // URL - "http://<host>/"
|
||||||
uint16_t getrequestptr;
|
uint16_t getrequestptr;
|
||||||
uint16_t getrequestleft;
|
uint16_t getrequestleft;
|
||||||
|
|
||||||
char httpheaderline[200];
|
char httpheaderline[WWW_CONF_MAX_URLLEN + 10]; // URL + "Location: "
|
||||||
uint16_t httpheaderlineptr;
|
uint16_t httpheaderlineptr;
|
||||||
|
|
||||||
char mimetype[32];
|
char mimetype[32];
|
||||||
|
@ -327,13 +327,12 @@ parse_headers(uint16_t len)
|
||||||
char *cptr;
|
char *cptr;
|
||||||
static unsigned char i;
|
static unsigned char i;
|
||||||
|
|
||||||
while(len > 0 && s.httpheaderlineptr < sizeof(s.httpheaderline)) {
|
while(len > 0) {
|
||||||
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
|
s.httpheaderline[s.httpheaderlineptr] = *(char *)uip_appdata;
|
||||||
uip_appdata = (char *)uip_appdata + 1;
|
uip_appdata = (char *)uip_appdata + 1;
|
||||||
--len;
|
--len;
|
||||||
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
|
if(s.httpheaderline[s.httpheaderlineptr] == ISO_nl) {
|
||||||
/* We have an entire HTTP header line in s.httpheaderline, so
|
/* We reached the end of an HTTP header line. */
|
||||||
we parse it. */
|
|
||||||
if(s.httpheaderline[0] == ISO_cr) {
|
if(s.httpheaderline[0] == ISO_cr) {
|
||||||
/* This was the last header line (i.e., and empty "\r\n"), so
|
/* This was the last header line (i.e., and empty "\r\n"), so
|
||||||
we are done with the headers and proceed with the actual
|
we are done with the headers and proceed with the actual
|
||||||
|
@ -342,46 +341,53 @@ parse_headers(uint16_t len)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
|
if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) {
|
||||||
/* Check for specific HTTP header fields. */
|
/* We have an entire HTTP header line in s.httpheaderline, so
|
||||||
if(casecmp(s.httpheaderline, http_content_type,
|
we parse it. */
|
||||||
sizeof(http_content_type) - 1) == 0) {
|
s.httpheaderline[s.httpheaderlineptr - 1] = 0;
|
||||||
/* Found Content-type field. */
|
/* Check for specific HTTP header fields. */
|
||||||
cptr = strchr(s.httpheaderline, ';');
|
if(casecmp(s.httpheaderline, http_content_type,
|
||||||
if(cptr != NULL) {
|
sizeof(http_content_type) - 1) == 0) {
|
||||||
*cptr = 0;
|
/* Found Content-type field. */
|
||||||
}
|
cptr = strchr(s.httpheaderline, ';');
|
||||||
strncpy(s.mimetype, s.httpheaderline +
|
if(cptr != NULL) {
|
||||||
sizeof(http_content_type) - 1, sizeof(s.mimetype));
|
*cptr = 0;
|
||||||
} else if(casecmp(s.httpheaderline, http_location,
|
|
||||||
sizeof(http_location) - 1) == 0) {
|
|
||||||
cptr = s.httpheaderline +
|
|
||||||
sizeof(http_location) - 1;
|
|
||||||
|
|
||||||
if(strncmp(cptr, http_http, 7) == 0) {
|
|
||||||
cptr += 7;
|
|
||||||
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
|
|
||||||
if(*cptr == 0 ||
|
|
||||||
*cptr == '/' ||
|
|
||||||
*cptr == ' ' ||
|
|
||||||
*cptr == ':') {
|
|
||||||
s.host[i] = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
s.host[i] = *cptr;
|
|
||||||
++cptr;
|
|
||||||
}
|
}
|
||||||
}
|
strncpy(s.mimetype, s.httpheaderline +
|
||||||
strncpy(s.file, cptr, sizeof(s.file));
|
sizeof(http_content_type) - 1, sizeof(s.mimetype));
|
||||||
/* s.file[s.httpheaderlineptr - i] = 0;*/
|
} else if(casecmp(s.httpheaderline, http_location,
|
||||||
}
|
sizeof(http_location) - 1) == 0) {
|
||||||
|
cptr = s.httpheaderline +
|
||||||
|
sizeof(http_location) - 1;
|
||||||
|
|
||||||
|
if(strncmp(cptr, http_https, sizeof(http_https) - 1) == 0) {
|
||||||
|
s.httpflag = HTTPFLAG_HTTPS;
|
||||||
|
} else if(strncmp(cptr, http_http, 7) == 0) {
|
||||||
|
cptr += 7;
|
||||||
|
for(i = 0; i < s.httpheaderlineptr - 7; ++i) {
|
||||||
|
if(*cptr == 0 ||
|
||||||
|
*cptr == '/' ||
|
||||||
|
*cptr == ' ' ||
|
||||||
|
*cptr == ':') {
|
||||||
|
s.host[i] = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
s.host[i] = *cptr;
|
||||||
|
++cptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strncpy(s.file, cptr, sizeof(s.file));
|
||||||
|
/* s.file[s.httpheaderlineptr - i] = 0;*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* We're done parsing, so we reset the pointer and start the
|
/* We're done parsing, so we reset the pointer and start the
|
||||||
next line. */
|
next line. */
|
||||||
s.httpheaderlineptr = 0;
|
s.httpheaderlineptr = 0;
|
||||||
} else {
|
} else {
|
||||||
++s.httpheaderlineptr;
|
if(s.httpheaderlineptr < sizeof(s.httpheaderline) - 1) {
|
||||||
|
++s.httpheaderlineptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return len;
|
return len;
|
||||||
|
@ -403,7 +409,7 @@ newdata(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
|
if(len > 0 && s.state == WEBCLIENT_STATE_DATA &&
|
||||||
s.httpflag != HTTPFLAG_MOVED) {
|
s.httpflag == HTTPFLAG_OK) {
|
||||||
webclient_datahandler((char *)uip_appdata, len);
|
webclient_datahandler((char *)uip_appdata, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,7 +447,6 @@ webclient_appcall(void *state)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* The acked() and newdata() functions may alter the uip_appdata
|
/* The acked() and newdata() functions may alter the uip_appdata
|
||||||
ptr, so we need to store it in the "dataptr" variable so that we
|
ptr, so we need to store it in the "dataptr" variable so that we
|
||||||
can restore it before the senddata() function is called. */
|
can restore it before the senddata() function is called. */
|
||||||
|
@ -474,10 +479,18 @@ webclient_appcall(void *state)
|
||||||
|
|
||||||
if(uip_closed()) {
|
if(uip_closed()) {
|
||||||
tcp_markconn(uip_conn, NULL);
|
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. */
|
/* Send NULL data to signal EOF. */
|
||||||
webclient_datahandler(NULL, 0);
|
webclient_datahandler(NULL, 0);
|
||||||
} else {
|
break;
|
||||||
|
case HTTPFLAG_MOVED:
|
||||||
/* conn = uip_connect(uip_conn->ripaddr, s.port);
|
/* conn = uip_connect(uip_conn->ripaddr, s.port);
|
||||||
if(conn != NULL) {
|
if(conn != NULL) {
|
||||||
dispatcher_markconn(conn, NULL);
|
dispatcher_markconn(conn, NULL);
|
||||||
|
@ -489,6 +502,7 @@ webclient_appcall(void *state)
|
||||||
}
|
}
|
||||||
#endif /* UIP_UDP */
|
#endif /* UIP_UDP */
|
||||||
webclient_get(s.host, s.port, s.file);
|
webclient_get(s.host, s.port, s.file);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -125,7 +125,7 @@ static struct ctk_button wgetyesbutton =
|
||||||
#if WWW_CONF_HISTORY_SIZE > 0
|
#if WWW_CONF_HISTORY_SIZE > 0
|
||||||
/* The char arrays that hold the history of visited URLs. */
|
/* The char arrays that hold the history of visited URLs. */
|
||||||
static char history[WWW_CONF_HISTORY_SIZE][WWW_CONF_MAX_URLLEN];
|
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 */
|
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
||||||
|
|
||||||
struct linkattrib {
|
struct linkattrib {
|
||||||
|
@ -170,17 +170,19 @@ static struct inputattrib *currptr;
|
||||||
|
|
||||||
#define ISO_nl 0x0a
|
#define ISO_nl 0x0a
|
||||||
#define ISO_space 0x20
|
#define ISO_space 0x20
|
||||||
|
#define ISO_hash 0x23
|
||||||
#define ISO_ampersand 0x26
|
#define ISO_ampersand 0x26
|
||||||
#define ISO_plus 0x2b
|
#define ISO_plus 0x2b
|
||||||
#define ISO_slash 0x2f
|
#define ISO_slash 0x2f
|
||||||
#define ISO_eq 0x3d
|
#define ISO_eq 0x3d
|
||||||
#define ISO_questionmark 0x3f
|
#define ISO_questionmark 0x3f
|
||||||
|
|
||||||
/* The state of the rendering code. */
|
/* The state of the rendering code. */
|
||||||
static char *webpageptr;
|
static char *webpageptr;
|
||||||
static unsigned char x, y;
|
static unsigned char x, y;
|
||||||
static unsigned char loading;
|
static unsigned char loading;
|
||||||
static unsigned short firsty, pagey;
|
static unsigned short firsty, pagey;
|
||||||
|
static unsigned char newlines;
|
||||||
|
|
||||||
static unsigned char count;
|
static unsigned char count;
|
||||||
static char receivingmsgs[4][23] = {
|
static char receivingmsgs[4][23] = {
|
||||||
|
@ -194,7 +196,7 @@ PROCESS(www_process, "Web browser");
|
||||||
|
|
||||||
AUTOSTART_PROCESSES(&www_process);
|
AUTOSTART_PROCESSES(&www_process);
|
||||||
|
|
||||||
static void CC_FASTCALL formsubmit(struct formattrib *form);
|
static void CC_FASTCALL formsubmit(struct inputattrib *trigger);
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* make_window()
|
/* make_window()
|
||||||
|
@ -277,6 +279,7 @@ start_loading(void)
|
||||||
loading = 1;
|
loading = 1;
|
||||||
x = y = 0;
|
x = y = 0;
|
||||||
pagey = 0;
|
pagey = 0;
|
||||||
|
newlines = 0;
|
||||||
webpageptr = webpage;
|
webpageptr = webpage;
|
||||||
|
|
||||||
clear_page();
|
clear_page();
|
||||||
|
@ -305,10 +308,13 @@ open_url(void)
|
||||||
static uip_ipaddr_t addr;
|
static uip_ipaddr_t addr;
|
||||||
|
|
||||||
/* Trim off any spaces in the end of the url. */
|
/* Trim off any spaces in the end of the url. */
|
||||||
urlptr = url + strlen(url) - 1;
|
urlptr = url + strlen(url);
|
||||||
while(*urlptr == ' ' && urlptr > url) {
|
while(urlptr > url) {
|
||||||
*urlptr = 0;
|
if(*(urlptr - 1) == ' ') {
|
||||||
--urlptr;
|
*--urlptr = 0;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Don't even try to go further if the URL is empty. */
|
/* Don't even try to go further if the URL is empty. */
|
||||||
|
@ -376,7 +382,6 @@ open_url(void)
|
||||||
} else {
|
} else {
|
||||||
show_statustext("Connecting...");
|
show_statustext("Connecting...");
|
||||||
}
|
}
|
||||||
redraw_window();
|
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
/* set_link(link):
|
/* set_link(link):
|
||||||
|
@ -510,15 +515,17 @@ PROCESS_THREAD(www_process, ev, data)
|
||||||
firsty = 0;
|
firsty = 0;
|
||||||
start_loading();
|
start_loading();
|
||||||
--history_last;
|
--history_last;
|
||||||
|
/* Note: history_last is unsigned ! */
|
||||||
if(history_last > WWW_CONF_HISTORY_SIZE) {
|
if(history_last > WWW_CONF_HISTORY_SIZE) {
|
||||||
history_last = WWW_CONF_HISTORY_SIZE - 1;
|
history_last = WWW_CONF_HISTORY_SIZE - 1;
|
||||||
}
|
}
|
||||||
memcpy(url, history[(int)history_last], WWW_CONF_MAX_URLLEN);
|
memcpy(url, history[(int)history_last], WWW_CONF_MAX_URLLEN);
|
||||||
|
*history[(int)history_last] = 0;
|
||||||
open_url();
|
open_url();
|
||||||
CTK_WIDGET_FOCUS(&mainwindow, &backbutton);
|
CTK_WIDGET_FOCUS(&mainwindow, &backbutton);
|
||||||
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
#endif /* WWW_CONF_HISTORY_SIZE > 0 */
|
||||||
} else if(w == (struct ctk_widget *)&downbutton) {
|
} else if(w == (struct ctk_widget *)&downbutton) {
|
||||||
firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 4;
|
firsty = pagey + WWW_CONF_WEBPAGE_HEIGHT - 2;
|
||||||
start_loading();
|
start_loading();
|
||||||
open_url();
|
open_url();
|
||||||
CTK_WIDGET_FOCUS(&mainwindow, &downbutton);
|
CTK_WIDGET_FOCUS(&mainwindow, &downbutton);
|
||||||
|
@ -557,9 +564,8 @@ PROCESS_THREAD(www_process, ev, data)
|
||||||
#if WWW_CONF_FORMS
|
#if WWW_CONF_FORMS
|
||||||
} else {
|
} else {
|
||||||
/* Assume form widget. */
|
/* Assume form widget. */
|
||||||
struct inputattrib *input = (struct inputattrib *)
|
formsubmit((struct inputattrib *)
|
||||||
(((char *)w) - offsetof(struct inputattrib, widget));
|
(((char *)w) - offsetof(struct inputattrib, widget)));
|
||||||
formsubmit(input->formptr);
|
|
||||||
#endif /* WWW_CONF_FORMS */
|
#endif /* WWW_CONF_FORMS */
|
||||||
}
|
}
|
||||||
} else if(ev == ctk_signal_hyperlink_activate) {
|
} else if(ev == ctk_signal_hyperlink_activate) {
|
||||||
|
@ -670,8 +676,6 @@ webclient_connected(void)
|
||||||
{
|
{
|
||||||
start_loading();
|
start_loading();
|
||||||
|
|
||||||
clear_page();
|
|
||||||
|
|
||||||
show_statustext("Request sent...");
|
show_statustext("Request sent...");
|
||||||
set_url(webclient_hostname(), webclient_port(), webclient_filename());
|
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;
|
char *wptr;
|
||||||
static unsigned char maxwidth;
|
static unsigned char maxwidth;
|
||||||
|
|
||||||
|
newlines = 0;
|
||||||
|
|
||||||
if(!loading) {
|
if(!loading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -770,49 +776,50 @@ add_pagewidget(char *text, unsigned char size, char *attrib, unsigned char type,
|
||||||
wptr[size + border] = ' ';
|
wptr[size + border] = ' ';
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case CTK_WIDGET_HYPERLINK: {
|
case CTK_WIDGET_HYPERLINK: {
|
||||||
struct linkattrib *linkptr =
|
struct linkattrib *linkptr =
|
||||||
(struct linkattrib *)add_pageattrib(sizeof(struct linkattrib) /* incl 1 attrib char */ + attriblen);
|
(struct linkattrib *)add_pageattrib(sizeof(struct linkattrib) /* incl 1 attrib char */ + attriblen);
|
||||||
if(linkptr != NULL) {
|
if(linkptr != NULL) {
|
||||||
CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url);
|
CTK_HYPERLINK_NEW(&linkptr->hyperlink, x, y + 3, size, wptr, linkptr->url);
|
||||||
strcpy(linkptr->url, attrib);
|
strcpy(linkptr->url, attrib);
|
||||||
CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE);
|
CTK_WIDGET_SET_FLAG(&linkptr->hyperlink, CTK_WIDGET_FLAG_MONOSPACE);
|
||||||
CTK_WIDGET_ADD(&mainwindow, &linkptr->hyperlink);
|
CTK_WIDGET_ADD(&mainwindow, &linkptr->hyperlink);
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
#if WWW_CONF_FORMS
|
#if WWW_CONF_FORMS
|
||||||
case CTK_WIDGET_BUTTON: {
|
case CTK_WIDGET_BUTTON: {
|
||||||
struct submitattrib *submitptr =
|
struct submitattrib *submitptr =
|
||||||
(struct submitattrib *)add_pageattrib(sizeof(struct submitattrib) /* incl 1 attrib char */ + attriblen);
|
(struct submitattrib *)add_pageattrib(sizeof(struct submitattrib) /* incl 1 attrib char */ + attriblen);
|
||||||
if(submitptr != NULL) {
|
if(submitptr != NULL) {
|
||||||
CTK_BUTTON_NEW((struct ctk_button *)&submitptr->button, x, y + 3, size, wptr);
|
CTK_BUTTON_NEW((struct ctk_button *)&submitptr->button, x, y + 3, size, wptr);
|
||||||
add_forminput((struct inputattrib *)submitptr);
|
add_forminput((struct inputattrib *)submitptr);
|
||||||
submitptr->formptr = formptr;
|
submitptr->formptr = formptr;
|
||||||
strcpy(submitptr->name, attrib);
|
strcpy(submitptr->name, attrib);
|
||||||
CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE);
|
CTK_WIDGET_SET_FLAG(&submitptr->button, CTK_WIDGET_FLAG_MONOSPACE);
|
||||||
CTK_WIDGET_ADD(&mainwindow, &submitptr->button);
|
CTK_WIDGET_ADD(&mainwindow, &submitptr->button);
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case CTK_WIDGET_TEXTENTRY: {
|
break;
|
||||||
struct textattrib *textptr =
|
}
|
||||||
(struct textattrib *)add_pageattrib(sizeof(struct textattrib) /* incl 1 attrib char */ + attriblen
|
case CTK_WIDGET_TEXTENTRY: {
|
||||||
+ (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1);
|
struct textattrib *textptr =
|
||||||
if(textptr != NULL) {
|
(struct textattrib *)add_pageattrib(sizeof(struct textattrib) /* incl 1 attrib char */ + attriblen
|
||||||
CTK_TEXTENTRY_NEW((struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1,
|
+ (size ? WWW_CONF_MAX_INPUTVALUELEN : strlen(text)) + 1);
|
||||||
textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN);
|
if(textptr != NULL) {
|
||||||
add_forminput((struct inputattrib *)textptr);
|
CTK_TEXTENTRY_NEW((struct ctk_textentry *)&textptr->textentry, x, y + 3, size, 1,
|
||||||
textptr->formptr = formptr;
|
textptr->name + attriblen + 1, WWW_CONF_MAX_INPUTVALUELEN);
|
||||||
strcpy(textptr->textentry.text, text);
|
add_forminput((struct inputattrib *)textptr);
|
||||||
strcpy(textptr->name, attrib);
|
textptr->formptr = formptr;
|
||||||
if(size) {
|
petsciiconv_topetscii(text, strlen(text));
|
||||||
CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE);
|
strcpy(textptr->textentry.text, text);
|
||||||
CTK_WIDGET_ADD(&mainwindow, &textptr->textentry);
|
strcpy(textptr->name, attrib);
|
||||||
}
|
if(size) {
|
||||||
|
CTK_WIDGET_SET_FLAG(&textptr->textentry, CTK_WIDGET_FLAG_MONOSPACE);
|
||||||
|
CTK_WIDGET_ADD(&mainwindow, &textptr->textentry);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif /* WWW_CONF_FORMS */
|
#endif /* WWW_CONF_FORMS */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -837,6 +844,10 @@ htmlparser_newline(void)
|
||||||
{
|
{
|
||||||
char *wptr;
|
char *wptr;
|
||||||
|
|
||||||
|
if(++newlines > 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(pagey < firsty) {
|
if(pagey < firsty) {
|
||||||
++pagey;
|
++pagey;
|
||||||
x = 0;
|
x = 0;
|
||||||
|
@ -863,6 +874,8 @@ htmlparser_newline(void)
|
||||||
void
|
void
|
||||||
htmlparser_word(char *word, unsigned char wordlen)
|
htmlparser_word(char *word, unsigned char wordlen)
|
||||||
{
|
{
|
||||||
|
newlines = 0;
|
||||||
|
|
||||||
if(loading) {
|
if(loading) {
|
||||||
if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) {
|
if(wordlen + 1 > WWW_CONF_WEBPAGE_WIDTH - x) {
|
||||||
htmlparser_newline();
|
htmlparser_newline();
|
||||||
|
@ -886,7 +899,12 @@ htmlparser_word(char *word, unsigned char wordlen)
|
||||||
void
|
void
|
||||||
htmlparser_link(char *text, unsigned char textlen, char *url)
|
htmlparser_link(char *text, unsigned char textlen, char *url)
|
||||||
{
|
{
|
||||||
add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0);
|
/* No link for https or fragment-only as we would't be able to handle it anyway. */
|
||||||
|
if(url[0] == ISO_hash || strncmp(url, http_https, sizeof(http_https) - 1) == 0) {
|
||||||
|
htmlparser_word(text, textlen);
|
||||||
|
} else {
|
||||||
|
add_pagewidget(text, textlen, url, CTK_WIDGET_HYPERLINK, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
#if WWW_CONF_FORMS
|
#if WWW_CONF_FORMS
|
||||||
|
@ -946,23 +964,36 @@ add_query(char delimiter, char *string)
|
||||||
}
|
}
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
static void CC_FASTCALL
|
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;
|
char delimiter = ISO_questionmark;
|
||||||
|
|
||||||
set_link(form->action);
|
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 *name;
|
||||||
char *value;
|
char *value;
|
||||||
|
|
||||||
if(inputptr->widget.type == CTK_WIDGET_BUTTON) {
|
if(input->widget.type == CTK_WIDGET_TEXTENTRY) {
|
||||||
name = ((struct submitattrib *)inputptr)->name;
|
name = ((struct textattrib *)input)->name;
|
||||||
value = ((struct submitattrib *)inputptr)->button.text;
|
value = ((struct textattrib *)input)->textentry.text;
|
||||||
} else {
|
} else {
|
||||||
name = ((struct textattrib *)inputptr)->name;
|
/* Consider first button as default button. */
|
||||||
value = ((struct textattrib *)inputptr)->textentry.text;
|
if(trigger == NULL) {
|
||||||
|
trigger = input;
|
||||||
|
}
|
||||||
|
if(input != trigger) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
name = ((struct submitattrib *)input)->name;
|
||||||
|
value = ((struct submitattrib *)input)->button.text;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_query(delimiter, name);
|
add_query(delimiter, name);
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#define WWW_CONF_HISTORY_SIZE 10
|
#define WWW_CONF_HISTORY_SIZE 10
|
||||||
#endif
|
#endif
|
||||||
#ifndef WWW_CONF_MAX_URLLEN
|
#ifndef WWW_CONF_MAX_URLLEN
|
||||||
#define WWW_CONF_MAX_URLLEN 300
|
#define WWW_CONF_MAX_URLLEN 255
|
||||||
#endif
|
#endif
|
||||||
#ifndef WWW_CONF_PAGEATTRIB_SIZE
|
#ifndef WWW_CONF_PAGEATTRIB_SIZE
|
||||||
#define WWW_CONF_PAGEATTRIB_SIZE 2000
|
#define WWW_CONF_PAGEATTRIB_SIZE 2000
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
http_http "http://"
|
http_http "http://"
|
||||||
|
http_https "https://"
|
||||||
http_200 "200 "
|
http_200 "200 "
|
||||||
http_301 "301 "
|
http_301 "301 "
|
||||||
http_302 "302 "
|
http_302 "302 "
|
||||||
|
@ -32,4 +33,4 @@ http_gif ".gif"
|
||||||
http_jpg ".jpg"
|
http_jpg ".jpg"
|
||||||
http_text ".text"
|
http_text ".text"
|
||||||
http_txt ".txt"
|
http_txt ".txt"
|
||||||
|
http_redirect "<body>Redirect to "
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
const char http_http[8] =
|
const char http_http[8] =
|
||||||
/* "http://" */
|
/* "http://" */
|
||||||
{0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, };
|
{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] =
|
const char http_200[5] =
|
||||||
/* "200 " */
|
/* "200 " */
|
||||||
{0x32, 0x30, 0x30, 0x20, };
|
{0x32, 0x30, 0x30, 0x20, };
|
||||||
|
@ -100,3 +103,6 @@ const char http_text[6] =
|
||||||
const char http_txt[5] =
|
const char http_txt[5] =
|
||||||
/* ".txt" */
|
/* ".txt" */
|
||||||
{0x2e, 0x74, 0x78, 0x74, };
|
{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, };
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
extern const char http_http[8];
|
extern const char http_http[8];
|
||||||
|
extern const char http_https[9];
|
||||||
extern const char http_200[5];
|
extern const char http_200[5];
|
||||||
extern const char http_301[5];
|
extern const char http_301[5];
|
||||||
extern const char http_302[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_jpg[5];
|
||||||
extern const char http_text[6];
|
extern const char http_text[6];
|
||||||
extern const char http_txt[5];
|
extern const char http_txt[5];
|
||||||
|
extern const char http_redirect[19];
|
||||||
|
|
|
@ -80,7 +80,7 @@ galois_mul2(uint8_t value)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
set_key(uint8_t *key)
|
set_key(const uint8_t *key)
|
||||||
{
|
{
|
||||||
uint8_t i;
|
uint8_t i;
|
||||||
uint8_t j;
|
uint8_t j;
|
||||||
|
|
|
@ -59,7 +59,7 @@ struct aes_128_driver {
|
||||||
/**
|
/**
|
||||||
* \brief Sets the current key.
|
* \brief Sets the current key.
|
||||||
*/
|
*/
|
||||||
void (* set_key)(uint8_t *key);
|
void (* set_key)(const uint8_t *key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Encrypts.
|
* \brief Encrypts.
|
||||||
|
|
|
@ -34,44 +34,37 @@
|
||||||
* \file
|
* \file
|
||||||
* AES_128-based CCM* implementation.
|
* AES_128-based CCM* implementation.
|
||||||
* \author
|
* \author
|
||||||
* Konrad Krentz <konrad.krentz@gmail.com>
|
* Original: Konrad Krentz <konrad.krentz@gmail.com>
|
||||||
|
* Generified version: Justin King-Lacroix <justin.kinglacroix@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
#include "ccm-star.h"
|
||||||
* \addtogroup llsec802154
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "net/llsec/ccm-star.h"
|
|
||||||
#include "net/llsec/llsec802154.h"
|
|
||||||
#include "net/packetbuf.h"
|
|
||||||
#include "lib/aes-128.h"
|
#include "lib/aes-128.h"
|
||||||
#include <string.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
|
static void
|
||||||
set_nonce(uint8_t *nonce,
|
set_nonce(uint8_t *iv,
|
||||||
uint8_t flags,
|
uint8_t flags,
|
||||||
const uint8_t *extended_source_address,
|
const uint8_t *nonce,
|
||||||
uint8_t counter)
|
uint8_t counter)
|
||||||
{
|
{
|
||||||
/* 1 byte|| 8 bytes || 4 bytes || 1 byte || 2 bytes */
|
/* 1 byte|| 8 bytes || 4 bytes || 1 byte || 2 bytes */
|
||||||
/* flags || extended_source_address || frame_counter || sec_lvl || counter */
|
/* flags || extended_source_address || frame_counter || sec_lvl || counter */
|
||||||
|
|
||||||
nonce[0] = flags;
|
iv[0] = flags;
|
||||||
memcpy(nonce + 1, extended_source_address, 8);
|
memcpy(iv + 1, nonce, CCM_STAR_NONCE_LENGTH);
|
||||||
nonce[9] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) >> 8;
|
iv[14] = 0;
|
||||||
nonce[10] = packetbuf_attr(PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3) & 0xff;
|
iv[15] = counter;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* XORs the block m[pos] ... m[pos + 15] with K_{counter} */
|
/* XORs the block m[pos] ... m[pos + 15] with K_{counter} */
|
||||||
static void
|
static void
|
||||||
ctr_step(const uint8_t *extended_source_address,
|
ctr_step(const uint8_t *nonce,
|
||||||
uint8_t pos,
|
uint8_t pos,
|
||||||
uint8_t *m_and_result,
|
uint8_t *m_and_result,
|
||||||
uint8_t m_len,
|
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 a[AES_128_BLOCK_SIZE];
|
||||||
uint8_t i;
|
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);
|
AES_128.encrypt(a);
|
||||||
|
|
||||||
for(i = 0; (pos + i < m_len) && (i < AES_128_BLOCK_SIZE); i++) {
|
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
|
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 *result,
|
||||||
uint8_t mic_len)
|
uint8_t mic_len)
|
||||||
{
|
{
|
||||||
uint8_t x[AES_128_BLOCK_SIZE];
|
uint8_t x[AES_128_BLOCK_SIZE];
|
||||||
uint8_t pos;
|
uint8_t pos;
|
||||||
uint8_t i;
|
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);
|
set_nonce(x, CCM_STAR_AUTH_FLAGS(a_len, mic_len), nonce, m_len);
|
||||||
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 */
|
|
||||||
AES_128.encrypt(x);
|
AES_128.encrypt(x);
|
||||||
|
|
||||||
a = packetbuf_hdrptr();
|
if(a_len > 0) {
|
||||||
if(a_len) {
|
|
||||||
x[1] = x[1] ^ a_len;
|
x[1] = x[1] ^ a_len;
|
||||||
for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
|
for(i = 2; (i - 2 < a_len) && (i < AES_128_BLOCK_SIZE); i++) {
|
||||||
x[i] ^= a[i - 2];
|
x[i] ^= a[i - 2];
|
||||||
|
@ -143,8 +113,7 @@ mic(const uint8_t *extended_source_address,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if LLSEC802154_USES_ENCRYPTION
|
if(m_len > 0) {
|
||||||
if(shall_encrypt) {
|
|
||||||
m = a + a_len;
|
m = a + a_len;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
while(pos < m_len) {
|
while(pos < m_len) {
|
||||||
|
@ -155,36 +124,33 @@ mic(const uint8_t *extended_source_address,
|
||||||
AES_128.encrypt(x);
|
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);
|
memcpy(result, x, mic_len);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
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 pos;
|
||||||
uint8_t counter;
|
uint8_t counter;
|
||||||
|
|
||||||
m_len = packetbuf_datalen();
|
|
||||||
m = (uint8_t *) packetbuf_dataptr();
|
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
counter = 1;
|
counter = 1;
|
||||||
while(pos < m_len) {
|
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;
|
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 = {
|
const struct ccm_star_driver ccm_star_driver = {
|
||||||
mic,
|
mic,
|
||||||
ctr
|
ctr,
|
||||||
|
set_key
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -34,23 +34,13 @@
|
||||||
* \file
|
* \file
|
||||||
* CCM* header file.
|
* CCM* header file.
|
||||||
* \author
|
* \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_
|
#ifndef CCM_STAR_H_
|
||||||
#define CCM_STAR_H_
|
#define CCM_STAR_H_
|
||||||
|
|
||||||
#include "contiki.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
|
#ifdef CCM_STAR_CONF
|
||||||
#define CCM_STAR CCM_STAR_CONF
|
#define CCM_STAR CCM_STAR_CONF
|
||||||
|
@ -58,28 +48,43 @@
|
||||||
#define CCM_STAR ccm_star_driver
|
#define CCM_STAR ccm_star_driver
|
||||||
#endif /* CCM_STAR_CONF */
|
#endif /* CCM_STAR_CONF */
|
||||||
|
|
||||||
|
#define CCM_STAR_NONCE_LENGTH 13
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure of CCM* drivers.
|
* Structure of CCM* drivers.
|
||||||
*/
|
*/
|
||||||
struct ccm_star_driver {
|
struct ccm_star_driver {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Generates a MIC over the frame in the packetbuf.
|
* \brief Generates a MIC over the data supplied.
|
||||||
* \param result The generated MIC will be put here
|
* \param data The data buffer to read.
|
||||||
* \param mic_len <= 16; set to LLSEC802154_MIC_LENGTH to be compliant
|
* \param data_length The data buffer length.
|
||||||
|
* \param nonce The nonce to use. CCM_STAR_NONCE_LENGTH bytes long.
|
||||||
|
* \param result The generated MIC will be put here
|
||||||
|
* \param mic_len The size of the MIC to be generated. <= 16.
|
||||||
*/
|
*/
|
||||||
void (* mic)(const uint8_t *extended_source_address,
|
void (* mic)(const uint8_t* data, uint8_t data_length,
|
||||||
|
const uint8_t* nonce,
|
||||||
|
const uint8_t* add, uint8_t add_len,
|
||||||
uint8_t *result,
|
uint8_t *result,
|
||||||
uint8_t mic_len);
|
uint8_t mic_len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief XORs the frame in the packetbuf with the key stream.
|
* \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;
|
extern const struct ccm_star_driver CCM_STAR;
|
||||||
|
|
||||||
#endif /* CCM_STAR_H_ */
|
#endif /* CCM_STAR_H_ */
|
||||||
|
|
||||||
/** @} */
|
|
|
@ -300,7 +300,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
||||||
}
|
}
|
||||||
|
|
||||||
selecting:
|
selecting:
|
||||||
xid++;
|
|
||||||
s.ticks = CLOCK_SECOND;
|
s.ticks = CLOCK_SECOND;
|
||||||
do {
|
do {
|
||||||
while(ev != tcpip_event) {
|
while(ev != tcpip_event) {
|
||||||
|
@ -366,7 +365,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* renewing: */
|
/* renewing: */
|
||||||
xid++;
|
|
||||||
do {
|
do {
|
||||||
while(ev != tcpip_event) {
|
while(ev != tcpip_event) {
|
||||||
tcpip_poll_udp(s.conn);
|
tcpip_poll_udp(s.conn);
|
||||||
|
|
|
@ -394,7 +394,7 @@ dns_name_isequal(const unsigned char *queryptr, const char *name,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(tolower(*name++) != tolower(*queryptr++)) {
|
if(tolower((unsigned int)*name++) != tolower((unsigned int)*queryptr++)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,14 +43,16 @@
|
||||||
void
|
void
|
||||||
uip_debug_ipaddr_print(const uip_ipaddr_t *addr)
|
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
|
#if NETSTACK_CONF_WITH_IPV6
|
||||||
uint16_t a;
|
uint16_t a;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int f;
|
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) {
|
for(i = 0, f = 0; i < sizeof(uip_ipaddr_t); i += 2) {
|
||||||
a = (addr->u8[i] << 8) + addr->u8[i + 1];
|
a = (addr->u8[i] << 8) + addr->u8[i + 1];
|
||||||
if(a == 0 && f >= 0) {
|
if(a == 0 && f >= 0) {
|
||||||
|
@ -75,6 +77,10 @@ void
|
||||||
uip_debug_lladdr_print(const uip_lladdr_t *addr)
|
uip_debug_lladdr_print(const uip_lladdr_t *addr)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
if(addr == NULL) {
|
||||||
|
PRINTA("(NULL LL addr)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
for(i = 0; i < sizeof(uip_lladdr_t); i++) {
|
for(i = 0; i < sizeof(uip_lladdr_t); i++) {
|
||||||
if(i > 0) {
|
if(i > 0) {
|
||||||
PRINTA(":");
|
PRINTA(":");
|
||||||
|
|
|
@ -59,7 +59,7 @@ typedef struct uip_nameserver_record {
|
||||||
#if UIP_NAMESERVER_POOL_SIZE > 1
|
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||||
/** \brief Initialization flag */
|
/** \brief Initialization flag */
|
||||||
static uint8_t initialized = 0;
|
static uint8_t initialized = 0;
|
||||||
#endif
|
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
|
|
||||||
/** \name List and memory block
|
/** \name List and memory block
|
||||||
* @{
|
* @{
|
||||||
|
@ -92,7 +92,7 @@ init(void)
|
||||||
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
#endif /* UIP_NAMESERVER_POOL_SIZE > 1 */
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
void
|
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
|
#if UIP_NAMESERVER_POOL_SIZE > 1
|
||||||
register uip_nameserver_record *e;
|
register uip_nameserver_record *e;
|
||||||
|
|
|
@ -74,7 +74,7 @@
|
||||||
* considered to remove an entry. Maximum is 0xFFFFFFFF which
|
* considered to remove an entry. Maximum is 0xFFFFFFFF which
|
||||||
* is considered infinite.
|
* 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
|
* \brief Get a Nameserver ip address given in RA
|
||||||
|
|
|
@ -308,7 +308,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
||||||
}
|
}
|
||||||
|
|
||||||
selecting:
|
selecting:
|
||||||
xid++;
|
|
||||||
s.ticks = CLOCK_SECOND;
|
s.ticks = CLOCK_SECOND;
|
||||||
do {
|
do {
|
||||||
while(ev != tcpip_event) {
|
while(ev != tcpip_event) {
|
||||||
|
@ -374,7 +373,6 @@ PT_THREAD(handle_dhcp(process_event_t ev, void *data))
|
||||||
}
|
}
|
||||||
|
|
||||||
/* renewing: */
|
/* renewing: */
|
||||||
xid++;
|
|
||||||
do {
|
do {
|
||||||
while(ev != tcpip_event) {
|
while(ev != tcpip_event) {
|
||||||
tcpip_poll_udp(s.conn);
|
tcpip_poll_udp(s.conn);
|
||||||
|
|
|
@ -1107,26 +1107,26 @@ icmp_input()
|
||||||
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
ROLL_TM_STATS_ADD(icmp_bad);
|
ROLL_TM_STATS_ADD(icmp_bad);
|
||||||
return;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!uip_is_addr_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr)
|
if(!uip_is_addr_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr)
|
||||||
&& !uip_is_addr_linklocal_allrouters_mcast(&UIP_IP_BUF->destipaddr)) {
|
&& !uip_is_addr_linklocal_allrouters_mcast(&UIP_IP_BUF->destipaddr)) {
|
||||||
PRINTF("ROLL TM: ICMPv6 In, bad destination\n");
|
PRINTF("ROLL TM: ICMPv6 In, bad destination\n");
|
||||||
ROLL_TM_STATS_ADD(icmp_bad);
|
ROLL_TM_STATS_ADD(icmp_bad);
|
||||||
return;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UIP_ICMP_BUF->icode != ROLL_TM_ICMP_CODE) {
|
if(UIP_ICMP_BUF->icode != ROLL_TM_ICMP_CODE) {
|
||||||
PRINTF("ROLL TM: ICMPv6 In, bad ICMP code\n");
|
PRINTF("ROLL TM: ICMPv6 In, bad ICMP code\n");
|
||||||
ROLL_TM_STATS_ADD(icmp_bad);
|
ROLL_TM_STATS_ADD(icmp_bad);
|
||||||
return;
|
goto discard;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(UIP_IP_BUF->ttl != ROLL_TM_IP_HOP_LIMIT) {
|
if(UIP_IP_BUF->ttl != ROLL_TM_IP_HOP_LIMIT) {
|
||||||
PRINTF("ROLL TM: ICMPv6 In, bad TTL\n");
|
PRINTF("ROLL TM: ICMPv6 In, bad TTL\n");
|
||||||
ROLL_TM_STATS_ADD(icmp_bad);
|
ROLL_TM_STATS_ADD(icmp_bad);
|
||||||
return;
|
goto discard;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1311,6 +1311,9 @@ drop:
|
||||||
t[1].c++;
|
t[1].c++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
discard:
|
||||||
|
|
||||||
|
uip_len = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
52
core/net/llsec/ccm-star-packetbuf.c
Normal file
52
core/net/llsec/ccm-star-packetbuf.c
Normal 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);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
24
core/net/llsec/ccm-star-packetbuf.h
Normal file
24
core/net/llsec/ccm-star-packetbuf.h
Normal 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_ */
|
||||||
|
|
|
@ -45,13 +45,13 @@
|
||||||
#include "net/llsec/noncoresec/noncoresec.h"
|
#include "net/llsec/noncoresec/noncoresec.h"
|
||||||
#include "net/llsec/anti-replay.h"
|
#include "net/llsec/anti-replay.h"
|
||||||
#include "net/llsec/llsec802154.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/mac/frame802154.h"
|
||||||
#include "net/netstack.h"
|
#include "net/netstack.h"
|
||||||
#include "net/packetbuf.h"
|
#include "net/packetbuf.h"
|
||||||
#include "net/nbr-table.h"
|
#include "net/nbr-table.h"
|
||||||
#include "net/linkaddr.h"
|
#include "net/linkaddr.h"
|
||||||
#include "lib/aes-128.h"
|
#include "lib/ccm-star.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define WITH_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2))
|
#define WITH_ENCRYPTION (LLSEC802154_SECURITY_LEVEL & (1 << 2))
|
||||||
|
@ -110,15 +110,12 @@ send(mac_callback_t sent, void *ptr)
|
||||||
static int
|
static int
|
||||||
on_frame_created(void)
|
on_frame_created(void)
|
||||||
{
|
{
|
||||||
uint8_t *dataptr;
|
uint8_t *dataptr = packetbuf_dataptr();
|
||||||
uint8_t data_len;
|
uint8_t data_len = packetbuf_datalen();
|
||||||
|
|
||||||
dataptr = packetbuf_dataptr();
|
ccm_star_mic_packetbuf(get_extended_address(&linkaddr_node_addr), dataptr + data_len, LLSEC802154_MIC_LENGTH);
|
||||||
data_len = packetbuf_datalen();
|
|
||||||
|
|
||||||
CCM_STAR.mic(get_extended_address(&linkaddr_node_addr), dataptr + data_len, LLSEC802154_MIC_LENGTH);
|
|
||||||
#if WITH_ENCRYPTION
|
#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 */
|
#endif /* WITH_ENCRYPTION */
|
||||||
packetbuf_set_datalen(data_len + LLSEC802154_MIC_LENGTH);
|
packetbuf_set_datalen(data_len + LLSEC802154_MIC_LENGTH);
|
||||||
|
|
||||||
|
@ -132,6 +129,8 @@ input(void)
|
||||||
uint8_t *received_mic;
|
uint8_t *received_mic;
|
||||||
const linkaddr_t *sender;
|
const linkaddr_t *sender;
|
||||||
struct anti_replay_info* info;
|
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) {
|
if(packetbuf_attr(PACKETBUF_ATTR_SECURITY_LEVEL) != LLSEC802154_SECURITY_LEVEL) {
|
||||||
PRINTF("noncoresec: received frame with wrong security level\n");
|
PRINTF("noncoresec: received frame with wrong security level\n");
|
||||||
|
@ -143,14 +142,15 @@ input(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
packetbuf_set_datalen(packetbuf_datalen() - LLSEC802154_MIC_LENGTH);
|
data_len -= LLSEC802154_MIC_LENGTH;
|
||||||
|
packetbuf_set_datalen(data_len);
|
||||||
|
|
||||||
#if WITH_ENCRYPTION
|
#if WITH_ENCRYPTION
|
||||||
CCM_STAR.ctr(get_extended_address(sender));
|
ccm_star_ctr_packetbuf(get_extended_address(sender));
|
||||||
#endif /* WITH_ENCRYPTION */
|
#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) {
|
if(memcmp(generated_mic, received_mic, LLSEC802154_MIC_LENGTH) != 0) {
|
||||||
PRINTF("noncoresec: received nonauthentic frame %"PRIu32"\n",
|
PRINTF("noncoresec: received nonauthentic frame %"PRIu32"\n",
|
||||||
anti_replay_get_counter());
|
anti_replay_get_counter());
|
||||||
|
@ -203,7 +203,7 @@ get_overhead(void)
|
||||||
static void
|
static void
|
||||||
bootstrap(llsec_on_bootstrapped_t on_bootstrapped)
|
bootstrap(llsec_on_bootstrapped_t on_bootstrapped)
|
||||||
{
|
{
|
||||||
AES_128.set_key(key);
|
CCM_STAR.set_key(key);
|
||||||
nbr_table_register(anti_replay_table, NULL);
|
nbr_table_register(anti_replay_table, NULL);
|
||||||
on_bootstrapped();
|
on_bootstrapped();
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,11 +136,15 @@ static int we_are_receiving_burst = 0;
|
||||||
|
|
||||||
/* CCA_SLEEP_TIME is the time between two successive CCA checks. */
|
/* CCA_SLEEP_TIME is the time between two successive CCA checks. */
|
||||||
/* Add 1 when rtimer ticks are coarse */
|
/* 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
|
#if RTIMER_ARCH_SECOND > 8000
|
||||||
#define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000
|
#define CCA_SLEEP_TIME RTIMER_ARCH_SECOND / 2000
|
||||||
#else
|
#else
|
||||||
#define CCA_SLEEP_TIME (RTIMER_ARCH_SECOND / 2000) + 1
|
#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
|
/* CHECK_TIME is the total time it takes to perform CCA_COUNT_MAX
|
||||||
CCAs. */
|
CCAs. */
|
||||||
|
@ -153,7 +157,11 @@ static int we_are_receiving_burst = 0;
|
||||||
/* LISTEN_TIME_AFTER_PACKET_DETECTED is the time that we keep checking
|
/* LISTEN_TIME_AFTER_PACKET_DETECTED is the time that we keep checking
|
||||||
for activity after a potential packet has been detected by a CCA
|
for activity after a potential packet has been detected by a CCA
|
||||||
check. */
|
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
|
#define LISTEN_TIME_AFTER_PACKET_DETECTED RTIMER_ARCH_SECOND / 80
|
||||||
|
#endif
|
||||||
|
|
||||||
/* MAX_SILENCE_PERIODS is the maximum amount of periods (a period is
|
/* 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
|
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. */
|
to a neighbor for which we have a phase lock. */
|
||||||
#define MAX_PHASE_STROBE_TIME RTIMER_ARCH_SECOND / 60
|
#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
|
#define ACK_LEN 3
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -490,7 +504,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
||||||
int is_receiver_awake)
|
int is_receiver_awake)
|
||||||
{
|
{
|
||||||
rtimer_clock_t t0;
|
rtimer_clock_t t0;
|
||||||
|
#if WITH_PHASE_OPTIMIZATION
|
||||||
rtimer_clock_t encounter_time = 0;
|
rtimer_clock_t encounter_time = 0;
|
||||||
|
#endif
|
||||||
int strobes;
|
int strobes;
|
||||||
uint8_t got_strobe_ack = 0;
|
uint8_t got_strobe_ack = 0;
|
||||||
int len;
|
int len;
|
||||||
|
@ -664,7 +680,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
||||||
|
|
||||||
{
|
{
|
||||||
rtimer_clock_t wt;
|
rtimer_clock_t wt;
|
||||||
|
#if WITH_PHASE_OPTIMIZATION
|
||||||
rtimer_clock_t txtime = RTIMER_NOW();
|
rtimer_clock_t txtime = RTIMER_NOW();
|
||||||
|
#endif
|
||||||
#if RDC_CONF_HARDWARE_ACK
|
#if RDC_CONF_HARDWARE_ACK
|
||||||
int ret = NETSTACK_RADIO.transmit(transmit_len);
|
int ret = NETSTACK_RADIO.transmit(transmit_len);
|
||||||
#else
|
#else
|
||||||
|
@ -677,7 +695,9 @@ send_packet(mac_callback_t mac_callback, void *mac_callback_ptr,
|
||||||
if(ret == RADIO_TX_OK) {
|
if(ret == RADIO_TX_OK) {
|
||||||
if(!is_broadcast) {
|
if(!is_broadcast) {
|
||||||
got_strobe_ack = 1;
|
got_strobe_ack = 1;
|
||||||
|
#if WITH_PHASE_OPTIMIZATION
|
||||||
encounter_time = txtime;
|
encounter_time = txtime;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (ret == RADIO_TX_NOACK) {
|
} 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);
|
len = NETSTACK_RADIO.read(ackbuf, ACK_LEN);
|
||||||
if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) {
|
if(len == ACK_LEN && seqno == ackbuf[ACK_LEN - 1]) {
|
||||||
got_strobe_ack = 1;
|
got_strobe_ack = 1;
|
||||||
|
#if WITH_PHASE_OPTIMIZATION
|
||||||
encounter_time = txtime;
|
encounter_time = txtime;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
PRINTF("contikimac: collisions while sending\n");
|
PRINTF("contikimac: collisions while sending\n");
|
||||||
|
@ -861,10 +883,26 @@ static void
|
||||||
input_packet(void)
|
input_packet(void)
|
||||||
{
|
{
|
||||||
static struct ctimer ct;
|
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) {
|
if(!we_are_receiving_burst) {
|
||||||
off();
|
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);*/
|
/* printf("cycle_start 0x%02x 0x%02x\n", cycle_start, cycle_start % CYCLE_TIME);*/
|
||||||
|
|
||||||
if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) {
|
if(packetbuf_totlen() > 0 && NETSTACK_FRAMER.parse() >= 0) {
|
||||||
|
@ -892,12 +930,13 @@ input_packet(void)
|
||||||
|
|
||||||
#if RDC_WITH_DUPLICATE_DETECTION
|
#if RDC_WITH_DUPLICATE_DETECTION
|
||||||
/* Check for duplicate packet. */
|
/* Check for duplicate packet. */
|
||||||
if(mac_sequence_is_duplicate()) {
|
duplicate = mac_sequence_is_duplicate();
|
||||||
|
if(duplicate) {
|
||||||
/* Drop the packet. */
|
/* Drop the packet. */
|
||||||
/* printf("Drop duplicate ContikiMAC layer packet\n");*/
|
PRINTF("contikimac: Drop duplicate\n");
|
||||||
return;
|
} else {
|
||||||
|
mac_sequence_register_seqno();
|
||||||
}
|
}
|
||||||
mac_sequence_register_seqno();
|
|
||||||
#endif /* RDC_WITH_DUPLICATE_DETECTION */
|
#endif /* RDC_WITH_DUPLICATE_DETECTION */
|
||||||
|
|
||||||
#if CONTIKIMAC_CONF_COMPOWER
|
#if CONTIKIMAC_CONF_COMPOWER
|
||||||
|
@ -915,7 +954,30 @@ input_packet(void)
|
||||||
#endif /* CONTIKIMAC_CONF_COMPOWER */
|
#endif /* CONTIKIMAC_CONF_COMPOWER */
|
||||||
|
|
||||||
PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen());
|
PRINTDEBUG("contikimac: data (%u)\n", packetbuf_datalen());
|
||||||
NETSTACK_MAC.input();
|
|
||||||
|
#if CONTIKIMAC_SEND_SW_ACK
|
||||||
|
{
|
||||||
|
frame802154_t info154;
|
||||||
|
frame802154_parse(original_dataptr, original_datalen, &info154);
|
||||||
|
if(info154.fcf.frame_type == FRAME802154_DATAFRAME &&
|
||||||
|
info154.fcf.ack_required != 0 &&
|
||||||
|
linkaddr_cmp((linkaddr_t *)&info154.dest_addr,
|
||||||
|
&linkaddr_node_addr)) {
|
||||||
|
uint8_t ackdata[ACK_LEN] = {0, 0, 0};
|
||||||
|
|
||||||
|
we_are_sending = 1;
|
||||||
|
ackdata[0] = FRAME802154_ACKFRAME;
|
||||||
|
ackdata[1] = 0;
|
||||||
|
ackdata[2] = info154.seq;
|
||||||
|
NETSTACK_RADIO.send(ackdata, ACK_LEN);
|
||||||
|
we_are_sending = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CONTIKIMAC_SEND_SW_ACK */
|
||||||
|
|
||||||
|
if(!duplicate) {
|
||||||
|
NETSTACK_MAC.input();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
PRINTDEBUG("contikimac: data not for us\n");
|
PRINTDEBUG("contikimac: data not for us\n");
|
||||||
|
|
|
@ -254,13 +254,11 @@ collect_neighbor_list_remove(struct collect_neighbor_list *neighbors_list,
|
||||||
struct collect_neighbor *
|
struct collect_neighbor *
|
||||||
collect_neighbor_list_best(struct collect_neighbor_list *neighbors_list)
|
collect_neighbor_list_best(struct collect_neighbor_list *neighbors_list)
|
||||||
{
|
{
|
||||||
int found;
|
|
||||||
struct collect_neighbor *n, *best;
|
struct collect_neighbor *n, *best;
|
||||||
uint16_t rtmetric;
|
uint16_t rtmetric;
|
||||||
|
|
||||||
rtmetric = RTMETRIC_MAX;
|
rtmetric = RTMETRIC_MAX;
|
||||||
best = NULL;
|
best = NULL;
|
||||||
found = 0;
|
|
||||||
|
|
||||||
if(neighbors_list == NULL) {
|
if(neighbors_list == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -950,14 +950,18 @@ node_packet_received(struct unicast_conn *c, const linkaddr_t *from)
|
||||||
if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
|
if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) ==
|
||||||
PACKETBUF_ATTR_PACKET_TYPE_DATA) {
|
PACKETBUF_ATTR_PACKET_TYPE_DATA) {
|
||||||
linkaddr_t ack_to;
|
linkaddr_t ack_to;
|
||||||
|
#if DEBUG
|
||||||
uint8_t packet_seqno;
|
uint8_t packet_seqno;
|
||||||
|
#endif
|
||||||
|
|
||||||
stats.datarecv++;
|
stats.datarecv++;
|
||||||
|
|
||||||
/* Remember to whom we should send the ACK, since we reuse the
|
/* Remember to whom we should send the ACK, since we reuse the
|
||||||
packet buffer and its attributes when sending the ACK. */
|
packet buffer and its attributes when sending the ACK. */
|
||||||
linkaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
linkaddr_copy(&ack_to, packetbuf_addr(PACKETBUF_ADDR_SENDER));
|
||||||
|
#if DEBUG
|
||||||
packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
|
packet_seqno = packetbuf_attr(PACKETBUF_ATTR_PACKET_ID);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If the queue is more than half filled, we add the CONGESTED
|
/* If the queue is more than half filled, we add the CONGESTED
|
||||||
flag to our outgoing acks. */
|
flag to our outgoing acks. */
|
||||||
|
|
|
@ -105,6 +105,22 @@
|
||||||
#define RPL_MAX_DAG_PER_INSTANCE 2
|
#define RPL_MAX_DAG_PER_INSTANCE 2
|
||||||
#endif /* RPL_CONF_MAX_DAG_PER_INSTANCE */
|
#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 */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -481,8 +481,7 @@ rpl_set_default_route(rpl_instance_t *instance, uip_ipaddr_t *from)
|
||||||
PRINT6ADDR(from);
|
PRINT6ADDR(from);
|
||||||
PRINTF("\n");
|
PRINTF("\n");
|
||||||
instance->def_route = uip_ds6_defrt_add(from,
|
instance->def_route = uip_ds6_defrt_add(from,
|
||||||
RPL_LIFETIME(instance,
|
RPL_DEFAULT_ROUTE_INFINITE_LIFETIME ? 0 : RPL_LIFETIME(instance, instance->default_lifetime));
|
||||||
instance->default_lifetime));
|
|
||||||
if(instance->def_route == NULL) {
|
if(instance->def_route == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -814,6 +813,9 @@ rpl_select_parent(rpl_dag_t *dag)
|
||||||
|
|
||||||
if(best != NULL) {
|
if(best != NULL) {
|
||||||
rpl_set_preferred_parent(dag, best);
|
rpl_set_preferred_parent(dag, best);
|
||||||
|
dag->rank = dag->instance->of->calculate_rank(dag->preferred_parent, 0);
|
||||||
|
} else {
|
||||||
|
dag->rank = INFINITE_RANK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return best;
|
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 ");
|
PRINTF("RPL: preferred DAG ");
|
||||||
PRINT6ADDR(&instance->current_dag->dag_id);
|
PRINT6ADDR(&instance->current_dag->dag_id);
|
||||||
PRINTF(", rank %u, min_rank %u, ",
|
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.
|
/* We received a new DIO from our preferred parent.
|
||||||
* Call uip_ds6_defrt_add to set a fresh value for the lifetime counter */
|
* 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;
|
p->dtsn = dio->dtsn;
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,9 +277,9 @@ rpl_ipv6_neighbor_callback(uip_ds6_nbr_t *nbr)
|
||||||
rpl_instance_t *instance;
|
rpl_instance_t *instance;
|
||||||
rpl_instance_t *end;
|
rpl_instance_t *end;
|
||||||
|
|
||||||
PRINTF("RPL: Removing neighbor ");
|
PRINTF("RPL: Neighbor state changed for ");
|
||||||
PRINT6ADDR(&nbr->ipaddr);
|
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) {
|
for(instance = &instance_table[0], end = instance + RPL_MAX_INSTANCES; instance < end; ++instance) {
|
||||||
if(instance->used == 1 ) {
|
if(instance->used == 1 ) {
|
||||||
p = rpl_find_parent_any_dag(instance, &nbr->ipaddr);
|
p = rpl_find_parent_any_dag(instance, &nbr->ipaddr);
|
||||||
|
|
|
@ -61,7 +61,7 @@ typedef int32_t s32_t;
|
||||||
#define HAVE_SNPRINTF
|
#define HAVE_SNPRINTF
|
||||||
#define snprintf(buf, len, ...) sprintf(buf, __VA_ARGS__)
|
#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 clock_time_t;
|
||||||
|
|
||||||
typedef unsigned short uip_stats_t;
|
typedef unsigned short uip_stats_t;
|
||||||
|
@ -72,7 +72,6 @@ typedef unsigned short uip_stats_t;
|
||||||
#define UIP_CONF_LLH_LEN 14
|
#define UIP_CONF_LLH_LEN 14
|
||||||
#define RESOLV_CONF_SUPPORTS_MDNS 0
|
#define RESOLV_CONF_SUPPORTS_MDNS 0
|
||||||
#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0
|
#define RESOLV_CONF_SUPPORTS_RECORD_EXPIRATION 0
|
||||||
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 1
|
|
||||||
|
|
||||||
#define LOADER_CONF_ARCH "lib/unload.h"
|
#define LOADER_CONF_ARCH "lib/unload.h"
|
||||||
|
|
||||||
|
@ -85,7 +84,7 @@ typedef unsigned short uip_stats_t;
|
||||||
#if CONNECTIONS
|
#if CONNECTIONS
|
||||||
#define UIP_CONF_MAX_CONNECTIONS CONNECTIONS
|
#define UIP_CONF_MAX_CONNECTIONS CONNECTIONS
|
||||||
#else /* CONNECTIONS */
|
#else /* CONNECTIONS */
|
||||||
#define UIP_CONF_MAX_CONNECTIONS 10
|
#define UIP_CONF_MAX_CONNECTIONS 2
|
||||||
#endif /* CONNECTIONS */
|
#endif /* CONNECTIONS */
|
||||||
|
|
||||||
#if WITH_LOGGING
|
#if WITH_LOGGING
|
||||||
|
|
|
@ -6,7 +6,7 @@ $(OBJECTDIR)/%.o: %.c | $(OBJECTDIR)
|
||||||
CUSTOM_RULE_C_TO_CO = 1
|
CUSTOM_RULE_C_TO_CO = 1
|
||||||
%.co: %.c
|
%.co: %.c
|
||||||
$(TRACE_CC)
|
$(TRACE_CC)
|
||||||
$(Q)$(CC) -c -o $@ $(CFLAGS) -DAUTOSTART_ENABLE --create-dep $(@:.o=.d) $<
|
$(Q)$(CC) -c -o $@ $(CFLAGS) -DAUTOSTART_ENABLE $<
|
||||||
|
|
||||||
CUSTOM_RULE_LINK = 1
|
CUSTOM_RULE_LINK = 1
|
||||||
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a
|
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a
|
||||||
|
|
|
@ -37,7 +37,7 @@ high-level configuration macros may be set:
|
||||||
- Purpose: Set the Maximum Transfer Unit size.
|
- Purpose: Set the Maximum Transfer Unit size.
|
||||||
|
|
||||||
- CONNECTIONS
|
- CONNECTIONS
|
||||||
- Default: 10
|
- Default: 2
|
||||||
- Purpose: Set the maximum number of concurrent TCP connections.
|
- Purpose: Set the maximum number of concurrent TCP connections.
|
||||||
|
|
||||||
- ETHERNET
|
- ETHERNET
|
||||||
|
|
|
@ -177,9 +177,9 @@ app_quit(void)
|
||||||
PROCESS_THREAD(ipconfig_process, ev, data)
|
PROCESS_THREAD(ipconfig_process, ev, data)
|
||||||
{
|
{
|
||||||
PROCESS_BEGIN();
|
PROCESS_BEGIN();
|
||||||
|
|
||||||
ctk_window_new(&window, 29, 14, "IP config");
|
ctk_window_new(&window, 29, 14, "IP config");
|
||||||
|
|
||||||
CTK_WIDGET_ADD(&window, &requestbutton);
|
CTK_WIDGET_ADD(&window, &requestbutton);
|
||||||
CTK_WIDGET_ADD(&window, &statuslabel);
|
CTK_WIDGET_ADD(&window, &statuslabel);
|
||||||
CTK_WIDGET_ADD(&window, &ipaddrlabel);
|
CTK_WIDGET_ADD(&window, &ipaddrlabel);
|
||||||
|
@ -208,11 +208,11 @@ PROCESS_THREAD(ipconfig_process, ev, data)
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
PROCESS_WAIT_EVENT();
|
PROCESS_WAIT_EVENT();
|
||||||
|
|
||||||
if(ev == PROCESS_EVENT_MSG) {
|
if(ev == PROCESS_EVENT_MSG) {
|
||||||
makestrings();
|
makestrings();
|
||||||
ctk_window_redraw(&window);
|
ctk_window_redraw(&window);
|
||||||
} else if(ev == tcpip_event) {
|
} else if(ev == tcpip_event || ev == PROCESS_EVENT_TIMER) {
|
||||||
dhcpc_appcall(ev, data);
|
dhcpc_appcall(ev, data);
|
||||||
} else if(ev == ctk_signal_button_activate) {
|
} else if(ev == ctk_signal_button_activate) {
|
||||||
if(data == (process_data_t)&requestbutton) {
|
if(data == (process_data_t)&requestbutton) {
|
||||||
|
|
|
@ -92,12 +92,13 @@ fixups = * - fixup
|
||||||
|
|
||||||
;---------------------------------------------------------------------
|
;---------------------------------------------------------------------
|
||||||
|
|
||||||
rxtxreg := $FF00 ; High byte patched at runtime
|
; 3 most significant nibbles are fixed up at runtime
|
||||||
txcmd := $FF04 ; High byte patched at runtime
|
rxtxreg := $FFF0
|
||||||
txlen := $FF06 ; High byte patched at runtime
|
txcmd := $FFF4
|
||||||
isq := $FF08 ; High byte patched at runtime
|
txlen := $FFF6
|
||||||
packetpp := $FF0A ; High byte patched at runtime
|
isq := $FFF8
|
||||||
ppdata := $FF0C ; High byte patched at runtime
|
packetpp := $FFFA
|
||||||
|
ppdata := $FFFC
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
|
@ -117,8 +118,9 @@ init:
|
||||||
ldy #$00
|
ldy #$00
|
||||||
|
|
||||||
; Fixup address at location
|
; Fixup address at location
|
||||||
: lda reg
|
: lda (ptr),y
|
||||||
eor (ptr),y ; Use XOR to support C64 RR-Net
|
and #$0F
|
||||||
|
eor reg ; Use XOR to support C64 RR-Net
|
||||||
sta (ptr),y
|
sta (ptr),y
|
||||||
iny
|
iny
|
||||||
lda reg+1
|
lda reg+1
|
||||||
|
|
|
@ -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
|
; Register bank 0
|
||||||
ethtcr := $FF00 ; Transmition control register R/W (2B)
|
ethtcr := $FFF0 ; Transmition control register R/W (2B)
|
||||||
ethephsr := $FF02 ; EPH status register R/O (2B)
|
ethephsr := $FFF2 ; EPH status register R/O (2B)
|
||||||
ethrcr := $FF04 ; Receive control register R/W (2B)
|
ethrcr := $FFF4 ; Receive control register R/W (2B)
|
||||||
ethecr := $FF06 ; Counter register R/O (2B)
|
ethecr := $FFF6 ; Counter register R/O (2B)
|
||||||
ethmir := $FF08 ; Memory information register R/O (2B)
|
ethmir := $FFF8 ; Memory information register R/O (2B)
|
||||||
ethmcr := $FF0A ; Memory Config. reg. +0 R/W +1 R/O (2B)
|
ethmcr := $FFFA ; Memory Config. reg. +0 R/W +1 R/O (2B)
|
||||||
|
|
||||||
; Register bank 1
|
; Register bank 1
|
||||||
ethcr := $FF00 ; Configuration register R/W (2B)
|
ethcr := $FFF0 ; Configuration register R/W (2B)
|
||||||
ethbar := $FF02 ; Base address register R/W (2B)
|
ethbar := $FFF2 ; Base address register R/W (2B)
|
||||||
ethiar := $FF04 ; Individual address register R/W (6B)
|
ethiar := $FFF4 ; Individual address register R/W (6B)
|
||||||
ethgpr := $FF0A ; General address register R/W (2B)
|
ethgpr := $FFFA ; General address register R/W (2B)
|
||||||
ethctr := $FF0C ; Control register R/W (2B)
|
ethctr := $FFFC ; Control register R/W (2B)
|
||||||
|
|
||||||
; Register bank 2
|
; Register bank 2
|
||||||
ethmmucr := $FF00 ; MMU command register W/O (1B)
|
ethmmucr := $FFF0 ; MMU command register W/O (1B)
|
||||||
ethautotx := $FF01 ; AUTO TX start register R/W (1B)
|
ethautotx := $FFF1 ; AUTO TX start register R/W (1B)
|
||||||
ethpnr := $FF02 ; Packet number register R/W (1B)
|
ethpnr := $FFF2 ; Packet number register R/W (1B)
|
||||||
etharr := $FF03 ; Allocation result register R/O (1B)
|
etharr := $FFF3 ; Allocation result register R/O (1B)
|
||||||
ethfifo := $FF04 ; FIFO ports register R/O (2B)
|
ethfifo := $FFF4 ; FIFO ports register R/O (2B)
|
||||||
ethptr := $FF06 ; Pointer register R/W (2B)
|
ethptr := $FFF6 ; Pointer register R/W (2B)
|
||||||
ethdata := $FF08 ; Data register R/W (4B)
|
ethdata := $FFF8 ; Data register R/W (4B)
|
||||||
ethist := $FF0C ; Interrupt status register R/O (1B)
|
ethist := $FFFC ; Interrupt status register R/O (1B)
|
||||||
ethack := $FF0C ; Interrupt acknowledge register W/O (1B)
|
ethack := $FFFC ; Interrupt acknowledge register W/O (1B)
|
||||||
ethmsk := $FF0D ; Interrupt mask register R/W (1B)
|
ethmsk := $FFFD ; Interrupt mask register R/W (1B)
|
||||||
|
|
||||||
; Register bank 3
|
; Register bank 3
|
||||||
ethmt := $FF00 ; Multicast table R/W (8B)
|
ethmt := $FFF0 ; Multicast table R/W (8B)
|
||||||
ethmgmt := $FF08 ; Management interface R/W (2B)
|
ethmgmt := $FFF8 ; Management interface R/W (2B)
|
||||||
ethrev := $FF0A ; Revision register R/W (2B)
|
ethrev := $FFFA ; Revision register R/W (2B)
|
||||||
ethercv := $FF0C ; Early RCV register R/W (2B)
|
ethercv := $FFFC ; Early RCV register R/W (2B)
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
|
@ -148,8 +149,9 @@ init:
|
||||||
ldy #$00
|
ldy #$00
|
||||||
|
|
||||||
; Fixup address at location
|
; Fixup address at location
|
||||||
: lda reg
|
: lda (ptr),y
|
||||||
ora (ptr),y
|
and #$0F
|
||||||
|
ora reg
|
||||||
sta (ptr),y
|
sta (ptr),y
|
||||||
iny
|
iny
|
||||||
lda reg+1
|
lda reg+1
|
||||||
|
|
|
@ -103,9 +103,10 @@ fixups = * - fixup
|
||||||
|
|
||||||
;---------------------------------------------------------------------
|
;---------------------------------------------------------------------
|
||||||
|
|
||||||
mode := $FF00 ; High byte patched at runtime
|
; 14 most significant bits are fixed up at runtime
|
||||||
addr := $FF01 ; High byte patched at runtime
|
mode := $FFFC|0
|
||||||
data := $FF03 ; High byte patched at runtime
|
addr := $FFFC|1
|
||||||
|
data := $FFFC|3
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
|
@ -125,8 +126,9 @@ init:
|
||||||
ldy #$00
|
ldy #$00
|
||||||
|
|
||||||
; Fixup address at location
|
; Fixup address at location
|
||||||
: lda reg
|
: lda (ptr),y
|
||||||
ora (ptr),y
|
and #$03
|
||||||
|
ora reg
|
||||||
sta (ptr),y
|
sta (ptr),y
|
||||||
iny
|
iny
|
||||||
lda reg+1
|
lda reg+1
|
||||||
|
|
|
@ -45,11 +45,8 @@ clock_time(void)
|
||||||
* of overhead for cc65 targets.
|
* of overhead for cc65 targets.
|
||||||
* On the other hand we want to avoid wrapping around frequently so the idea
|
* 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
|
* 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
|
* the DNS resolver using a 1/4 second timer. So CLOCK_CONF_SECOND needs to
|
||||||
* needs to be defined at least as 2.
|
* be defined at least as 4. */
|
||||||
* 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. */
|
|
||||||
return clock() / (CLK_TCK / CLOCK_CONF_SECOND);
|
return clock() / (CLK_TCK / CLOCK_CONF_SECOND);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -34,17 +34,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup Cortex_M0
|
* @defgroup Cortex_M0 Cortex-M0
|
||||||
* @ingroup cmsis
|
* @ingroup cmsis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup Cortex_M3
|
* @defgroup Cortex_M3 Cortex-M3
|
||||||
* @ingroup cmsis
|
* @ingroup cmsis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup Cortex_M4
|
* @defgroup Cortex_M4 Cortex-M4
|
||||||
* @ingroup cmsis
|
* @ingroup cmsis
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -170,7 +170,7 @@
|
||||||
* \addtogroup avr
|
* \addtogroup avr
|
||||||
* @{ */
|
* @{ */
|
||||||
/*!
|
/*!
|
||||||
* \defgroup xgSmscRegs
|
* \defgroup xgSmscRegs SMSC Registers
|
||||||
*
|
*
|
||||||
* @{ */
|
* @{ */
|
||||||
|
|
||||||
|
@ -1203,6 +1203,7 @@ PROCESS_THREAD(lanc111_process, ev, data)
|
||||||
PROCESS_END();
|
PROCESS_END();
|
||||||
}
|
}
|
||||||
#endif /* 0 */
|
#endif /* 0 */
|
||||||
|
#if 0
|
||||||
/*!
|
/*!
|
||||||
* \brief Send Ethernet packet.
|
* \brief Send Ethernet packet.
|
||||||
*
|
*
|
||||||
|
@ -1213,7 +1214,6 @@ PROCESS_THREAD(lanc111_process, ev, data)
|
||||||
*
|
*
|
||||||
* \return 0 on success, -1 in case of any errors.
|
* \return 0 on success, -1 in case of any errors.
|
||||||
*/
|
*/
|
||||||
#if 0
|
|
||||||
int LancOutput(NUTDEVICE * dev, NETBUF * nb)
|
int LancOutput(NUTDEVICE * dev, NETBUF * nb)
|
||||||
{
|
{
|
||||||
static u_long mx_wait = 5000;
|
static u_long mx_wait = 5000;
|
||||||
|
|
|
@ -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
|
/** \brief Read SRAM
|
||||||
*
|
*
|
||||||
* This function reads from the SRAM of the radio transceiver.
|
* 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 length Length of the read burst
|
||||||
* \param data Pointer to buffer where data is stored.
|
* \param data Pointer to buffer where data is stored.
|
||||||
*/
|
*/
|
||||||
#if 0 //Uses 80 bytes (on Raven) omit unless needed
|
|
||||||
void
|
void
|
||||||
hal_sram_read(uint8_t address, uint8_t length, uint8_t *data)
|
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
|
#endif
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
#if 0 //omit unless needed
|
||||||
/** \brief Write SRAM
|
/** \brief Write SRAM
|
||||||
*
|
*
|
||||||
* This function writes into the SRAM of the radio transceiver. It can reduce
|
* 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 length Length of the write burst
|
||||||
* \param data Pointer to an array of bytes that should be written
|
* \param data Pointer to an array of bytes that should be written
|
||||||
*/
|
*/
|
||||||
#if 0 //omit unless needed
|
|
||||||
void
|
void
|
||||||
hal_sram_write(uint8_t address, uint8_t length, uint8_t *data)
|
hal_sram_write(uint8_t address, uint8_t length, uint8_t *data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,7 @@ CONTIKI_CPU_DIRS += ../cc253x/usb/common ../cc253x/usb/common/cdc-acm
|
||||||
### CPU-dependent source files
|
### CPU-dependent source files
|
||||||
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c uart.c watchdog.c
|
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 += 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 += cc2538-rf.c udma.c lpm.c
|
||||||
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
CONTIKI_CPU_SOURCEFILES += dbg.c ieee-addr.c
|
||||||
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
CONTIKI_CPU_SOURCEFILES += slip-arch.c slip.c
|
||||||
|
|
|
@ -85,12 +85,13 @@ SECTIONS
|
||||||
*(.udma_channel_control_table)
|
*(.udma_channel_control_table)
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
.data :
|
.data : ALIGN(4)
|
||||||
{
|
{
|
||||||
_data = .;
|
_data = .;
|
||||||
*(.data*)
|
*(.data*)
|
||||||
_edata = .;
|
_edata = .;
|
||||||
} > SRAM AT > FLASH
|
} > SRAM AT > FLASH
|
||||||
|
_ldata = LOADADDR(.data);
|
||||||
|
|
||||||
.ARM.exidx :
|
.ARM.exidx :
|
||||||
{
|
{
|
||||||
|
@ -105,6 +106,11 @@ SECTIONS
|
||||||
_ebss = .;
|
_ebss = .;
|
||||||
} > SRAM
|
} > SRAM
|
||||||
|
|
||||||
|
.stack (NOLOAD) :
|
||||||
|
{
|
||||||
|
*(.stack)
|
||||||
|
} > SRAM
|
||||||
|
|
||||||
#if (LPM_CONF_MAX_PM==2) && (LPM_CONF_ENABLE != 0)
|
#if (LPM_CONF_MAX_PM==2) && (LPM_CONF_ENABLE != 0)
|
||||||
.nrdata (NOLOAD) :
|
.nrdata (NOLOAD) :
|
||||||
{
|
{
|
||||||
|
|
152
cpu/cc2538/dev/aes.c
Normal file
152
cpu/cc2538/dev/aes.c
Normal 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
495
cpu/cc2538/dev/aes.h
Normal 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
413
cpu/cc2538/dev/ccm.c
Normal 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
141
cpu/cc2538/dev/ccm.h
Normal 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
120
cpu/cc2538/dev/crypto.c
Normal 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
89
cpu/cc2538/dev/crypto.h
Normal 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
356
cpu/cc2538/dev/sha256.c
Normal 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
103
cpu/cc2538/dev/sha256.h
Normal 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_ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
* @}
|
||||||
|
*/
|
|
@ -161,6 +161,34 @@
|
||||||
#define SYS_CTRL_SRGPT_GPT0 0x00000001 /**< GPT0 is reset */
|
#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
|
/** \name SYS_CTRL_PWRDBG register bits
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -359,7 +359,7 @@ uart_write_byte(uint8_t uart, uint8_t b)
|
||||||
REG(uart_base + UART_DR) = b;
|
REG(uart_base + UART_DR) = b;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
static void
|
||||||
uart_isr(uint8_t uart)
|
uart_isr(uint8_t uart)
|
||||||
{
|
{
|
||||||
uint32_t uart_base;
|
uint32_t uart_base;
|
||||||
|
|
|
@ -88,15 +88,6 @@ watchdog_periodic(void)
|
||||||
REG(SMWDTHROSC_WDCTL) = (SMWDTHROSC_WDCTL_CLR_2 | SMWDTHROSC_WDCTL_CLR_0);
|
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
|
/** \brief Keeps control until the WDT throws a reset signal. Starts the WDT
|
||||||
* if not already started. */
|
* if not already started. */
|
||||||
void
|
void
|
||||||
|
|
|
@ -101,7 +101,7 @@ static uint8_t max_pm;
|
||||||
#ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
#ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||||
#else
|
#else
|
||||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 2
|
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 3
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static lpm_periph_permit_pm1_func_t
|
static lpm_periph_permit_pm1_func_t
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include "reg.h"
|
#include "reg.h"
|
||||||
#include "flash-cca.h"
|
#include "flash-cca.h"
|
||||||
#include "sys-ctrl.h"
|
#include "sys-ctrl.h"
|
||||||
|
#include "rom-util.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -66,6 +67,7 @@ void udma_err_isr(void);
|
||||||
void usb_isr(void) WEAK_ALIAS(default_handler);
|
void usb_isr(void) WEAK_ALIAS(default_handler);
|
||||||
void uart0_isr(void) WEAK_ALIAS(default_handler);
|
void uart0_isr(void) WEAK_ALIAS(default_handler);
|
||||||
void uart1_isr(void) WEAK_ALIAS(default_handler);
|
void uart1_isr(void) WEAK_ALIAS(default_handler);
|
||||||
|
void crypto_isr(void);
|
||||||
|
|
||||||
/* Boot Loader Backdoor selection */
|
/* Boot Loader Backdoor selection */
|
||||||
#if FLASH_CCA_CONF_BOOTLDR_BACKDOOR
|
#if FLASH_CCA_CONF_BOOTLDR_BACKDOOR
|
||||||
|
@ -89,7 +91,7 @@ void uart1_isr(void) WEAK_ALIAS(default_handler);
|
||||||
#endif
|
#endif
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Allocate stack space */
|
/* Allocate stack space */
|
||||||
static unsigned long stack[512];
|
static unsigned long stack[512] __attribute__ ((section(".stack")));
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Linker construct indicating .text section location */
|
/* Linker construct indicating .text section location */
|
||||||
extern uint8_t _text[0];
|
extern uint8_t _text[0];
|
||||||
|
@ -268,18 +270,18 @@ void(*const vectors[])(void) =
|
||||||
usb_isr, /* 156 USB */
|
usb_isr, /* 156 USB */
|
||||||
cc2538_rf_rx_tx_isr, /* 157 RFCORE RX/TX */
|
cc2538_rf_rx_tx_isr, /* 157 RFCORE RX/TX */
|
||||||
cc2538_rf_err_isr, /* 158 RFCORE Error */
|
cc2538_rf_err_isr, /* 158 RFCORE Error */
|
||||||
default_handler, /* 159 AES */
|
crypto_isr, /* 159 AES */
|
||||||
default_handler, /* 160 PKA */
|
default_handler, /* 160 PKA */
|
||||||
rtimer_isr, /* 161 SM Timer */
|
rtimer_isr, /* 161 SM Timer */
|
||||||
default_handler, /* 162 MACTimer */
|
default_handler, /* 162 MACTimer */
|
||||||
};
|
};
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Linker constructs indicating .data and .bss segment locations */
|
/* Linker constructs indicating .data and .bss segment locations */
|
||||||
extern unsigned long _etext;
|
extern uint8_t _ldata;
|
||||||
extern unsigned long _data;
|
extern uint8_t _data;
|
||||||
extern unsigned long _edata;
|
extern uint8_t _edata;
|
||||||
extern unsigned long _bss;
|
extern uint8_t _bss;
|
||||||
extern unsigned long _ebss;
|
extern uint8_t _ebss;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Weak interrupt handlers. */
|
/* Weak interrupt handlers. */
|
||||||
void
|
void
|
||||||
|
@ -298,26 +300,13 @@ default_handler(void)
|
||||||
void
|
void
|
||||||
reset_handler(void)
|
reset_handler(void)
|
||||||
{
|
{
|
||||||
unsigned long *pul_src, *pul_dst;
|
|
||||||
|
|
||||||
REG(SYS_CTRL_EMUOVR) = 0xFF;
|
REG(SYS_CTRL_EMUOVR) = 0xFF;
|
||||||
|
|
||||||
/* Copy the data segment initializers from flash to SRAM. */
|
/* Copy the data segment initializers from flash to SRAM. */
|
||||||
pul_src = &_etext;
|
rom_util_memcpy(&_data, &_ldata, &_edata - &_data);
|
||||||
|
|
||||||
for(pul_dst = &_data; pul_dst < &_edata;) {
|
|
||||||
*pul_dst++ = *pul_src++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Zero-fill the bss segment. */
|
/* Zero-fill the bss segment. */
|
||||||
__asm(" ldr r0, =_bss\n"
|
rom_util_memset(&_bss, 0, &_ebss - &_bss);
|
||||||
" 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");
|
|
||||||
|
|
||||||
/* call the application's entry point. */
|
/* call the application's entry point. */
|
||||||
main();
|
main();
|
||||||
|
|
|
@ -872,7 +872,7 @@ fill_buffers(usb_buffer *buffer, uint8_t hw_ep, unsigned int len,
|
||||||
static uint8_t
|
static uint8_t
|
||||||
ep0_get_setup_pkt(void)
|
ep0_get_setup_pkt(void)
|
||||||
{
|
{
|
||||||
uint8_t res;
|
uint8_t res = 0;
|
||||||
usb_buffer *buffer =
|
usb_buffer *buffer =
|
||||||
skip_buffers_until(usb_endpoints[0].buffer, USB_BUFFER_SETUP,
|
skip_buffers_until(usb_endpoints[0].buffer, USB_BUFFER_SETUP,
|
||||||
USB_BUFFER_SETUP, &res);
|
USB_BUFFER_SETUP, &res);
|
||||||
|
@ -916,8 +916,6 @@ ep0_get_data_pkt(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if(buffer->flags & (USB_BUFFER_SETUP | USB_BUFFER_IN)) {
|
if(buffer->flags & (USB_BUFFER_SETUP | USB_BUFFER_IN)) {
|
||||||
uint8_t temp;
|
|
||||||
|
|
||||||
buffer->flags |= USB_BUFFER_FAILED;
|
buffer->flags |= USB_BUFFER_FAILED;
|
||||||
buffer->flags &= ~USB_BUFFER_SUBMITTED;
|
buffer->flags &= ~USB_BUFFER_SUBMITTED;
|
||||||
if(buffer->flags & USB_BUFFER_NOTIFY) {
|
if(buffer->flags & USB_BUFFER_NOTIFY) {
|
||||||
|
@ -925,7 +923,7 @@ ep0_get_data_pkt(void)
|
||||||
}
|
}
|
||||||
/* Flush the fifo */
|
/* Flush the fifo */
|
||||||
while(len--) {
|
while(len--) {
|
||||||
temp = REG(USB_F0);
|
REG(USB_F0);
|
||||||
}
|
}
|
||||||
usb_endpoints[0].buffer = buffer->next;
|
usb_endpoints[0].buffer = buffer->next;
|
||||||
/* Force data stage end */
|
/* Force data stage end */
|
||||||
|
|
|
@ -14,11 +14,6 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#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
|
/* This port no longer implements the legacy clock_delay. Hack its usages
|
||||||
* outta the way till it gets phased out completely
|
* outta the way till it gets phased out completely
|
||||||
* NB: This also overwrites the prototype so delay_usec() is declared twice */
|
* NB: This also overwrites the prototype so delay_usec() is declared twice */
|
||||||
|
|
|
@ -486,7 +486,7 @@ transmit(unsigned short transmit_len)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static int
|
static int
|
||||||
send(void *payload, unsigned short payload_len)
|
send(const void *payload, unsigned short payload_len)
|
||||||
{
|
{
|
||||||
prepare(payload, payload_len);
|
prepare(payload, payload_len);
|
||||||
return transmit(payload_len);
|
return transmit(payload_len);
|
||||||
|
|
7
cpu/cc26xx-cc13xx/Makefile.cc13xx
Normal file
7
cpu/cc26xx-cc13xx/Makefile.cc13xx
Normal 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
|
3
cpu/cc26xx-cc13xx/Makefile.cc26xx
Normal file
3
cpu/cc26xx-cc13xx/Makefile.cc26xx
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
TI_XXWARE_PATH = lib/cc26xxware
|
||||||
|
|
||||||
|
include $(CONTIKI_CPU)/Makefile.cc26xx-cc13xx
|
|
@ -8,25 +8,24 @@ NM = arm-none-eabi-nm
|
||||||
SIZE = arm-none-eabi-size
|
SIZE = arm-none-eabi-size
|
||||||
SREC_CAT = srec_cat
|
SREC_CAT = srec_cat
|
||||||
|
|
||||||
CPU_ABS_PATH = cpu/cc26xx
|
CPU_ABS_PATH = cpu/cc26xx-cc13xx
|
||||||
TI_CC26XXWARE_PATH = lib/cc26xxware
|
TI_XXWARE = $(CONTIKI_CPU)/$(TI_XXWARE_PATH)
|
||||||
TI_CC26XXWARE = $(CONTIKI_CPU)/$(TI_CC26XXWARE_PATH)
|
|
||||||
|
|
||||||
### cc26xxware sources under driverlib will be added to the MODULES list
|
### 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
|
### 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
|
### and the sources therein are added to the sources list explicitly. They are
|
||||||
### also listed explicitly in the linker command (through TARGET_STARTFILES),
|
### also listed explicitly in the linker command (through TARGET_STARTFILES),
|
||||||
### to make sure they always get linked in the image
|
### to make sure they always get linked in the image
|
||||||
TI_CC26XXWARE_STARTUP_DIR = $(TI_CC26XXWARE_PATH)/startup_files
|
TI_XXWARE_STARTUP_DIR = $(TI_XXWARE_PATH)/startup_files
|
||||||
TI_CC26XXWARE_STARTUP_SRCS = ccfg.c startup_gcc.c
|
TI_XXWARE_STARTUP_SRCS = ccfg.c startup_gcc.c
|
||||||
|
|
||||||
### MODULES will add some of these to the include path, but we need to add
|
### 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
|
### them earlier to prevent filename clashes with Contiki core files
|
||||||
CFLAGS += -I$(TI_CC26XXWARE) -I$(CONTIKI)/$(TI_CC26XXWARE_SRC)
|
CFLAGS += -I$(TI_XXWARE) -I$(CONTIKI)/$(TI_XXWARE_SRC)
|
||||||
CFLAGS += -I$(TI_CC26XXWARE)/inc
|
CFLAGS += -I$(TI_XXWARE)/inc
|
||||||
MODULES += $(TI_CC26XXWARE_SRC)
|
MODULES += $(TI_XXWARE_SRC)
|
||||||
|
|
||||||
LDSCRIPT = $(CONTIKI_CPU)/cc26xx.ld
|
LDSCRIPT = $(CONTIKI_CPU)/cc26xx.ld
|
||||||
|
|
||||||
|
@ -35,10 +34,6 @@ CFLAGS += -ffunction-sections -fdata-sections
|
||||||
CFLAGS += -fshort-enums -fomit-frame-pointer -fno-strict-aliasing
|
CFLAGS += -fshort-enums -fomit-frame-pointer -fno-strict-aliasing
|
||||||
CFLAGS += -Wall -std=c99
|
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 += -mcpu=cortex-m3 -mthumb -mlittle-endian -nostartfiles
|
||||||
LDFLAGS += -T $(LDSCRIPT)
|
LDFLAGS += -T $(LDSCRIPT)
|
||||||
LDFLAGS += -Wl,--gc-sections,--sort-section=alignment
|
LDFLAGS += -Wl,--gc-sections,--sort-section=alignment
|
||||||
|
@ -62,23 +57,24 @@ endif
|
||||||
CLEAN += symbols.c symbols.h *.d *.elf *.hex
|
CLEAN += symbols.c symbols.h *.d *.elf *.hex
|
||||||
|
|
||||||
### CPU-dependent directories
|
### 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
|
### Use the existing debug I/O in cpu/arm/common
|
||||||
CONTIKI_CPU_DIRS += ../arm/common/dbg-io
|
CONTIKI_CPU_DIRS += ../arm/common/dbg-io
|
||||||
|
|
||||||
### CPU-dependent source files
|
### CPU-dependent source files
|
||||||
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c cc26xx-rtc.c uart.c
|
CONTIKI_CPU_SOURCEFILES += clock.c rtimer-arch.c soc-rtc.c uart.c
|
||||||
CONTIKI_CPU_SOURCEFILES += cc26xx-rf.c contiki-watchdog.c
|
CONTIKI_CPU_SOURCEFILES += contiki-watchdog.c
|
||||||
CONTIKI_CPU_SOURCEFILES += putchar.c ieee-addr.c batmon-sensor.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 += slip-arch.c slip.c cc26xx-uart.c lpm.c
|
||||||
CONTIKI_CPU_SOURCEFILES += gpio-interrupt.c oscillators.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
|
DEBUG_IO_SOURCEFILES += dbg-printf.c dbg-snprintf.c dbg-sprintf.c strformat.c
|
||||||
|
|
||||||
CONTIKI_SOURCEFILES += $(CONTIKI_CPU_SOURCEFILES) $(DEBUG_IO_SOURCEFILES)
|
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)))
|
TARGET_STARTFILES = $(addprefix $(OBJECTDIR)/,$(call oname, $(TARGET_START_SOURCEFILES)))
|
||||||
|
|
||||||
### Don't treat the .elf as intermediate
|
### Don't treat the .elf as intermediate
|
|
@ -44,8 +44,11 @@ MEMORY
|
||||||
*/
|
*/
|
||||||
FLASH_CCFG (RX) : ORIGIN = 0x0001FFA8, LENGTH = 88
|
FLASH_CCFG (RX) : ORIGIN = 0x0001FFA8, LENGTH = 88
|
||||||
|
|
||||||
/* RAM Size 20KB (PG2.1) */
|
/* RAM Size 20KB */
|
||||||
SRAM (RWX) : ORIGIN = 0x20000000, LENGTH = 0x00005000
|
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 .*/
|
/*. Highest address of the stack. Used in startup file .*/
|
||||||
|
@ -99,5 +102,10 @@ SECTIONS
|
||||||
. = . + _Min_Heap_Size;
|
. = . + _Min_Heap_Size;
|
||||||
. = . + _Min_Stack_Size;
|
. = . + _Min_Stack_Size;
|
||||||
. = ALIGN(4);
|
. = ALIGN(4);
|
||||||
} >SRAM
|
} > SRAM
|
||||||
|
|
||||||
|
.gpram :
|
||||||
|
{
|
||||||
|
} > GPRAM
|
||||||
|
|
||||||
}
|
}
|
|
@ -35,30 +35,35 @@
|
||||||
* \defgroup cc26xx-platforms TI CC26xx-powered Platforms
|
* \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
|
* \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
|
* The software clock uses the facilities provided by the AON RTC driver
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
* Software clock implementation for the TI CC26xx
|
* Software clock implementation for the TI CC13xx/CC26xx
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
|
|
||||||
#include "ti-lib.h"
|
#include "ti-lib.h"
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static volatile clock_time_t count;
|
static volatile uint64_t count;
|
||||||
static volatile clock_time_t second_countdown;
|
|
||||||
static volatile unsigned long secs;
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
static void
|
static void
|
||||||
power_domain_on(void)
|
power_domain_on(void)
|
||||||
|
@ -72,8 +77,6 @@ void
|
||||||
clock_init(void)
|
clock_init(void)
|
||||||
{
|
{
|
||||||
count = 0;
|
count = 0;
|
||||||
secs = 0;
|
|
||||||
second_countdown = CLOCK_SECOND;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Here, we configure GPT0 Timer A, which we subsequently use in
|
* Here, we configure GPT0 Timer A, which we subsequently use in
|
||||||
|
@ -120,33 +123,50 @@ clock_init(void)
|
||||||
CCIF clock_time_t
|
CCIF clock_time_t
|
||||||
clock_time(void)
|
clock_time(void)
|
||||||
{
|
{
|
||||||
return count;
|
return (clock_time_t)(count & 0xFFFFFFFF);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
clock_update(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()) {
|
if(etimer_pending()) {
|
||||||
etimer_request_poll();
|
etimer_request_poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(--second_countdown == 0) {
|
|
||||||
secs++;
|
|
||||||
second_countdown = CLOCK_SECOND;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
void
|
|
||||||
clock_set_seconds(unsigned long sec)
|
|
||||||
{
|
|
||||||
secs = sec;
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
CCIF unsigned long
|
CCIF unsigned long
|
||||||
clock_seconds(void)
|
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
|
void
|
|
@ -32,13 +32,13 @@
|
||||||
* \addtogroup cc26xx
|
* \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
|
* \file
|
||||||
* Header file for the CC26xx Debug I/O module
|
* Header file for the CC13xx/CC26xx Debug I/O module
|
||||||
*/
|
*/
|
||||||
#ifndef DBG_H_
|
#ifndef DBG_H_
|
||||||
#define DBG_H_
|
#define DBG_H_
|
|
@ -33,7 +33,7 @@
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
* Driver for the CC26xx AON battery monitor
|
* Driver for the CC13xx/CC26xx AON battery monitor
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#include "contiki-conf.h"
|
#include "contiki-conf.h"
|
|
@ -32,13 +32,13 @@
|
||||||
* \addtogroup cc26xx
|
* \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.
|
* Driver for the on-chip battery voltage and chip temperature sensor.
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
* Header file for the CC26xx battery monitor
|
* Header file for the CC13xx/CC26xx battery monitor
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#ifndef BATMON_SENSOR_H_
|
#ifndef BATMON_SENSOR_H_
|
|
@ -27,6 +27,15 @@
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \addtogroup cc26xx-uart
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \file
|
||||||
|
* Implementation of the CC13xx/CC26xx UART driver.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#include "contiki-conf.h"
|
#include "contiki-conf.h"
|
||||||
#include "cc26xx-uart.h"
|
#include "cc26xx-uart.h"
|
||||||
#include "hw_types.h"
|
#include "hw_types.h"
|
||||||
|
@ -41,6 +50,7 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* Which events to trigger a UART interrupt */
|
/* Which events to trigger a UART interrupt */
|
||||||
#define CC26XX_UART_RX_INTERRUPT_TRIGGERS (UART_INT_RX | UART_INT_RT)
|
#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);
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
}
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
|
@ -31,13 +31,13 @@
|
||||||
* \addtogroup cc26xx
|
* \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
|
* \file
|
||||||
* Header file for the CC26xx UART driver
|
* Header file for the CC13xx/CC26xx UART driver
|
||||||
*/
|
*/
|
||||||
#ifndef CC26XX_UART_H_
|
#ifndef CC26XX_UART_H_
|
||||||
#define CC26XX_UART_H_
|
#define CC26XX_UART_H_
|
|
@ -31,16 +31,16 @@
|
||||||
* \addtogroup cc26xx-clocks
|
* \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
|
* This file is not called watchdog.c because the filename is in use by
|
||||||
* TI CC26xxware
|
* TI CC26xxware/CC13xxware
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
* Implementation of the cc26xx watchdog driver.
|
* Implementation of the CC13xx/CC26xx watchdog driver.
|
||||||
*/
|
*/
|
||||||
#include "watchdog.h"
|
#include "watchdog.h"
|
||||||
#include "ti-lib.h"
|
#include "ti-lib.h"
|
||||||
|
@ -75,14 +75,6 @@ watchdog_periodic(void)
|
||||||
ti_lib_watchdog_int_clear();
|
ti_lib_watchdog_int_clear();
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
|
||||||
* \brief Stub function to satisfy API requirements
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
watchdog_stop(void)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
/**
|
||||||
* \brief Manually trigger a WDT reboot
|
* \brief Manually trigger a WDT reboot
|
||||||
*/
|
*/
|
|
@ -28,6 +28,14 @@
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* \addtogroup cc26xx-gpio-interrupts
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \file
|
||||||
|
* Implementation of CC13xx/CC26xx GPIO interrupt handling.
|
||||||
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#include "ioc.h"
|
#include "ioc.h"
|
||||||
#include "gpio-interrupt.h"
|
#include "gpio-interrupt.h"
|
||||||
#include "sys/energest.h"
|
#include "sys/energest.h"
|
||||||
|
@ -94,4 +102,4 @@ gpio_interrupt_isr(void)
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/** @} */
|
|
@ -32,15 +32,15 @@
|
||||||
* \addtogroup cc26xx
|
* \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
|
* The CC13xx/CC26xx GPIO interrupt handler and an API which can be used by
|
||||||
* parts of the code when they wish to be notified of a GPIO interrupt
|
* other parts of the code when they wish to be notified of a GPIO interrupt
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
* Header file for the CC26xx GPIO interrupt management
|
* Header file for the CC13xx/CC26xx GPIO interrupt management
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#ifndef GPIO_INTERRUPT_H_
|
#ifndef GPIO_INTERRUPT_H_
|
|
@ -166,7 +166,4 @@ oscillators_switch_to_hf_rc(void)
|
||||||
osc_interface_dis(smph_clk_state);
|
osc_interface_dis(smph_clk_state);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/** @} */
|
||||||
* @}
|
|
||||||
* @}
|
|
||||||
*/
|
|
|
@ -32,9 +32,9 @@
|
||||||
* \addtogroup cc26xx
|
* \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
|
* All CC26xxware OSC control requires access to the semaphore module within
|
||||||
* AUX. Thus, in addition to enabling the oscillator interface, we need to
|
* AUX. Thus, in addition to enabling the oscillator interface, we need to
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
* Header file for the CC26XX oscillator control
|
* Header file for the CC13xx/CC26xx oscillator control
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#ifndef OSCILLATORS_H_
|
#ifndef OSCILLATORS_H_
|
|
@ -27,15 +27,15 @@
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* \addtogroup cc26xx-rtc
|
* \addtogroup cc13xx-cc26xx-rtc
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* \file
|
* \file
|
||||||
* Implementation of the CC26xx AON RTC driver
|
* Implementation of the CC13xx/CC26xx AON RTC driver
|
||||||
*/
|
*/
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
#include "sys/energest.h"
|
#include "sys/energest.h"
|
||||||
#include "rtimer.h"
|
#include "rtimer.h"
|
||||||
|
@ -46,16 +46,31 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.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 */
|
/* Prototype of a function in clock.c. Called every time the handler fires */
|
||||||
void clock_update(void);
|
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
|
void
|
||||||
cc26xx_rtc_init(void)
|
soc_rtc_init(void)
|
||||||
{
|
{
|
||||||
uint32_t compare_value;
|
|
||||||
bool interrupts_disabled;
|
bool interrupts_disabled;
|
||||||
|
uint32_t next;
|
||||||
|
|
||||||
/* Disable and clear interrupts */
|
/* Disable and clear interrupts */
|
||||||
interrupts_disabled = ti_lib_int_master_disable();
|
interrupts_disabled = ti_lib_int_master_disable();
|
||||||
|
@ -63,22 +78,22 @@ cc26xx_rtc_init(void)
|
||||||
ti_lib_aon_rtc_disable();
|
ti_lib_aon_rtc_disable();
|
||||||
|
|
||||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH0);
|
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 */
|
/* 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_WU0, AON_EVENT_RTC_CH0);
|
||||||
ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU1, AON_EVENT_RTC2);
|
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_CH2);
|
ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1);
|
||||||
|
|
||||||
/* Configure channel 2 in continuous compare, 128 ticks / sec */
|
HWREG(AON_RTC_BASE + AON_RTC_O_SEC) = SOC_RTC_START_TICK_COUNT;
|
||||||
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);
|
|
||||||
|
|
||||||
/* Enable channel 2 and the RTC */
|
next = ti_lib_aon_rtc_current_compare_value_get() + COMPARE_INCREMENT;
|
||||||
ti_lib_aon_rtc_channel_enable(AON_RTC_CH2);
|
|
||||||
|
/* 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_aon_rtc_enable();
|
||||||
|
|
||||||
ti_lib_int_enable(INT_AON_RTC);
|
ti_lib_int_enable(INT_AON_RTC);
|
||||||
|
@ -90,41 +105,60 @@ cc26xx_rtc_init(void)
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
rtimer_clock_t
|
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) {
|
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
|
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 */
|
/* 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_compare_value_set(channel, ticks);
|
||||||
ti_lib_aon_rtc_channel_enable(AON_RTC_CH0);
|
ti_lib_aon_rtc_channel_enable(channel);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/* The AON RTC interrupt handler */
|
/* The AON RTC interrupt handler */
|
||||||
void
|
void
|
||||||
cc26xx_rtc_isr(void)
|
soc_rtc_isr(void)
|
||||||
{
|
{
|
||||||
|
uint32_t now, next;
|
||||||
|
|
||||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||||
|
|
||||||
if(ti_lib_aon_rtc_event_get(AON_RTC_CH0)) {
|
now = ti_lib_aon_rtc_current_compare_value_get();
|
||||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH0);
|
|
||||||
rtimer_run_next();
|
/* 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)) {
|
if(ti_lib_aon_rtc_event_get(AON_RTC_CH0)) {
|
||||||
ti_lib_aon_rtc_event_clear(AON_RTC_CH2);
|
ti_lib_aon_rtc_channel_disable(AON_RTC_CH0);
|
||||||
clock_update();
|
HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH0;
|
||||||
|
rtimer_run_next();
|
||||||
}
|
}
|
||||||
|
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
|
@ -31,34 +31,28 @@
|
||||||
* \addtogroup cc26xx
|
* \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
|
* We use two of the aviable AON RTC channels. Channel 0 is used by the rtimer
|
||||||
* 128 interrupts / second. In continuous mode, the next compare event is
|
* sub-system. Channel 1 is used by the system clock and the LPM module.
|
||||||
* 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
|
|
||||||
*
|
*
|
||||||
* The RTC runs in all power modes except 'shutdown'
|
* 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
|
* Underpins the platform's software clocks and timers
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
* \file
|
* \file
|
||||||
* Header file for the CC26XX AON RTC driver
|
* Header file for the CC13xx/CC26xx AON RTC driver
|
||||||
*/
|
*/
|
||||||
#ifndef CC26XX_RTC_H_
|
#ifndef SOC_RTC_H_
|
||||||
#define CC26XX_RTC_H_
|
#define SOC_RTC_H_
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
|
|
||||||
|
@ -67,12 +61,13 @@
|
||||||
#include <stdint.h>
|
#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()
|
* 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
|
* \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
|
* This function will check both AON RTC channels and will only take CH0's
|
||||||
* compare into account if the channel is actually enabled
|
* 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
|
* \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
|
* \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,
|
* time, in other words the event will fire AT time \e t,
|
||||||
* not IN \e t ticks
|
* 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_ */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
|
@ -34,7 +34,7 @@
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
* Driver for the CC26xx IEEE addresses
|
* Driver for the CC13xx/CC26xx IEEE addresses
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#include "contiki-conf.h"
|
#include "contiki-conf.h"
|
|
@ -33,7 +33,7 @@
|
||||||
* \addtogroup cc26xx
|
* \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
|
* Driver for the retrieval of an IEEE address from flash
|
||||||
*
|
*
|
1
cpu/cc26xx-cc13xx/lib/cc13xxware
Submodule
1
cpu/cc26xx-cc13xx/lib/cc13xxware
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 63ed52888467ea7d403b0c743852162395232c9e
|
1
cpu/cc26xx-cc13xx/lib/cc26xxware
Submodule
1
cpu/cc26xx-cc13xx/lib/cc26xxware
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 0e82b18bf2c69fb0a40af4d2496db2a3dc721cec
|
|
@ -32,12 +32,12 @@
|
||||||
* \addtogroup cc26xx-lpm
|
* \addtogroup cc26xx-lpm
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* Implementation of CC26xx low-power operation functionality
|
* Implementation of CC13xx/CC26xx low-power operation functionality
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
* \file
|
* \file
|
||||||
* Driver for CC26xx's low-power operation
|
* Driver for CC13xx/CC26xx low-power operation
|
||||||
*/
|
*/
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#include "prcm.h"
|
#include "prcm.h"
|
||||||
|
@ -48,8 +48,11 @@
|
||||||
#include "lib/list.h"
|
#include "lib/list.h"
|
||||||
#include "dev/leds.h"
|
#include "dev/leds.h"
|
||||||
#include "dev/watchdog.h"
|
#include "dev/watchdog.h"
|
||||||
#include "dev/cc26xx-rtc.h"
|
#include "dev/soc-rtc.h"
|
||||||
#include "dev/oscillators.h"
|
#include "dev/oscillators.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if ENERGEST_CONF_ON
|
#if ENERGEST_CONF_ON
|
||||||
static unsigned long irq_energest = 0;
|
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
|
* Don't consider standby mode if the next AON RTC event is scheduled to fire
|
||||||
* in less than STANDBY_MIN_DURATION rtimer ticks
|
* 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
|
void
|
||||||
lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
|
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 */
|
/* Reset AON even fabric to default wakeup sources */
|
||||||
for(i = AON_EVENT_MCU_WU0; i <= AON_EVENT_MCU_WU3; i++) {
|
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++) {
|
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();
|
ti_lib_sys_ctrl_aon_sync();
|
||||||
|
@ -222,6 +228,14 @@ wake_up(void)
|
||||||
/* Check operating conditions, optimally choose DCDC versus GLDO */
|
/* Check operating conditions, optimally choose DCDC versus GLDO */
|
||||||
ti_lib_sys_ctrl_dcdc_voltage_conditional_control();
|
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 */
|
/* Notify all registered modules that we've just woken up */
|
||||||
for(module = list_head(modules_list); module != NULL;
|
for(module = list_head(modules_list); module != NULL;
|
||||||
module = module->next) {
|
module = module->next) {
|
||||||
|
@ -237,10 +251,11 @@ lpm_drop()
|
||||||
lpm_registered_module_t *module;
|
lpm_registered_module_t *module;
|
||||||
uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
|
uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
|
||||||
uint8_t module_pm;
|
uint8_t module_pm;
|
||||||
|
clock_time_t next_event;
|
||||||
|
|
||||||
uint32_t domains = LOCKABLE_DOMAINS;
|
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)) {
|
RTIMER_NOW() + STANDBY_MIN_DURATION)) {
|
||||||
lpm_sleep();
|
lpm_sleep();
|
||||||
return;
|
return;
|
||||||
|
@ -269,6 +284,18 @@ lpm_drop()
|
||||||
/* Critical. Don't get interrupted! */
|
/* Critical. Don't get interrupted! */
|
||||||
ti_lib_int_master_disable();
|
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
|
* Notify all registered modules that we are dropping to mode X. We do not
|
||||||
* need to do this for simple sleep.
|
* 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);
|
while(ti_lib_aon_wuc_power_status_get() & AONWUC_AUX_POWER_ON);
|
||||||
|
|
||||||
/* Configure the recharge controller */
|
/* 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
|
* If both PERIPH and SERIAL PDs are off, request the uLDO as the power
|
||||||
|
@ -436,6 +463,9 @@ void
|
||||||
lpm_init()
|
lpm_init()
|
||||||
{
|
{
|
||||||
list_init(modules_list);
|
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
|
void
|
|
@ -32,14 +32,14 @@
|
||||||
* \addtogroup cc26xx
|
* \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
|
* \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_
|
#ifndef LPM_H_
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue