/*
Copyright 2003/2004, Freie Universitaet Berlin. All rights reserved.

These sources were developed at the Freie Universität Berlin, Computer
Systems and Telematics group.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
 
- Neither the name of Freie Universitaet Berlin (FUB) nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

This software is provided by FUB and the contributors on an "as is"
basis, without any representations or warranties of any kind, express
or implied including, but not limited to, representations or
warranties of non-infringement, merchantability or fitness for a
particular purpose. In no event shall FUB or contributors be liable
for any direct, indirect, incidental, special, exemplary, or
consequential damages (including, but not limited to, procurement of
substitute goods or services; loss of use, data, or profits; or
business interruption) however caused and on any theory of liability,
whether in contract, strict liability, or tort (including negligence
or otherwise) arising in any way out of the use of this software, even
if advised of the possibility of such damage.

This implementation was developed by the CST group at the FUB.
Contributors: Marco Hutta

For documentation and questions please use the web site
http://www.scatterweb.net and the mailinglist
scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website).
Berlin, 2003/2004/2005
*/

/** \page lpm Power saving
 **
 ** The sensorboard features low power modes to reduce power consumption.<br> 
 ** This increases battery-powered lifetime up to years and makes it even 
 ** possible to run the sensorboard solely with a goldcap/solar cell combo.
 **
 ** Following units can be switched off to reduce power consumption:
 **
 ** <table>
 ** <tr><th>Unit</th><th>Power consumption</th>
 **     <th>Corresponding function</th><th>Comments</th></tr>
 **
 ** <tr><td>Radio</td><td>4,7 - 5,2 ma</td>
 **      <td>::disableRadio, ::enableRadio</td><td></td></tr>
 ** <tr><td>Sensors</td><td>2,9 ma</td>
 **      <td>::disableSensors, ::enableSensors</td><td></td></tr>
 ** <tr><td>ADU</td><td>1,2 ma</td>
 **      <td>::disableADU, ::enableADU</td><td>Radio Carrier Detect and Microphone(ESB) depend on the ADU</td></tr>
 ** </td></tr>
 ** </table>
 **
 ** The MSP430 itself goes to sleep when nothing more has to be done (see super loop in main).
 ** Power consumption with everything disabled (Radio, Sensor, ADU) goes below 1 mA. 
 **  
 ** There exists an <a href="../data/ESB_Strombedarf.xls">Excel sheet</a>
 ** with detailed power consumption for every device. You can also calculate 
 ** the lifetime for batteries with a given configuration. 
 **
 ** A good strategy to sleep periodically and reduce power consumption while
 ** keeping up the sensor network must be still found.
 **/
 
/** \file firmware.h
 ** \ingroup Firmware
 ** \brief This file contains special definitions & configuration options for the firmware and includes all other headers.
 **/

/** \defgroup Firmware Firmware

The firmware provides abstract functions to 
interface and use the hardware, contains the main execution loop + interrupts 
and provides some os-like concepts. 
The firmware supports all four ScatterWeb/MSP430 devices: 
ESB, USB430Stick, EWS430Stick, ECR430

The first reprogramming concept which produced the firmware/application seperation
was abandoned for two main reasons:

- It relied on a stable almost never changing firmware. At the moment this is
  absolutely wrong and its questionable if it will ever be.
- It relied on the compiler/linker to produce always the same assembler output
  for the firmware when it gets always the same sources/object files.
  This was only partially right (it depended on too many factors: compiler version,
  compiler flags, even the machine the compiler is running on, ...) and could
  be wrong under other or future conditions.

Perhaps one needs to write his own compiler/linker (or at least modify an existing one)
to really seperate these two software parts on a MCU cleanly.

*/
//@{
//@}
 
#ifndef ScatterWeb_System
#define ScatterWeb_System

// Must be either DCO_2458KHZ DCO_4506KHZ
#define DCO_4506KHZ
//#define DCO_2458KHZ

typedef unsigned char     UINT8;
typedef unsigned int      UINT16;
typedef unsigned long     UINT32;

/** \brief Temperature type (built on a signed int). It's a signed (twos complement) 
 **        fixed point value with 8 bits before comma and 7 bits after. So Bit 15 is
 **        sign, Bit14-7 is before comma and Bit 6-0 after comma. 
 **/   
typedef union { unsigned int u; signed int s; } temp_t; 
/// \name Several predefined function pointer types. 
//@{
typedef void(*fp_t)();                      ///< For functions like: void function(void).
typedef void(*fp_string_t)(UINT8*); ///< For functions like: form: void function(UINT8*)
typedef void(*fp_char_t)(UINT8);    ///< For functions like: void function(UINT8)
typedef void(*fp_int_t)(UINT16);      ///< For functions like: void function(UINT16)
typedef void(*fp_vp)(void*);                ///< For functions like: void function(void*).
//@}
// Bool
enum {
  True = 1,
  False = 0,
};
typedef char bool;
/// \name Buffer sizes
//@{
#define TERM_BUFSIZE        (82)  ///< Maximum size for normal terminal replies.
#define SERIAL_BUFSIZE      (82)  ///< Maximum size of a line received by uart, rest will be cut.
#define RADIO_RXBUF_SIZE    (270) ///< Maximum size of packets that can be received, header included is 8 bytes.
#define RADIO_TXBUF_SIZE    (400) ///< Size of the TX ring buffer.
#define ROUTING_TABLE_SIZE  (20) ///< Size of routing table entries, each entry is 10 bytes long.
#define MAX_TIMERS          (20) ///< Maximum number of timers, each timer requires 6 bytes of RAM (==sizeof(::timerEntry)).
#define MAX_TASKS           (10) ///< Maximum number of tasks, each entry is 10 bytes.
//@}

// Check if any device was specified, should be done in the makefiles with var $DEVICE.
#if !(defined(ESB) || defined(eGate) || defined(ECR) || defined(EYE))
#error "No device specified: ECR, ESB, EYE, eGate"
#endif

/// \name Callback types
/// Use these with ::registerCallback().
//@{

#define C_SERIAL              1 ///< Gets called everytime a whole line is received via serial port. 
#define C_RADIO               2 ///< Gets called everytime an unknown packet (not handled by the firmware) is received. 
#define C_SENSOR              3 ///< Gets called for sensor values.

#define NUMBER_CALLBACKS	    4 ///< The ::callbacks[] Array will get this size.

extern fp_vp callbacks[];    ///< Table where callbacks are hold, defined in main.c
//@}

/*
 * Registers callback
 *
 * @return True always
 *    
 */
bool System_registerCallback( UINT8 type, void(*fp_t)() ); 

/// \name Special section definitions for linking
//@{
#define INFOMEM            __attribute__((section(".infomem")))
#define INFOMEMNOBITS      __attribute__((section(".infomemnobits")))
//@}

/// \name Standard bit manipulation macros.
//@{
#define   SET(x, y)     ((x) |= (y))
#define   CLEAR(x, y)   ((x) &= (~y))
//@}

/// \name Module flags for low power management
//@{

#define MF_SCOS       (0x0001) ///< Set if scos_heartbeat should be called.
#define MF_RADIO_RX   (0x0002) ///< Set if radio_rx_heartbeat should be called.
#define MF_RADIO_TX   (0x0004) ///< Set if radio_tx_heartbeat should be called.
#define MF_TIMER      (0x0008) ///< Set if timer_heartbeat should be called.
#define MF_SERIAL_RX  (0x0010) ///< Set if a serial line is complete.
#define MF_SENSORS    (0x0020) ///<
#define MF_CAM        (0x0040) ///<
#define MF_RC5        (0x0080) ///< Set if a RC5 code is received via IR Receiver.

extern volatile UINT16 runModule;

#define WAKEUPLPM1(irqname, bit)  do {     \
    __asm__ __volatile__ ("bic %0, .L__FrameOffset_" #irqname "(r1)": : "i" ((uint16_t)LPM1_bits)); \
    runModule |= bit; \
    }while(0)

//@}

#if defined(ESB) || defined(EYE)
void cl_startConversion();
#endif

/*
 * Returns temperature
 *
 * @return current temperature
 *    
 */
#if defined(ESB) || defined(EYE) || defined(ECR)
temp_t System_getTemperature();
#endif

extern volatile UINT16 rxpTemp;  ///< Last updated RXPower AD value.
extern volatile UINT16 rxpValue; ///< RXPower AD value for last received packet, cleared by ::rxClear().

#if defined(ESB) || defined(EYE)
#define MICIFG    (0x01)
#define MICIE     (0x02)
extern volatile UINT8 MIC; ///< 0x01 is like IFG, 0x02 like IE and will set sensorFlags.MIC
#define MICVOLTAGE        (ADC12MEM2)
#define EXTERNVOLTAGE     (ADC12MEM3)
#define BATTERYVOLTAGE    (ADC12MEM4)
#define RXPVOLTAGE        (ADC12MEM5)
#endif

#if defined(ECR)
#define BATTERYVOLTAGE    (ADC12MEM4)
#endif

/*
 * Sets DCO
 *
 * @return True always
 *    
 */
bool System_setDCO();

/// \name 
//@{

#define STARTUP_POR       (0) ///< Power on or reset button.
#define STARTUP_SWRESET   (1) ///< call via reset().
#define STARTUP_REPROGRAM (2) ///< reprogramming
#define STARTUP_PANIC     (3) ///< call via wd_panic(). All states <=STARTUP_PANIC are considered OK!
#define STARTUP_WATCHDOG  (4) ///< Reason for reset was watchdog expiry.
#define STARTUP_KEYV      (5) ///< Flash control register key violation.
#define STARTUP_UNKNOWN   (6) ///< Unknown type of reset.
#define WDS_RUNNING       (0xAB01) ///< System at startup.
#define WDS_SWRESET       (0xAB02) ///< Software sets this shortly before writing bad value into FCTL3 to recognize a wanted reset.
#define WDS_REPROGRAM     (0xAB03)
#define WDS_PANIC         (0xAB04)
//@}

/// \name Reset & Watchdog control.
/** 
High byte of WDTCTL must be written as 0x5A (WDTPW) to avoid a reset.
High byte of WDTCTL always reads as 0x69, so WDTCTL |= wont work and
generate resets!

use startWatchdog() to start the WDT and to keep the watchdog alive at least 
1000 ms after the last startWatchdog() call; or stop the Watchdog, else => reset
1000ms, WDT is clocked by fACLK (assumed 32KHz)
*/
//@{

/*
 * Starts watchdog
 *
 * @return True always
 *    
 */
bool System_startWatchdog();

/*
 * Stops watchdog
 *
 * @return True always
 *    
 */
bool System_stopWatchdog();

/*
 * Resets System
 *
 * @return True always
 *    
 */
bool System_reset();         
//@}

/// \name Initialization
//@{

/*
 * Checks the reset
 *
 * @return pointer of reset message 
 *    
 */
const UINT8* System_resetReason();
//@}

/// \name Panic.
//@{

/*
 * Sets panic flag
 *
 * @return True always 
 *    
 */
bool System_panic(const char *fmt, ...);

/*
 * Checks panic flag
 *
 * @return pointer of panic message
 *    
 */
UINT8* System_panicReason(UINT16 n);

/*
 * Clears the panic flags
 *
 * @return True always 
 *    
 */
bool System_panicClear();

//@}

/* 
 * This member supports the ScatterWeb infrastructure
 * and is not intended to be used directly from your code.
 */
UINT16 System_reprogram();

#include <stdarg.h>

/*
 * Waits
 *
 * @return True always 
 *    
 */
bool System_wait(UINT32 w);

/*
 * Waits which is more precise than wait
 * because it uses TimerA to produce its interval, also blocking.
 *
 * @return True always 
 *    
 */
bool System_waitA(UINT16 i);

#define INIT_FCS  0xffff   /* Initial FCS value */

/* 
 * This member supports the ScatterWeb infrastructure
 * and is not intended to be used directly from your code.
 */
UINT16 System_crcCalc(UINT16 fcs, UINT8 const *buf, UINT16 len);

/* 
 * This member supports the ScatterWeb infrastructure
 * and is not intended to be used directly from your code.
 */
UINT16 System_ccittFcs(UINT16 fcs, UINT8 c);

/* Include all headers here so other files only need to include this file. */
#include <msp430x14x.h>
#include <io.h>
#include <signal.h>
#include <stdlib.h>

#if defined(ECR)
#include "../lib/ecr/programming.h"
#include "../lib/ecr/flasher.h"
#elif defined(ESB)
#include "../lib/esb/programming.h"
#include "../lib/esb/flasher.h"
#elif defined(EYE)
#include "../lib/eye/programming.h"
#include "../lib/eye/flasher.h"
#elif defined(eGate)
#include "../lib/egate/programming.h"
#include "../lib/egate/flasher.h"
#endif

#include "ScatterWeb.Configuration.h"
#include "ScatterWeb.Data.h"
#include "ScatterWeb.Timers.h"
#include "ScatterWeb.Time.h"
#include "ScatterWeb.IO.h"
#include "ScatterWeb.Comm.h"
#include "ScatterWeb.Net.h"
#include "ScatterWeb.Messaging.h"
#include "ScatterWeb.Threading.h"
#include "ScatterWeb.String.h"

#endif
