branch merge
This commit is contained in:
commit
8264cde342
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
*.o
|
||||
doc/doxygen/html
|
||||
doc/doxygen/latex
|
||||
doc/doxygen/man
|
||||
*bin
|
||||
2
Jamfile
2
Jamfile
@ -67,8 +67,8 @@ Debug debug : $(TARGET) ;
|
||||
ListModules listmodules ;
|
||||
ShowFlags showflags : $(TARGET) ;
|
||||
|
||||
SubInclude TOP projects $(PROJECT) ;
|
||||
SubInclude TOP sys ;
|
||||
SubInclude TOP core ;
|
||||
SubInclude TOP drivers ;
|
||||
SubInclude TOP board ;
|
||||
SubInclude TOP projects $(PROJECT) ;
|
||||
|
||||
6
Jamrules
6
Jamrules
@ -31,9 +31,9 @@
|
||||
include $(TOP)$(SLASH)Jamrules.common ;
|
||||
|
||||
#
|
||||
# Setup FeuerWare build system configuration (default values for common options)
|
||||
# Setup ukleos build system configuration (default values for common options)
|
||||
#
|
||||
PROJECT = $(PROJECT:E=hello-world) ;
|
||||
PROJECT = $(PROJECT:E=default) ;
|
||||
BOARD = $(BOARD:E=msba2) ;
|
||||
SUFFIX ?= "" ; # must be at least "" !!!
|
||||
TARGET = "$(BOARD)-$(PROJECT)$(SUFFIX)$(SUFEXE)" ; # main target binary
|
||||
@ -53,7 +53,6 @@ CCFLAGS += -DBOARD=BOARD_$(BOARD:U) ;
|
||||
# core source directories
|
||||
HDRS += $(TOP) ;
|
||||
HDRS += [ FPath $(TOP) core include ] ;
|
||||
HDRS += [ FPath $(TOP) hal include ] ;
|
||||
HDRS += [ FPath $(TOP) sys include ] [ FPath $(TOP) sys config ] [ FPath $(TOP) sys drivers include ] [ FPath $(TOP) sys drivers cc110x ] [ FPath $(TOP) sys drivers nanopan5375 ] ;
|
||||
HDRS += [ FPath $(TOP) sys net ] ;
|
||||
HDRS += [ FPath $(TOP) sys lib ] [ FPath $(TOP) sys lib fat include ] ;
|
||||
@ -74,3 +73,4 @@ HDRS += [ FPath $(TOP) projects $(PROJECT) ] ;
|
||||
# drivers
|
||||
HDRS += [ FPath $(TOP) drivers include ] ;
|
||||
HDRS += [ FPath $(TOP) drivers cc110x ] ;
|
||||
HDRS += [ FPath $(TOP) drivers cc110x_ng ] ;
|
||||
|
||||
@ -177,7 +177,7 @@ rule Test
|
||||
}
|
||||
actions Test
|
||||
{
|
||||
for tst in projects/$(PROJECT)/tests/*; do $tst; done
|
||||
export PORT=$(PORT); for tst in projects/$(PROJECT)/tests/*; do $tst; done
|
||||
}
|
||||
|
||||
# Reset connected sensor node
|
||||
@ -357,4 +357,3 @@ actions ShowFlags {
|
||||
echo "" | $(CC) -E -dD -
|
||||
}
|
||||
|
||||
|
||||
|
||||
1
README
1
README
@ -7,3 +7,4 @@ License
|
||||
a separate license.
|
||||
|
||||
All code files contain licensing information.
|
||||
|
||||
|
||||
33
board/msb-430-common/Jamfile
Normal file
33
board/msb-430-common/Jamfile
Normal file
@ -0,0 +1,33 @@
|
||||
# ******************************************************************************
|
||||
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
#
|
||||
# These sources were developed at the Freie Universitaet Berlin, Computer
|
||||
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
# ------------------------------------------------------------------------------
|
||||
# This file is part of FeuerWare.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see http://www.gnu.org/licenses/ .
|
||||
# ------------------------------------------------------------------------------
|
||||
# For further information and questions please use the web site
|
||||
# http://scatterweb.mi.fu-berlin.de
|
||||
# and the mailinglist (subscription via web site)
|
||||
# scatterweb@lists.spline.inf.fu-berlin.de
|
||||
# ******************************************************************************
|
||||
# $Id$
|
||||
|
||||
SubDir TOP board msb-430-common ;
|
||||
|
||||
Module board : board_init.c debug_uart.c ;
|
||||
UseModule board ;
|
||||
|
||||
SubInclude TOP cpu $(CPU) ;
|
||||
37
board/msb-430-common/Jamrules.msb-430-common
Normal file
37
board/msb-430-common/Jamrules.msb-430-common
Normal file
@ -0,0 +1,37 @@
|
||||
# ******************************************************************************
|
||||
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
#
|
||||
# These sources were developed at the Freie Universitaet Berlin, Computer
|
||||
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
# ------------------------------------------------------------------------------
|
||||
# This file is part of FeuerWare.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see http://www.gnu.org/licenses/ .
|
||||
# ------------------------------------------------------------------------------
|
||||
# For further information and questions please use the web site
|
||||
# http://scatterweb.mi.fu-berlin.de
|
||||
# and the mailinglist (subscription via web site)
|
||||
# scatterweb@lists.spline.inf.fu-berlin.de
|
||||
# ******************************************************************************
|
||||
# $Id$
|
||||
|
||||
CPU = msp430 ;
|
||||
MCU = msp430x1612 ;
|
||||
|
||||
FLASH_PORT ?= /dev/ttyUSB0 ;
|
||||
FLASHER ?= mspdebug ;
|
||||
FLASHFLAGS ?= -d $(FLASH_PORT) -j uif ;
|
||||
|
||||
RESET ?= $(FLASHER) $(FLASHFLAGS) reset ;
|
||||
|
||||
HDRS += [ FPath $(TOP) board msb-430-common drivers include ] ;
|
||||
@ -201,7 +201,7 @@ void board_init() {
|
||||
msp430_cpu_init();
|
||||
msb_ports_init();
|
||||
|
||||
RED_ON;
|
||||
LED_RED_ON;
|
||||
|
||||
msp430_set_cpu_speed(7372800uL);
|
||||
}
|
||||
61
board/msb-430-common/drivers/include/sht11-board.h
Normal file
61
board/msb-430-common/drivers/include/sht11-board.h
Normal file
@ -0,0 +1,61 @@
|
||||
/******************************************************************************
|
||||
Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of FeuerWare.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef SHT11BOARD_H_
|
||||
#define SHT11BOARD_H_
|
||||
|
||||
/**
|
||||
* @ingroup msb_430h
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief SHT11 Device Driver Configuration For MSB-430 Platform
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics, µkleos
|
||||
* @version $Revision$
|
||||
*
|
||||
* @note $Id$
|
||||
*/
|
||||
#include <msp430x16x.h>
|
||||
#include <bitarithm.h>
|
||||
|
||||
/* SCK = P3B5
|
||||
* DATA = P3B4
|
||||
*/
|
||||
|
||||
#define SHT11_SCK_LOW P3OUT &= ~(BIT5); /**< serial clock line low */
|
||||
#define SHT11_SCK_HIGH P3OUT |= BIT5; /**< serial clock line high */
|
||||
#define SHT11_DATA (P3IN & BIT5) /**< read serial I/O */
|
||||
#define SHT11_DATA_LOW P3OUT &= ~(BIT5); /**< serial I/O line low */
|
||||
#define SHT11_DATA_HIGH P3OUT |= BIT5; /**< serial I/O line high */
|
||||
#define SHT11_DATA_IN P3DIR &= ~(BIT5); /**< serial I/O as input */
|
||||
#define SHT11_DATA_OUT P3DIR |= BIT5; /**< serial I/O as output */
|
||||
#define SHT11_INIT P3DIR |= BIT5; /* FIO1DIR |= BIT25; PINSEL3 &= ~(BIT14|BIT15 | BIT16|BIT17); */
|
||||
|
||||
/** @} */
|
||||
#endif /* SHT11BOARD_H_ */
|
||||
32
board/msb-430/Jamfile
Normal file
32
board/msb-430/Jamfile
Normal file
@ -0,0 +1,32 @@
|
||||
# ******************************************************************************
|
||||
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
#
|
||||
# These sources were developed at the Freie Universitaet Berlin, Computer
|
||||
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
# ------------------------------------------------------------------------------
|
||||
# This file is part of FeuerWare.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see http://www.gnu.org/licenses/ .
|
||||
# ------------------------------------------------------------------------------
|
||||
# For further information and questions please use the web site
|
||||
# http://scatterweb.mi.fu-berlin.de
|
||||
# and the mailinglist (subscription via web site)
|
||||
# scatterweb@lists.spline.inf.fu-berlin.de
|
||||
# ******************************************************************************
|
||||
# $Id$
|
||||
|
||||
SubDir TOP board msb-430 ;
|
||||
|
||||
SubInclude TOP board msb-430-common ;
|
||||
SubInclude TOP cpu $(CPU) ;
|
||||
|
||||
3
board/msb-430/Jamrules.msb-430
Normal file
3
board/msb-430/Jamrules.msb-430
Normal file
@ -0,0 +1,3 @@
|
||||
BOARD = msb-430 ;
|
||||
|
||||
include $(TOP)/board/msb-430-common/Jamrules.msb-430-common ;
|
||||
70
board/msb-430/include/board.h
Normal file
70
board/msb-430/include/board.h
Normal file
@ -0,0 +1,70 @@
|
||||
/******************************************************************************
|
||||
Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of FeuerWare.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef _MSB_BOARD_H
|
||||
#define _MSB_BOARD_H
|
||||
|
||||
/**
|
||||
* @defgroup msb_430h ScatterWeb MSB-430H
|
||||
* @ingroup msp430
|
||||
*
|
||||
<h2>Compontents</h2>
|
||||
\li MSP430
|
||||
\li CC1100
|
||||
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief MSB-430H Board
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
|
||||
* @version $Revision$
|
||||
*
|
||||
* @note $Id$
|
||||
*/
|
||||
|
||||
//MSB430 core
|
||||
#define MSP430_INITIAL_CPU_SPEED 7372800uL
|
||||
#define MSP430_HAS_DCOR 1
|
||||
#define MSP430_HAS_EXTERNAL_CRYSTAL 0
|
||||
|
||||
/* LEDs ports MSB430 */
|
||||
#define LEDS_PxDIR P5DIR
|
||||
#define LEDS_PxOUT P5OUT
|
||||
#define LEDS_CONF_RED 0x80
|
||||
#define LEDS_CONF_GREEN 0x00
|
||||
#define LEDS_CONF_YELLOW 0x00
|
||||
|
||||
#define LED_RED_ON LEDS_PxOUT &=~LEDS_CONF_RED
|
||||
#define LED_RED_OFF LEDS_PxOUT |= LEDS_CONF_RED
|
||||
#define LED_RED_TOGGLE LEDS_PxOUT ^= LEDS_CONF_RED
|
||||
|
||||
#include <msp430x16x.h>
|
||||
|
||||
/** @} */
|
||||
#endif // _MSB_BOARD_H
|
||||
@ -27,9 +27,8 @@
|
||||
|
||||
SubDir TOP board msb-430h ;
|
||||
|
||||
Module board : board_init.c debug_uart.c ;
|
||||
UseModule board ;
|
||||
|
||||
Module board_cc1100 : driver_cc1100.c ;
|
||||
|
||||
SubInclude TOP board msb-430-common ;
|
||||
SubInclude TOP cpu $(CPU) ;
|
||||
|
||||
|
||||
@ -1,37 +1,3 @@
|
||||
# ******************************************************************************
|
||||
# Copyright 2009, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
#
|
||||
# These sources were developed at the Freie Universitaet Berlin, Computer
|
||||
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
# ------------------------------------------------------------------------------
|
||||
# This file is part of FeuerWare.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see http://www.gnu.org/licenses/ .
|
||||
# ------------------------------------------------------------------------------
|
||||
# For further information and questions please use the web site
|
||||
# http://scatterweb.mi.fu-berlin.de
|
||||
# and the mailinglist (subscription via web site)
|
||||
# scatterweb@lists.spline.inf.fu-berlin.de
|
||||
# ******************************************************************************
|
||||
# $Id$
|
||||
|
||||
BOARD = msb-430h ;
|
||||
CPU = msp430 ;
|
||||
MCU = msp430x1612 ;
|
||||
|
||||
FLASH_PORT ?= /dev/ttyUSB0 ;
|
||||
FLASHER ?= mspdebug ;
|
||||
FLASHFLAGS ?= -d $(FLASH_PORT) -j uif ;
|
||||
|
||||
RESET ?= $(FLASHER) $(FLASHFLAGS) reset ;
|
||||
|
||||
include $(TOP)/board/msb-430-common/Jamrules.msb-430-common ;
|
||||
|
||||
@ -60,8 +60,9 @@ and the mailinglist (subscription via web site)
|
||||
#define LEDS_CONF_GREEN 0x00
|
||||
#define LEDS_CONF_YELLOW 0x00
|
||||
|
||||
#define RED_ON LEDS_PxOUT &=~LEDS_CONF_RED
|
||||
#define RED_OFF LEDS_PxOUT |= LEDS_CONF_RED
|
||||
#define LED_RED_ON LEDS_PxOUT &=~LEDS_CONF_RED
|
||||
#define LED_RED_OFF LEDS_PxOUT |= LEDS_CONF_RED
|
||||
#define LED_RED_TOGGLE LEDS_PxOUT ^= LEDS_CONF_RED
|
||||
|
||||
#include <msp430x16x.h>
|
||||
|
||||
|
||||
@ -29,5 +29,5 @@ CPU = lpc2387 ;
|
||||
|
||||
HDRS += [ FPath $(TOP) board $(BOARD) drivers include ] ;
|
||||
|
||||
FLASHER ?= $(POSIXSHELL) $(TOP)/board/msba2/tools/flashutil.sh ;
|
||||
FLASHFLAGS ?= --basedir $(TOP)/board/msba2/tools --id "MSB-A2" --ports "$(PORT)" ;
|
||||
FLASHER ?= $(POSIXSHELL) lpc2k_pgm ;
|
||||
FLASHFLAGS ?= "$(PORT)" ;
|
||||
|
||||
@ -54,10 +54,5 @@ and the mailinglist (subscription via web site)
|
||||
#define SHT11_DATA_OUT (FIO1DIR |= BIT26) // serial I/O as output
|
||||
#define SHT11_INIT FIO1DIR |= BIT25; PINSEL3 &= ~(BIT14|BIT15 | BIT16|BIT17);
|
||||
|
||||
/* time to wait after toggling the data line */
|
||||
#define SHT11_DATA_WAIT (50)
|
||||
/* time to wait after toggling the clock line */
|
||||
#define SHT11_CLK_WAIT (10)
|
||||
|
||||
/** @} */
|
||||
#endif /* SHT11BOARD_H_ */
|
||||
|
||||
@ -35,6 +35,7 @@ and the mailinglist (subscription via web site)
|
||||
#include <stdio.h>
|
||||
#include "lpc23xx.h"
|
||||
#include "VIC.h"
|
||||
#include <kernel.h>
|
||||
|
||||
#include <board_uart0.h>
|
||||
|
||||
@ -78,12 +79,14 @@ static inline void dequeue(void) {
|
||||
|
||||
static void push_queue(void) {
|
||||
running = 1;
|
||||
lpm_prevent_sleep |= LPM_PREVENT_SLEEP_UART;
|
||||
start:
|
||||
if (!actual) {
|
||||
if (queue_items) {
|
||||
dequeue();
|
||||
} else {
|
||||
running = 0;
|
||||
lpm_prevent_sleep &= ~LPM_PREVENT_SLEEP_UART;
|
||||
if (!fifo)
|
||||
while(!(U0LSR & BIT6)){};
|
||||
return;
|
||||
@ -149,7 +152,7 @@ void UART0_IRQHandler(void)
|
||||
|
||||
static inline int uart0_puts(char *astring,int length)
|
||||
{
|
||||
while (queue_items == (QUEUESIZE-1)) {} ;
|
||||
/* while (queue_items == (QUEUESIZE-1)) {} ;
|
||||
U0IER = 0;
|
||||
queue[queue_tail] = malloc(length+sizeof(unsigned int));
|
||||
queue[queue_tail]->len = length;
|
||||
@ -158,14 +161,14 @@ static inline int uart0_puts(char *astring,int length)
|
||||
if (!running)
|
||||
push_queue();
|
||||
U0IER |= BIT0 | BIT1; // enable RX irq
|
||||
|
||||
/* alternative without queue:
|
||||
*/
|
||||
/* alternative without queue:*/
|
||||
int i;
|
||||
for (i=0;i<length;i++) {
|
||||
while (!(U0LSR & BIT5));
|
||||
U0THR = astring[i];
|
||||
}
|
||||
*/
|
||||
/* */
|
||||
|
||||
return length;
|
||||
}
|
||||
@ -199,7 +202,8 @@ bl_uart_init(void)
|
||||
|
||||
/* irq */
|
||||
install_irq(UART0_INT, UART0_IRQHandler, 6);
|
||||
U0IER |= BIT0 | BIT1; // enable RX+TX irq
|
||||
// U0IER |= BIT0 | BIT1; // enable RX+TX irq
|
||||
U0IER |= BIT0; // enable only RX irq
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -12,9 +12,11 @@ PSEUDOTERM_OBJS = ${addprefix obj/,${patsubst %.c,%.o,$(PSEUDOTERM_SRC)}}
|
||||
TARGETDIR = bin
|
||||
|
||||
lpc2k_pgm: $(OBJS)
|
||||
mkdir -p $(TARGETDIR)
|
||||
$(CC) -o $(TARGETDIR)/lpc2k_pgm $(OBJS)
|
||||
|
||||
pseudoterm: $(PSEUDOTERM_OBJS)
|
||||
mkdir -p $(TARGETDIR)
|
||||
$(CC) -lpthread -o $(TARGETDIR)/pseudoterm $(PSEUDOTERM_OBJS)
|
||||
|
||||
chipinfo.o: boot_2xxx.h boot_23xx.h
|
||||
|
||||
@ -78,8 +78,6 @@ int main(int argc, char **argv)
|
||||
char* port_name = argv[1];
|
||||
char* file_name = argv[2];
|
||||
|
||||
sleep(1);
|
||||
|
||||
if (open_serial_port(port_name) < 0) {
|
||||
return(1);
|
||||
}
|
||||
|
||||
@ -1,135 +1,156 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "serial.h"
|
||||
#include "pthread.h"
|
||||
#include "download.h"
|
||||
|
||||
int tty_fd;
|
||||
int stopped = 0;
|
||||
char* port_name = "/dev/ttyUSB1";
|
||||
pthread_t serial_reader;
|
||||
|
||||
void* serial_reader_func(void* arg) {
|
||||
unsigned char buf[255];
|
||||
while(1) {
|
||||
int n = read_serial_port(buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
write(tty_fd, buf, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int init() {
|
||||
int result = open_serial_port(port_name);
|
||||
pthread_create(&serial_reader, NULL, serial_reader_func, NULL);
|
||||
hard_reset_to_user_code();
|
||||
return result;
|
||||
}
|
||||
|
||||
void sig_handler(int signal) {
|
||||
if (signal == SIGUSR1) {
|
||||
if (stopped) {
|
||||
stopped = 0;
|
||||
printf("\nSignal received, opening port.\r\n");
|
||||
if (init() < 0) {
|
||||
printf("Cannot open port.\r\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else if (signal == SIGUSR2) {
|
||||
if (!stopped) {
|
||||
stopped = 1;
|
||||
printf("\nSignal received, closing port. \r\n");
|
||||
pthread_cancel(serial_reader);
|
||||
close_serial_port();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int open_tty(void)
|
||||
{
|
||||
int r, fd;
|
||||
struct termios term_setting;
|
||||
|
||||
fd = open("/dev/tty", O_RDWR);
|
||||
if (fd < 0) return -1;
|
||||
r = tcgetattr(fd, &term_setting);
|
||||
if (r != 0) return -2;
|
||||
term_setting.c_oflag |= ( ONLRET );
|
||||
term_setting.c_iflag |= (IGNBRK | IGNPAR);
|
||||
term_setting.c_iflag &= ~(ISTRIP | BRKINT);
|
||||
term_setting.c_lflag &= ~(ICANON | ISIG | ECHO);
|
||||
term_setting.c_cflag |= CREAD;
|
||||
term_setting.c_cc[VMIN] = 1;
|
||||
term_setting.c_cc[VTIME] = 1;
|
||||
r = tcsetattr(fd, TCSANOW, &term_setting);
|
||||
if (r != 0) return -3;
|
||||
return fd;
|
||||
}
|
||||
|
||||
void install_sighandler() {
|
||||
struct sigaction action;
|
||||
sigemptyset (&action.sa_mask);
|
||||
sigaddset( &action.sa_mask, SIGUSR1 );
|
||||
sigaddset( &action.sa_mask, SIGUSR2 );
|
||||
action.sa_flags = 0;
|
||||
action.sa_handler = sig_handler;
|
||||
sigaction(SIGUSR1, &action, NULL);
|
||||
sigaction(SIGUSR2, &action, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc == 2) {
|
||||
port_name = argv[1];
|
||||
}
|
||||
|
||||
printf("Using %s as serial device.\n", port_name);
|
||||
|
||||
char ttybuf[255];
|
||||
tty_fd = open_tty();
|
||||
if (tty_fd < 0) {
|
||||
printf("Error opening terminal.\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
install_sighandler();
|
||||
|
||||
if (init() < 0) {
|
||||
printf("Cannot open port.\r\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int n = read(tty_fd, ttybuf, sizeof(ttybuf));
|
||||
int i;
|
||||
|
||||
/* check for 0x3 (ctrl-c), clean exit */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (ttybuf[i] == 0x3) {
|
||||
if (i > 0) {
|
||||
write_serial_port(ttybuf, i);
|
||||
}
|
||||
close_serial_port();
|
||||
system("tset -c");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
write_serial_port(ttybuf,n);
|
||||
}
|
||||
|
||||
close_serial_port();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "serial.h"
|
||||
#include "pthread.h"
|
||||
#include "download.h"
|
||||
|
||||
int tty_fd;
|
||||
int stopped = 0;
|
||||
char* port_name = "/dev/ttyUSB1";
|
||||
pthread_t serial_reader;
|
||||
|
||||
void* serial_reader_func(void* arg) {
|
||||
unsigned char buf[255];
|
||||
while(1) {
|
||||
int n = read_serial_port(buf, sizeof(buf));
|
||||
if (n > 0) {
|
||||
write(tty_fd, buf, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int init() {
|
||||
int result = open_serial_port(port_name);
|
||||
pthread_create(&serial_reader, NULL, serial_reader_func, NULL);
|
||||
hard_reset_to_user_code();
|
||||
return result;
|
||||
}
|
||||
|
||||
struct termios old_term_setting;
|
||||
|
||||
void close_tty() {
|
||||
tcsetattr(tty_fd, TCSANOW, &old_term_setting);
|
||||
}
|
||||
|
||||
void sig_handler(int signal) {
|
||||
if (signal == SIGUSR1) {
|
||||
if (stopped) {
|
||||
stopped = 0;
|
||||
printf("\nSignal received, opening port.\r\n");
|
||||
if (init() < 0) {
|
||||
printf("Cannot open port.\r\n");
|
||||
close_tty();
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
} else if (signal == SIGUSR2) {
|
||||
if (!stopped) {
|
||||
stopped = 1;
|
||||
printf("\nSignal received, closing port. \r\n");
|
||||
pthread_cancel(serial_reader);
|
||||
close_serial_port();
|
||||
}
|
||||
} else if (signal == SIGINT) {
|
||||
printf("SIGINT received, exiting...\n");
|
||||
pthread_cancel(serial_reader);
|
||||
close_serial_port();
|
||||
close_tty();
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int open_tty(void)
|
||||
{
|
||||
int r, fd;
|
||||
struct termios term_setting;
|
||||
|
||||
fd = open("/dev/tty", O_RDWR);
|
||||
if (fd < 0) return -1;
|
||||
r = tcgetattr(fd, &term_setting);
|
||||
if (r != 0) return -2;
|
||||
|
||||
old_term_setting = term_setting;
|
||||
|
||||
term_setting.c_oflag |= ( ONLRET );
|
||||
term_setting.c_iflag |= (/*IGNBRK |*/ BRKINT | IGNPAR);
|
||||
term_setting.c_iflag &= ~(ISTRIP);
|
||||
term_setting.c_lflag &= ~(ICANON |/* ISIG |*/ ECHO);
|
||||
term_setting.c_lflag |= ( ISIG );
|
||||
term_setting.c_cflag |= CREAD;
|
||||
term_setting.c_cc[VMIN] = 1;
|
||||
term_setting.c_cc[VTIME] = 1;
|
||||
r = tcsetattr(fd, TCSANOW, &term_setting);
|
||||
if (r != 0) return -3;
|
||||
return fd;
|
||||
}
|
||||
|
||||
void install_sighandler() {
|
||||
struct sigaction action;
|
||||
sigemptyset (&action.sa_mask);
|
||||
sigaddset( &action.sa_mask, SIGINT );
|
||||
sigaddset( &action.sa_mask, SIGUSR1 );
|
||||
sigaddset( &action.sa_mask, SIGUSR2 );
|
||||
action.sa_flags = 0;
|
||||
action.sa_handler = sig_handler;
|
||||
sigaction(SIGINT, &action, NULL);
|
||||
sigaction(SIGUSR1, &action, NULL);
|
||||
sigaction(SIGUSR2, &action, NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc == 2) {
|
||||
port_name = argv[1];
|
||||
}
|
||||
|
||||
printf("Using %s as serial device.\n", port_name);
|
||||
|
||||
char ttybuf[255];
|
||||
tty_fd = open_tty();
|
||||
if (tty_fd < 0) {
|
||||
printf("Error opening terminal.\n");
|
||||
return(1);
|
||||
}
|
||||
|
||||
install_sighandler();
|
||||
|
||||
if (init() < 0) {
|
||||
printf("Cannot open port.\r\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
while (1) {
|
||||
int n = read(tty_fd, ttybuf, sizeof(ttybuf));
|
||||
int i;
|
||||
|
||||
/* check for 0x3 (ctrl-c), clean exit */
|
||||
for (i = 0; i < n; i++) {
|
||||
if (ttybuf[i] == 0x3) {
|
||||
if (i > 0) {
|
||||
write_serial_port(ttybuf, i);
|
||||
}
|
||||
close_serial_port();
|
||||
close_tty();
|
||||
system("tset -c");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
write_serial_port(ttybuf,n);
|
||||
}
|
||||
|
||||
close_tty();
|
||||
close_serial_port();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -28,7 +28,11 @@
|
||||
SubDir TOP core ;
|
||||
|
||||
Module core : kernel_init.c sched.c mutex.c msg.c queue.c
|
||||
<<<<<<< HEAD
|
||||
clist.c thread.c bitarithm.c ;
|
||||
=======
|
||||
clist.c thread.c bitarithm.c cib.c ;
|
||||
>>>>>>> master
|
||||
|
||||
Module hwtimer : hwtimer.c : hwtimer_cpu ;
|
||||
|
||||
|
||||
@ -15,8 +15,6 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#define ARCH_32_BIT (__INT_MAX__ == 2147483647)
|
||||
|
||||
unsigned
|
||||
number_of_highest_bit(unsigned v)
|
||||
{
|
||||
|
||||
43
core/cib.c
Normal file
43
core/cib.c
Normal file
@ -0,0 +1,43 @@
|
||||
#include <cib.h>
|
||||
|
||||
void cib_init(cib_t *cib, unsigned int size) {
|
||||
cib->read_count = 0;
|
||||
cib->write_count = 0;
|
||||
cib->complement = 0-size;
|
||||
}
|
||||
|
||||
int cib_avail (cib_t *cib) {
|
||||
return cib->write_count - cib->read_count;
|
||||
}
|
||||
|
||||
int cib_get(cib_t *cib) {
|
||||
int avail = cib_avail (cib);
|
||||
|
||||
if (avail > 0) {
|
||||
return cib->read_count++ & ~cib->complement;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int cib_put(cib_t *cib) {
|
||||
int avail = cib_avail (cib);
|
||||
|
||||
if ((int)(avail + cib->complement) < 0 ) {
|
||||
return cib->write_count++ & ~(cib->complement);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
int main() {
|
||||
cib_t cib;
|
||||
|
||||
cib_init(&cib, 0);
|
||||
|
||||
int res = cib_get(&cib);
|
||||
|
||||
printf("%i\n", res);
|
||||
}
|
||||
*/
|
||||
@ -16,18 +16,14 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hwtimer.h"
|
||||
#include "hwtimer_cpu.h"
|
||||
#include "hwtimer_arch.h"
|
||||
#include <hwtimer.h>
|
||||
#include <hwtimer_cpu.h>
|
||||
#include <hwtimer_arch.h>
|
||||
|
||||
#include <bitarithm.h>
|
||||
|
||||
#define USE_NONBLOCKING_WAIT 1
|
||||
#if USE_NONBLOCKING_WAIT
|
||||
//#include <stdlib.h>
|
||||
#include "kernel.h"
|
||||
#include "mutex.h"
|
||||
#endif
|
||||
#include <kernel.h>
|
||||
#include <thread.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -37,8 +33,14 @@ typedef struct hwtimer_t {
|
||||
uint8_t checksum;
|
||||
} hwtimer_t;
|
||||
|
||||
typedef struct hwtimer_wait_t {
|
||||
unsigned int pid; /**< pid of waiting thread */
|
||||
uint8_t state; /**<state of waiting thread */
|
||||
} hwtimer_wait_t;
|
||||
|
||||
#define HWTIMER_QUEUESIZE ARCH_MAXTIMERS
|
||||
#define Q_FULL HWTIMER_QUEUESIZE + 1
|
||||
#define HWTIMER_WAIT_BACKOFF (10)
|
||||
|
||||
static hwtimer_t timer[HWTIMER_QUEUESIZE];
|
||||
static int queue[HWTIMER_QUEUESIZE];
|
||||
@ -52,8 +54,8 @@ static volatile long available_timers = 0;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int enqueue(int item) {
|
||||
// Test if timer is already cleared:
|
||||
// (hack to prevent race-condition with proccing timer (ISR) and manual hwtimer_remove)
|
||||
/* Test if timer is already cleared:
|
||||
* (hack to prevent race-condition with proccing timer (ISR) and manual hwtimer_remove) */
|
||||
if (available_timers & (1 << item)) {
|
||||
return 1;
|
||||
}
|
||||
@ -62,7 +64,8 @@ static int enqueue(int item) {
|
||||
queue_tail = (queue_tail + 1) % HWTIMER_QUEUESIZE;
|
||||
queue_items++;
|
||||
if (queue_items == HWTIMER_QUEUESIZE) {
|
||||
lpm_prevent_sleep &= ~LPM_PREVENT_SLEEP_HWTIMER; // Allow power down
|
||||
/* Allow power down */
|
||||
lpm_prevent_sleep &= ~LPM_PREVENT_SLEEP_HWTIMER;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -71,10 +74,12 @@ static int dequeue(void) {
|
||||
register int ret;
|
||||
if (!queue_items)
|
||||
return Q_FULL;
|
||||
lpm_prevent_sleep |= LPM_PREVENT_SLEEP_HWTIMER; // No power down while a timer is active
|
||||
/* No power down while a timer is active */
|
||||
lpm_prevent_sleep |= LPM_PREVENT_SLEEP_HWTIMER;
|
||||
queue_items--;
|
||||
ret = queue[queue_head];
|
||||
queue[queue_head] = 0xff; // Mark as empty
|
||||
/* Mark as empty */
|
||||
queue[queue_head] = 0xff;
|
||||
available_timers &= ~(1 << ret);
|
||||
queue_head = (queue_head + 1) % HWTIMER_QUEUESIZE;
|
||||
return ret;
|
||||
@ -85,8 +90,11 @@ static void multiplexer(int source) {
|
||||
timer[source].callback(timer[source].data);
|
||||
}
|
||||
|
||||
static void hwtimer_releasemutex(void* mutex) {
|
||||
mutex_unlock((mutex_t*)mutex, true);
|
||||
static void hwtimer_wakeup(void* hwt) {
|
||||
((hwtimer_wait_t*)hwt)->state = 0;
|
||||
while (!(thread_wakeup((*((hwtimer_wait_t*)hwt)).pid))) {
|
||||
hwtimer_set(HWTIMER_WAIT_BACKOFF, hwtimer_wakeup, (void*) &hwt);
|
||||
}
|
||||
}
|
||||
|
||||
void hwtimer_spin(unsigned long ticks)
|
||||
@ -113,7 +121,8 @@ void hwtimer_init_comp(uint32_t fcpu) {
|
||||
available_timers = 0;
|
||||
hwtimer_arch_init(multiplexer, fcpu);
|
||||
for (i = 0; i < HWTIMER_QUEUESIZE; i++) {
|
||||
queue[i] = 0xff; // init queue as empty
|
||||
/* init queue as empty */
|
||||
queue[i] = 0xff;
|
||||
}
|
||||
for (i = 0; i < HWTIMER_QUEUESIZE; i++) {
|
||||
enqueue(i);
|
||||
@ -123,7 +132,7 @@ void hwtimer_init_comp(uint32_t fcpu) {
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
int hwtimer_active(void) {
|
||||
return queue_items != HWTIMER_QUEUESIZE;
|
||||
return (queue_items != HWTIMER_QUEUESIZE);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
@ -137,34 +146,37 @@ unsigned long hwtimer_now(void)
|
||||
|
||||
void hwtimer_wait(unsigned long ticks)
|
||||
{
|
||||
mutex_t mutex;
|
||||
if (ticks <= 4 || inISR()) {
|
||||
if (ticks <= 6 || inISR()) {
|
||||
hwtimer_spin(ticks);
|
||||
return;
|
||||
}
|
||||
mutex_init(&mutex);
|
||||
mutex_lock(&mutex);
|
||||
// -2 is to adjust the real value
|
||||
int res = hwtimer_set(ticks-2, hwtimer_releasemutex, &mutex);
|
||||
hwtimer_wait_t hwt;
|
||||
hwt.pid = active_thread->pid;
|
||||
hwt.state = 1;
|
||||
/* -2 is to adjust the real value */
|
||||
int res = hwtimer_set(ticks-2, hwtimer_wakeup, (void*) &hwt);
|
||||
if (res == -1) {
|
||||
mutex_unlock(&mutex, true);
|
||||
hwtimer_spin(ticks);
|
||||
return;
|
||||
}
|
||||
mutex_lock(&mutex);
|
||||
while (hwt.state) {
|
||||
thread_sleep();
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static int _hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr, bool absolute)
|
||||
{
|
||||
if (! inISR() ) dINT();
|
||||
// hwtimer_arch_disable_interrupt();
|
||||
if (!inISR()) {
|
||||
dINT();
|
||||
}
|
||||
int x = dequeue();
|
||||
if (x == Q_FULL) {
|
||||
if (! inISR()) {
|
||||
eINT();
|
||||
}
|
||||
printf("[KT] no timers left\n");
|
||||
// hwtimer_arch_enable_interrupt();
|
||||
if (! inISR()) eINT();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -172,13 +184,16 @@ static int _hwtimer_set(unsigned long offset, void (*callback)(void*), void *ptr
|
||||
timer[x].data = ptr;
|
||||
timer[x].checksum = ++timer_id;
|
||||
|
||||
if (absolute)
|
||||
if (absolute) {
|
||||
hwtimer_arch_set_absolute(offset, x);
|
||||
else
|
||||
}
|
||||
else {
|
||||
hwtimer_arch_set(offset, x);
|
||||
}
|
||||
|
||||
//hwtimer_arch_enable_interrupt();
|
||||
if (! inISR()) eINT();
|
||||
if (!inISR()) {
|
||||
eINT();
|
||||
}
|
||||
return (timer[x].checksum << 8) + x;
|
||||
}
|
||||
|
||||
|
||||
@ -64,6 +64,8 @@
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#define ARCH_32_BIT (__INT_MAX__ == 2147483647)
|
||||
|
||||
/**
|
||||
* @brief Returns the number of the highest '1' bit in a value
|
||||
* @param[in] v Input value
|
||||
|
||||
15
core/include/cib.h
Normal file
15
core/include/cib.h
Normal file
@ -0,0 +1,15 @@
|
||||
#ifndef __CIB_H
|
||||
#define __CIB_H
|
||||
|
||||
typedef struct cib_t {
|
||||
unsigned int read_count;
|
||||
unsigned int write_count;
|
||||
unsigned int complement;
|
||||
} cib_t;
|
||||
|
||||
void cib_init(cib_t *cib, unsigned int size);
|
||||
int cib_get(cib_t *cib);
|
||||
int cib_put(cib_t *cib);
|
||||
int cib_avail(cib_t *cib);
|
||||
|
||||
#endif /* __CIB_H */
|
||||
@ -15,9 +15,9 @@
|
||||
#ifndef _FLAGS_H
|
||||
#define _FLAGS_H
|
||||
|
||||
#define CREATE_WOUT_YIELD 4
|
||||
#define CREATE_SLEEPING 1
|
||||
#define EXPECTS_REPLY 2
|
||||
#define AUTO_FREE 2
|
||||
#define CREATE_WOUT_YIELD 4
|
||||
#define CREATE_STACKTEST 8
|
||||
|
||||
/**
|
||||
|
||||
@ -30,7 +30,7 @@
|
||||
#define __HWTIMER_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "hwtimer_cpu.h"
|
||||
#include <hwtimer_cpu.h>
|
||||
|
||||
/**
|
||||
* @def HWTIMER_SPEED
|
||||
@ -124,6 +124,7 @@ void hwtimer_t0_enable_interrupt(void);
|
||||
void hwtimer_t0_set(unsigned long value, short timer);
|
||||
void hwtimer_t0_unset(short timer);
|
||||
unsigned long hwtimer_t0_now(void);
|
||||
unsigned long hwtimer_now(void);
|
||||
|
||||
/** @} */
|
||||
#endif /* __HWTIMER_H */
|
||||
|
||||
@ -70,15 +70,7 @@
|
||||
#define PRIORITY_MIN SCHED_PRIO_LEVELS-1
|
||||
|
||||
#define PRIORITY_IDLE PRIORITY_MIN
|
||||
#define PRIORITY_MAIN PRIORITY_MIN-1
|
||||
#define PRIORITY_CMD_THREADS PRIORITY_MIN-2 ///< all cmd handler threads
|
||||
#define PRIORITY_CBD PRIORITY_MIN-3
|
||||
#define PRIORITY_CMDD PRIORITY_MIN-4 ///< cmdengine demon
|
||||
#define PRIORITY_PRINTTHREAD PRIORITY_MIN-5 ///< mprint worker thread
|
||||
#define PRIORITY_HAL PRIORITY_MIN-6
|
||||
#define PRIORITY_UTIMER PRIORITY_MIN-7
|
||||
#define PRIORITY_MMREQ PRIORITY_MIN-8
|
||||
#define PRIORITY_CC1100 PRIORITY_MIN-9
|
||||
#define PRIORITY_MAIN (PRIORITY_MIN - (SCHED_PRIO_LEVELS/2))
|
||||
|
||||
/**
|
||||
* @brief Check whether called from interrupt service routine
|
||||
@ -88,6 +80,7 @@
|
||||
*/
|
||||
int inISR(void);
|
||||
|
||||
#define LPM_PREVENT_SLEEP_UART BIT2
|
||||
#define LPM_PREVENT_SLEEP_HWTIMER BIT1
|
||||
|
||||
extern volatile int lpm_prevent_sleep;
|
||||
|
||||
@ -105,7 +105,13 @@ int msg_send_receive(msg *m, msg *reply, unsigned int target_pid);
|
||||
*/
|
||||
int msg_reply(msg *m, msg *reply);
|
||||
|
||||
uint16_t msg_alloc_event(void);
|
||||
/**
|
||||
* @brief Initialize the current thread's message queue.
|
||||
*
|
||||
* @param array Pointer to preallocated array of msg objects
|
||||
* @param num Number of msg objects in array. MUST BE POWER OF TWO!
|
||||
*/
|
||||
int msg_init_queue(msg* array, int num);
|
||||
|
||||
/** @} */
|
||||
#endif /* __MSG_H */
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
|
||||
#define MAXTHREADS 32
|
||||
|
||||
#ifdef ARCH_32_BIT
|
||||
#if ARCH_32_BIT
|
||||
#define SCHED_PRIO_LEVELS 32
|
||||
#else
|
||||
#define SCHED_PRIO_LEVELS 16
|
||||
@ -25,6 +25,7 @@ void sched_init();
|
||||
void sched_run();
|
||||
|
||||
void sched_set_status(tcb *process, unsigned int status);
|
||||
void sched_switch(uint16_t current_prio, uint16_t other_prio, int in_isr);
|
||||
|
||||
volatile unsigned int sched_context_switch_request;
|
||||
|
||||
|
||||
@ -17,33 +17,39 @@
|
||||
#define TCB_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "queue.h"
|
||||
#include "clist.h"
|
||||
#include <queue.h>
|
||||
#include <clist.h>
|
||||
#include <cib.h>
|
||||
#include <msg.h>
|
||||
|
||||
/* uneven means has to be on runqueue */
|
||||
#define STATUS_NOT_FOUND 0
|
||||
#define STATUS_ON_RUNQUEUE 1
|
||||
#define STATUS_RUNNING 2 + STATUS_ON_RUNQUEUE
|
||||
#define STATUS_PENDING 4 + STATUS_ON_RUNQUEUE
|
||||
#define STATUS_STOPPED 8
|
||||
#define STATUS_SLEEPING 16
|
||||
#define STATUS_MUTEX_BLOCKED 32
|
||||
#define STATUS_RECEIVE_BLOCKED 64
|
||||
#define STATUS_SEND_BLOCKED 128
|
||||
#define STATUS_REPLY_BLOCKED 256
|
||||
#define STATUS_NOT_FOUND (0x0000)
|
||||
#define STATUS_ON_RUNQUEUE (0x0001)
|
||||
#define STATUS_RUNNING (0x0002) + STATUS_ON_RUNQUEUE
|
||||
#define STATUS_PENDING (0x0004) + STATUS_ON_RUNQUEUE
|
||||
#define STATUS_STOPPED (0x0008)
|
||||
#define STATUS_SLEEPING (0x0010)
|
||||
#define STATUS_MUTEX_BLOCKED (0x0020)
|
||||
#define STATUS_RECEIVE_BLOCKED (0x0040)
|
||||
#define STATUS_SEND_BLOCKED (0x0080)
|
||||
#define STATUS_REPLY_BLOCKED (0x0100)
|
||||
#define STATUS_TIMER_WAITING (0x0200)
|
||||
|
||||
typedef struct tcb {
|
||||
char* sp;
|
||||
unsigned int status;
|
||||
uint16_t status;
|
||||
|
||||
uint16_t pid;
|
||||
uint16_t priority;
|
||||
|
||||
void* wait_data;
|
||||
queue_node_t msg_queue;
|
||||
|
||||
clist_node_t rq_entry;
|
||||
|
||||
void* wait_data;
|
||||
queue_node_t msg_waiters;
|
||||
|
||||
cib_t msg_queue;
|
||||
msg* msg_array;
|
||||
|
||||
const char* name;
|
||||
char* stack_start;
|
||||
int stack_size;
|
||||
|
||||
@ -14,12 +14,15 @@
|
||||
*/
|
||||
|
||||
#include <kernel.h>
|
||||
#include <tcb.h>
|
||||
|
||||
/** Minimum stack size */
|
||||
#define MINIMUM_STACK_SIZE (sizeof(tcb))
|
||||
|
||||
/**
|
||||
* @brief Creates a new thread.
|
||||
* This version will allocate it's stack itself using malloc.
|
||||
*
|
||||
*
|
||||
* @param stack Lowest address of preallocated stack space
|
||||
* @param stacksize
|
||||
* @param flags Options:
|
||||
* YIELD: force context switch.
|
||||
@ -32,7 +35,7 @@
|
||||
*
|
||||
* @return returns <0 on error, pid of newly created task else.
|
||||
*/
|
||||
int thread_create(int stacksize, char priority, int flags, void (*function) (void), const char* name);
|
||||
int thread_create(char *stack, int stacksize, char priority, int flags, void (*function) (void), const char* name);
|
||||
|
||||
/**
|
||||
* @brief returns the status of a process.
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <errno.h>
|
||||
<<<<<<< HEAD
|
||||
#include "tcb.h"
|
||||
#include "kernel.h"
|
||||
#include "kernel_intern.h"
|
||||
@ -26,13 +27,24 @@
|
||||
#include "lpm.h"
|
||||
#include "thread.h"
|
||||
#include "hwtimer.h"
|
||||
=======
|
||||
#include <tcb.h>
|
||||
#include <kernel.h>
|
||||
#include <kernel_intern.h>
|
||||
#include <sched.h>
|
||||
#include <flags.h>
|
||||
#include <cpu.h>
|
||||
#include <lpm.h>
|
||||
#include <thread.h>
|
||||
#include <hwtimer.h>
|
||||
>>>>>>> master
|
||||
|
||||
#ifdef MODULE_AUTO_INIT
|
||||
#include <auto_init.h>
|
||||
#endif
|
||||
|
||||
#define ENABLE_DEBUG
|
||||
#include "debug.h"
|
||||
#include <debug.h>
|
||||
|
||||
volatile tcb *sched_threads[MAXTHREADS];
|
||||
volatile tcb *active_thread;
|
||||
@ -57,6 +69,9 @@ static void idle_thread(void) {
|
||||
const char *main_name = "main";
|
||||
const char *idle_name = "idle";
|
||||
|
||||
static char main_stack[KERNEL_CONF_STACKSIZE_MAIN];
|
||||
static char idle_stack[KERNEL_CONF_STACKSIZE_IDLE];
|
||||
|
||||
#ifdef MODULE_AUTO_INIT
|
||||
#define MAIN_FUNC auto_init
|
||||
#else
|
||||
@ -66,15 +81,19 @@ const char *idle_name = "idle";
|
||||
void kernel_init(void)
|
||||
{
|
||||
dINT();
|
||||
printf("kernel_init(): This is µkleos!\n");
|
||||
printf("kernel_init(): This is ukleos!\n");
|
||||
|
||||
sched_init();
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (thread_create(KERNEL_CONF_STACKSIZE_IDLE, PRIORITY_IDLE, CREATE_WOUT_YIELD | CREATE_STACKTEST, idle_thread, idle_name) < 0) {
|
||||
=======
|
||||
if (thread_create(idle_stack, sizeof(idle_stack), PRIORITY_IDLE, CREATE_WOUT_YIELD | CREATE_STACKTEST, idle_thread, idle_name) < 0) {
|
||||
>>>>>>> master
|
||||
printf("kernel_init(): error creating idle task.\n");
|
||||
}
|
||||
|
||||
if (thread_create(KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN, CREATE_WOUT_YIELD | CREATE_STACKTEST, MAIN_FUNC, main_name) < 0) {
|
||||
if (thread_create(main_stack, sizeof(main_stack), PRIORITY_MAIN, CREATE_WOUT_YIELD | CREATE_STACKTEST, MAIN_FUNC, main_name) < 0) {
|
||||
printf("kernel_init(): error creating main task.\n");
|
||||
}
|
||||
|
||||
|
||||
98
core/msg.c
98
core/msg.c
@ -20,32 +20,56 @@
|
||||
#include "tcb.h"
|
||||
#include <stddef.h>
|
||||
#include <irq.h>
|
||||
#include <cib.h>
|
||||
|
||||
#include "flags.h"
|
||||
|
||||
//#define ENABLE_DEBUG
|
||||
#include "debug.h"
|
||||
|
||||
static int queue_msg(tcb *target, msg *m) {
|
||||
int n = cib_put(&(target->msg_queue));
|
||||
|
||||
if (n != -1) {
|
||||
target->msg_array[n] = *m;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msg_send(msg* m, unsigned int target_pid, bool block) {
|
||||
if (inISR()) {
|
||||
return msg_send_int(m, target_pid);
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
int result = 1;
|
||||
|
||||
tcb *target = (tcb*)sched_threads[target_pid];
|
||||
|
||||
m->sender_pid = thread_pid;
|
||||
if (m->sender_pid == target_pid) return -1;
|
||||
=======
|
||||
tcb *target = (tcb*)sched_threads[target_pid];
|
||||
>>>>>>> master
|
||||
|
||||
dINT();
|
||||
|
||||
if (target == NULL) {
|
||||
eINT();
|
||||
m->sender_pid = thread_pid;
|
||||
if (m->sender_pid == target_pid) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (target == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
dINT();
|
||||
if (target->status != STATUS_RECEIVE_BLOCKED) {
|
||||
if (target->msg_array && queue_msg(target, m)) {
|
||||
eINT();
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (! block ) {
|
||||
DEBUG("%s: receiver not waiting. block=%u\n", active_thread->name, block);
|
||||
eINT();
|
||||
@ -56,9 +80,13 @@ int msg_send(msg* m, unsigned int target_pid, bool block) {
|
||||
queue_node_t n;
|
||||
n.priority = active_thread->priority;
|
||||
n.data = (unsigned int) active_thread;
|
||||
<<<<<<< HEAD
|
||||
DEBUG("%s: Adding node to msg_queue:\n", active_thread->name);
|
||||
=======
|
||||
DEBUG("%s: Adding node to msg_waiters:\n", active_thread->name);
|
||||
>>>>>>> master
|
||||
|
||||
queue_priority_add(&(target->msg_queue), &n);
|
||||
queue_priority_add(&(target->msg_waiters), &n);
|
||||
|
||||
active_thread->wait_data = (void*) m;
|
||||
|
||||
@ -83,7 +111,7 @@ int msg_send(msg* m, unsigned int target_pid, bool block) {
|
||||
eINT();
|
||||
thread_yield();
|
||||
|
||||
return result;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int msg_send_int(msg* m, unsigned int target_pid) {
|
||||
@ -103,9 +131,8 @@ int msg_send_int(msg* m, unsigned int target_pid) {
|
||||
return 1;
|
||||
} else {
|
||||
DEBUG("msg_send_int: receiver not waiting.\n");
|
||||
return 0;
|
||||
return (queue_msg(target, m));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int msg_send_receive(msg *m, msg *reply, unsigned int target_pid) {
|
||||
@ -148,35 +175,68 @@ int msg_reply_int(msg *m, msg *reply) {
|
||||
return -1;
|
||||
}
|
||||
msg* target_message = (msg*)target->wait_data;
|
||||
*target_message = *m;
|
||||
*target_message = *reply;
|
||||
sched_set_status(target, STATUS_PENDING);
|
||||
sched_context_switch_request = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int msg_receive(msg* m) {
|
||||
dINT();
|
||||
DEBUG("%s: msg_receive.\n", active_thread->name);
|
||||
|
||||
tcb *me = (tcb*) sched_threads[thread_pid];
|
||||
|
||||
me->wait_data = (void*) m;
|
||||
int n = -1;
|
||||
if (me->msg_array) {
|
||||
n = cib_get(&(me->msg_queue));
|
||||
}
|
||||
|
||||
queue_node_t *n = queue_remove_head(&(me->msg_queue));
|
||||
if (n >= 0) {
|
||||
DEBUG("%s: msg_receive(): We've got a queued message.\n", active_thread->name);
|
||||
*m = me->msg_array[n];
|
||||
} else {
|
||||
me->wait_data = (void*) m;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
if (n == NULL) {
|
||||
DEBUG("%s: msg_receive blocked\n", active_thread->name);
|
||||
sched_set_status(me, STATUS_RECEIVE_BLOCKED);
|
||||
|
||||
eINT();
|
||||
thread_yield();
|
||||
=======
|
||||
queue_node_t *node = queue_remove_head(&(me->msg_waiters));
|
||||
|
||||
/* sender copied message */
|
||||
if (node == NULL) {
|
||||
DEBUG("%s: msg_receive(): No thread in waiting list.\n", active_thread->name);
|
||||
if (n < 0) {
|
||||
DEBUG("%s: msg_receive(): No msg in queue. Going blocked.\n", active_thread->name);
|
||||
sched_set_status(me, STATUS_RECEIVE_BLOCKED);
|
||||
>>>>>>> master
|
||||
|
||||
eINT();
|
||||
thread_yield();
|
||||
|
||||
/* sender copied message */
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
<<<<<<< HEAD
|
||||
DEBUG("%s: msg_receive direct copy.\n", active_thread->name);
|
||||
tcb *sender = (tcb*)n->data;
|
||||
=======
|
||||
DEBUG("%s: msg_receive(): Wakeing up waiting thread.\n", active_thread->name);
|
||||
tcb *sender = (tcb*)node->data;
|
||||
|
||||
if (n >= 0) {
|
||||
/* we've already got a messgage from the queue. as there is a
|
||||
* waiter, take it's message into the just freed queue space.
|
||||
*/
|
||||
m = &(me->msg_array[cib_put(&(me->msg_queue))]);
|
||||
}
|
||||
>>>>>>> master
|
||||
|
||||
/* copy msg */
|
||||
msg* sender_msg = (msg*)sender->wait_data;
|
||||
@ -190,3 +250,15 @@ int msg_receive(msg* m) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int msg_init_queue(msg* array, int num) {
|
||||
/* make sure brainfuck condition is met */
|
||||
if (num && (num & (num - 1)) == 0) {
|
||||
tcb *me = (tcb*)active_thread;
|
||||
me->msg_array = array;
|
||||
cib_init(&(me->msg_queue), num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
51
core/mutex.c
51
core/mutex.c
@ -20,6 +20,10 @@
|
||||
#include "tcb.h"
|
||||
#include "kernel.h"
|
||||
#include "sched.h"
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
#include <irq.h>
|
||||
>>>>>>> master
|
||||
|
||||
//#define ENABLE_DEBUG
|
||||
#include <debug.h>
|
||||
@ -35,6 +39,7 @@ int mutex_init(struct mutex_t* mutex) {
|
||||
}
|
||||
|
||||
int mutex_trylock(struct mutex_t* mutex) {
|
||||
<<<<<<< HEAD
|
||||
return (atomic_set_return(&mutex->val, thread_pid ) == 0);
|
||||
}
|
||||
|
||||
@ -46,12 +51,23 @@ int mutex_lock(struct mutex_t* mutex) {
|
||||
DEBUG("%s: trying to get mutex. val: %u\n", active_thread->name, mutex->val);
|
||||
|
||||
if (atomic_set_return(&mutex->val,thread_pid) != 0) {
|
||||
=======
|
||||
DEBUG("%s: trylocking to get mutex. val: %u\n", active_thread->name, mutex->val);
|
||||
return atomic_set_return(&mutex->val, 1 ) == 0;
|
||||
}
|
||||
|
||||
int mutex_lock(struct mutex_t* mutex) {
|
||||
DEBUG("%s: trying to get mutex. val: %u\n", active_thread->name, mutex->val);
|
||||
|
||||
if (atomic_set_return(&mutex->val,1) != 0) {
|
||||
>>>>>>> master
|
||||
// mutex was locked.
|
||||
mutex_wait(mutex);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
void mutex_unlock(struct mutex_t* mutex, int yield) {
|
||||
DEBUG("%s: unlocking mutex. val: %u pid: %u\n", active_thread->name, mutex->val, thread_pid);
|
||||
int me_value;
|
||||
@ -71,12 +87,20 @@ void mutex_unlock(struct mutex_t* mutex, int yield) {
|
||||
|
||||
void mutex_wait(struct mutex_t *mutex) {
|
||||
dINT();
|
||||
=======
|
||||
void mutex_wait(struct mutex_t *mutex) {
|
||||
int irqstate = disableIRQ();
|
||||
>>>>>>> master
|
||||
DEBUG("%s: Mutex in use. %u\n", active_thread->name, mutex->val);
|
||||
if (mutex->val == 0) {
|
||||
// somebody released the mutex. return.
|
||||
mutex->val = thread_pid;
|
||||
DEBUG("%s: mutex_wait early out. %u\n", active_thread->name, mutex->val);
|
||||
<<<<<<< HEAD
|
||||
eINT();
|
||||
=======
|
||||
restoreIRQ(irqstate);
|
||||
>>>>>>> master
|
||||
return;
|
||||
}
|
||||
|
||||
@ -87,17 +111,22 @@ void mutex_wait(struct mutex_t *mutex) {
|
||||
n.data = (unsigned int) active_thread;
|
||||
n.next = NULL;
|
||||
|
||||
<<<<<<< HEAD
|
||||
DEBUG("%s: Adding node to mutex queue: prio: %u data: %u\n", active_thread->name, n.priority, n.data);
|
||||
=======
|
||||
DEBUG("%s: Adding node to mutex queue: prio: %u\n", active_thread->name, n.priority);
|
||||
>>>>>>> master
|
||||
|
||||
queue_priority_add(&(mutex->queue), &n);
|
||||
|
||||
eINT();
|
||||
restoreIRQ(irqstate);
|
||||
|
||||
thread_yield();
|
||||
|
||||
/* we were woken up by scheduler. waker removed us from queue. we have the mutex now. */
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
void mutex_wake_waiters(struct mutex_t *mutex, int flags) {
|
||||
if ( ! (flags & MUTEX_INISR)) dINT();
|
||||
DEBUG("%s: waking up waiters.\n", active_thread->name);
|
||||
@ -122,5 +151,25 @@ void mutex_wake_waiters(struct mutex_t *mutex, int flags) {
|
||||
} else {
|
||||
sched_context_switch_request = 1;
|
||||
}
|
||||
=======
|
||||
void mutex_unlock(struct mutex_t* mutex, int yield) {
|
||||
DEBUG("%s: unlocking mutex. val: %u pid: %u\n", active_thread->name, mutex->val, thread_pid);
|
||||
int irqstate = disableIRQ();
|
||||
|
||||
if (mutex->val != 0) {
|
||||
if (mutex->queue.next) {
|
||||
queue_node_t *next = queue_remove_head(&(mutex->queue));
|
||||
tcb* process = (tcb*)next->data;
|
||||
DEBUG("%s: waking up waiter %s.\n", process->name);
|
||||
sched_set_status(process, STATUS_PENDING);
|
||||
|
||||
sched_switch(active_thread->priority, process->priority, inISR());
|
||||
} else {
|
||||
mutex->val = 0;
|
||||
}
|
||||
}
|
||||
|
||||
restoreIRQ(irqstate);
|
||||
>>>>>>> master
|
||||
}
|
||||
|
||||
|
||||
@ -56,7 +56,7 @@ void queue_priority_add(queue_node_t* root, queue_node_t* new_obj) {
|
||||
queue_node_t* node = root;
|
||||
|
||||
while (node->next != NULL) {
|
||||
if (node->next->priority < new_obj->priority) {
|
||||
if (node->next->priority > new_obj->priority) {
|
||||
new_obj->next = node->next;
|
||||
node->next = new_obj;
|
||||
return;
|
||||
|
||||
29
core/sched.c
29
core/sched.c
@ -14,15 +14,22 @@
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
<<<<<<< HEAD:core/sched.c
|
||||
#include <malloc.h>
|
||||
#include "sched.h"
|
||||
#include "kernel.h"
|
||||
#include "kernel_intern.h"
|
||||
#include "clist.h"
|
||||
=======
|
||||
#include <sched.h>
|
||||
#include <kernel.h>
|
||||
#include <kernel_intern.h>
|
||||
#include <clist.h>
|
||||
>>>>>>> master:core/sched.c
|
||||
#include <bitarithm.h>
|
||||
|
||||
//#define ENABLE_DEBUG
|
||||
#include "debug.h"
|
||||
#include <debug.h>
|
||||
|
||||
volatile int num_tasks = 0;
|
||||
|
||||
@ -144,6 +151,20 @@ void sched_set_status(tcb *process, unsigned int status) {
|
||||
process->status = status;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD:core/sched.c
|
||||
=======
|
||||
void sched_switch(uint16_t current_prio, uint16_t other_prio, int in_isr) {
|
||||
DEBUG("%s: %i %i %i\n", active_thread->name, (int)current_prio, (int)other_prio, in_isr);
|
||||
if (current_prio <= other_prio) {
|
||||
if (in_isr) {
|
||||
sched_context_switch_request = 1;
|
||||
} else {
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
>>>>>>> master:core/sched.c
|
||||
extern void cpu_switch_context_exit(void);
|
||||
|
||||
void sched_task_exit(void) {
|
||||
@ -152,9 +173,15 @@ void sched_task_exit(void) {
|
||||
dINT();
|
||||
sched_threads[active_thread->pid] = NULL;
|
||||
num_tasks--;
|
||||
<<<<<<< HEAD:core/sched.c
|
||||
sched_set_status((tcb*)active_thread, STATUS_STOPPED);
|
||||
|
||||
free(((tcb*)active_thread)->stack_start);
|
||||
=======
|
||||
|
||||
sched_set_status((tcb*)active_thread, STATUS_STOPPED);
|
||||
|
||||
>>>>>>> master:core/sched.c
|
||||
active_thread = NULL;
|
||||
cpu_switch_context_exit();
|
||||
}
|
||||
|
||||
@ -14,7 +14,6 @@
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "thread.h"
|
||||
@ -45,11 +44,19 @@ void thread_sleep() {
|
||||
}
|
||||
|
||||
int thread_wakeup(int pid) {
|
||||
DEBUG("thread_wakeup: Trying to wakeup PID %i...\n", pid);
|
||||
int isr = inISR();
|
||||
if (! isr) dINT();
|
||||
if (! isr) {
|
||||
DEBUG("thread_wakeup: Not in interrupt.\n");
|
||||
dINT();
|
||||
}
|
||||
|
||||
int result = sched_threads[pid]->status;
|
||||
if (result == STATUS_SLEEPING) {
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
DEBUG("thread_wakeup: Thread is sleeping.\n");
|
||||
>>>>>>> master
|
||||
sched_set_status((tcb*)sched_threads[pid], STATUS_RUNNING);
|
||||
if (!isr) {
|
||||
eINT();
|
||||
@ -57,8 +64,9 @@ int thread_wakeup(int pid) {
|
||||
} else {
|
||||
sched_context_switch_request = 1;
|
||||
}
|
||||
return 0;
|
||||
return 1;
|
||||
} else {
|
||||
DEBUG("thread_wakeup: Thread is not sleeping!\n");
|
||||
if (!isr) eINT();
|
||||
return STATUS_NOT_FOUND;
|
||||
}
|
||||
@ -74,32 +82,28 @@ int thread_measure_stack_usage(char* stack) {
|
||||
return space;
|
||||
}
|
||||
|
||||
int thread_create(int stacksize, char priority, int flags, void (*function) (void), const char* name)
|
||||
int thread_create(char *stack, int stacksize, char priority, int flags, void (*function) (void), const char* name)
|
||||
{
|
||||
/* stacksize must be a multitude of 4 for alignment and stacktest */
|
||||
// assert( ((stacksize & 0x03) == 0) && (stacksize > 0) );
|
||||
/* allocate our thread control block at the top of our stackspace */
|
||||
int total_stacksize = stacksize;
|
||||
stacksize -= sizeof(tcb);
|
||||
|
||||
// TODO: shall we autoalign the stack?
|
||||
// stacksize += 4-(~(stacksize & 0x0003));
|
||||
/* align tcb address on 32bit boundary */
|
||||
unsigned int tcb_address = (unsigned int) stack + stacksize;
|
||||
if ( tcb_address & 1 ) {
|
||||
tcb_address--;
|
||||
stacksize--;
|
||||
}
|
||||
if ( tcb_address & 2 ) {
|
||||
tcb_address-=2;
|
||||
stacksize-=2;
|
||||
}
|
||||
tcb *cb = (tcb*) tcb_address;
|
||||
|
||||
if (priority >= SCHED_PRIO_LEVELS) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
tcb *pd = (tcb*)malloc(sizeof(tcb));
|
||||
if ( pd == NULL) {
|
||||
DEBUG("thread_create(): out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
char *stack = (char*)malloc(stacksize);
|
||||
if (stack==NULL)
|
||||
{
|
||||
DEBUG("thread_create(): out of memory\n");
|
||||
free (pd);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (flags & CREATE_STACKTEST) {
|
||||
/* assign each int of the stack the value of it's address */
|
||||
unsigned int *stackmax = (unsigned int*) ((char*)stack + stacksize);
|
||||
@ -120,8 +124,13 @@ int thread_create(int stacksize, char priority, int flags, void (*function) (voi
|
||||
int pid = 0;
|
||||
while (pid < MAXTHREADS) {
|
||||
if (sched_threads[pid] == NULL) {
|
||||
<<<<<<< HEAD
|
||||
sched_threads[pid] = pd;
|
||||
pd->pid = pid;
|
||||
=======
|
||||
sched_threads[pid] = cb;
|
||||
cb->pid = pid;
|
||||
>>>>>>> master
|
||||
break;
|
||||
}
|
||||
pid++;
|
||||
@ -130,42 +139,48 @@ int thread_create(int stacksize, char priority, int flags, void (*function) (voi
|
||||
if (pid == MAXTHREADS) {
|
||||
DEBUG("thread_create(): too many threads!\n");
|
||||
|
||||
free (pd);
|
||||
free (stack);
|
||||
|
||||
if (! inISR()) {
|
||||
eINT();
|
||||
}
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
pd->sp = thread_stack_init(function,stack+stacksize);
|
||||
pd->stack_start = stack;
|
||||
pd->stack_size = stacksize;
|
||||
=======
|
||||
cb->sp = thread_stack_init(function,stack+stacksize);
|
||||
cb->stack_start = stack;
|
||||
cb->stack_size = total_stacksize;
|
||||
|
||||
pd->priority = priority;
|
||||
pd->status = 0;
|
||||
cb->priority = priority;
|
||||
cb->status = 0;
|
||||
>>>>>>> master
|
||||
|
||||
pd->name = name;
|
||||
cb->rq_entry.data = (unsigned int) cb;
|
||||
cb->rq_entry.next = NULL;
|
||||
cb->rq_entry.prev = NULL;
|
||||
|
||||
pd->wait_data = NULL;
|
||||
cb->name = name;
|
||||
|
||||
pd->msg_queue.data = 0;
|
||||
pd->msg_queue.priority = 0;
|
||||
pd->msg_queue.next = NULL;
|
||||
cb->wait_data = NULL;
|
||||
|
||||
pd->rq_entry.data = (unsigned int) pd;
|
||||
pd->rq_entry.next = NULL;
|
||||
pd->rq_entry.prev = NULL;
|
||||
cb->msg_waiters.data = 0;
|
||||
cb->msg_waiters.priority = 0;
|
||||
cb->msg_waiters.next = NULL;
|
||||
|
||||
cib_init(&(cb->msg_queue),0);
|
||||
cb->msg_array = NULL;
|
||||
|
||||
num_tasks++;
|
||||
|
||||
DEBUG("Created thread %s. PID: %u. Priority: %u.\n", name, pd->pid, priority);
|
||||
DEBUG("Created thread %s. PID: %u. Priority: %u.\n", name, cb->pid, priority);
|
||||
|
||||
if (flags & CREATE_SLEEPING) {
|
||||
sched_set_status(pd, STATUS_SLEEPING);
|
||||
sched_set_status(cb, STATUS_SLEEPING);
|
||||
} else {
|
||||
sched_set_status(pd, STATUS_PENDING);
|
||||
sched_set_status(cb, STATUS_PENDING);
|
||||
if (!(flags & CREATE_WOUT_YIELD)) {
|
||||
if (! inISR()) {
|
||||
eINT();
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
SubDir TOP cpu arm_common ;
|
||||
|
||||
Module arm_common : common.s bootloader.c VIC.c atomic.s arm_cpu.c ;
|
||||
Module arm_common : common.s bootloader.c VIC.c atomic.s arm_cpu.c iap.c ;
|
||||
UseModule arm_common ;
|
||||
|
||||
Module hwtimer_cpu : hwtimer_cpu.c ;
|
||||
|
||||
254
cpu/arm_common/iap.c
Normal file
254
cpu/arm_common/iap.c
Normal file
@ -0,0 +1,254 @@
|
||||
/* iap driver
|
||||
*
|
||||
* based on iap driver for LPC2148 Controller made by Andreas Weschenfelder, 2008
|
||||
* see:
|
||||
*
|
||||
*/
|
||||
|
||||
#include <iap.h>
|
||||
#include <lpc2387.h>
|
||||
|
||||
#define ENABLE_DEBUG
|
||||
#include <debug.h>
|
||||
|
||||
static unsigned int iap_command[5]; // contains parameters for IAP command
|
||||
static unsigned int iap_result[2]; // contains results
|
||||
typedef void (*IAP) (unsigned int[],unsigned int[]); // typedefinition for IAP entry function
|
||||
IAP IAP_Entry;
|
||||
|
||||
/* some function prototypes */
|
||||
static uint32_t blank_check_sector(uint32_t tmp_sect1, uint32_t tmp_sect2);
|
||||
static uint32_t prepare_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2);
|
||||
static uint32_t erase_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2);
|
||||
static uint32_t copy_ram_to_flash(uint32_t tmp_adr_dst, uint32_t tmp_adr_src, uint32_t tmp_size);
|
||||
static uint32_t compare(uint32_t tmp_adr_dst, uint32_t tmp_adr_src, uint32_t tmp_size);
|
||||
static uint32_t iap(uint32_t code, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4);
|
||||
|
||||
/******************************************************************************
|
||||
* P U B L I C F U N C T I O N S
|
||||
*****************************************************************************/
|
||||
uint8_t iap_write(uint32_t dst, char *src, uint32_t size) {
|
||||
char err;
|
||||
uint32_t buffer_vic;
|
||||
uint8_t sec;
|
||||
|
||||
buffer_vic = VICIntEnable; // save interrupt enable
|
||||
VICIntEnClr = 0xFFFFFFFF; // clear vic
|
||||
|
||||
sec = iap_get_sector(dst);
|
||||
|
||||
/* check sector */
|
||||
if(blank_check_sector(sec, sec) == SECTOR_NOT_BLANK) {
|
||||
DEBUG("Warning: Sector %i not blank\n", sec);
|
||||
}
|
||||
|
||||
/* prepare sector */
|
||||
err = prepare_sectors(iap_get_sector(dst), iap_get_sector(dst));
|
||||
if (err) {
|
||||
DEBUG("\n-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION: %u", err);
|
||||
/* set interrupts back and return */
|
||||
VICIntEnable = buffer_vic;
|
||||
return 0;
|
||||
}
|
||||
/* write flash */
|
||||
else {
|
||||
err = copy_ram_to_flash(dst, (uint32_t) src, size);
|
||||
if(err) {
|
||||
DEBUG("ERROR: COPY_RAM_TO_FLASH: %u\n", err);
|
||||
/* set interrupts back and return */
|
||||
VICIntEnable = buffer_vic;
|
||||
return 0;
|
||||
}
|
||||
/* check result */
|
||||
else {
|
||||
err = compare(dst, (uint32_t) src, size);
|
||||
if (err) {
|
||||
DEBUG("ERROR: COMPARE: %i (at position %u)\n", err, iap_result[1]);
|
||||
/* set interrupts back and return */
|
||||
VICIntEnable = buffer_vic;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG("Data successfully written!\n");
|
||||
/* set interrupts back and return */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t iap_erase(uint32_t addr) {
|
||||
/* check sector */
|
||||
if (!blank_check_sector(iap_get_sector(addr), iap_get_sector(addr))) {
|
||||
DEBUG("Sector already blank!\n");
|
||||
return 1;
|
||||
}
|
||||
/* prepare sector */
|
||||
if (prepare_sectors(iap_get_sector(addr), iap_get_sector(addr))) {
|
||||
DEBUG("-- ERROR: PREPARE_SECTOR_FOR_WRITE_OPERATION --\n");
|
||||
return 0;
|
||||
}
|
||||
/* erase sector */
|
||||
if (erase_sectors(iap_get_sector(addr), iap_get_sector(addr))) {
|
||||
DEBUG("-- ERROR: ERASE SECTOR --\n");
|
||||
return 0;
|
||||
}
|
||||
/* check again */
|
||||
if (blank_check_sector(iap_get_sector(addr), iap_get_sector(addr))) {
|
||||
DEBUG("-- ERROR: BLANK_CHECK_SECTOR\n");
|
||||
return 0;
|
||||
}
|
||||
DEBUG("Sector successfully erased.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* PRIVATE FUNCTIONS
|
||||
*****************************************************************************/
|
||||
|
||||
static uint32_t iap(uint32_t code, uint32_t p1, uint32_t p2, uint32_t p3, uint32_t p4) {
|
||||
iap_command[0] = code; // set command code
|
||||
iap_command[1] = p1; // set 1st param
|
||||
iap_command[2] = p2; // set 2nd param
|
||||
iap_command[3] = p3; // set 3rd param
|
||||
iap_command[4] = p4; // set 4th param
|
||||
|
||||
((void (*)())0x7ffffff1)(iap_command, iap_result); // IAP entry point
|
||||
return *iap_result;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* Function: blank_check_sector
|
||||
*
|
||||
* Description: This command is used to blank check a sector or multiple sectors
|
||||
* of on-chip Flash memory. To blank check a single sector use the
|
||||
* same "Start" and "End" sector numbers.
|
||||
* Command: 53
|
||||
* Param0: Start Sector Number
|
||||
* Param1: End Sector Number (should be greater than equal to the start
|
||||
* sector number)
|
||||
*
|
||||
* Parameters: long tmp_sect1: Param0
|
||||
* long tmp_sect2: Param1
|
||||
*
|
||||
* Return: Code CMD_SUCCESS |
|
||||
* BUSY |
|
||||
* SECTOR_NOT_BLANK |
|
||||
* INVALID_SECTOR
|
||||
* Result0: Offset of the first non blank word location if the status code is SECTOR_NOT_BLANK.
|
||||
* Result1: Contents of non blank wird location.
|
||||
*****************************************************************************/
|
||||
uint32_t blank_check_sector(uint32_t tmp_sect1, uint32_t tmp_sect2) {
|
||||
return iap(BLANK_CHECK_SECTOR, tmp_sect1, tmp_sect2, 0 , 0);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Function: copy_ram_to_flash
|
||||
*
|
||||
* Description: This command is used to programm the flash memory. the affected should be
|
||||
* prepared first by calling "Prepare Sector for Write Operation" command. the
|
||||
* affected sectors are automatically protected again once the copy command is
|
||||
* successfully executed. the boot sector cannot be written by this command.
|
||||
* Command: 51
|
||||
* Param0: (DST) Destination Flash adress where data bytes are to be written.
|
||||
* This address should be a 512 byte boundary.
|
||||
* Param1: (SRC) Source RAM adress from which data byre are to be read.
|
||||
* Param2: Number of bytes to be written. Should be 512 | 1024 | 4096 | 8192.
|
||||
* Param3: System Clock Frequency (CCLK) in KHz.
|
||||
*
|
||||
* Parameters: long tmp_adr_dst: Param0
|
||||
* long tmp_adr_src: Param1
|
||||
* long tmp_size: Param2
|
||||
*
|
||||
* Return: Code CMD_SUCCESS |
|
||||
* SRC_ADDR_ERROR (Address not on word boundary) |
|
||||
* DST_ADDR_ERROR (Address not on correct boundary) |
|
||||
* SRC_ADDR_NOT_MAPPED |
|
||||
* DST_ADDR_NOT_MAPPED |
|
||||
* COUNT_ERROR (Byte count is not 512 | 1024 | 4096 | 8192) |
|
||||
* SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION |
|
||||
* BUSY
|
||||
*****************************************************************************/
|
||||
uint32_t copy_ram_to_flash(uint32_t tmp_adr_dst, uint32_t tmp_adr_src, uint32_t tmp_size) {
|
||||
return iap(COPY_RAM_TO_FLASH, tmp_adr_dst, tmp_adr_src, tmp_size, _XTAL);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Function: Prepare_Sector
|
||||
*
|
||||
* Description: This command must be executed before executing "Copy RAM to Flash" or "Erase Sector(s)"
|
||||
* command. Successful execution of the "Copy RAM to Flash" or "Erase Sector(s)" command causes
|
||||
* relevant sectors to be protected again. The boot sector can not be prepared by this command. To
|
||||
* prepare a single sector use the same "Start" and "End" sector numbers..
|
||||
* Command code: 50
|
||||
* Param0: Start Sector Number
|
||||
* Param1: End Sector Number: Should be greater than or equal to start sector number.
|
||||
*
|
||||
* Parameters: long tmp_sect1: Param0
|
||||
* long tmp_sect2: Param1
|
||||
*
|
||||
* Return: Code CMD_SUCCESS |
|
||||
* BUSY |
|
||||
* INVALID_SECTOR
|
||||
*****************************************************************************/
|
||||
uint32_t prepare_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2) {
|
||||
return iap(PREPARE_SECTOR_FOR_WRITE_OPERATION, tmp_sect1, tmp_sect2, 0 , 0);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Function: erase_sectors
|
||||
*
|
||||
* Description: This command is used to erase a sector or multiple sectors of on-chip Flash memory. The boot
|
||||
* sector can not be erased by this command. To erase a single sector use the same "Start" and "End"
|
||||
* sector numbers.
|
||||
* Command code: 52
|
||||
* Param0: Start Sector Number
|
||||
* Param1: End Sector Number: Should be greater than or equal to start sector number.
|
||||
* Param2: System Clock Frequency (CCLK) in KHz.
|
||||
*
|
||||
* Parameters: long tmp_sect1: Param0
|
||||
* long tmp_sect2: Param1
|
||||
*
|
||||
* Return: Code CMD_SUCCESS |
|
||||
* BUSY |
|
||||
* SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION |
|
||||
* INVALID_SECTOR
|
||||
*****************************************************************************/
|
||||
uint32_t erase_sectors(uint32_t tmp_sect1, uint32_t tmp_sect2) {
|
||||
return iap(ERASE_SECTOR, tmp_sect1, tmp_sect2, _XTAL, 0);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Function: compare
|
||||
*
|
||||
* Description: This command is used to compare the memory contents at two locations. compare result may not
|
||||
* be correct when source or destination address contains any of the first 64 bytes starting
|
||||
* from address zero. First 64 bytes can be re-mapped to RAM.
|
||||
* Command Code: 56
|
||||
* Param0(DST): Starting Flash or RAM address from where data bytes are to be
|
||||
* address should be a word boundary.
|
||||
* Param1(SRC): Starting Flash or RAM address from where data bytes are to be
|
||||
* address should be a word boundary.
|
||||
* Param2: Number of bytes to be compared. Count should be in multiple of 4.
|
||||
*
|
||||
* Parameters: long tmp_adr_dst
|
||||
* long tmp_adr_src
|
||||
* long tmp_size
|
||||
*
|
||||
* Return: Code CMD_SUCCESS |
|
||||
* COMPARE_ERROR |
|
||||
* COUNT_ERROR (Byte count is not multiple of 4) |
|
||||
* ADDR_ERROR |
|
||||
* ADDR_NOT_MAPPED
|
||||
* Result0: Offset of the first mismatch if the Status Code is COMPARE_ERROR.
|
||||
*****************************************************************************/
|
||||
uint32_t compare(uint32_t tmp_adr_dst, uint32_t tmp_adr_src, uint32_t tmp_size) {
|
||||
return iap(COMPARE, tmp_adr_dst, tmp_adr_src, tmp_size, 0);
|
||||
}
|
||||
67
cpu/arm_common/include/iap.h
Normal file
67
cpu/arm_common/include/iap.h
Normal file
@ -0,0 +1,67 @@
|
||||
#ifndef IAP_H_
|
||||
#define IAP_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* IAP-Commands */
|
||||
#define PREPARE_SECTOR_FOR_WRITE_OPERATION (50)
|
||||
#define COPY_RAM_TO_FLASH (51)
|
||||
#define ERASE_SECTOR (52)
|
||||
#define BLANK_CHECK_SECTOR (53)
|
||||
#define READ_PART_ID (54)
|
||||
#define READ_BOOT_CODE_VERSION (55)
|
||||
#define COMPARE (56)
|
||||
|
||||
/* IAP status codes */
|
||||
#define CMD_SUCCESS (0)
|
||||
#define INVALID_COMMAND (1)
|
||||
#define SRC_ADDR_ERROR (2)
|
||||
#define DST_ADDR_ERROR (3)
|
||||
#define SRC_ADDR_NOT_MAPPED (4)
|
||||
#define DST_ADDR_NOT_MAPPED (5)
|
||||
#define COUNT_ERROR (6)
|
||||
#define INVALID_SECTOR (7)
|
||||
#define SECTOR_NOT_BLANK (8)
|
||||
#define SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION (9)
|
||||
#define COMPARE_ERROR (10)
|
||||
#define BUSY (11)
|
||||
|
||||
/* IAP start location on flash */
|
||||
#define IAP_LOCATION (0x7FFFFFF1)
|
||||
|
||||
/* PLL */
|
||||
#define PLLCON_PLLE (0x01) ///< PLL Enable
|
||||
#define PLLCON_PLLD (0x00) ///< PLL Disable
|
||||
#define PLLCON_PLLC (0x03) ///< PLL Connect
|
||||
#define PLLSTAT_PLOCK (0x0400) //</ PLL Lock Status
|
||||
|
||||
/*
|
||||
* @brief Erase sector
|
||||
*
|
||||
* @param addr Address within a flash sector to erase
|
||||
*
|
||||
* @return 1 on success, 0 otherwise
|
||||
*/
|
||||
uint8_t iap_erase(uint32_t addr);
|
||||
|
||||
/* @brief Write buffer from ram to flash
|
||||
*
|
||||
* @param dst Address within a flash sector to write, must be a 256 byte boundary
|
||||
* @param src Address within ram, must be a word boundary
|
||||
* @param size Bytes to write
|
||||
*
|
||||
* @return 1 on success, 0 otherwise
|
||||
*/
|
||||
uint8_t iap_write(uint32_t dst, char *src, uint32_t size);
|
||||
|
||||
/*
|
||||
* @brief: Converts 'addr' to sector number
|
||||
* @note: Sector table (Users Manual P. 610)
|
||||
*
|
||||
* @param addr Flash address
|
||||
*
|
||||
* @return Sector number. 0xFF on error
|
||||
*/
|
||||
uint8_t iap_get_sector(uint32_t addr);
|
||||
|
||||
#endif /*IAP_H_*/
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
SubDir TOP cpu lpc2387 ;
|
||||
|
||||
Module cpu : cpu.c lpc2387-lpm.c ;
|
||||
Module cpu : cpu.c lpc2387-lpm.c lpc23xx-iap.c ;
|
||||
UseModule cpu ;
|
||||
|
||||
Module rtc : lpc2387-rtc.c ;
|
||||
|
||||
@ -68,7 +68,7 @@ and the mailinglist (subscription via web site)
|
||||
* @{
|
||||
*/
|
||||
#ifndef KERNEL_CONF_STACKSIZE_DEFAULT
|
||||
#define KERNEL_CONF_STACKSIZE_DEFAULT 2500
|
||||
#define KERNEL_CONF_STACKSIZE_DEFAULT 4500
|
||||
#endif
|
||||
|
||||
#define KERNEL_CONF_STACKSIZE_IDLE 500
|
||||
|
||||
@ -51,7 +51,6 @@ and the mailinglist (subscription via web site)
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include "lpc2387.h"
|
||||
#include "clock.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/**
|
||||
@ -82,9 +81,9 @@ enum rtc_alarm_mask {
|
||||
* @internal
|
||||
* During reboots only alarms are reset.
|
||||
*/
|
||||
void _rtc_init(void);
|
||||
void rtc_init(void);
|
||||
|
||||
void _rtc_reset(void);
|
||||
void rtc_reset(void);
|
||||
|
||||
/**
|
||||
* @brief Returns the time of compilation in seconds
|
||||
@ -92,6 +91,12 @@ void _rtc_reset(void);
|
||||
*/
|
||||
time_t rtc_get_compile_time(void) __attribute__((noinline));
|
||||
|
||||
/**
|
||||
* @brief Sets the current time in broken down format directly from to RTC
|
||||
* @param[in] localt Pointer to structure with time to set
|
||||
*/
|
||||
void rtc_set_localtime(struct tm* localt);
|
||||
|
||||
/**
|
||||
* @brief Returns the current clock time
|
||||
* @param[out] time optional return value
|
||||
@ -132,7 +137,7 @@ void rtc_get_localtime(struct tm* localt);
|
||||
*
|
||||
* @see ::rtc_alarm_mask
|
||||
*/
|
||||
void _rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask);
|
||||
void rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask);
|
||||
|
||||
/**
|
||||
* @brief Gets the current alarm setting
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
#ifndef __LPC2387_H
|
||||
#define __LPC2387_H
|
||||
|
||||
#include "lpc23xx.h"
|
||||
#include "bitarithm.h"
|
||||
#include <lpc23xx.h>
|
||||
#include <bitarithm.h>
|
||||
|
||||
#define F_CCO 288000000
|
||||
#define CL_CPU_DIV 4 ///< CPU clock divider
|
||||
@ -23,6 +23,8 @@
|
||||
#define GPIO_INT 17
|
||||
#define IRQP_GPIO 4
|
||||
|
||||
#define _XTAL (72000)
|
||||
|
||||
/**
|
||||
* @name Timer Symbols
|
||||
* @{
|
||||
|
||||
@ -28,6 +28,7 @@ and the mailinglist (subscription via web site)
|
||||
MEMORY
|
||||
{
|
||||
flash : ORIGIN = 0, LENGTH = 512K /* FLASH ROM */
|
||||
infomem : ORIGIN = 0x0007D000, LENGTH = 4K /* Last sector in FLASH ROM for config data */
|
||||
ram_battery : ORIGIN = 0xE0084000, LENGTH = 2K /* Battery RAM */
|
||||
ram : ORIGIN = 0x40000000, LENGTH = 64K /* LOCAL ON-CHIP STATIC RAM */
|
||||
ram_usb : ORIGIN = 0x7FD00000, LENGTH = 16K /* USB RAM */
|
||||
@ -98,6 +99,13 @@ SECTIONS
|
||||
. = ALIGN(4);
|
||||
_etext = . ; /* define a global symbol _etext just after the last code byte */
|
||||
|
||||
.config :
|
||||
{
|
||||
*(.configmem)
|
||||
. = ALIGN(256);
|
||||
} >infomem
|
||||
. = ALIGN(4);
|
||||
|
||||
/**************************************************************************
|
||||
* RAM
|
||||
**************************************************************************/
|
||||
|
||||
@ -55,22 +55,14 @@ static enum lpm_mode lpm;
|
||||
extern void init_clks1(void);
|
||||
extern void init_clks2(void);
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#endif
|
||||
#define ENABLE_DEBUG 0
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
void
|
||||
lpm_init(void)
|
||||
{
|
||||
void lpm_init(void) {
|
||||
lpm = LPM_ON;
|
||||
}
|
||||
|
||||
#define LPM_DEBUG 0
|
||||
#define LPM_DEBUG 1
|
||||
|
||||
void lpm_begin_awake(void) {
|
||||
if (lpm >= LPM_SLEEP ) { // wake up from deep sleep
|
||||
@ -96,7 +88,7 @@ void lpm_awake(void) {
|
||||
// Debug tests
|
||||
#if LPM_DEBUG
|
||||
usec = RTC_CTC-usec;
|
||||
printf("Wakeup in %lu usecs\n",usec * 31);
|
||||
DEBUG("Wakeup in %lu usecs\n",usec * 31);
|
||||
#endif
|
||||
}
|
||||
lpm = LPM_ON;
|
||||
@ -118,8 +110,8 @@ enum lpm_mode lpm_set(enum lpm_mode target) {
|
||||
|
||||
lpm = target;
|
||||
|
||||
#if DEBUG
|
||||
PRINTF("# LPM power down %u -> %u", lpm, target);
|
||||
#if iENABLE_DEBUG
|
||||
DEBUG("# LPM power down %u -> %u", lpm, target);
|
||||
#endif
|
||||
|
||||
PCON |= target_flags; // set target power mode
|
||||
|
||||
@ -45,20 +45,12 @@ and the mailinglist (subscription via web site)
|
||||
#include "lpc2387.h"
|
||||
#include "lpc2387-rtc.h"
|
||||
#include "lpm.h"
|
||||
#include "clock.h"
|
||||
|
||||
#define PREINT_RTC 0x000001C8 /* Prescaler value, integer portion, PCLK = 15Mhz */
|
||||
#define PREFRAC_RTC 0x000061C0 /* Prescaler value, fraction portion, PCLK = 15Mhz */
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(fmt, args...) printf("rtc: " fmt "\n", ##args)
|
||||
#else
|
||||
#define PRINTF(fmt, args...)
|
||||
#endif
|
||||
|
||||
extern void _clock_alarm(void);
|
||||
#define ENABLE_DEBUG 0
|
||||
#include <debug.h>
|
||||
|
||||
/**
|
||||
* @brief epoch time in hour granularity
|
||||
@ -70,7 +62,7 @@ static volatile time_t epoch;
|
||||
* @brief Sets the current time in broken down format directly from to RTC
|
||||
* @param[in] localt Pointer to structure with time to set
|
||||
*/
|
||||
static void
|
||||
void
|
||||
rtc_set_localtime(struct tm* localt)
|
||||
{
|
||||
if( localt == NULL )
|
||||
@ -95,14 +87,14 @@ void rtc_set(time_t time) {
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/// set clock to start of unix epoch
|
||||
void _rtc_reset(void)
|
||||
void rtc_reset(void)
|
||||
{
|
||||
rtc_set(0);
|
||||
epoch = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
_rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask)
|
||||
rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask)
|
||||
{
|
||||
if( localt != NULL ) {
|
||||
RTC_ALSEC = localt->tm_sec;
|
||||
@ -114,7 +106,7 @@ _rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask)
|
||||
RTC_ALMON = localt->tm_mon + 1;
|
||||
RTC_ALYEAR = localt->tm_year;
|
||||
RTC_AMR = ~mask; // set wich alarm fields to check
|
||||
PRINTF("alarm set %2lu.%2lu.%4lu %2lu:%2lu:%2lu",
|
||||
DEBUG("alarm set %2lu.%2lu.%4lu %2lu:%2lu:%2lu\n",
|
||||
RTC_ALDOM, RTC_ALMON, RTC_ALYEAR, RTC_ALHOUR, RTC_ALMIN, RTC_ALSEC);
|
||||
} else {
|
||||
RTC_AMR = 0xff;
|
||||
@ -122,7 +114,7 @@ _rtc_set_alarm(struct tm* localt, enum rtc_alarm_mask mask)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
enum rtc_alarm_mask
|
||||
_rtc_get_alarm(struct tm* localt)
|
||||
rtc_get_alarm(struct tm* localt)
|
||||
{
|
||||
if( localt != NULL ) {
|
||||
localt->tm_sec = RTC_ALSEC;
|
||||
@ -153,9 +145,8 @@ void RTC_IRQHandler (void)
|
||||
} else if( RTC_ILR & ILR_RTCALF ) {
|
||||
RTC_ILR |= ILR_RTCALF;
|
||||
RTC_AMR = 0xff; // disable alarm irq
|
||||
PRINTF("alarm");
|
||||
DEBUG("Ring\n");
|
||||
lpm_end_awake();
|
||||
_clock_alarm();
|
||||
}
|
||||
|
||||
VICVectAddr = 0; // Acknowledge Interrupt
|
||||
@ -172,7 +163,7 @@ void rtc_enable(void)
|
||||
epoch = now - (now % 3600);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void _rtc_init(void)
|
||||
void rtc_init(void)
|
||||
{
|
||||
PCONP |= BIT9;
|
||||
RTC_AMR = 0xff; // disable alarm irq
|
||||
@ -186,10 +177,10 @@ void _rtc_init(void)
|
||||
/* initialize clock with valid unix compatible values
|
||||
* If RTC_YEAR contains an value larger unix time_t we must reset. */
|
||||
if( RTC_YEAR > 2037 ) {
|
||||
_rtc_reset();
|
||||
rtc_reset();
|
||||
}
|
||||
|
||||
PRINTF("%2lu.%2lu.%4lu %2lu:%2lu:%2lu epoch %lu",
|
||||
DEBUG("%2lu.%2lu.%4lu %2lu:%2lu:%2lu epoch %lu\n",
|
||||
RTC_DOM, RTC_MONTH, RTC_YEAR, RTC_HOUR, RTC_MIN, RTC_SEC,
|
||||
epoch);
|
||||
}
|
||||
@ -245,7 +236,7 @@ rtc_get_localtime(struct tm* localt)
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void _gettimeofday_r(struct _reent *r, struct timeval *ptimeval, struct timezone *ptimezone)
|
||||
void gettimeofday_r(struct _reent *r, struct timeval *ptimeval, struct timezone *ptimezone)
|
||||
{
|
||||
r->_errno = 0;
|
||||
if( ptimeval != NULL ) {
|
||||
|
||||
92
cpu/lpc2387/lpc23xx-iap.c
Normal file
92
cpu/lpc2387/lpc23xx-iap.c
Normal file
@ -0,0 +1,92 @@
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t iap_get_sector(uint32_t addr) {
|
||||
if ((addr >=0x00000000) && (addr <= 0x00000FFF)) {
|
||||
return 0;
|
||||
}
|
||||
if ((addr >=0x00001000) && (addr <= 0x00001FFF)) {
|
||||
return 1;
|
||||
}
|
||||
if ((addr >=0x00002000) && (addr <= 0x00002FFF)) {
|
||||
return 2;
|
||||
}
|
||||
if ((addr >=0x00003000) && (addr <= 0x00003FFF)) {
|
||||
return 3;
|
||||
}
|
||||
if ((addr >=0x00004000) && (addr <= 0x00004FFF)) {
|
||||
return 4;
|
||||
}
|
||||
if ((addr >=0x00005000) && (addr <= 0x00005FFF)) {
|
||||
return 5;
|
||||
}
|
||||
if ((addr >=0x00006000) && (addr <= 0x00006FFF)) {
|
||||
return 6;
|
||||
}
|
||||
if ((addr >=0x00007000) && (addr <= 0x00007FFF)) {
|
||||
return 7;
|
||||
}
|
||||
|
||||
if ((addr >=0x00008000) && (addr <= 0x0000FFFF)) {
|
||||
return 8;
|
||||
}
|
||||
if ((addr >=0x00010000) && (addr <= 0x00017FFF)) {
|
||||
return 9;
|
||||
}
|
||||
if ((addr >=0x00018000) && (addr <= 0x0001FFFF)) {
|
||||
return 10;
|
||||
}
|
||||
if ((addr >=0x00020000) && (addr <= 0x00027FFF)) {
|
||||
return 11;
|
||||
}
|
||||
if ((addr >=0x00028000) && (addr <= 0x0002FFFF)) {
|
||||
return 12;
|
||||
}
|
||||
if ((addr >=0x00030000) && (addr <= 0x00037FFF)) {
|
||||
return 13;
|
||||
}
|
||||
if ((addr >=0x00038000) && (addr <= 0x0003FFFF)) {
|
||||
return 14;
|
||||
}
|
||||
if ((addr >=0x00040000) && (addr <= 0x00047FFF)) {
|
||||
return 15;
|
||||
}
|
||||
if ((addr >=0x00048000) && (addr <= 0x0004FFFF)) {
|
||||
return 16;
|
||||
}
|
||||
if ((addr >=0x00050000) && (addr <= 0x00057FFF)) {
|
||||
return 17;
|
||||
}
|
||||
if ((addr >=0x00058000) && (addr <= 0x0005FFFF)) {
|
||||
return 18;
|
||||
}
|
||||
if ((addr >=0x00060000) && (addr <= 0x00067FFF)) {
|
||||
return 19;
|
||||
}
|
||||
if ((addr >=0x00068000) && (addr <= 0x0006FFFF)) {
|
||||
return 20;
|
||||
}
|
||||
if ((addr >=0x00070000) && (addr <= 0x00077FFF)) {
|
||||
return 21;
|
||||
}
|
||||
if ((addr >=0x00078000) && (addr <= 0x00078FFF)) {
|
||||
return 22;
|
||||
}
|
||||
if ((addr >=0x00079000) && (addr <= 0x00079FFF)) {
|
||||
return 23;
|
||||
}
|
||||
if ((addr >=0x0007A000) && (addr <= 0x0007AFFF)) {
|
||||
return 24;
|
||||
}
|
||||
if ((addr >=0x0007B000) && (addr <= 0x0007BFFF)) {
|
||||
return 25;
|
||||
}
|
||||
if ((addr >=0x0007C000) && (addr <= 0x0007CFFF)) {
|
||||
return 26;
|
||||
}
|
||||
if ((addr >=0x0007D000) && (addr <= 0x0007DFFF)) {
|
||||
return 27;
|
||||
}
|
||||
|
||||
/* no valid address within flash */
|
||||
return 0xFF;
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include "board.h"
|
||||
#include "kernel_intern.h"
|
||||
#include <board.h>
|
||||
#include <kernel_intern.h>
|
||||
|
||||
extern void board_init();
|
||||
|
||||
@ -10,7 +10,7 @@ __attribute__ ((constructor)) static void startup() {
|
||||
|
||||
board_init();
|
||||
|
||||
puts("FireKernel MSP430 hardware initialization complete.\n");
|
||||
puts("ukleos MSP430 hardware initialization complete.\n");
|
||||
|
||||
kernel_init();
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ WARN_LOGFILE =
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
INPUT = ../../core ../../cpu ../../board ../../sys ../manual
|
||||
INPUT = ../../core ../../cpu ../../board ../../sys ../manual ../../drivers
|
||||
INPUT_ENCODING = UTF-8
|
||||
FILE_PATTERNS = *.doc *.c *.h
|
||||
RECURSIVE = YES
|
||||
@ -125,7 +125,7 @@ HTML_OUTPUT = html
|
||||
HTML_FILE_EXTENSION = .html
|
||||
HTML_HEADER = src/ukleos-header.html
|
||||
HTML_FOOTER = src/ukleos-footer.html
|
||||
HTML_STYLESHEET = src/ukleos.css
|
||||
HTML_STYLESHEET =
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
HTML_DYNAMIC_SECTIONS = YES
|
||||
GENERATE_DOCSET = NO
|
||||
|
||||
@ -32,3 +32,4 @@ Module sht11 : sht11.c : hwtimer ;
|
||||
Module ltc4150 : ltc4150.c : board_ltc4150 ;
|
||||
|
||||
SubInclude TOP drivers cc110x ;
|
||||
SubInclude TOP drivers cc110x_ng ;
|
||||
|
||||
@ -60,6 +60,8 @@ and the mailinglist (subscription via web site)
|
||||
#include "msg.h"
|
||||
#include "debug.h"
|
||||
|
||||
#define PRIORITY_CC1100 PRIORITY_MAIN-1
|
||||
|
||||
#define MSG_POLL 12346
|
||||
|
||||
#define FLAGS_IDENTIFICATION (0x01) ///< Bit mask for reading the identification out of the flags field
|
||||
@ -94,10 +96,13 @@ static const pm_table_t handler_table;
|
||||
static const char *cc1100_event_handler_name = "cc1100_event_handler";
|
||||
static mutex_t cc1100_mutex;
|
||||
volatile int cc1100_mutex_pid;
|
||||
static swtimer_t cc1100_watch_dog;
|
||||
static swtime_t cc1100_watch_dog_period = 0;
|
||||
|
||||
static uint16_t cc1100_event_handler_pid;
|
||||
static void cc1100_event_handler_function(void);
|
||||
static swtimer_t cc1100_watch_dog;
|
||||
static uint64_t cc1100_watch_dog_period = 0;
|
||||
|
||||
static char event_handler_stack[KERNEL_CONF_STACKSIZE_MAIN];
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Sequence number buffer management data structures
|
||||
@ -188,7 +193,7 @@ void cc1100_phy_init()
|
||||
mutex_init(&cc1100_mutex);
|
||||
|
||||
// Allocate event numbers and start cc1100 event process
|
||||
cc1100_event_handler_pid = thread_create(2500, PRIORITY_CC1100, CREATE_STACKTEST,
|
||||
cc1100_event_handler_pid = thread_create(event_handler_stack, sizeof(event_handler_stack), PRIORITY_CC1100, CREATE_STACKTEST,
|
||||
cc1100_event_handler_function, cc1100_event_handler_name);
|
||||
|
||||
// Active watchdog for the first time
|
||||
|
||||
33
drivers/cc110x_ng/Jamfile
Executable file
33
drivers/cc110x_ng/Jamfile
Executable file
@ -0,0 +1,33 @@
|
||||
# ******************************************************************************
|
||||
# Copyright 2010, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
#
|
||||
# These sources were developed at the Freie Universitaet Berlin, Computer
|
||||
# Systems and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
# ------------------------------------------------------------------------------
|
||||
# This file is part of µkleos.
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation, either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program. If not, see http://www.gnu.org/licenses/ .
|
||||
# ------------------------------------------------------------------------------
|
||||
# For further information and questions please use the web site
|
||||
# http://scatterweb.mi.fu-berlin.de
|
||||
# and the mailinglist (subscription via web site)
|
||||
# scatterweb@lists.spline.inf.fu-berlin.de
|
||||
# ******************************************************************************
|
||||
# $Id: Jamfile 832 2009-03-13 16:45:41Z kaspar $
|
||||
|
||||
SubDir TOP drivers cc110x_ng ;
|
||||
|
||||
HDRS += $(TOP)/drivers/cc110x_ng ;
|
||||
|
||||
Module cc110x_ng : cc1100.c cc1100-rx.c cc1100-tx.c cc1100-defaultSettings.c cc1100_spi.c : board_cc1100 swtimer gpioint ;
|
||||
|
||||
50
drivers/cc110x_ng/cc1100-arch.h
Normal file
50
drivers/cc110x_ng/cc1100-arch.h
Normal file
@ -0,0 +1,50 @@
|
||||
/******************************************************************************
|
||||
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of FeuerWare.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @ingroup LPC2387
|
||||
* @brief CC1100 LPC2387 dependend functions
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
|
||||
* @author Heiko Will <hwill@inf.fu-berlin.de>
|
||||
* @version $Revision: 1775 $
|
||||
*
|
||||
* @note $Id: arch_cc1100.h 1775 2010-01-26 09:37:03Z hillebra $
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
uint8_t cc1100_txrx(uint8_t c);
|
||||
|
||||
void cc1100_gdo0_enable(void);
|
||||
void cc1100_gdo0_disable(void);
|
||||
void cc1100_gdo2_enable(void);
|
||||
void cc1100_gdo2_disable(void);
|
||||
void cc1100_init_interrupts(void);
|
||||
|
||||
void cc1100_before_send(void);
|
||||
void cc1100_after_send(void);
|
||||
94
drivers/cc110x_ng/cc1100-config.h
Normal file
94
drivers/cc110x_ng/cc1100-config.h
Normal file
@ -0,0 +1,94 @@
|
||||
#ifndef CC1100_CONFIG_H
|
||||
#define CC1100_CONFIG_H
|
||||
|
||||
/** CC1100 register configuration */
|
||||
typedef struct {
|
||||
uint8_t IOCFG2;
|
||||
uint8_t IOCFG1;
|
||||
uint8_t IOCFG0;
|
||||
uint8_t FIFOTHR;
|
||||
uint8_t SYNC1;
|
||||
uint8_t SYNC0;
|
||||
uint8_t PKTLEN;
|
||||
uint8_t PKTCTRL1;
|
||||
uint8_t PKTCTRL0;
|
||||
uint8_t ADDR;
|
||||
uint8_t CHANNR;
|
||||
uint8_t FSCTRL1;
|
||||
uint8_t FSCTRL0;
|
||||
uint8_t FREQ2;
|
||||
uint8_t FREQ1;
|
||||
uint8_t FREQ0;
|
||||
uint8_t MDMCFG4;
|
||||
uint8_t MDMCFG3;
|
||||
uint8_t MDMCFG2;
|
||||
uint8_t MDMCFG1;
|
||||
uint8_t MDMCFG0;
|
||||
uint8_t DEVIATN;
|
||||
uint8_t MCSM2;
|
||||
uint8_t MCSM1;
|
||||
uint8_t MCSM0;
|
||||
uint8_t FOCCFG;
|
||||
uint8_t BSCFG;
|
||||
uint8_t AGCCTRL2;
|
||||
uint8_t AGCCTRL1;
|
||||
uint8_t AGCCTRL0;
|
||||
uint8_t WOREVT1;
|
||||
uint8_t WOREVT0;
|
||||
uint8_t WORCTRL;
|
||||
uint8_t FREND1;
|
||||
uint8_t FREND0;
|
||||
uint8_t FSCAL3;
|
||||
uint8_t FSCAL2;
|
||||
uint8_t FSCAL1;
|
||||
uint8_t FSCAL0;
|
||||
} cc1100_reg_t;
|
||||
|
||||
/** CC1100 radio configuration */
|
||||
typedef struct {
|
||||
cc1100_reg_t reg_cfg; ///< CC1100 register configuration
|
||||
uint8_t pa_power; ///< Output power setting
|
||||
} cc1100_cfg_t;
|
||||
|
||||
/**
|
||||
* @brief Radio Control Flags
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t TOF; ///< Time of flight of the last packet and last ACK
|
||||
uint32_t TCP; ///< Time to compute packet
|
||||
unsigned RPS : 16; ///< Raw packets sent to transmit last packet
|
||||
unsigned RTC : 8; ///< Retransmission count of last send packet
|
||||
unsigned RSSI : 8; ///< The RSSI value of last received packet
|
||||
unsigned RSSI_SEND : 8; ///< The RSSI value of the last send unicast packet of this node
|
||||
unsigned LQI : 8; ///< The LQI value of the last received packet
|
||||
unsigned LL_ACK : 1; ///< Is set if Link-Level ACK is received, otherwise 0 (reset on new burst)
|
||||
unsigned CAA : 1; ///< The status of the air (1 = air free, 0 = air not free)
|
||||
unsigned CRC : 1; ///< The CRC status of last received packet (1 = OK, 0 = not OK)
|
||||
unsigned SEQ : 1; ///< Sequence number (toggles between 0 and 1)
|
||||
unsigned MAN_WOR : 1; ///< Manual WOR set (for randomized WOR times => no synch)
|
||||
unsigned KT_RES_ERR : 1; ///< A hwtimer resource error has occurred (no free timers available)
|
||||
unsigned TX : 1; ///< State machine TX lock, only ACKs will be received
|
||||
unsigned WOR_RST : 1; ///< Reset CC1100 real time clock (WOR) on next WOR strobe
|
||||
} cc1100_flags;
|
||||
|
||||
/**
|
||||
* @brief Statistic interface for debugging
|
||||
*/
|
||||
typedef struct cc1100_statistic {
|
||||
uint32_t packets_in;
|
||||
uint32_t packets_in_crc_fail;
|
||||
uint32_t packets_in_while_tx;
|
||||
uint32_t packets_in_dups;
|
||||
uint32_t packets_in_up;
|
||||
uint32_t packets_out;
|
||||
uint32_t packets_out_acked;
|
||||
uint32_t packets_out_broadcast;
|
||||
uint32_t raw_packets_out;
|
||||
uint32_t raw_packets_out_acked;
|
||||
uint32_t acks_send;
|
||||
uint32_t rx_buffer_max;
|
||||
uint32_t watch_dog_resets;
|
||||
} cc1100_statistic_t;
|
||||
|
||||
#endif
|
||||
141
drivers/cc110x_ng/cc1100-defaultSettings.c
Normal file
141
drivers/cc110x_ng/cc1100-defaultSettings.c
Normal file
@ -0,0 +1,141 @@
|
||||
/******************************************************************************
|
||||
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of FeuerWare.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* @ingroup dev_cc110x
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief TI Chipcon CC110x default settings
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
|
||||
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
|
||||
* @author Heiko Will <hwill@inf.fu-berlin.de>
|
||||
* @version $Revision: 2058 $
|
||||
*
|
||||
* @note $Id: cc1100-defaultSettings.c 2058 2010-03-31 08:59:31Z hillebra $
|
||||
*/
|
||||
|
||||
#include <cc1100-defaultSettings.h>
|
||||
|
||||
/**
|
||||
* Usable, non overlapping channels and corresponding frequencies
|
||||
* for use with CC1100. CHANNR is the register for selecting a channel.
|
||||
*
|
||||
* channel number | CHANNR | frequency [MHz]
|
||||
* -----------------------------------------
|
||||
* 0 | 0 | 869.525
|
||||
* 1 | 10 | 871.61
|
||||
* 2 | 20 | 873.58 ~ seems to be bad (hang-ups with this channel)
|
||||
* 3 | 30 | 875.61
|
||||
* 4 | 40 | 877.58
|
||||
* 5 | 50 | 879.61
|
||||
* 6 | 60 | 881.58
|
||||
* 7 | 70 | 883.61
|
||||
* 8 | 80 | 885.58
|
||||
* 9 | 90 | 887.61
|
||||
* 10 | 100 | 889.58
|
||||
* 11 | 110 | 891.57
|
||||
* 12 | 120 | 893.58
|
||||
* 13 | 130 | 895.61
|
||||
* 14 | 140 | 897.58
|
||||
* 15 | 150 | 899.57
|
||||
* 16 | 160 | 901.57
|
||||
* 17 | 170 | 903.61
|
||||
* 18 | 180 | 905.57
|
||||
* 19 | 190 | 907.57
|
||||
* 20 | 200 | 909.57
|
||||
* 21 | 210 | 911.57
|
||||
* 22 | 220 | 913.57
|
||||
* 23 | 230 | 915.61
|
||||
* 24 | 240 | 917.61
|
||||
*/
|
||||
|
||||
// 400 kbps, MSK, X-tal: 26 MHz (Chip Revision F)
|
||||
char cc1100_conf[] = {
|
||||
0x06, // IOCFG2
|
||||
0x2E, // IOCFG1
|
||||
0x0E, // IOCFG0
|
||||
0x0F, // FIFOTHR
|
||||
0x9B, // SYNC1
|
||||
0xAD, // SYNC0
|
||||
0x3D, // PKTLEN (maximum value of packet length byte = 61)
|
||||
0x06, // PKTCTRL1
|
||||
0x45, // PKTCTRL0 (variable packet length)
|
||||
0xFF, // ADDR
|
||||
CC1100_DEFAULT_CHANNR*10, // CHANNR
|
||||
0x0B, // FSCTRL1
|
||||
0x00, // FSCTRL0
|
||||
0x21, // FREQ2
|
||||
0x71, // FREQ1
|
||||
0x7A, // FREQ0
|
||||
0x2D, // MDMCFG4
|
||||
0xF8, // MDMCFG3
|
||||
0x73, // MDMCFG2
|
||||
0x42, // MDMCFG1
|
||||
0xF8, // MDMCFG0
|
||||
0x00, // DEVIATN
|
||||
0x07, // MCSM2
|
||||
0x03, // MCSM1
|
||||
0x18, // MCSM0
|
||||
0x1D, // FOCCFG
|
||||
0x1C, // BSCFG
|
||||
0xC0, // AGCCTRL2
|
||||
0x49, // AGCCTRL1, (old value was 0x49 -> made carrier sense less sensitive!)
|
||||
// 0x47 - 7 dB above MAGN_TARGET setting
|
||||
0xB2, // AGCCTRL0
|
||||
0x87, // WOREVT1
|
||||
0x6B, // WOREVT0
|
||||
0xF8, // WORCTRL
|
||||
0xB6, // FREND1
|
||||
0x10, // FREND0
|
||||
0xEA, // FSCAL3
|
||||
0x2A, // FSCAL2
|
||||
0x00, // FSCAL1
|
||||
0x1F, // FSCAL0
|
||||
0x00 // padding to 4 bytes
|
||||
};
|
||||
|
||||
uint8_t pa_table_index = PATABLE; ///< Current PATABLE Index
|
||||
uint8_t pa_table[] = { ///< PATABLE with available output powers
|
||||
0x00, ///< -52 dBm
|
||||
0x03, ///< -30 dBm
|
||||
0x0D, ///< -20 dBm
|
||||
0x1C, ///< -15 dBm
|
||||
0x34, ///< -10 dBm
|
||||
0x57, ///< - 5 dBm
|
||||
0x3F, ///< - 1 dBm
|
||||
0x8E, ///< 0 dBm
|
||||
0x85, ///< + 5 dBm
|
||||
0xCC, ///< + 7 dBm
|
||||
0xC6, ///< + 9 dBm
|
||||
0xC3 ///< +10 dBm
|
||||
}; // If PATABLE is changed in size, adjust MAX_OUTPUT_POWER definition in CC1100 interface!
|
||||
|
||||
|
||||
/** @} */
|
||||
110
drivers/cc110x_ng/cc1100-defaultSettings.h
Normal file
110
drivers/cc110x_ng/cc1100-defaultSettings.h
Normal file
@ -0,0 +1,110 @@
|
||||
/******************************************************************************
|
||||
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of FeuerWare.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef CC1100_DEFAULTSETTINGS_H
|
||||
#define CC1100_DEFAULTSETTINGS_H
|
||||
|
||||
/**
|
||||
* @ingroup dev_cc110x
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief TI Chipcon CC110x default settings
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
|
||||
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
|
||||
* @author Heiko Will <hwill@inf.fu-berlin.de>
|
||||
* @version $Revision: 2139 $
|
||||
*
|
||||
* @note $Id: cc1100-defaultSettings.h 2139 2010-05-26 08:04:04Z hillebra $
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// returns hwtimer ticks per us
|
||||
#define RTIMER_TICKS(us) HWTIMER_TICKS(us)
|
||||
|
||||
#define TIMER_TICK_USEC_RES (122)
|
||||
|
||||
// Default PA table index (output power)
|
||||
#define PATABLE (11)
|
||||
|
||||
// Watchdog cycle time in seconds, set 0 to disable watchdog
|
||||
#define CC1100_WATCHDOG_PERIOD (5)
|
||||
|
||||
// Number of transmission retries for unicast packets (constant RX mode)
|
||||
#define TRANSMISSION_RETRIES_CRX_UC (5)
|
||||
|
||||
// Number of transmission retries for unicast packets (WOR mode)
|
||||
#define TRANSMISSION_RETRIES_WOR_UC (1)
|
||||
|
||||
// Number of transmission retries for broadcast packets (constant RX mode)
|
||||
#define TRANSMISSION_RETRIES_CRX_BC (0)
|
||||
|
||||
// Number of transmission retries for broadcast packets (WOR mode)
|
||||
#define TRANSMISSION_RETRIES_WOR_BC (0)
|
||||
|
||||
// Time before chip goes back to RX (= stays in PWD after incoming packet)
|
||||
#define WOR_TIMEOUT_1 (3200) // ~ 32 milliseconds
|
||||
|
||||
// Time before chip goes back to WOR (= stays in RX after elapsed WOR_TIMEOUT_1)
|
||||
#define WOR_TIMEOUT_2 (800) // ~ 8 milliseconds
|
||||
|
||||
// XOSC startup + FS calibration (300 + 809 us ~ 1.38 ms)
|
||||
#define FS_CAL_TIME RTIMER_TICKS(12 * TIMER_TICK_USEC_RES)
|
||||
|
||||
// Manual FS calibration (721 us)
|
||||
#define MANUAL_FS_CAL_TIME RTIMER_TICKS(7 * TIMER_TICK_USEC_RES)
|
||||
|
||||
// Reset wait time (in reset procedure)
|
||||
#define RESET_WAIT_TIME RTIMER_TICKS(4 * TIMER_TICK_USEC_RES)
|
||||
|
||||
// Time chip needs to go to RX
|
||||
#define IDLE_TO_RX_TIME RTIMER_TICKS(1 * TIMER_TICK_USEC_RES)
|
||||
|
||||
// Time chip needs to go to RX and CS signal is ready
|
||||
#define CS_READY_TIME RTIMER_TICKS(3 * TIMER_TICK_USEC_RES)
|
||||
|
||||
// Default RX interval for WOR in milliseconds
|
||||
#define T_RX_INTERVAL (542)
|
||||
|
||||
// Time of packet interval in microseconds (at 400 kbps)
|
||||
#define T_PACKET_INTERVAL (3800)
|
||||
|
||||
// The size of the configuration array for CC1100 in bytes
|
||||
#define CC1100_CONF_SIZE (39)
|
||||
|
||||
// The default channel number (0-24) for CC1100
|
||||
#define CC1100_DEFAULT_CHANNR (0)
|
||||
|
||||
// Burst retry to TX switch time (measured ~ 230 us)
|
||||
#define BURST_RETRY_TX_SWITCH_TIME (23)
|
||||
|
||||
|
||||
/** @} */
|
||||
#endif
|
||||
218
drivers/cc110x_ng/cc1100-internal.h
Normal file
218
drivers/cc110x_ng/cc1100-internal.h
Normal file
@ -0,0 +1,218 @@
|
||||
/******************************************************************************
|
||||
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of FeuerWare.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef CC1100_INTERNAL_H
|
||||
#define CC1100_INTERNAL_H
|
||||
|
||||
/**
|
||||
* @ingroup dev_cc110x
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @internal
|
||||
* @brief TI Chipcon CC110x internal hardware constants
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
|
||||
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
|
||||
* @author Heiko Will <hwill@inf.fu-berlin.de>
|
||||
* @version $Revision: 1231 $
|
||||
*
|
||||
* @note $Id: cc1100-internal.h 1231 2009-08-20 08:31:32Z baar $
|
||||
*/
|
||||
|
||||
#define FIXED_PKTLEN (0x00) ///< Fixed length packets, length configured in PKTLEN register.
|
||||
#define VARIABLE_PKTLEN (0x01) ///< Variable length packets, packet length configured by the first
|
||||
///< byte after synch word.
|
||||
|
||||
/**
|
||||
* @name Bitmasks for reading out status register values
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Bitmask (=10000000) for reading CRC_OK.
|
||||
*
|
||||
* If CRC_OK == 1: CRC for received data OK (or CRC disabled).
|
||||
* If CRC_OK == 0: CRC error in received data.
|
||||
*/
|
||||
#define CRC_OK (0x80)
|
||||
/**
|
||||
* @brief Bitmask (=01111111) for reading LQI_EST.
|
||||
*
|
||||
* The Link Quality Indicator estimates how easily a received signal can be demodulated.
|
||||
*/
|
||||
#define LQI_EST (0x7F)
|
||||
#define I_RSSI (0x00) ///< Index 0 contains RSSI information (from optionally appended packet status bytes).
|
||||
#define I_LQI (0x01) ///< Index 1 contains LQI & CRC_OK information (from optionally appended packet status bytes).
|
||||
#define MARC_STATE (0x1F) ///< Bitmask (=00011111) for reading MARC_STATE in MARCSTATE status register.
|
||||
#define CS (0x40) ///< Bitmask (=01000000) for reading CS (Carrier Sense) in PKTSTATUS status register.
|
||||
#define PQT_REACHED (0x20) ///< Bitmask (=00100000) for reading PQT_REACHED (Preamble Quality reached) in PKTSTATUS status register.
|
||||
#define CCA (0x10) ///< Bitmask (=00010000) for reading CCA (clear channel assessment) in PKTSTATUS status register.
|
||||
#define SFD (0x08) ///< Bitmask (=00001000) for reading SFD (Sync word found) in PKTSTATUS status register.
|
||||
#define GDO2 (0x04) ///< Bitmask (=00000100) for reading GDO2 (current value on GDO2 pin) in PKTSTATUS status register.
|
||||
#define GDO1 (0x02) ///< Bitmask (=00000010) for reading GDO1 (current value on GDO1 pin) in PKTSTATUS status register.
|
||||
#define GDO0 (0x01) ///< Bitmask (=00000001) for reading GDO0 (current value on GDO0 pin) in PKTSTATUS status register.
|
||||
#define TXFIFO_UNDERFLOW (0x80) ///< Bitmask (=10000000) for reading TXFIFO_UNDERFLOW in TXBYTES status register.
|
||||
#define BYTES_IN_TXFIFO (0x7F) ///< Bitmask (=01111111) for reading NUM_TXBYTES in TXBYTES status register.
|
||||
#define RXFIFO_OVERFLOW (0xBF) ///< Bitmask (=10000000) for reading RXFIFO_OVERFLOW in RXBYTES status register.
|
||||
#define BYTES_IN_RXFIFO (0xFF) ///< Bitmask (=01111111) for reading NUM_RXBYTES in RXBYTES status register.
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Bitmasks for reading out configuration register values
|
||||
* @{
|
||||
*/
|
||||
#define PKT_LENGTH_CONFIG (0x03) ///< Bitmask (=00000011) for reading LENGTH_CONFIG in PKTCTRL0 configuration register.
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Definitions to support burst/single access
|
||||
* @{
|
||||
*/
|
||||
#define CC1100_WRITE_BURST (0x40) ///< Offset for burst write.
|
||||
#define CC1100_READ_SINGLE (0x80) ///< Offset for read single byte.
|
||||
#define CC1100_READ_BURST (0xC0) ///< Offset for read burst.
|
||||
#define CC1100_NOBYTE (0x00) ///< No command (for reading).
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Configuration Registers (47x)
|
||||
* @{
|
||||
*/
|
||||
#define CC1100_IOCFG2 (0x00) ///< GDO2 output pin configuration
|
||||
#define CC1100_IOCFG1 (0x01) ///< GDO1 output pin configuration
|
||||
#define CC1100_IOCFG0 (0x02) ///< GDO0 output pin configuration
|
||||
#define CC1100_FIFOTHR (0x03) ///< RX FIFO and TX FIFO thresholds
|
||||
#define CC1100_SYNC1 (0x04) ///< Sync word, high byte
|
||||
#define CC1100_SYNC0 (0x05) ///< Sync word, low byte
|
||||
#define CC1100_PKTLEN (0x06) ///< Packet length
|
||||
#define CC1100_PKTCTRL1 (0x07) ///< Packet automation control
|
||||
#define CC1100_PKTCTRL0 (0x08) ///< Packet automation control
|
||||
#define CC1100_ADDR (0x09) ///< Device address
|
||||
#define CC1100_CHANNR (0x0A) ///< Channel number
|
||||
#define CC1100_FSCTRL1 (0x0B) ///< Frequency synthesizer control
|
||||
#define CC1100_FSCTRL0 (0x0C) ///< Frequency synthesizer control
|
||||
#define CC1100_FREQ2 (0x0D) ///< Frequency control word, high byte
|
||||
#define CC1100_FREQ1 (0x0E) ///< Frequency control word, middle byte
|
||||
#define CC1100_FREQ0 (0x0F) ///< Frequency control word, low byte
|
||||
#define CC1100_MDMCFG4 (0x10) ///< Modem configuration
|
||||
#define CC1100_MDMCFG3 (0x11) ///< Modem configuration
|
||||
#define CC1100_MDMCFG2 (0x12) ///< Modem configuration
|
||||
#define CC1100_MDMCFG1 (0x13) ///< Modem configuration
|
||||
#define CC1100_MDMCFG0 (0x14) ///< Modem configuration
|
||||
#define CC1100_DEVIATN (0x15) ///< Modem deviation setting
|
||||
#define CC1100_MCSM2 (0x16) ///< Main Radio Control State Machine configuration
|
||||
#define CC1100_MCSM1 (0x17) ///< Main Radio Control State Machine configuration
|
||||
#define CC1100_MCSM0 (0x18) ///< Main Radio Control State Machine configuration
|
||||
#define CC1100_FOCCFG (0x19) ///< Frequency Offset Compensation configuration
|
||||
#define CC1100_BSCFG (0x1A) ///< Bit Synchronization configuration
|
||||
#define CC1100_AGCCTRL2 (0x1B) ///< AGC control
|
||||
#define CC1100_AGCCTRL1 (0x1C) ///< AGC control
|
||||
#define CC1100_AGCCTRL0 (0x1D) ///< AGC control
|
||||
#define CC1100_WOREVT1 (0x1E) ///< High byte Event 0 timeout
|
||||
#define CC1100_WOREVT0 (0x1F) ///< Low byte Event 0 timeout
|
||||
#define CC1100_WORCTRL (0x20) ///< Wake On Radio control
|
||||
#define CC1100_FREND1 (0x21) ///< Front end RX configuration
|
||||
#define CC1100_FREND0 (0x22) ///< Front end TX configuration
|
||||
#define CC1100_FSCAL3 (0x23) ///< Frequency synthesizer calibration
|
||||
#define CC1100_FSCAL2 (0x24) ///< Frequency synthesizer calibration
|
||||
#define CC1100_FSCAL1 (0x25) ///< Frequency synthesizer calibration
|
||||
#define CC1100_FSCAL0 (0x26) ///< Frequency synthesizer calibration
|
||||
#define CC1100_RCCTRL1 (0x27) ///< RC oscillator configuration
|
||||
#define CC1100_RCCTRL0 (0x28) ///< RC oscillator configuration
|
||||
#define CC1100_FSTEST (0x29) ///< Frequency synthesizer calibration control
|
||||
#define CC1100_PTEST (0x2A) ///< Production test
|
||||
#define CC1100_AGCTEST (0x2B) ///< AGC test
|
||||
#define CC1100_TEST2 (0x2C) ///< Various test settings
|
||||
#define CC1100_TEST1 (0x2D) ///< Various test settings
|
||||
#define CC1100_TEST0 (0x2E) ///< Various test settings
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Strobe commands (14x)
|
||||
* @{
|
||||
*/
|
||||
#define CC1100_SRES (0x30) ///< Reset chip.
|
||||
/**
|
||||
* @brief Enable and calibrate frequency synthesizer (if MCSM0.FS_AUTOCAL=1).
|
||||
*
|
||||
* If in RX/TX: Go to a wait state where only the synthesizer is running (for quick RX / TX turnaround).
|
||||
*/
|
||||
#define CC1100_SFSTXON (0x31)
|
||||
#define CC1100_SXOFF (0x32) ///< Turn off crystal oscillator.
|
||||
#define CC1100_SCAL (0x33) ///< Calibrate frequency synthesizer and turn it off (enables quick start).
|
||||
#define CC1100_SRX (0x34) ///< Enable RX. Perform calibration first if coming from IDLE and MCSM0.FS_AUTOCAL=1.
|
||||
/**
|
||||
* In IDLE state: Enable TX. Perform calibration first if MCSM0.FS_AUTOCAL=1.
|
||||
* If in RX state and CCA is enabled: Only go to TX if channel is clear.
|
||||
*/
|
||||
#define CC1100_STX (0x35)
|
||||
#define CC1100_SIDLE (0x36) ///< Exit RX / TX, turn off frequency synthesizer and exit WOR mode if applicable.
|
||||
#define CC1100_SAFC (0x37) ///< Perform AFC adjustment of the frequency synthesizer
|
||||
#define CC1100_SWOR (0x38) ///< Start automatic RX polling sequence (Wake-on-Radio)
|
||||
#define CC1100_SPWD (0x39) ///< Enter power down mode when CSn goes high.
|
||||
#define CC1100_SFRX (0x3A) ///< Flush the RX FIFO buffer (CC1100 should be in IDLE state).
|
||||
#define CC1100_SFTX (0x3B) ///< Flush the TX FIFO buffer (CC1100 should be in IDLE state).
|
||||
#define CC1100_SWORRST (0x3C) ///< Reset real time clock.
|
||||
#define CC1100_SNOP (0x3D) ///< No operation. May be used to pad strobe commands to two bytes for simpler software.
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Status registers (12x)
|
||||
* @{
|
||||
*/
|
||||
#define CC1100_PARTNUM (0x30) ///< Part number of CC1100.
|
||||
#define CC1100_VERSION (0x31) ///< Current version number.
|
||||
#define CC1100_FREQEST (0x32) ///< Frequency Offset Estimate.
|
||||
#define CC1100_LQI (0x33) ///< Demodulator estimate for Link Quality.
|
||||
#define CC1100_RSSI (0x34) ///< Received signal strength indication.
|
||||
#define CC1100_MARCSTATE (0x35) ///< Control state machine state.
|
||||
#define CC1100_WORTIME1 (0x36) ///< High byte of WOR timer.
|
||||
#define CC1100_WORTIME0 (0x37) ///< Low byte of WOR timer.
|
||||
#define CC1100_PKTSTATUS (0x38) ///< Current GDOx status and packet status.
|
||||
#define CC1100_VCO_VC_DAC (0x39) ///< Current setting from PLL calibration module.
|
||||
#define CC1100_TXBYTES (0x3A) ///< Underflow and number of bytes in the TX FIFO.
|
||||
#define CC1100_RXBYTES (0x3B) ///< Overflow and number of bytes in the RX FIFO.
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Multi byte registers
|
||||
* @{
|
||||
*/
|
||||
/**
|
||||
* @brief Register for eight user selected output power settings.
|
||||
*
|
||||
* 3-bit FREND0.PA_POWER value selects the PATABLE entry to use.
|
||||
*/
|
||||
#define CC1100_PATABLE (0x3E)
|
||||
#define CC1100_TXFIFO (0x3F) ///< TX FIFO: Write operations write to the TX FIFO (SB: +0x00; BURST: +0x40)
|
||||
#define CC1100_RXFIFO (0x3F) ///< RX FIFO: Read operations read from the RX FIFO (SB: +0x80; BURST: +0xC0)
|
||||
|
||||
/** @} */
|
||||
|
||||
#endif
|
||||
153
drivers/cc110x_ng/cc1100-rx.c
Normal file
153
drivers/cc110x_ng/cc1100-rx.c
Normal file
@ -0,0 +1,153 @@
|
||||
#include <cc1100_ng.h>
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100-config.h>
|
||||
#include <cc1100-defaultSettings.h>
|
||||
#include <cc1100_spi.h>
|
||||
|
||||
#include <hwtimer.h>
|
||||
#include <msg.h>
|
||||
#include <transceiver.h>
|
||||
|
||||
#include <board.h>
|
||||
|
||||
static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length);
|
||||
static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length);
|
||||
|
||||
rx_buffer_t cc1100_rx_buffer[RX_BUF_SIZE]; ///< RX buffer
|
||||
volatile uint8_t rx_buffer_next; ///< Next packet in RX queue
|
||||
|
||||
void cc1100_rx_handler(void) {
|
||||
uint8_t res = 0;
|
||||
|
||||
// Possible packet received, RX -> IDLE (0.1 us)
|
||||
rflags.CAA = 0;
|
||||
rflags.MAN_WOR = 0;
|
||||
cc1100_statistic.packets_in++;
|
||||
|
||||
res = receive_packet((uint8_t*)&(cc1100_rx_buffer[rx_buffer_next].packet), sizeof(cc1100_packet_t));
|
||||
if (res) {
|
||||
// If we are sending a burst, don't accept packets.
|
||||
// Only ACKs are processed (for stopping the burst).
|
||||
// Same if state machine is in TX lock.
|
||||
if (radio_state == RADIO_SEND_BURST || rflags.TX)
|
||||
{
|
||||
cc1100_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
cc1100_rx_buffer[rx_buffer_next].rssi = rflags.RSSI;
|
||||
cc1100_rx_buffer[rx_buffer_next].lqi = rflags.LQI;
|
||||
|
||||
// Valid packet. After a wake-up, the radio should be in IDLE.
|
||||
// So put CC1100 to RX for WOR_TIMEOUT (have to manually put
|
||||
// the radio back to sleep/WOR).
|
||||
//cc1100_spi_write_reg(CC1100_MCSM0, 0x08); // Turn off FS-Autocal
|
||||
cc1100_spi_write_reg(CC1100_MCSM2, 0x07); // Configure RX_TIME (until end of packet)
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
radio_state = RADIO_RX;
|
||||
|
||||
/* notify transceiver thread if any */
|
||||
if (transceiver_pid) {
|
||||
msg m;
|
||||
m.type = (uint16_t) RCV_PKT_CC1100;
|
||||
m.content.value = rx_buffer_next;
|
||||
msg_send_int(&m, transceiver_pid);
|
||||
}
|
||||
|
||||
/* shift to next buffer element */
|
||||
if (++rx_buffer_next == RX_BUF_SIZE) {
|
||||
rx_buffer_next = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// No ACK received so TOF is unpredictable
|
||||
rflags.TOF = 0;
|
||||
|
||||
// CRC false or RX buffer full -> clear RX FIFO in both cases
|
||||
cc1100_spi_strobe(CC1100_SIDLE); // Switch to IDLE (should already be)...
|
||||
cc1100_spi_strobe(CC1100_SFRX); // ...for flushing the RX FIFO
|
||||
|
||||
// If packet interrupted this nodes send call,
|
||||
// don't change anything after this point.
|
||||
if (radio_state == RADIO_AIR_FREE_WAITING)
|
||||
{
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
hwtimer_wait(IDLE_TO_RX_TIME);
|
||||
return;
|
||||
}
|
||||
// If currently sending, exit here (don't go to RX/WOR)
|
||||
if (radio_state == RADIO_SEND_BURST)
|
||||
{
|
||||
cc1100_statistic.packets_in_while_tx++;
|
||||
return;
|
||||
}
|
||||
|
||||
// No valid packet, so go back to RX/WOR as soon as possible
|
||||
cc1100_switch_to_rx();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t receive_packet_variable(uint8_t *rxBuffer, uint8_t length) {
|
||||
uint8_t status[2];
|
||||
uint8_t packetLength = 0;
|
||||
|
||||
/* Any bytes available in RX FIFO? */
|
||||
if ((cc1100_spi_read_status(CC1100_RXBYTES) & BYTES_IN_RXFIFO)) {
|
||||
LED_GREEN_TOGGLE;
|
||||
// Read length byte (first byte in RX FIFO)
|
||||
packetLength = cc1100_spi_read_reg(CC1100_RXFIFO);
|
||||
// Read data from RX FIFO and store in rxBuffer
|
||||
if (packetLength <= length)
|
||||
{
|
||||
// Put length byte at first position in RX Buffer
|
||||
rxBuffer[0] = packetLength;
|
||||
|
||||
// Read the rest of the packet
|
||||
cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)rxBuffer+1, packetLength);
|
||||
|
||||
// Read the 2 appended status bytes (status[0] = RSSI, status[1] = LQI)
|
||||
cc1100_spi_readburst_reg(CC1100_RXFIFO, (char*)status, 2);
|
||||
|
||||
// Store RSSI value of packet
|
||||
rflags.RSSI = status[I_RSSI];
|
||||
|
||||
// MSB of LQI is the CRC_OK bit
|
||||
rflags.CRC = (status[I_LQI] & CRC_OK) >> 7;
|
||||
if (!rflags.CRC) {
|
||||
cc1100_statistic.packets_in_crc_fail++;
|
||||
}
|
||||
|
||||
// Bit 0-6 of LQI indicates the link quality (LQI)
|
||||
rflags.LQI = status[I_LQI] & LQI_EST;
|
||||
|
||||
return rflags.CRC;
|
||||
}
|
||||
/* too many bytes in FIFO */
|
||||
else {
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* no bytes in RX FIFO */
|
||||
else {
|
||||
LED_RED_TOGGLE;
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t receive_packet(uint8_t *rxBuffer, uint8_t length) {
|
||||
uint8_t pkt_len_cfg = cc1100_spi_read_reg(CC1100_PKTCTRL0) & PKT_LENGTH_CONFIG;
|
||||
if (pkt_len_cfg == VARIABLE_PKTLEN)
|
||||
{
|
||||
return receive_packet_variable(rxBuffer, length);
|
||||
}
|
||||
// Fixed packet length not supported.
|
||||
// RX FIFO get automatically flushed if return value is false
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
76
drivers/cc110x_ng/cc1100-tx.c
Normal file
76
drivers/cc110x_ng/cc1100-tx.c
Normal file
@ -0,0 +1,76 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cc1100_ng.h>
|
||||
#include <cc1100-defaultSettings.h>
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100-arch.h>
|
||||
#include <cc1100_spi.h>
|
||||
|
||||
#include <irq.h>
|
||||
|
||||
#include <board.h>
|
||||
|
||||
uint8_t cc1100_send(cc1100_packet_t *packet) {
|
||||
volatile uint32_t abort_count;
|
||||
uint8_t size;
|
||||
/* TODO: burst sending */
|
||||
radio_state = RADIO_SEND_BURST;
|
||||
rflags.LL_ACK = 0;
|
||||
|
||||
/*
|
||||
* Number of bytes to send is:
|
||||
* length of phy payload (packet->length)
|
||||
* + size of length field (1 byte)
|
||||
*/
|
||||
size = packet->length + 1;
|
||||
|
||||
// The number of bytes to be transmitted must be smaller
|
||||
// or equal to PACKET_LENGTH (62 bytes). So the receiver
|
||||
// can put the whole packet in its RX-FIFO (with appended
|
||||
// packet status bytes).
|
||||
if (size > PACKET_LENGTH) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
packet->phy_src = cc1100_get_address();
|
||||
|
||||
// Disables RX interrupt etc.
|
||||
cc1100_before_send();
|
||||
|
||||
// But CC1100 in IDLE mode to flush the FIFO
|
||||
cc1100_spi_strobe(CC1100_SIDLE);
|
||||
// Flush TX FIFO to be sure it is empty
|
||||
cc1100_spi_strobe(CC1100_SFTX);
|
||||
// Write packet into TX FIFO
|
||||
cc1100_spi_writeburst_reg(CC1100_TXFIFO, (char*) packet, size);
|
||||
// Switch to TX mode
|
||||
abort_count = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_strobe(CC1100_STX);
|
||||
// Wait for GDO2 to be set -> sync word transmitted
|
||||
while (cc1100_get_gdo2() == 0) {
|
||||
abort_count++;
|
||||
if (abort_count > CC1100_SYNC_WORD_TX_TIME) {
|
||||
// Abort waiting. CC1100 maybe in wrong mode
|
||||
// e.g. sending preambles for always
|
||||
puts("[CC1100 TX] fatal error\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
restoreIRQ(cpsr);
|
||||
// Wait for GDO2 to be cleared -> end of packet
|
||||
while (cc1100_get_gdo2() != 0);
|
||||
|
||||
// Experimental - TOF Measurement
|
||||
cc1100_after_send();
|
||||
cc1100_statistic.raw_packets_out++;
|
||||
|
||||
// Store number of transmission retries
|
||||
rflags.TX = 0;
|
||||
|
||||
// Go to mode after TX (CONST_RX -> RX, WOR -> WOR)
|
||||
cc1100_switch_to_rx();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
302
drivers/cc110x_ng/cc1100.c
Normal file
302
drivers/cc110x_ng/cc1100.c
Normal file
@ -0,0 +1,302 @@
|
||||
#include <cc1100_ng.h>
|
||||
#include <cc1100-arch.h>
|
||||
#include <cc1100-config.h>
|
||||
#include <cc1100-defaultSettings.h>
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100_spi.h>
|
||||
|
||||
#include <hwtimer.h>
|
||||
|
||||
//#define ENABLE_DEBUG (1)
|
||||
#include <debug.h>
|
||||
|
||||
/* some externals */
|
||||
extern uint8_t pa_table[]; ///< PATABLE with available output powers
|
||||
extern uint8_t pa_table_index; ///< Current PATABLE Index
|
||||
|
||||
/* global variables */
|
||||
|
||||
cc1100_statistic_t cc1100_statistic;
|
||||
|
||||
volatile cc1100_flags rflags; ///< Radio control flags
|
||||
volatile uint8_t radio_state = RADIO_UNKNOWN; ///< Radio state
|
||||
|
||||
static uint8_t radio_address; ///< Radio address
|
||||
static uint8_t radio_channel; ///< Radio channel
|
||||
|
||||
int transceiver_pid; ///< the transceiver thread pid
|
||||
|
||||
/* internal function prototypes */
|
||||
static int rd_set_mode(int mode);
|
||||
static void reset(void);
|
||||
static void power_up_reset(void);
|
||||
static void write_register(uint8_t r, uint8_t value);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// Radio Driver API
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void cc1100_init(int tpid) {
|
||||
transceiver_pid = tpid;
|
||||
DEBUG("Transceiver PID: %i\n", transceiver_pid);
|
||||
|
||||
rx_buffer_next = 0;
|
||||
|
||||
/* Initialize SPI */
|
||||
cc1100_spi_init();
|
||||
|
||||
/* Load driver & reset */
|
||||
power_up_reset();
|
||||
|
||||
/* Write configuration to configuration registers */
|
||||
cc1100_spi_writeburst_reg(0x00, cc1100_conf, CC1100_CONF_SIZE);
|
||||
|
||||
/* Write PATABLE (power settings) */
|
||||
cc1100_spi_write_reg(CC1100_PATABLE, pa_table[pa_table_index]);
|
||||
|
||||
/* Initialize Radio Flags */
|
||||
rflags.RSSI = 0x00;
|
||||
rflags.LL_ACK = 0;
|
||||
rflags.CAA = 0;
|
||||
rflags.CRC = 0;
|
||||
rflags.SEQ = 0;
|
||||
rflags.MAN_WOR = 0;
|
||||
rflags.KT_RES_ERR = 0;
|
||||
rflags.TX = 0;
|
||||
rflags.WOR_RST = 0;
|
||||
|
||||
/* Set default channel number */
|
||||
cc1100_set_channel(CC1100_DEFAULT_CHANNR);
|
||||
DEBUG("CC1100 initialized and set to channel %i\n", radio_channel);
|
||||
|
||||
// Switch to desired mode (WOR or RX)
|
||||
rd_set_mode(RADIO_MODE_ON);
|
||||
}
|
||||
|
||||
void cc1100_disable_interrupts(void) {
|
||||
cc1100_gdo2_disable();
|
||||
cc1100_gdo0_disable();
|
||||
}
|
||||
|
||||
void cc1100_gdo0_irq(void) {
|
||||
// Air was not free -> Clear CCA flag
|
||||
rflags.CAA = false;
|
||||
// Disable carrier sense detection (GDO0 interrupt)
|
||||
cc1100_gdo0_disable();
|
||||
}
|
||||
|
||||
void cc1100_gdo2_irq(void) {
|
||||
cc1100_rx_handler();
|
||||
}
|
||||
|
||||
uint8_t cc1100_get_buffer_pos(void) {
|
||||
return (rx_buffer_next-1);
|
||||
}
|
||||
|
||||
radio_address_t cc1100_get_address() {
|
||||
return radio_address;
|
||||
}
|
||||
|
||||
radio_address_t cc1100_set_address(radio_address_t address) {
|
||||
if ((address < MIN_UID) || (address > MAX_UID)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t id = (uint8_t) address;
|
||||
if (radio_state != RADIO_UNKNOWN) {
|
||||
write_register(CC1100_ADDR, id);
|
||||
}
|
||||
|
||||
radio_address = id;
|
||||
return radio_address;
|
||||
}
|
||||
|
||||
void cc1100_set_monitor(uint8_t mode) {
|
||||
if (mode) {
|
||||
write_register(CC1100_PKTCTRL1, (0x04));
|
||||
}
|
||||
else {
|
||||
write_register(CC1100_PKTCTRL1, (0x06));
|
||||
}
|
||||
}
|
||||
|
||||
void cc1100_setup_rx_mode(void) {
|
||||
// Stay in RX mode until end of packet
|
||||
cc1100_spi_write_reg(CC1100_MCSM2, 0x07);
|
||||
cc1100_switch_to_rx();
|
||||
}
|
||||
|
||||
void cc1100_switch_to_rx(void) {
|
||||
radio_state = RADIO_RX;
|
||||
cc1100_spi_strobe(CC1100_SRX);
|
||||
}
|
||||
|
||||
void cc1100_wakeup_from_rx(void) {
|
||||
if (radio_state != RADIO_RX) {
|
||||
return;
|
||||
}
|
||||
DEBUG("CC1100 going to idle\n");
|
||||
cc1100_spi_strobe(CC1100_SIDLE);
|
||||
radio_state = RADIO_IDLE;
|
||||
}
|
||||
|
||||
char* cc1100_get_marc_state(void) {
|
||||
uint8_t state;
|
||||
|
||||
// Save old radio state
|
||||
uint8_t old_state = radio_state;
|
||||
|
||||
// Read content of status register
|
||||
state = cc1100_spi_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
|
||||
// Make sure in IDLE state.
|
||||
// Only goes to IDLE if state was RX/WOR
|
||||
cc1100_wakeup_from_rx();
|
||||
|
||||
// Have to put radio back to WOR/RX if old radio state
|
||||
// was WOR/RX, otherwise no action is necessary
|
||||
if (old_state == RADIO_WOR || old_state == RADIO_RX) {
|
||||
cc1100_switch_to_rx();
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
// Note: it is not possible to read back the SLEEP or XOFF state numbers
|
||||
// because setting CSn low will make the chip enter the IDLE mode from the
|
||||
// SLEEP (0) or XOFF (2) states.
|
||||
case 1: return "IDLE";
|
||||
case 3: case 4: case 5: return "MANCAL";
|
||||
case 6: case 7: return "FS_WAKEUP";
|
||||
case 8: case 12: return "CALIBRATE";
|
||||
case 9: case 10: case 11: return "SETTLING";
|
||||
case 13: case 14: case 15: return "RX";
|
||||
case 16: return "TXRX_SETTLING";
|
||||
case 17: return "RXFIFO_OVERFLOW";
|
||||
case 18: return "FSTXON";
|
||||
case 19: case 20: return "TX";
|
||||
case 21: return "RXTX_SETTLING";
|
||||
case 22: return "TXFIFO_UNDERFLOW";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
char* cc1100_state_to_text(uint8_t state) {
|
||||
switch (state)
|
||||
{
|
||||
case RADIO_UNKNOWN:
|
||||
return "Unknown";
|
||||
case RADIO_AIR_FREE_WAITING:
|
||||
return "CS";
|
||||
case RADIO_WOR:
|
||||
return "WOR";
|
||||
case RADIO_IDLE:
|
||||
return "IDLE";
|
||||
case RADIO_SEND_BURST:
|
||||
return "TX BURST";
|
||||
case RADIO_RX:
|
||||
return "RX";
|
||||
case RADIO_SEND_ACK:
|
||||
return "TX ACK";
|
||||
case RADIO_PWD:
|
||||
return "PWD";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cc1100_print_config(void) {
|
||||
printf("Current radio state: %s\r\n", cc1100_state_to_text(radio_state));
|
||||
printf("Current MARC state: %s\r\n", cc1100_get_marc_state());
|
||||
printf("Current channel number: %u\r\n", radio_channel);
|
||||
}
|
||||
|
||||
void switch_to_pwd(void) {
|
||||
cc1100_wakeup_from_rx();
|
||||
cc1100_spi_strobe(CC1100_SPWD);
|
||||
radio_state = RADIO_PWD;
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int16_t cc1100_set_channel(uint8_t channr) {
|
||||
uint8_t state = cc1100_spi_read_status(CC1100_MARCSTATE) & MARC_STATE;
|
||||
if ((state != 1) && (channr > MAX_CHANNR)) {
|
||||
return 0;
|
||||
}
|
||||
write_register(CC1100_CHANNR, channr*10);
|
||||
radio_channel = channr;
|
||||
return radio_channel;
|
||||
}
|
||||
|
||||
int16_t cc1100_get_channel(void) {
|
||||
return radio_channel;
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// CC1100 reset functionality
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
static void reset(void) {
|
||||
cc1100_wakeup_from_rx();
|
||||
cc1100_spi_select();
|
||||
cc1100_spi_strobe(CC1100_SRES);
|
||||
hwtimer_wait(RTIMER_TICKS(10));
|
||||
}
|
||||
|
||||
static void power_up_reset(void) {
|
||||
cc1100_spi_unselect();
|
||||
cc1100_spi_cs();
|
||||
cc1100_spi_unselect();
|
||||
hwtimer_wait(RESET_WAIT_TIME);
|
||||
reset();
|
||||
radio_state = RADIO_IDLE;
|
||||
}
|
||||
|
||||
static void write_register(uint8_t r, uint8_t value) {
|
||||
// Save old radio state
|
||||
uint8_t old_state = radio_state;
|
||||
|
||||
/* Wake up from WOR/RX (if in WOR/RX, else no effect) */
|
||||
cc1100_wakeup_from_rx();
|
||||
cc1100_spi_write_reg(r, value);
|
||||
|
||||
// Have to put radio back to WOR/RX if old radio state
|
||||
// was WOR/RX, otherwise no action is necessary
|
||||
if ((old_state == RADIO_WOR) || (old_state == RADIO_RX)) {
|
||||
cc1100_switch_to_rx();
|
||||
}
|
||||
}
|
||||
|
||||
static int rd_set_mode(int mode) {
|
||||
int result;
|
||||
|
||||
// Get current radio mode
|
||||
if ((radio_state == RADIO_UNKNOWN) || (radio_state == RADIO_PWD)) {
|
||||
result = RADIO_MODE_OFF;
|
||||
}
|
||||
else {
|
||||
result = RADIO_MODE_ON;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case RADIO_MODE_ON:
|
||||
DEBUG("Enabling rx mode\n");
|
||||
cc1100_init_interrupts(); // Enable interrupts
|
||||
cc1100_setup_rx_mode(); // Set chip to desired mode
|
||||
break;
|
||||
case RADIO_MODE_OFF:
|
||||
cc1100_disable_interrupts(); // Disable interrupts
|
||||
cc1100_switch_to_pwd(); // Set chip to power down mode
|
||||
break;
|
||||
case RADIO_MODE_GET:
|
||||
// do nothing, just return current mode
|
||||
default:
|
||||
// do nothing
|
||||
break;
|
||||
}
|
||||
|
||||
// Return previous mode
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
122
drivers/cc110x_ng/cc1100_ng.h
Normal file
122
drivers/cc110x_ng/cc1100_ng.h
Normal file
@ -0,0 +1,122 @@
|
||||
#ifndef CC1100_H
|
||||
#define CC1100_H
|
||||
|
||||
#include <radio/radio.h>
|
||||
#include <radio/types.h>
|
||||
#include <stdint.h>
|
||||
#include <cc1100-config.h>
|
||||
|
||||
#define RX_BUF_SIZE (10)
|
||||
|
||||
#define CC1100_MAX_DATA_LENGTH (58)
|
||||
|
||||
#define CC1100_HEADER_LENGTH (3) ///< Header covers SRC, DST and FLAGS
|
||||
|
||||
#define CC1100_BROADCAST_ADDRESS (0x00) ///< CC1100 broadcast address
|
||||
|
||||
#define MAX_UID (0xFF) ///< Maximum UID of a node is 255
|
||||
#define MIN_UID (0x01) ///< Minimum UID of a node is 1
|
||||
|
||||
#define MIN_CHANNR (0) ///< Minimum channel number
|
||||
#define MAX_CHANNR (24) ///< Maximum channel number
|
||||
|
||||
#define MIN_OUTPUT_POWER (0) ///< Minimum output power value
|
||||
#define MAX_OUTPUT_POWER (11) ///< Maximum output power value
|
||||
|
||||
#define PACKET_LENGTH (0x3E) ///< Packet length = 62 Bytes.
|
||||
#define CC1100_SYNC_WORD_TX_TIME (90000) // loop count (max. timeout ~ 15 ms) to wait for
|
||||
// sync word to be transmitted (GDO2 from low to high)
|
||||
/**
|
||||
* @name Defines used as state values for state machine
|
||||
* @{
|
||||
*/
|
||||
#define RADIO_UNKNOWN (0)
|
||||
#define RADIO_AIR_FREE_WAITING (1)
|
||||
#define RADIO_WOR (2)
|
||||
#define RADIO_IDLE (3)
|
||||
#define RADIO_SEND_BURST (4)
|
||||
#define RADIO_RX (5)
|
||||
#define RADIO_SEND_ACK (6)
|
||||
#define RADIO_PWD (7)
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
extern volatile cc1100_flags rflags; ///< Radio flags
|
||||
extern char cc1100_conf[];
|
||||
|
||||
/**
|
||||
* @brief CC1100 layer 0 protocol
|
||||
*
|
||||
* <pre>
|
||||
---------------------------------------------------
|
||||
| | | | | |
|
||||
| Length | Address | PhySrc | Flags | Data |
|
||||
| | | | | |
|
||||
---------------------------------------------------
|
||||
1 byte 1 byte 1 byte 1 byte <= 58 bytes
|
||||
|
||||
Flags:
|
||||
Bit | Meaning
|
||||
--------------------
|
||||
7:4 | -
|
||||
3:1 | Protocol
|
||||
0 | Identification
|
||||
</pre>
|
||||
Notes:
|
||||
\li length & address are given by CC1100
|
||||
\li Identification is increased is used to scan duplicates. It must be increased
|
||||
for each new packet and kept for packet retransmissions.
|
||||
*/
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
uint8_t length; ///< Length of the packet (without length byte)
|
||||
uint8_t address; ///< Destination address
|
||||
uint8_t phy_src; ///< Source address (physical source)
|
||||
uint8_t flags; ///< Flags
|
||||
uint8_t data[CC1100_MAX_DATA_LENGTH]; ///< Data (high layer protocol)
|
||||
} cc1100_packet_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t rssi;
|
||||
uint8_t lqi;
|
||||
cc1100_packet_t packet;
|
||||
} rx_buffer_t;
|
||||
|
||||
enum radio_mode {
|
||||
RADIO_MODE_GET = -1, ///< leave mode unchanged
|
||||
RADIO_MODE_OFF = 0, ///< turn radio off
|
||||
RADIO_MODE_ON = 1 ///< turn radio on
|
||||
};
|
||||
|
||||
extern rx_buffer_t cc1100_rx_buffer[];
|
||||
|
||||
extern volatile uint8_t rx_buffer_next; ///< Next packet in RX queue
|
||||
|
||||
extern volatile uint8_t radio_state; ///< Radio state
|
||||
extern cc1100_statistic_t cc1100_statistic;
|
||||
|
||||
int transceiver_pid; ///< the transceiver thread pid
|
||||
|
||||
void cc1100_init(int transceiver_pid);
|
||||
|
||||
void cc1100_rx_handler(void);
|
||||
|
||||
uint8_t cc1100_send(cc1100_packet_t *pkt);
|
||||
|
||||
uint8_t cc1100_get_buffer_pos(void);
|
||||
|
||||
void cc1100_setup_rx_mode(void);
|
||||
void cc1100_switch_to_rx(void);
|
||||
void cc1100_wakeup_from_rx(void);
|
||||
void cc1100_switch_to_pwd(void);
|
||||
|
||||
void cc1100_disable_interrupts(void);
|
||||
int16_t cc1100_set_channel(uint8_t channr);
|
||||
int16_t cc1100_get_channel(void);
|
||||
|
||||
radio_address_t cc1100_set_address(radio_address_t addr);
|
||||
radio_address_t cc1100_get_address(void);
|
||||
void cc1100_set_monitor(uint8_t mode);
|
||||
|
||||
void cc1100_print_config(void);
|
||||
#endif
|
||||
128
drivers/cc110x_ng/cc1100_spi.c
Normal file
128
drivers/cc110x_ng/cc1100_spi.c
Normal file
@ -0,0 +1,128 @@
|
||||
/******************************************************************************
|
||||
Copyright 2010, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of µkleos.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
|
||||
/**
|
||||
* @ingroup dev_cc110x
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @internal
|
||||
* @brief TI Chipcon CC1100 SPI driver
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
|
||||
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
|
||||
* @author Heiko Will <hwill@inf.fu-berlin.de>
|
||||
* @version $Revision: 1775 $
|
||||
*
|
||||
* @note $Id: cc1100_spi.c 1775 2010-01-26 09:37:03Z hillebra $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <cc1100_ng.h>
|
||||
#include <cc1100-arch.h>
|
||||
#include <cc1100-internal.h>
|
||||
#include <cc1100_spi.h>
|
||||
|
||||
#include <irq.h>
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
// CC1100 SPI access
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#define NOBYTE 0xFF
|
||||
|
||||
uint8_t cc1100_spi_writeburst_reg(uint8_t addr, char *src, uint8_t count) {
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
cc1100_txrx(addr | CC1100_WRITE_BURST);
|
||||
while (i < count) {
|
||||
cc1100_txrx(src[i]);
|
||||
i++;
|
||||
}
|
||||
cc1100_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return count;
|
||||
}
|
||||
|
||||
void cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count) {
|
||||
int i = 0;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
cc1100_txrx(addr | CC1100_READ_BURST);
|
||||
while (i < count) {
|
||||
buffer[i] = cc1100_txrx(NOBYTE);
|
||||
i++;
|
||||
}
|
||||
cc1100_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
void cc1100_spi_write_reg(uint8_t addr, uint8_t value) {
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
cc1100_txrx(addr);
|
||||
cc1100_txrx(value);
|
||||
cc1100_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
}
|
||||
|
||||
uint8_t cc1100_spi_read_reg(uint8_t addr) {
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
cc1100_txrx(addr | CC1100_READ_SINGLE);
|
||||
result = cc1100_txrx(NOBYTE);
|
||||
cc1100_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t cc1100_spi_read_status(uint8_t addr) {
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
cc1100_txrx(addr | CC1100_READ_BURST);
|
||||
result = cc1100_txrx(NOBYTE);
|
||||
cc1100_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
}
|
||||
|
||||
uint8_t cc1100_spi_strobe(uint8_t c) {
|
||||
uint8_t result;
|
||||
unsigned int cpsr = disableIRQ();
|
||||
cc1100_spi_select();
|
||||
result = cc1100_txrx(c);
|
||||
cc1100_spi_unselect();
|
||||
restoreIRQ(cpsr);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
64
drivers/cc110x_ng/cc1100_spi.h
Normal file
64
drivers/cc110x_ng/cc1100_spi.h
Normal file
@ -0,0 +1,64 @@
|
||||
/******************************************************************************
|
||||
Copyright 2008, Freie Universitaet Berlin (FUB). All rights reserved.
|
||||
|
||||
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
||||
and Telematics group (http://cst.mi.fu-berlin.de).
|
||||
-------------------------------------------------------------------------------
|
||||
This file is part of FeuerWare.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
Foundation, either version 3 of the License, or (at your option) any later
|
||||
version.
|
||||
|
||||
FeuerWare is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along with
|
||||
this program. If not, see http://www.gnu.org/licenses/ .
|
||||
--------------------------------------------------------------------------------
|
||||
For further information and questions please use the web site
|
||||
http://scatterweb.mi.fu-berlin.de
|
||||
and the mailinglist (subscription via web site)
|
||||
scatterweb@lists.spline.inf.fu-berlin.de
|
||||
*******************************************************************************/
|
||||
/**
|
||||
* @ingroup dev_cc110x
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @internal
|
||||
* @brief TI Chipcon CC1100 SPI driver
|
||||
*
|
||||
* @author Freie Universität Berlin, Computer Systems & Telematics, FeuerWhere project
|
||||
* @author Thomas Hillebrandt <hillebra@inf.fu-berlin.de>
|
||||
* @author Heiko Will <hwill@inf.fu-berlin.de>
|
||||
* @version $Revision: 1775 $
|
||||
*
|
||||
* @note $Id: cc1100_spi.h 1775 2010-01-26 09:37:03Z hillebra $
|
||||
*/
|
||||
|
||||
#ifndef CC1100_SPI_H_
|
||||
#define CC1100_SPI_H_
|
||||
|
||||
int cc1100_get_gdo0(void);
|
||||
int cc1100_get_gdo1(void);
|
||||
int cc1100_get_gdo2(void);
|
||||
|
||||
void cc1100_spi_init(void);
|
||||
void cc1100_spi_cs(void);
|
||||
void cc1100_spi_select(void);
|
||||
void cc1100_spi_unselect(void);
|
||||
|
||||
uint8_t cc1100_spi_writeburst_reg(uint8_t addr, char *buffer, uint8_t count);
|
||||
void cc1100_spi_readburst_reg(uint8_t addr, char *buffer, uint8_t count);
|
||||
void cc1100_spi_write_reg(uint8_t addr, uint8_t value);
|
||||
uint8_t cc1100_spi_read_reg(uint8_t addr);
|
||||
uint8_t cc1100_spi_read_status(uint8_t addr);
|
||||
uint8_t cc1100_spi_strobe(uint8_t c);
|
||||
|
||||
/** @} */
|
||||
#endif /* CC1100_SPI_H_ */
|
||||
@ -8,7 +8,8 @@ void ltc4150_start();
|
||||
void ltc4150_stop();
|
||||
|
||||
double ltc4150_get_current_mA();
|
||||
double ltc4150_get_total_mA();
|
||||
double ltc4150_get_total_mAh();
|
||||
double ltc4150_get_avg_mA();
|
||||
int ltc4150_get_interval();
|
||||
|
||||
#endif /* __LTC4150_H */
|
||||
|
||||
@ -40,6 +40,7 @@ and the mailinglist (subscription via web site)
|
||||
*
|
||||
* @note $Id: sht11.h 667 2009-02-19 15:06:38Z baar $
|
||||
*/
|
||||
#include <stdint.h>
|
||||
|
||||
#define SHT11_NO_ACK (0)
|
||||
#define SHT11_ACK (1)
|
||||
@ -50,17 +51,21 @@ and the mailinglist (subscription via web site)
|
||||
#define SHT11_MEASURE_HUMI (0x05) //000 0010 1
|
||||
#define SHT11_RESET (0x1E) //000 1111 0
|
||||
|
||||
/* time to wait after toggling the data line */
|
||||
#define SHT11_DATA_WAIT (HWTIMER_TICKS(1))
|
||||
/* time to wait after toggling the clock line */
|
||||
#define SHT11_CLK_WAIT (HWTIMER_TICKS(1))
|
||||
|
||||
/* set measurement timeout to 1 second */
|
||||
#define SHT11_MEASURE_TIMEOUT (1000)
|
||||
|
||||
/** sht11 measureable data */
|
||||
/**
|
||||
* @brief sht11 measureable data
|
||||
*/
|
||||
typedef struct {
|
||||
/* temperature value */
|
||||
float temperature;
|
||||
/* linear relative humidity */
|
||||
float relhum;
|
||||
/* temperature compensated relative humidity */
|
||||
float relhum_temp;
|
||||
float temperature; /**< temperature value */
|
||||
float relhum; /**< linear relative humidity */
|
||||
float relhum_temp; /**< temperature compensated relative humidity */
|
||||
} sht11_val_t;
|
||||
|
||||
/**
|
||||
@ -79,9 +84,14 @@ void sht11_init(void);
|
||||
/**
|
||||
* @brief Read sensor
|
||||
*
|
||||
* @param value The struct to be filled with measured values
|
||||
* @param mode Specifies type of data to be read
|
||||
*
|
||||
* @return 1 on success, 0 otherwise
|
||||
*
|
||||
* Example:
|
||||
* \code struct sht11_val sht11;
|
||||
* sht11_Read_Sensor(&sht11, HUMIDITY|TEMPERATURE);
|
||||
* \code sht11_val sht11;
|
||||
* sht11_read_sensor(&sht11, HUMIDITY|TEMPERATURE);
|
||||
* printf("%-6.2f °C %5.2f %% %5.2f %%\n", sht11.temperature, sht11.relhum, sht11.relhum_temp); \endcode
|
||||
*/
|
||||
uint8_t sht11_read_sensor(sht11_val_t *value, sht11_mode_t mode);
|
||||
|
||||
@ -62,7 +62,7 @@ double ltc4150_get_current_mA() {
|
||||
return 1000000000/(ltc4150_get_last_int_duration_us()*(_GFH * _R_SENSE));
|
||||
}
|
||||
|
||||
double ltc4150_get_total_mA() {
|
||||
double ltc4150_get_total_mAh() {
|
||||
return coulomb_to_mA(int_to_coulomb(int_count));
|
||||
}
|
||||
|
||||
@ -70,6 +70,10 @@ double ltc4150_get_avg_mA() {
|
||||
return (int_to_coulomb(int_count)*1000000000)/HWTIMER_TICKS_TO_US(last_int_time - start_time);
|
||||
}
|
||||
|
||||
int ltc4150_get_interval() {
|
||||
return HWTIMER_TICKS_TO_US(last_int_time - start_time);
|
||||
}
|
||||
|
||||
unsigned long ltc4150_get_intcount() {
|
||||
return int_count;
|
||||
}
|
||||
|
||||
@ -37,7 +37,6 @@ and the mailinglist (subscription via web site)
|
||||
* @note $Id: sht11.c 2396 2010-07-06 15:12:35Z ziegert $
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@ -46,6 +45,11 @@ and the mailinglist (subscription via web site)
|
||||
#include <sht11.h>
|
||||
#include <sht11-board.h>
|
||||
|
||||
//#define ENABLE_DEBUG (1)
|
||||
#include <debug.h>
|
||||
|
||||
float sht11_temperature_offset;
|
||||
|
||||
/**
|
||||
* @brief Perform measurement
|
||||
*
|
||||
@ -147,6 +151,7 @@ static uint8_t read_byte (uint8_t ack)
|
||||
value = value << 1;
|
||||
SHT11_SCK_HIGH;
|
||||
hwtimer_wait(SHT11_CLK_WAIT);
|
||||
|
||||
if (SHT11_DATA) {
|
||||
/* increase data by one when DATA is high */
|
||||
value++;
|
||||
@ -230,10 +235,10 @@ static uint8_t measure(uint8_t *p_value, uint8_t *p_checksum, uint8_t mode)
|
||||
uint8_t ack = 1;
|
||||
uint16_t i;
|
||||
|
||||
transmission_start();
|
||||
transmission_start();
|
||||
error = write_byte(mode);
|
||||
|
||||
hwtimer_wait(HWTIMER_MSEC);
|
||||
hwtimer_wait(HWTIMER_TICKS(1000));
|
||||
|
||||
/* wait untile sensor has finished measurement or timeout */
|
||||
for (i = 0; (i < SHT11_MEASURE_TIMEOUT) && (!error); i++) {
|
||||
@ -242,7 +247,7 @@ static uint8_t measure(uint8_t *p_value, uint8_t *p_checksum, uint8_t mode)
|
||||
if (!ack) {
|
||||
break;
|
||||
}
|
||||
hwtimer_wait(HWTIMER_MSEC);
|
||||
hwtimer_wait(HWTIMER_TICKS(1000));
|
||||
}
|
||||
error += ack;
|
||||
|
||||
@ -257,9 +262,10 @@ static uint8_t measure(uint8_t *p_value, uint8_t *p_checksum, uint8_t mode)
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void sht11_init(void) {
|
||||
sht11_temperature_offset = 0;
|
||||
mutex_init(&sht11_mutex);
|
||||
SHT11_INIT;
|
||||
hwtimer_wait(11 * HWTIMER_MSEC);
|
||||
hwtimer_wait(11 * HWTIMER_TICKS(1000));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t sht11_read_status(uint8_t *p_value, uint8_t *p_checksum) {
|
||||
@ -303,7 +309,9 @@ uint8_t sht11_read_sensor(sht11_val_t *value, sht11_mode_t mode) {
|
||||
const float T2 = +0.00008;
|
||||
|
||||
/* check for valid buffer */
|
||||
assert(value != NULL);
|
||||
if (value == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
value->temperature = 0;
|
||||
value->relhum = 0;
|
||||
@ -329,7 +337,7 @@ uint8_t sht11_read_sensor(sht11_val_t *value, sht11_mode_t mode) {
|
||||
}
|
||||
|
||||
if (mode & TEMPERATURE) {
|
||||
value->temperature = D1 + (D2 * ((float) temp_int));
|
||||
value->temperature = D1 + (D2 * ((float) temp_int)) + sht11_temperature_offset;
|
||||
}
|
||||
if (mode & HUMIDITY) {
|
||||
value->relhum = C1 + (C2 * ((float) humi_int)) + (C3 * ((float) humi_int) * ((float) humi_int));
|
||||
|
||||
@ -58,7 +58,7 @@ int main(void)
|
||||
// radio stack
|
||||
cc1100_init();
|
||||
cc1100_set_packet_handler(4, protocol_handler);
|
||||
cc1100_set_channel(10);
|
||||
cc1100_set_channel(0);
|
||||
// cc1100_set_output_power(5);
|
||||
printf("cc1100..[OK]\n");
|
||||
|
||||
@ -72,6 +72,7 @@ int main(void)
|
||||
puts(".");
|
||||
int result = cc1100_send_csmaca(1, 4, 2, i, sizeof(i));
|
||||
printf("%i\n", result);
|
||||
hwtimer_wait(1000 * 1000);
|
||||
}
|
||||
#else
|
||||
cc1100_set_address(1);
|
||||
|
||||
11
projects/default/Jamfile
Normal file
11
projects/default/Jamfile
Normal file
@ -0,0 +1,11 @@
|
||||
#
|
||||
# ukleos default project. Consists of a shell.
|
||||
#
|
||||
# Copyright (C) 2008, 2009 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
#
|
||||
|
||||
SubDir TOP projects default ;
|
||||
|
||||
Module default_project : main.c : shell posix_io uart0 shell_commands ps rtc sht11 ltc4150 cc110x auto_init ;
|
||||
|
||||
UseModule default_project ;
|
||||
38
projects/default/main.c
Normal file
38
projects/default/main.c
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (C) 2008, 2009, 2010 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <posix_io.h>
|
||||
#include <ltc4150.h>
|
||||
#include <shell.h>
|
||||
#include <shell_commands.h>
|
||||
#include <board_uart0.h>
|
||||
|
||||
int shell_readc() {
|
||||
char c = 0;
|
||||
posix_read(uart0_handler_pid, &c, 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
void shell_putchar(int c) {
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
posix_open(uart0_handler_pid, 0);
|
||||
ltc4150_start();
|
||||
|
||||
puts("Welcome to ukleos!");
|
||||
|
||||
shell_t shell;
|
||||
shell_init(&shell, NULL, shell_readc, shell_putchar);
|
||||
|
||||
shell_run(&shell);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
5
projects/laser/Jamfile
Normal file
5
projects/laser/Jamfile
Normal file
@ -0,0 +1,5 @@
|
||||
SubDir TOP projects laser ;
|
||||
|
||||
Module laser : main.c : sht11 swtimer auto_init ;
|
||||
|
||||
UseModule laser ;
|
||||
30
projects/laser/main.c
Normal file
30
projects/laser/main.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
#include <sht11.h>
|
||||
#include <board.h>
|
||||
#include <swtimer.h>
|
||||
#include <ltc4150.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
sht11_val_t sht11_val;
|
||||
uint8_t success = 0;
|
||||
|
||||
puts("");
|
||||
puts("LaSeR: Longterm Sensor Reader initialized.");
|
||||
puts("Printing \"temperature in °C;relative humidity;temperature compensated relative humidity\".");
|
||||
puts("");
|
||||
|
||||
ltc4150_start();
|
||||
|
||||
while (1) {
|
||||
success = sht11_read_sensor(&sht11_val, HUMIDITY|TEMPERATURE);
|
||||
if (!success) {
|
||||
printf("error;error;error\n");
|
||||
}
|
||||
else {
|
||||
printf("%.2f;%.2f;%.2f\n", sht11_val.temperature, sht11_val.relhum, sht11_val.relhum_temp);
|
||||
}
|
||||
LED_RED_TOGGLE;
|
||||
swtimer_usleep(60 * 1000*1000);
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,4 @@
|
||||
SubDir TOP projects pingpong ;
|
||||
# LOCATE_TARGET = $(SEARCH_SOURCE)/bin ;
|
||||
|
||||
Library pingpong : main.c ;
|
||||
|
||||
LinkLibraries $(BOARD).elf : pingpong ;
|
||||
Module pingpong : main.c ;
|
||||
UseModule pingpong ;
|
||||
|
||||
@ -15,13 +15,15 @@ void second_thread(void) {
|
||||
}
|
||||
}
|
||||
|
||||
char second_thread_stack[KERNEL_CONF_STACKSIZE_MAIN];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Hello world!\n");
|
||||
|
||||
msg m;
|
||||
|
||||
int pid = thread_create(KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "pong");
|
||||
int pid = thread_create(second_thread_stack, sizeof(second_thread_stack), PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "pong");
|
||||
|
||||
m.content.value = 1;
|
||||
|
||||
|
||||
@ -15,13 +15,15 @@ void second_thread(void) {
|
||||
}
|
||||
}
|
||||
|
||||
char second_thread_stack[8192];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("Hello world!\n");
|
||||
|
||||
msg m;
|
||||
|
||||
int pid = thread_create(8192, PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "pong");
|
||||
int pid = thread_create(second_thread_stack, sizeof(second_thread_stack), PRIORITY_MAIN-1, CREATE_WOUT_YIELD | CREATE_STACKTEST, second_thread, "pong");
|
||||
|
||||
m.content.value = 1;
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
set timeout 5
|
||||
|
||||
spawn board/msba2/tools/bin/pseudoterm $env(PORT)
|
||||
spawn pseudoterm $env(PORT)
|
||||
|
||||
expect {
|
||||
"Hello World!" {}
|
||||
|
||||
5
projects/test_cc110x_ng/Jamfile
Normal file
5
projects/test_cc110x_ng/Jamfile
Normal file
@ -0,0 +1,5 @@
|
||||
SubDir TOP projects test_cc110x_ng ;
|
||||
|
||||
Module test_cc110x_ng : main.c : cc110x_ng shell shell_commands transceiver ps rtc posix_io uart0 auto_init ;
|
||||
|
||||
UseModule test_cc110x_ng ;
|
||||
129
projects/test_cc110x_ng/main.c
Normal file
129
projects/test_cc110x_ng/main.c
Normal file
@ -0,0 +1,129 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <shell.h>
|
||||
#include <board_uart0.h>
|
||||
#include <posix_io.h>
|
||||
#include <thread.h>
|
||||
#include <board.h>
|
||||
#include <hwtimer.h>
|
||||
#include <swtimer.h>
|
||||
#include <msg.h>
|
||||
#include <transceiver.h>
|
||||
#include <cc1100_ng.h>
|
||||
|
||||
#define SHELL_STACK_SIZE (2048)
|
||||
#define RADIO_STACK_SIZE (2048)
|
||||
|
||||
#define SND_BUFFER_SIZE (100)
|
||||
#define RCV_BUFFER_SIZE (64)
|
||||
|
||||
#define SENDING_DELAY (1000)
|
||||
|
||||
char shell_stack_buffer[SHELL_STACK_SIZE];
|
||||
char radio_stack_buffer[RADIO_STACK_SIZE];
|
||||
|
||||
uint8_t snd_buffer[SND_BUFFER_SIZE][CC1100_MAX_DATA_LENGTH];
|
||||
|
||||
msg msg_q[RCV_BUFFER_SIZE];
|
||||
|
||||
static msg mesg;
|
||||
static transceiver_command_t tcmd;
|
||||
static radio_packet_t p;
|
||||
|
||||
void sender(char *count);
|
||||
void print_buffer(char *unused);
|
||||
|
||||
shell_t shell;
|
||||
const shell_command_t sc[] = {
|
||||
{"snd", "", sender},
|
||||
{"buffer", "", print_buffer},
|
||||
{NULL, NULL, NULL}};
|
||||
|
||||
void shell_runner(void) {
|
||||
shell_init(&shell, sc, uart0_readc, uart0_putc);
|
||||
posix_open(uart0_handler_pid, 0);
|
||||
shell_run(&shell);
|
||||
}
|
||||
|
||||
void sender(char *count) {
|
||||
unsigned int c, i;
|
||||
|
||||
mesg.type = SND_PKT;
|
||||
mesg.content.ptr = (char*) &tcmd;
|
||||
|
||||
tcmd.transceivers = TRANSCEIVER_CC1100;
|
||||
tcmd.data = &p;
|
||||
|
||||
p.length = CC1100_MAX_DATA_LENGTH;
|
||||
p.dst = 0;
|
||||
|
||||
sscanf(count, "snd %u", &c);
|
||||
for (i = 0; i < c; i++) {
|
||||
puts(".");
|
||||
p.data = snd_buffer[i % SND_BUFFER_SIZE];
|
||||
msg_send(&mesg, transceiver_pid, 1);
|
||||
swtimer_usleep(SENDING_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
void print_buffer(char *unused) {
|
||||
uint8_t i;
|
||||
extern radio_packet_t transceiver_buffer[];
|
||||
for (i = 0; i < TRANSCEIVER_BUFFER_SIZE; i++) {
|
||||
printf("[%u] %u # %u # %u\n", i, transceiver_buffer[i].processing, transceiver_buffer[i].length, transceiver_buffer[i].data[i]);
|
||||
}
|
||||
extern rx_buffer_t cc1100_rx_buffer[];
|
||||
for (i = 0; i < TRANSCEIVER_BUFFER_SIZE; i++) {
|
||||
printf("[%u] %u # %u \n", i, cc1100_rx_buffer[i].packet.length, cc1100_rx_buffer[i].packet.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void radio(void) {
|
||||
msg m;
|
||||
radio_packet_t *p;
|
||||
uint8_t i;
|
||||
|
||||
msg_init_queue(msg_q, RCV_BUFFER_SIZE);
|
||||
|
||||
while (1) {
|
||||
msg_receive(&m);
|
||||
if (m.type == PKT_PENDING) {
|
||||
p = (radio_packet_t*) m.content.ptr;
|
||||
printf("Packet waiting, process %p...\n", p);
|
||||
printf("\tLength:\t%u\n", p->length);
|
||||
printf("\tSrc:\t%u\n", p->src);
|
||||
printf("\tDst:\t%u\n", p->dst);
|
||||
|
||||
for (i = 0; i < p->length; i++) {
|
||||
printf("%02X ", p->data[i]);
|
||||
}
|
||||
p->processing--;
|
||||
printf("\n");
|
||||
}
|
||||
else if (m.type == ENOBUFFER) {
|
||||
puts("Transceiver buffer full");
|
||||
}
|
||||
else {
|
||||
puts("Unknown packet received");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
int radio_pid;
|
||||
uint8_t i;
|
||||
for (i = 0; i < SND_BUFFER_SIZE; i++) {
|
||||
memset(snd_buffer[i], i, CC1100_MAX_DATA_LENGTH);
|
||||
}
|
||||
thread_create(shell_stack_buffer, SHELL_STACK_SIZE, PRIORITY_MAIN-1, CREATE_STACKTEST, shell_runner, "shell");
|
||||
radio_pid = thread_create(radio_stack_buffer, RADIO_STACK_SIZE, PRIORITY_MAIN-2, CREATE_STACKTEST, radio, "radio");
|
||||
transceiver_init(TRANSCEIVER_CC1100);
|
||||
transceiver_start();
|
||||
transceiver_register(TRANSCEIVER_CC1100, radio_pid);
|
||||
|
||||
while (1) {
|
||||
// LED_GREEN_TOGGLE;
|
||||
hwtimer_wait(1000 * 1000);
|
||||
}
|
||||
}
|
||||
13
projects/test_cc110x_ng/tests/hello-world
Executable file
13
projects/test_cc110x_ng/tests/hello-world
Executable file
@ -0,0 +1,13 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout 5
|
||||
|
||||
spawn pseudoterm $env(PORT)
|
||||
|
||||
expect {
|
||||
"Hello World!" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
puts "\nTest successful!\n"
|
||||
|
||||
5
projects/test_hwtimer_basic/Jamfile
Normal file
5
projects/test_hwtimer_basic/Jamfile
Normal file
@ -0,0 +1,5 @@
|
||||
SubDir TOP projects test_hwtimer ;
|
||||
|
||||
Module test_hwtimer : main.c : hwtimer ;
|
||||
|
||||
UseModule test_hwtimer ;
|
||||
29
projects/test_hwtimer_basic/main.c
Normal file
29
projects/test_hwtimer_basic/main.c
Normal file
@ -0,0 +1,29 @@
|
||||
#include <stdio.h>
|
||||
#include <hwtimer.h>
|
||||
#include <kernel.h>
|
||||
#include <board.h>
|
||||
|
||||
void callback(void* ptr) {
|
||||
puts((char*)ptr);
|
||||
}
|
||||
|
||||
extern uint32_t hwtimer_now();
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("hwtimer test project.");
|
||||
|
||||
puts("Initializing hwtimer...");
|
||||
hwtimer_init();
|
||||
|
||||
puts("Initializing hwtimer [OK].");
|
||||
|
||||
|
||||
// while (TA0R < 20000);
|
||||
|
||||
hwtimer_set(20000LU, callback, (void*)"callback1");
|
||||
hwtimer_set(50000LU, callback, (void*)"callback2");
|
||||
hwtimer_set(30000LU, callback, (void*)"callback3");
|
||||
|
||||
puts("hwtimer set.");
|
||||
}
|
||||
17
projects/test_hwtimer_basic/tests/test_hwtimer.py
Executable file
17
projects/test_hwtimer_basic/tests/test_hwtimer.py
Executable file
@ -0,0 +1,17 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import pexpect
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
child = pexpect.spawn ("board/msba2/tools/bin/pseudoterm %s" % os.environ["PORT"])
|
||||
|
||||
null = open('/dev/null', 'wb')
|
||||
subprocess.call(['jam', 'reset'], stdout=null)
|
||||
|
||||
child.expect ('OK\r\n');
|
||||
child.expect ('callback1\r\n');
|
||||
child.expect ('callback3\r\n');
|
||||
child.expect ('callback2\r\n');
|
||||
print("Test successful!")
|
||||
|
||||
@ -29,9 +29,9 @@ void shell_putchar(int c) {
|
||||
}
|
||||
|
||||
const shell_command_t shell_commands[] = {
|
||||
{"start_test", print_teststart},
|
||||
{"end_test", print_testend},
|
||||
{NULL, NULL}
|
||||
{"start_test", "", print_teststart},
|
||||
{"end_test", "", print_testend},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
@ -43,10 +43,8 @@ int main(void) {
|
||||
posix_open(uart0_handler_pid, 0);
|
||||
|
||||
shell_t shell;
|
||||
shell_init(&shell, shell_readc, shell_putchar);
|
||||
shell_init(&shell, shell_commands, shell_readc, shell_putchar);
|
||||
|
||||
shell.command_list = shell_commands;
|
||||
|
||||
shell_run(&shell);
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
SubDir TOP projects test_sleep ;
|
||||
|
||||
Module test_sleep : main.c : hwtimer ;
|
||||
Module test_sleep : main.c : hwtimer ps ;
|
||||
|
||||
UseModule test_sleep ;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include <thread.h>
|
||||
#include <kernel.h>
|
||||
#include <hwtimer.h>
|
||||
#include <ps.h>
|
||||
|
||||
int integer = 0;
|
||||
int i = 0;
|
||||
@ -11,21 +12,20 @@ void second_thread(void) {
|
||||
while(1) {
|
||||
integer++;
|
||||
printf("sleeper: running. integer=%i, i=%i.\n", integer, i);
|
||||
if (integer % 100 == 0) {
|
||||
if (integer % 1 == 0) {
|
||||
printf("Going to sleep.\n");
|
||||
thread_sleep();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char second_thread_stack[KERNEL_CONF_STACKSIZE_DEFAULT*2];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
hwtimer_init();
|
||||
|
||||
printf("Hello world!\n");
|
||||
|
||||
int pid = thread_create(KERNEL_CONF_STACKSIZE_DEFAULT, PRIORITY_MAIN-1, CREATE_STACKTEST | CREATE_SLEEPING | CREATE_WOUT_YIELD, second_thread, "sleeper");
|
||||
int pid = thread_create(second_thread_stack, sizeof(second_thread_stack), PRIORITY_MAIN-1, CREATE_STACKTEST | CREATE_SLEEPING | CREATE_WOUT_YIELD, second_thread, "sleeper");
|
||||
|
||||
if (pid < 0) {
|
||||
puts("Error creating second_thread! Stopping test.");
|
||||
@ -35,9 +35,14 @@ int main(void)
|
||||
while(1) {
|
||||
i++;
|
||||
printf(" main: running. integer=%i, i=%i.\n", integer, i);
|
||||
if (i % 100 == 0) {
|
||||
if (i % 1 == 0) {
|
||||
thread_print_all();
|
||||
printf("Waking up sleeper.\n");
|
||||
thread_wakeup(pid);
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
thread_print_all();
|
||||
>>>>>>> master
|
||||
thread_yield();
|
||||
}
|
||||
}
|
||||
|
||||
12
projects/test_suite/Jamfile
Normal file
12
projects/test_suite/Jamfile
Normal file
@ -0,0 +1,12 @@
|
||||
#
|
||||
# Copyright (C) 2008, 2009, 2010 FU Berlin
|
||||
#
|
||||
# Author: Kaspar Schleiser <kaspar.schleiser@fu-berlin.de>
|
||||
#
|
||||
|
||||
SubDir TOP projects test_suite ;
|
||||
|
||||
Module test_suite : test_suite.c mutex_trylock_fail.c thread_sleep.c
|
||||
: shell posix_io ps uart0 hwtimer ;
|
||||
|
||||
UseModule test_suite ;
|
||||
30
projects/test_suite/mutex_trylock_fail.c
Normal file
30
projects/test_suite/mutex_trylock_fail.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <stdio.h>
|
||||
#include <mutex.h>
|
||||
|
||||
#include <thread.h>
|
||||
#include <flags.h>
|
||||
#include <kernel.h>
|
||||
|
||||
mutex_t mutex;
|
||||
|
||||
static void second_thread(void) {
|
||||
puts(" 2nd: trying to lock mutex...");
|
||||
mutex_trylock(&mutex);
|
||||
puts(" 2nd: done.");
|
||||
}
|
||||
|
||||
static char second_stack[KERNEL_CONF_STACKSIZE_MAIN];
|
||||
|
||||
void mutex_trylock_fail(char* cmdline)
|
||||
{
|
||||
puts("main: locking mutex...");
|
||||
mutex_lock(&mutex);
|
||||
|
||||
puts("main: creating thread...");
|
||||
thread_create(second_stack, KERNEL_CONF_STACKSIZE_MAIN, PRIORITY_MAIN-1, CREATE_STACKTEST, second_thread, "nr2");
|
||||
|
||||
puts("main: thread created. Unlocking mutex...");
|
||||
mutex_unlock(&mutex, true);
|
||||
|
||||
puts("main: mutex unlocked.");
|
||||
}
|
||||
58
projects/test_suite/test_suite.c
Normal file
58
projects/test_suite/test_suite.c
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (C) 2008, 2009, 2010 Kaspar Schleiser <kaspar@schleiser.de>
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include <posix_io.h>
|
||||
#include <shell.h>
|
||||
#include <board_uart0.h>
|
||||
|
||||
void print_teststart(char* str) {
|
||||
printf("[TEST_START]\n");
|
||||
}
|
||||
|
||||
void print_testend(char* str) {
|
||||
printf("[TEST_END]\n");
|
||||
}
|
||||
|
||||
int shell_readc() {
|
||||
char c = 0;
|
||||
posix_read(uart0_handler_pid, &c, 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
void shell_putchar(int c) {
|
||||
putchar(c);
|
||||
}
|
||||
|
||||
void mutex_trylock_fail(char* cmdline);
|
||||
void test_thread_sleep(char* line);
|
||||
|
||||
const shell_command_t shell_commands[] = {
|
||||
{"start_test", "", print_teststart},
|
||||
{"end_test", "", print_testend},
|
||||
{"mutex_trylock_fail", "", mutex_trylock_fail},
|
||||
{"thread_sleep", "", test_thread_sleep},
|
||||
{NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
int main(void) {
|
||||
//printf("Moin. build on %s %s SVN-Revision: %s\n", kernel_builddate, kernel_buildtime, kernel_svnrevision);
|
||||
printf("test_shell.\n");
|
||||
|
||||
board_uart0_init();
|
||||
|
||||
posix_open(uart0_handler_pid, 0);
|
||||
|
||||
shell_t shell;
|
||||
shell_init(&shell, shell_commands, shell_readc, shell_putchar);
|
||||
|
||||
shell_run(&shell);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
30
projects/test_suite/tests/01-basic
Executable file
30
projects/test_suite/tests/01-basic
Executable file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout 5
|
||||
|
||||
spawn pseudoterm $env(PORT)
|
||||
|
||||
expect {
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "start_test\n"
|
||||
expect {
|
||||
"\[TEST_START\]" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
expect {
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "end_test\n"
|
||||
|
||||
expect {
|
||||
"\[TEST_END\]" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
puts "\nTest successful!\n"
|
||||
81
projects/test_suite/tests/02-inputlength-regression
Executable file
81
projects/test_suite/tests/02-inputlength-regression
Executable file
@ -0,0 +1,81 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout 1
|
||||
|
||||
spawn pseudoterm $env(PORT)
|
||||
|
||||
sleep 1
|
||||
|
||||
expect {
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "123456789012345678901234567890123456789012345678901234567890\n"
|
||||
expect {
|
||||
"shell: command not found." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "123456789012345678901234567890123456789012345678901234567890\n"
|
||||
expect {
|
||||
"shell: command not found." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "123456789012345678901234567890123456789012345678901234567890\n"
|
||||
expect {
|
||||
"shell: command not found." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "123456789012345678901234567890123456789012345678901234567890\n"
|
||||
expect {
|
||||
"shell: command not found." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "123456789012345678901234567890123456789012345678901234567890\n"
|
||||
expect {
|
||||
"shell: command not found." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "123456789012345678901234567890123456789012345678901234567890\n"
|
||||
expect {
|
||||
"shell: command not found." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "123456789012345678901234567890123456789012345678901234567890\n"
|
||||
expect {
|
||||
"shell: command not found." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "123456789012345678901234567890123456789012345678901234567890\n"
|
||||
expect {
|
||||
"shell: command not found." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
|
||||
send "start_test\n"
|
||||
expect {
|
||||
"\[TEST_START\]" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
expect {
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "end_test\n"
|
||||
|
||||
expect {
|
||||
"\[TEST_END\]" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
puts "\nTest successful!\n"
|
||||
20
projects/test_suite/tests/02-unknown-command
Executable file
20
projects/test_suite/tests/02-unknown-command
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout 2
|
||||
|
||||
spawn pseudoterm $env(PORT)
|
||||
|
||||
sleep 1
|
||||
|
||||
expect {
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "some_definately_unknown_command\n"
|
||||
expect {
|
||||
"shell: command "some_definately_unknown_command" not found." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
puts "\nTest successful!\n"
|
||||
56
projects/test_suite/tests/03-mutex_trylock_fail
Executable file
56
projects/test_suite/tests/03-mutex_trylock_fail
Executable file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout 5
|
||||
|
||||
spawn pseudoterm $env(PORT)
|
||||
|
||||
expect {
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "start_test\n"
|
||||
expect {
|
||||
"\[TEST_START\]" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
expect {
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "mutex_trylock_fail\n"
|
||||
expect {
|
||||
"main: locking mutex..." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
expect {
|
||||
"main: creating thread..." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
expect {
|
||||
"2nd: trying to lock mutex..." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
expect {
|
||||
"2nd: done." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
expect {
|
||||
"main: thread created. Unlocking mutex..." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
expect {
|
||||
"main: mutex unlocked." {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "end_test\n"
|
||||
|
||||
expect {
|
||||
"\[TEST_END\]" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
puts "\nTest successful!\n"
|
||||
70
projects/test_suite/tests/04-thread_sleep
Executable file
70
projects/test_suite/tests/04-thread_sleep
Executable file
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/expect
|
||||
|
||||
set timeout 5
|
||||
|
||||
spawn pseudoterm $env(PORT)
|
||||
|
||||
expect {
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "start_test\n"
|
||||
expect {
|
||||
"\[TEST_START\]" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
expect {
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "thread_sleep\n"
|
||||
expect {
|
||||
" main: running. integer=0, i=1." {}
|
||||
" main: running. integer=0, i=2." {}
|
||||
"Waking up sleeper." {}
|
||||
"sleeper: running. integer=1, i=2." {}
|
||||
"sleeper: running. integer=2, i=2." {}
|
||||
"Going to sleep." {}
|
||||
" main: running. integer=2, i=3." {}
|
||||
" main: running. integer=2, i=4." {}
|
||||
"Waking up sleeper." {}
|
||||
"Woke up!" {}
|
||||
"sleeper: running. integer=3, i=4." {}
|
||||
"sleeper: running. integer=4, i=4." {}
|
||||
"Going to sleep." {}
|
||||
" main: running. integer=4, i=5." {}
|
||||
" main: running. integer=4, i=6." {}
|
||||
"Waking up sleeper." {}
|
||||
"Woke up!" {}
|
||||
"sleeper: running. integer=5, i=6." {}
|
||||
"sleeper: running. integer=6, i=6." {}
|
||||
"Going to sleep." {}
|
||||
" main: running. integer=6, i=7." {}
|
||||
" main: running. integer=6, i=8." {}
|
||||
"Waking up sleeper." {}
|
||||
"Woke up!" {}
|
||||
"sleeper: running. integer=7, i=8." {}
|
||||
"sleeper: running. integer=8, i=8." {}
|
||||
"Going to sleep." {}
|
||||
" main: running. integer=8, i=9." {}
|
||||
" main: running. integer=8, i=10." {}
|
||||
"Waking up sleeper." {}
|
||||
"Woke up!" {}
|
||||
"sleeper: running. integer=9, i=10." {}
|
||||
"sleeper: running. integer=10, i=10." {}
|
||||
"Going to sleep." {}
|
||||
">$" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
send "end_test\n"
|
||||
|
||||
expect {
|
||||
"\[TEST_END\]" {}
|
||||
timeout { exit 1 }
|
||||
}
|
||||
|
||||
puts "\nTest successful!\n"
|
||||
39
projects/test_suite/thread_sleep.c
Normal file
39
projects/test_suite/thread_sleep.c
Normal file
@ -0,0 +1,39 @@
|
||||
#include <stdio.h>
|
||||
#include <thread.h>
|
||||
#include <kernel.h>
|
||||
|
||||
static int integer = 0;
|
||||
static int i = 0;
|
||||
|
||||
static void second_thread(void) {
|
||||
while(1) {
|
||||
integer++;
|
||||
printf("sleeper: running. integer=%i, i=%i.\n", integer, i);
|
||||
if (integer % 2 == 0) {
|
||||
printf("Going to sleep.\n");
|
||||
thread_sleep();
|
||||
printf("Woke up!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char second_thread_stack[KERNEL_CONF_STACKSIZE_DEFAULT*2];
|
||||
|
||||
void test_thread_sleep(char* line)
|
||||
{
|
||||
int pid = thread_create(second_thread_stack, sizeof(second_thread_stack), PRIORITY_MAIN-1, CREATE_STACKTEST | CREATE_SLEEPING | CREATE_WOUT_YIELD, second_thread, "sleeper");
|
||||
|
||||
if (pid < 0) {
|
||||
puts("Error creating second_thread! Stopping test.");
|
||||
while(1);
|
||||
}
|
||||
|
||||
while(i < 10) {
|
||||
i++;
|
||||
printf(" main: running. integer=%i, i=%i.\n", integer, i);
|
||||
if (i % 2 == 0) {
|
||||
printf("Waking up sleeper.\n");
|
||||
thread_wakeup(pid);
|
||||
}
|
||||
}
|
||||
}
|
||||
5
projects/test_swtimer_basic/Jamfile
Normal file
5
projects/test_swtimer_basic/Jamfile
Normal file
@ -0,0 +1,5 @@
|
||||
SubDir TOP projects expect_swtimer ;
|
||||
|
||||
Module expect_swtimer : main.c : swtimer ;
|
||||
|
||||
UseModule expect_swtimer ;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user